CLI & Agent

Use the optional BlazeRules command-line binaries — the smoke driver and the multi-instance local ingest agent — and configure agent instances from YAML.

BlazeRules ships command-line binaries for local operation: a smoke driver for sanity-checking a rule set, and a local ingest agent that pulls records from HTTP, a tailed file, or stdin and runs them through the engine. This page covers building them and — for the agent — its instances: configuration.

🚧

These are convenience binaries, not the product

BlazeRules is a library, not a service. The CLI tools exist to make local testing and small ingest setups easy; they are not a hosted runtime, and they don't change how the engine evaluates rules. For production you normally embed the engine (C++ API / Python API).

The smoke driver

blazerules_driver loads a rule set and runs a quick evaluation pass — the fastest way to confirm a YAML file compiles and produces decisions. It is built alongside the core:

cmake --build cmake-build-release --target blazerules_core blazerules blazerules_driver -j
./cmake-build-release/blazerules_driver rules.yaml

If the rule set has malformed YAML, duplicate rule IDs, or references to missing lookups, the driver surfaces the load error here — before any of it reaches a real pipeline.

The ingest agent

blazerules_agent runs one or more instances, each reading from an input source, batching records, evaluating them against a rule set, optionally de-duplicating, and writing decisions out. Build it with the agent flag:

cmake -S . -B cmake-build-release -G Ninja
cmake --build cmake-build-release --target blazerules_agent -j

For the full list of flags, defaults, and valid values, use API and CLI Values Reference.

How an instance flows

flowchart LR
  input["input: http / file_tail / stdin"] --> batch["batch: batch_size + flush_ms"]
  batch --> engine["engine: load_rules(rules)"]
  engine --> dedupe["dedupe: key_fields within ttl_seconds"]
  dedupe --> output["output: ndjson / stdout"]

Each instance loads its own rules: file and accumulates incoming records until it has batch_size of them or flush_ms elapses, then evaluates the batch in one call. When dedupe.enabled is set, records repeating the same key_fields within ttl_seconds are dropped before evaluation.

input.type or --input selects the adapter: http, file_tail, or stdin. source / --source is a metadata label attached to wrapped log records and decisions; it does not select the input adapter.

instances: configuration reference

The agent reads a top-level instances: block (a list) from a YAML file. Each entry accepts:

KeyTypeRequiredMeaning
namestringyesInstance label.
rulespathyesRule YAML this instance evaluates against.
batch_sizeintyesRecords buffered before a forced flush.
flush_msintyesMax milliseconds to wait before flushing a partial batch.
servicestringnoFree-form service label attached to output.
sourcestringnoFree-form source label attached to output.
input.typeenumyeshttp | file_tail | stdin.
input.hoststringfor httpBind host (e.g. 127.0.0.1).
input.portintfor httpBind port.
input.pathpathfor file_tailFile to tail.
output.typeenumyesndjson | stdout.
output.pathpathfor ndjsonDestination NDJSON file.
dedupe.enabledboolnoTurn de-duplication on.
dedupe.key_fieldslistwith dedupeFields whose combination identifies a duplicate.
dedupe.ttl_secondsintwith dedupeWindow during which repeats are dropped.
📘

stdin is supported too

The example below shows http and file_tail inputs. stdin is also a valid input.type — pipe NDJSON into the agent and route decisions to stdout for quick local experiments.

A real two-instance configuration

This is the instances: block from the repository's rules.yaml:

instances:
  - name: payments-http
    rules: rules.yaml
    batch_size: 4096
    flush_ms: 50
    service: payments-api
    source: http-json
    input:
      type: http
      host: 127.0.0.1
      port: 9480
    output:
      type: ndjson
      path: decisions-payments.ndjson
    dedupe:
      enabled: true
      key_fields: [event_id]
      ttl_seconds: 86400
  - name: checkout-log-tail
    rules: rules.yaml
    batch_size: 2048
    flush_ms: 250
    service: checkout
    source: pod-stdout
    input:
      type: file_tail
      path: app.log
    output:
      type: stdout
    dedupe:
      enabled: true
      key_fields: [event_id]
      ttl_seconds: 3600

payments-http accepts JSON over HTTP on 127.0.0.1:9480, batches up to 4096 records (or every 50 ms), and appends decisions to decisions-payments.ndjson, de-duplicating by event_id for a day. checkout-log-tail tails app.log, batches more loosely (2048 / 250 ms), and prints decisions to stdout with a one-hour dedupe window.

CLI flags

Run a multi-instance config:

./cmake-build-release/blazerules_agent --config rules.yaml

Or run one instance directly from flags:

./cmake-build-release/blazerules_agent \
  --name payments-http \
  --rules rules.yaml \
  --input http \
  --host 127.0.0.1 \
  --port 9480 \
  --batch-size 4096 \
  --flush-ms 50 \
  --output ndjson \
  --output-path decisions-payments.ndjson \
  --service payments-api \
  --source http-json \
  --dedupe-key event_id \
  --dedupe-ttl-seconds 86400

Single-instance flags are --rules, --input stdin|file_tail|http, --path, --host, --port, --batch-size, --flush-ms, --output stdout|ndjson, --output-path, --service, --source, repeated --dedupe-key, and --dedupe-ttl-seconds.

Python equivalent: start the same single instance
import subprocess

subprocess.Popen([
    "./cmake-build-release/blazerules_agent",
    "--name", "payments-http",
    "--rules", "rules.yaml",
    "--input", "http",
    "--host", "127.0.0.1",
    "--port", "9480",
    "--batch-size", "4096",
    "--flush-ms", "50",
    "--output", "ndjson",
    "--output-path", "decisions-payments.ndjson",
    "--service", "payments-api",
    "--source", "http-json",
    "--dedupe-key", "event_id",
    "--dedupe-ttl-seconds", "86400",
])

Next steps