Live monitoring¶
Goal: watch a live stream - a log, a ticket queue, a feed - through semantic verbs, in real time.
Semantic tail -f¶
map, filter, and extend process each item as it arrives. No flag needed:
pipe a live source in and results appear as lines come through.
tail -f app.log \
| smartpipe filter "a user is hitting a real error"
Every new log line is judged as it lands; matches flow out immediately. The stderr
status line keeps score without touching your data:
⠹ Processing [847] 3.1/s · 23 matched
Classify a live stream into structured records the same way:
tail -f app.log \
| smartpipe map "Classify this log line. Add {severity enum(critical, warning, info), category}" \
| tee incidents.jsonl
Rolling synthesis: reduce --window¶
A stream never ends, so reduce needs a boundary. --window N gives it one: every
N lines, one synthesis, emitted immediately:
tail -f server.log \
| smartpipe reduce --window 100 "What's the current error trend?"
# → {"window_end": 100, "result": "Mostly timeouts against the payments service..."}
# → {"window_end": 200, "result": "The timeout cluster is resolving; new auth errors..."}
Add --every M to slide the window instead of resetting it - a fresh summary of the last N lines
after every M new ones:
tail -f server.log \
| smartpipe reduce --window 100 --every 20 "error trend?"
When the stream ends (or you press Ctrl-C), whatever is buffered is synthesized and
emitted as a final record marked "partial": true - buffered lines are flushed on shutdown rather than discarded.
The live leaderboard: top_k --stream¶
Keep a running "most relevant so far" over a stream:
tail -f tickets.jsonl \
| smartpipe top_k 5 --stream --near "billing dispute"
At a terminal, the top-5 block repaints in place as better matches arrive. In a
pipe, each change emits a JSONL snapshot: a {"__snapshot": N} marker line
followed by the K records in rank order, each with __score and __rank - split on
the markers to consume programmatically. No change, no output.
The on-call tail, end to end¶
The pieces above compose into the shift-long triage assistant - the upgrade
to the tail -f | grep every SRE already lives in:
# The on-call tail -f: free grep first, judgment second, a fresh digest every 20 lines
tail -f /var/log/api/api.log \
| smartpipe where 'text has "error" or text has "timeout"' \
| smartpipe filter "a real production failure, not a retry, health check, or graceful shutdown" \
| tee triage.log \
| smartpipe reduce --window 50 --every 20 "What is failing right now, which service, and is it getting worse or better?"
Reading it stage by stage: where is the free gate that keeps the paid calls
to a trickle, filter judges meaning (a retry storm is noise; a graceful
shutdown is not a page), tee keeps the raw matched lines for the postmortem,
and the sliding reduce narrates what is failing and whether it is getting
worse - a fresh written digest of the last 50 judged lines after every 20 new
ones.
Ending a live pipeline¶
Two natural exits, both clean:
| head- take what you need and go. smartpipe exits immediately with code 141 when the pipe closes:tail -f app.log | smartpipe filter "signals an outage" | head -1 && page-oncall- Ctrl-C - the first press stops intake, finishes what's in flight, flushes
reduce's partial window, prints adone: interrupted - …summary, and exits with the run's true outcome code. A second press bails immediately.
See also¶
- Pipes & items - batch vs stream in one picture
reduce·top_k·filter