Expand description
Hand-rolled JSON-lines logger. ~150 lines reusing the serde_json
serializer — deliberately not tracing (its implicit async span context
is moot for a processes-plus-threads design, and the process tree gives
us correlation for free).
One NDJSON event per line to stderr (stdout is reserved for the
agent’s result). The canonical line schema is:
ts level event run_id agent_id agent_path comp pid [span_id parent_span_id trace_id] [dur_ms] [err] <event-specific>.
Structs§
- Event
Window - A snapshot of the ring window an
agentd://events?after=<seq>read returns: the entries withseq > after(after optional level/event-prefix filtering), plus the ring’s current window bounds and cumulativedropped. - LogCtx
- The correlation context stamped on every line. Children inherit
run_idandtrace_idand extendagent_path(the cheap subtree-query superpower: anagent_pathprefix selects a subtree with no backend join). - Logger
- A logger bound to one
LogCtx. Cheap to clone (clones the ctx); writes serialize behind a process-global stderr mutex so lines never interleave. - TapDrain
Guard - Tapped
Event - One event awaiting its append: which stream, the subject (the event name), and the fields.
Enums§
Constants§
- EVENTS_
RING_ DEFAULT - Default ring capacity, overridable with
AGENTD_EVENTS_RING: the last N emitted lines held in memory. Bounds memory on a slow subscriber. - EVENTS_
SCHEMA - Envelope version for the
agentd://eventsread body. Bumped only on a breaking change to the{oldest_seq,newest_seq,dropped,events}envelope — never for the per-line schema, which is versioned independently of this. - EVENT_
FAMILIES - The families a runtime event can belong to — the segment before the first
dot in an event name. A closed vocabulary so
include: [pressur]is a startup error rather than a filter that silently matches nothing.families_cover_the_emitted_vocabularykeeps this honest against the tree.
Functions§
- drain_
runtime_ tap - Take everything queued since the last drain, plus how many were dropped. The reactor calls this once per tick and appends each to its stream.
- install_
event_ ring - Install the bounded event ring with capacity
cap. Called once by the supervisor when the servedagentd://eventsresource is wanted (gated by--serve-mcpplus theeventsfeature at the call site). Idempotent — a second call resizes and clears. Never fatal: telemetry must not crash the run, so a poisoned lock is recovered rather than propagated. - install_
runtime_ tap - Arm the tap.
allandsampledare family names;capbounds the queue. Idempotent — a second call replaces the selection and clears the queue. - read_
event_ window - Drain the ring into an
EventWindowfor a cursor read. Returns the entries withseq > after, capped atlimit(oldest-first), each with itsseqfolded into the emitted line object.level/event_prefixesare optional server-side filters — a cheap prefix match over the held lines, not a query engine.Nonewhen no ring is installed (the resource 404s at the server). - rfc3339_
millis - Format a
SystemTimeas RFC 3339 UTC with millisecond precision, with no date-library dependency. Uses Howard Hinnant’scivil_from_daysalgorithm. Pre-epoch times clamp to the epoch (we never log them). - runtime_
tap_ armed - Whether any tap is armed (the cheap check the audit sink also uses).
- take_
events_ dirty - Take-and-clear the “new events since last check” flag — the served
agentd://eventsresource calls this on its coalescing tick to decide whether to fire anotifications/resources/updated. Returnstrueif any line was captured since the last call. - tap_
direct - Queue one event for a stream directly, bypassing family selection. The
audit sink uses this: audit records are chosen by
audit.sink, not by the runtime-event family list, and they go to their own stream. - tap_
drain_ guard - Suspend capture for the duration of the returned guard.