-
-
Notifications
You must be signed in to change notification settings - Fork 0
Reports and Archiving
The report node reference covers the configuration surface; this page is the working guide — how to read reports well, and how to run a report directory as a proper post-mortem archive.
A report is built to tell the recording's story, not just list it. The pieces, in the order your eye should use them:
The header states the trigger loudly. MANUAL means someone asked; ERROR and WATERMARK mean the recorder decided. For error incidents the cause block sits directly under the header — the error message and which node reported it — because that's the question you came with.
The stats line defines "normal". 47 records · span 1m 34s · median gap 2.0s — the median gap is the recording's heartbeat, and it's printed precisely so the timeline's ⚠ flags are interpretable: a flag means this gap was at least 3× that number. On a steady 2-second flow, a flagged 8.0s gap is three missing beats — often the real story of an incident, especially with sources that swallow messages on failure.
The timeline's rule lines are narrative events, not records: ── MARK ── is an annotation someone laid deliberately ("about to test X"); ── MUTED ──/── UNMUTED ── bound a deliberately silenced window (the unmute rule carries how much was suppressed); ── RESTART ── marks a persistence restore boundary — everything above it predates a restart, and the first gap after it is the downtime, honestly stated.
✂ means summary, not loss of the record. A scissored row exceeded the byte cap; its preview comes from the summary form, and payloadBytes in the raw JSON still tells you the original size.
text is monospace-aligned for the debug sidebar and log files — the development-time default. Remember the sidebar's own 1000-character display cap (debugMaxLength in settings.js); the report is complete regardless. Markdown pastes cleanly into issues, chats, and docs. HTML is the post-mortem artifact: a single self-contained file (inline styles, no external resources) that opens straight from disk or a Samba share, anomaly rows tinted, months later, on any machine.
Destinations compose with formats freely; message + file is the common working setup — sidebar visibility while developing, archive accumulating regardless.
The pattern this node was built for: tap (auto-error on) → report node (file or both, HTML, Raw JSON on) → a directory. Every error becomes a dated, readable post-mortem with its bit-for-bit evidence beside it:
2026-07-13_14-32-07_error_tap1.html ← the readable story
2026-07-13_14-32-07_error_tap1.json ← the untouched incident
The pairing is the point. The HTML answers "what happened?"; the JSON answers "prove it" — feed it to jq, pandas, or your own tooling, re-derive anything the report summarized. The stems always match, collisions get -2/-3 suffixes (evidence is never overwritten), and retention prunes by pair — a report never orphans its evidence or vice versa.
Practical settings for a long-running archive:
- Retention sized to your incident rate, not disk size: 100 pairs of a typical incident is a few megabytes. The real reason retention exists is pathological cases — a misconfigured cooldown plus an error loop should hit a ceiling, not a full disk.
- Cooldown ≥ 30–60s on any tap feeding an archive. Repeated identical incidents seconds apart add files, not information.
-
Filename template: the default sorts chronologically in any file browser. Add
{incidentId}if you need guaranteed-unique stems for external tooling. - Retention only ever touches files matching the node's own template pattern — the directory can safely be shared with other content, though a dedicated directory is tidier.
Home Assistant hosts: use /share/flight-recorder/reports — it persists across add-on updates and is exposed by the Samba/SSH add-ons, so HTML reports open from your PC over the network. Details and the notification pairing on the Home Assistant page.
Snapshots file too: an inject on a schedule → control node (query) → the recorder's query output → a report node with file output gives you a dated status report ({trigger} renders as status) — state, counters, config, active mutes — on whatever cadence you like. With Raw JSON on, the snapshot archives beside it, giving you a machine-readable health history for free.
The report node is stateless, so fan out freely from one recorder output: one report node archiving HTML+JSON pairs, a second rendering text to the sidebar, a third feeding Markdown into a notification flow — same incident, three presentations, no interference. The original payload always survives at msg.report.source, so downstream nodes can still reach the raw incident after any rendering.
Flight Recorder
Node Reference
Reference
Guides
Testing