Recipe: Plain-Text Logs

Convert unstructured text lines into NDJSON records with a message field.

BlazeRules ingests records, not arbitrary byte streams. For plain stdout/stderr or terminal text, wrap each line into JSON before sending it to stdin, HTTP, or file-tail input.

Wrap stdin text

some_command 2>&1 | \
  python -c 'import json,sys,time
for line in sys.stdin:
    print(json.dumps({"ts_ms": int(time.time()*1000), "source": "terminal", "message": line.rstrip()}), flush=True)' | \
  blazerules_agent --rules rules.yaml --input stdin --output stdout
Python API: evaluate wrapped lines already in memory
import json
import time
import blazerules

engine = blazerules.RuleEngine()
engine.load_rules("rules.yaml")

lines = ["payment started", "payment error"]
records = []
for line in lines:
    records.append(json.dumps({
        "ts_ms": int(time.time() * 1000),
        "source": "terminal",
        "message": line,
    }))

payload = ("\n".join(records) + "\n").encode()
result = engine.evaluate_ndjson(payload)
print(result.grouped_decision_indices())

Rule:

ruleset:
  rules:
    - id: terminal_error
      action: REVIEW
      conditions:
        field: message
        op: contains
        value: error

Wrap a file tail

tail -F /var/log/app.log | \
  python -c 'import json,sys
for line in sys.stdin:
    print(json.dumps({"service":"app","message":line.rstrip()}), flush=True)' | \
  blazerules_agent --rules rules.yaml --input stdin --output ndjson --output-path decisions.ndjson

Why Wrap?

Wrapping gives rules stable fields:

  • message
  • service
  • source
  • level
  • ts_ms
  • any values parsed before BlazeRules evaluation.

Structured JSON logs can use stdin Logs, File Tail, or HTTP Logs directly.


Did this page help you?