Observability
In-process result counters, decision logs, dead-letter logs, and dashboard views available during and after evaluation.
BlazeRules observability is in-process. Every evaluate_* call returns a Result with timing and ingest counters, while the agent can write per-record decision logs and dead-letter logs. The host application aggregates or exports these values; the core does not run a metrics server.
Metrics live on the Result, not on a serverThe core engine has no daemon or
/metricsendpoint. Per-batch timing, processed and skipped record counts, and error details are returned on theResultobject for export by the host application.
Counters on every Result
These fields are returned by evaluate_ndjson, evaluate_batch, and the other evaluate methods.
| Field | Meaning |
|---|---|
n_records | Records in the batch the engine saw. |
n_matched | Records where at least one rule matched. |
timing | Python BatchResult timing dictionary, in milliseconds. |
messages_processed | Count of records successfully ingested and evaluated. |
messages_skipped | Count of records skipped during ingest (driven by ingest_error_mode). |
error_counts | Per-category counts of ingest/type errors encountered. |
error_samples | A bounded set of example error records/messages for diagnosis. |
result = engine.evaluate_ndjson(payload)
print("records:", result.n_records, "matched:", result.n_matched)
print("took ms:", result.timing["total"])
print("processed:", result.messages_processed, "skipped:", result.messages_skipped)
if result.messages_skipped:
print("error counts:", result.error_counts)
print("error samples:", result.error_samples)When messages_skipped is non-zero, error_counts and error_samples identify malformed JSON, type mismatches, and other causes. See Error Reference for category definitions and ingest-mode behavior.
Decision logs and dead-letter logs
The agent writes per-record decisions to its configured output. In the agent configuration file passed through --config, each instance defines an output: block. The agent configuration is separate from rules.yaml.
instances:
- name: payments-http
rules: rules.yaml
output:
type: ndjson
path: decisions-payments.ndjson
- name: checkout-log-tail
rules: rules.yaml
output:
type: stdoutAn ndjson output writes one decision record per line, producing a durable decision log suitable for tailing, archival, or downstream ingestion. The dashboard reads these logs into a local read-only view using --decision-log and --dead-letter-log paths (see Deployment).
A dead-letter log captures records that could not be ingested when ingest_error_mode = IngestErrorMode.SKIP_TO_DEAD_LETTER — instead of being counted and dropped, they are set aside for inspection. Pair the dead-letter log with the messages_skipped / error_samples counters above to see both the count and the offending payloads.
In-process metrics
Enable the built-in collecting metrics sink for cumulative counters, gauges, and histograms across batches.
engine.enable_metrics()
for payload in payloads:
engine.evaluate_ndjson(payload)
snapshot = engine.metrics_snapshot()
print(snapshot["counters"])
print(snapshot["gauges"])
print(snapshot["histograms"])
engine.reset_metrics()metrics_snapshot() returns:
| Key | Shape |
|---|---|
counters | {metric_name_or_labeled_key: int} |
gauges | {metric_name_or_labeled_key: float} |
histograms | {metric_name_or_labeled_key: {count, sum, min, max, mean}} |
Built-in metric names include:
blazerules.records_evaluated_total
blazerules.batches_evaluated_total
blazerules.records_skipped_total
blazerules.records_matched_total
blazerules.batch_total_latency_us
blazerules.batch_evaluation_latency_us
blazerules.batch_transpose_latency_us
blazerules.rule_fired_total{rule_id=...}
blazerules.rule_fire_rate{rule_id=...}
blazerules.decisions_total{action=...}
blazerules.hot_reload_success_total
blazerules.hot_reload_failed_totalThe core does not run a Prometheus HTTP server. Prometheus, OpenTelemetry, and other external systems can consume metrics_snapshot() through instrumentation in the host process.
Related documentation
Updated about 2 months ago