Skip to main content

Module log

Module log 

Source
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§

EventWindow
A snapshot of the ring window an agentd://events?after=<seq> read returns: the entries with seq > after (after optional level/event-prefix filtering), plus the ring’s current window bounds and cumulative dropped.
LogCtx
The correlation context stamped on every line. Children inherit run_id and trace_id and extend agent_path (the cheap subtree-query superpower: an agent_path prefix 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.
TapDrainGuard
TappedEvent
One event awaiting its append: which stream, the subject (the event name), and the fields.

Enums§

Comp
Which component is emitting. Part of the correlation tuple.
Level

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://events read 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_vocabulary keeps 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 served agentd://events resource is wanted (gated by --serve-mcp plus the events feature 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. all and sampled are family names; cap bounds the queue. Idempotent — a second call replaces the selection and clears the queue.
read_event_window
Drain the ring into an EventWindow for a cursor read. Returns the entries with seq > after, capped at limit (oldest-first), each with its seq folded into the emitted line object. level/event_prefixes are optional server-side filters — a cheap prefix match over the held lines, not a query engine. None when no ring is installed (the resource 404s at the server).
rfc3339_millis
Format a SystemTime as RFC 3339 UTC with millisecond precision, with no date-library dependency. Uses Howard Hinnant’s civil_from_days algorithm. 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://events resource calls this on its coalescing tick to decide whether to fire a notifications/resources/updated. Returns true if 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.