ChromeTrace
Category: Observability
Source: chrome_trace.dart
Functions
`String spansToChromeTrace(
Iterable<Map<String, dynamic>> spans, { required String sessionId, String processName = 'glue', String? version, })`
Converts a stream of serialized span maps — the JSONL shape produced by ObservabilitySpan.toMap (and written by FileSink) — into a JSON string in Chrome Trace Event Format, which Firefox Profiler imports natively via src/profile-logic/import/chrome.ts.
Mapping rules:
- Each completed span -> one
X(Complete) event withtsanddurin microseconds since epoch. Spans missingend_timeare dropped (they were in-flight when the log was sampled and have no duration). - Spans sharing a
trace_idshare atid. Firefox Profiler renders overlapping intervals on the same tid as visually nested, which matches parent/child span semantics. Each newtrace_idgets the next integer tid in first-seen order. - Per-span
events[]entries ->i(Instant) events on the same tid, scoped to the thread (s: "t"). - Span
kind-> Chromecat. Categories drive marker colors in the UI. Mmetadata events name the process and each thread (after the trace's root span — the one with noparent_span_idwithin the trace, falling back to the earliest-started span).- Spans with
status_code == "error"getargs.data.glue.status = "error"so the UI tooltip surfaces failures without polluting marker names.
The output uses the envelope form {"traceEvents": [...], "displayTimeUnit": "ms", "otherData": {...}} rather than a bare array, so [sessionId] and [version] show up in the profiler's "Profile Info" panel.
List<Map<String, dynamic>> parseSpansJsonl(String jsonl)
Reads a list of newline-delimited JSON span records from [jsonl] — the shape produced by FileSink and stored in $GLUE_HOME/logs/spans-*.jsonl. Malformed or empty lines are silently skipped, matching how SessionStore.loadConversation reads its sibling JSONL file.