rsigma engine tail
rsigma engine tail
Stream a running daemon’s live detections to the terminal.
Synopsis
rsigma engine tail [OPTIONS]
Description
engine tail answers “what is the daemon firing right now?” without standing up a sink or scraping /metrics. It opens a streaming connection to a running engine daemon on GET /api/v1/detections/stream and prints each detection and correlation result as it fires, in the same EvaluationResult shape the sinks emit, so engine tail and a saved sink file are the same format.
rsigma engine tail --level high --rule whoami
It is the detections-out counterpart to engine tap (events-in). Where the tap records what the engine received, tail shows what it fired, after post-evaluation enrichment and regardless of which sinks are configured.
The stream is lossy by design: it can never apply backpressure to the sink task or stall the at-least-once ack-join. If a session’s buffer fills under load, detections are dropped and counted, and the final summary record reports the gap.
Like engine status it is a read-only client over the admin API. It uses a synchronous HTTP client and does not need the daemon build feature, and it follows the same address convention as config reload: --addr defaults to daemon.api.addr, and wildcard binds (0.0.0.0, [::]) map to loopback.
The client does not send an Authorization header. Against a daemon with API authentication enabled, grant anonymous detections:read (or a broader read role such as reader), or open the stream with curl and a bearer token. HTTP 401/403 still exit 3.
The tail is disabled by default. Enable it on the daemon with the --enable-tail flag or daemon.tail.enabled: true in the config; otherwise the endpoint returns 503.
Filters
Two optional server-side filters keep a noisy daemon’s tail readable:
--level <severity>: minimum severity (informational,low,medium,high,critical). Results below it, or with no level, are excluded.--rule <substring>: a case-insensitive substring matched against the rule title or id.
Both are applied at the sink, so filtered-out results never cross the wire. Invalid level values are rejected with 400.
Flags
| Flag | Default | Description |
|---|---|---|
--addr <HOST:PORT or URL> |
from daemon.api.addr |
Daemon API address as host:port or a full URL. https:// URLs work for TLS deployments. |
--duration <D> |
unset | Capture window (humantime). Unset streams until interrupted or --limit is reached. There is no max_duration cap (unlike the event tap). |
--limit <N> |
unset | Stop after N detections, before the duration if reached first. |
--level <severity> |
unset | Minimum severity filter. |
--rule <substring> |
unset | Case-insensitive title/id substring filter (percent-encoded in the query string). |
-c, --config <PATH> |
discovery chain | Explicit config file used to resolve the daemon address. |
Rendered through the global --output-format layer: a TTY-aware default (pretty json on a terminal, ndjson when piped) plus csv/tsv row streaming and a table view (buffered, so table suits a bounded --duration/--limit tail rather than an open-ended one). The table/csv/tsv projection is LEVEL | RULE | TYPE | DETAIL, mirroring engine eval. The global --quiet / --no-stats flags suppress the stderr stats line. See Output Formats.
Examples
Watch high-severity detections
rsigma engine tail --level high
Follow a specific rule and pipe to jq
rsigma engine tail --rule "suspicious login" | jq '.matched_fields'
Capture a fixed window to a file
rsigma engine tail --duration 5m --output-format ndjson > detections.ndjson
Stop after the first N detections
rsigma engine tail --limit 20 --output-format table
Output
The stream is NDJSON on the wire: one result per line, followed by a final summary record the client uses for the stats line and keeps out of the rendered output:
{"rsigma_tail_summary":{"streamed":42,"dropped":0}}
A non-zero dropped means a session buffer filled under load; the tail missed detections. With --no-stats unset, stderr prints tail: streamed N, dropped M (and a warning when dropped is non-zero).
Exit codes
| Code | Meaning |
|---|---|
0 |
The stream ended cleanly (even with zero detections). |
3 |
The daemon could not be reached, returned a non-2xx status (401/403 auth, 503 when the tail is disabled, 409 at the session cap, 400 for bad params), or sent an unreadable stream. |
See also
engine tapfor the events-in counterpart.engine daemonfor the long-running service and thedaemon.tail.*limits.engine statusfor the sibling daemon-client--addrconvention.- HTTP API:
GET /api/v1/detections/streamfor the raw endpoint, query params, and error semantics. - HTTP API: Authentication when the daemon requires bearer tokens (
detections:read). - Streaming Detection for the daemon overview.
- Prometheus Metrics for
rsigma_tail_*counters and gauges.