-
-
Notifications
You must be signed in to change notification settings - Fork 0
Data Formats
The JSON reference for anyone consuming recorder output in their own tools. These shapes are the package's public contracts: fields may be added in future versions, but existing fields won't change meaning.
Every message on a recorder's incident, query, and events outputs:
{
"topic": "<node name or node type>",
"recorderEvent": "incident",
"recorderState": "recording",
"storeId": "<recorder node id>",
"payload": { ...event-specific... }
}recorderEvent values: incident, incidentSuppressed, marked, wrapped, truncatedMessage, paused, resumed, cleared, persisted, recorderError, commandIgnored, query — plus, on taps, muted, unmuted, muteIgnored.
{
"incidentId": "a1b2c3d4-…",
"storeId": "abc123",
"trigger": "error",
"triggeredAt": 1783987005544,
"context": { … },
"meta": {
"package": "node-red-contrib-flight-recorder@0.2.0",
"nodeRed": "4.0.2",
"node": "v22.11.0",
"hostname": "yellow"
},
"stats": { …see Stats… },
"records": [ …see Record… ]
}trigger is manual, error, or watermark. context depends on the trigger: manual dumps carry whatever msg.context the command supplied (or null); error dumps carry { error, source, msg } with the error structured (see encodings) and the emitting node identified; watermark dumps carry { condition, matchedSeq }. A context whose encoding exceeds the record byte cap is replaced by { "__contextTruncated": true, "preview": "…" }. meta (added in 0.2.0) records what produced the incident; older incidents simply lack it.
{
"seq": 1042,
"capturedAt": 1783987005544,
"deltaMs": 2001,
"source": { "id": "f1", "name": "worker", "type": "function", "port": 0 },
"truncated": false,
"redacted": ["payload.password"],
"annotation": null,
"msg": { … }
}-
seqis monotonic forever — it survives buffer wraps,clear, and restarts, so records are globally orderable. -
deltaMsis the time since the previous accepted capture, computed at capture time;nullon the first record. -
sourceis the recorder itself for inline captures, the true emitting node (with output port) for tap captures. Annotation marks have a null source. -
truncated: truemeans the message exceeded the byte cap andmsgis in summary form (below);redactedlists the property paths that were masked. -
Annotation marks:
annotationis set (the mark payload, or{muted: …}/{unmuted: …, suppressedCount}for mute boundaries) andmsgisnull. Marks occupy sequence positions on the tape. - Records restored from a persist file after a restart additionally carry
"restored": true.
{
"payloadType": "object",
"payloadBytes": 1049311,
"payloadPreview": "{\"blob\":\"zzzz…",
"topic": "sensors/demo",
"msgKeys": ["payload", "topic", "_msgid"]
}payloadBytes reflects the original size — a truncated record still tells you it was a megabyte.
| Original | Stored as |
|---|---|
| Circular reference | "[Circular]" |
| Buffer / TypedArray | { "__type": "buffer", "length": n, "preview": "<hex of first 32 bytes>" } |
| Error |
{ "__type": "error", "name", "message", "stack" } (stack capped) |
| Function | "[Function]" |
| Date | ISO string |
HTTP msg.req / msg.res
|
"[HttpRequest]" / "[HttpResponse]" — never deep-encoded |
undefined object properties |
dropped (JSON semantics) |
Redaction ("[REDACTED]") is applied before encoding or previewing.
{
"recordCount": 47,
"firstSeq": 955, "lastSeq": 1042,
"spanMs": 94100,
"droppedWhilePaused": 0,
"wrapCount": 12,
"truncatedCount": 1
}spanMs is first-capture → last-capture; null when empty, 0 for a single record.
{
"storeId": "abc123",
"state": "recording",
"capacity": 100,
"restoredFromPersist": false,
"config": { "capacity", "captureMode", "maxRecordBytes", "persist", "incidentCooldownMs" },
"stats": { … },
"tap": {
"autoErrorDump": true,
"mutes": [ { "kind": "node", "value": "m1", "suppressedCount": 4 } ],
"scopeSeen": { "inScope": 3, "outOfScope": 6 }
}
}The tap block appears only on tap recorders. scopeSeen counts distinct source nodes evaluated so far.
{ "ok": true, "command": "dump", "targetId": "abc123", "result": { … }, "reason": null }with msg.inReplyTo echoing the triggering _msgid. On failure: ok: false, result: null, and a reason string.
{
"kind": "incident",
"format": "html",
"source": { …the original payload, untouched… },
"files": [ { "kind": "report", "path": "…", "bytes": 8412, "ok": true } ]
}kind is incident, snapshot, event, or unknown; files entries are kind: "report" | "raw" with per-file ok/reason. Raw JSON files are the incident/snapshot serialized with JSON.stringify(payload, null, 2) — lossless.
{
"formatVersion": 1,
"storeId": "abc123",
"savedAt": 1783987005544,
"seqCounter": 1042,
"state": "recording",
"stats": { … },
"records": [ … ]
}The format is versioned from day one; a file with an unrecognized formatVersion (or any corruption) logs a warning and the recorder starts fresh — it never blocks startup. Files are written atomically (temp + rename), so an existing file can't be corrupted by a crash mid-write.
Flight Recorder
Node Reference
Reference
Guides
Testing