Centralizes process dictionary access for tracing context.
All tracing-related process dictionary keys are managed through this module, providing a single point of access for collector stacks, span stacks, and child step pass-through data.
Collector Stack
Supports nested trace collection. Each TraceLog.start/1 pushes a collector
onto the stack, and TraceLog.stop/1 pops it. Events are routed to all
active collectors.
Span Stack
Maintains parent-child span relationships for telemetry correlation.
Used by PtcRunner.SubAgent.Telemetry to track nested spans.
Cross-Process Propagation
Use capture/0 and attach/1 to propagate trace context across process
boundaries (e.g., Task.async_stream/3).
Child Step Pass-Through
Used by PtcRunner.Lisp.Eval to smuggle child execution metadata through
the process dictionary without polluting the Lisp value space.
See Also
- Observability Guide — cross-process tracing section
PtcRunner.TraceLog— JSONL trace capturePtcRunner.SubAgent.Telemetry— telemetry event emission
Summary
Functions
Restores trace context from a captured map in a child process.
Captures the current trace context into a portable map.
Returns all active collectors (innermost first).
Returns the innermost (current) collector, or nil.
Returns the current (innermost) span ID, or nil.
Merges collectors from another process into the current stack.
Returns the parent span ID (second element on the stack), or nil.
Pops the innermost collector and handler ID from the stack.
Pops the current span from the stack.
Pushes a collector and its handler ID onto the stack.
Pushes a span ID onto the stack. Returns the parent span ID (previous top).
Stores a child execution result for pass-through.
Removes a specific collector from the stack (not necessarily the top).
Sets the initial parent span for this process (for cross-process propagation).
Returns the span context map with :span_id and :parent_span_id.
Takes (gets and deletes) the child execution result. One-shot read.
Functions
@spec attach(map()) :: :ok
Restores trace context from a captured map in a child process.
Merges collectors (filtering dead PIDs) and restores the span stack.
@spec capture() :: map()
Captures the current trace context into a portable map.
Use with attach/1 to propagate context to child processes.
@spec collectors() :: [pid()]
Returns all active collectors (innermost first).
@spec current_collector() :: pid() | nil
Returns the innermost (current) collector, or nil.
@spec current_span_id() :: String.t() | nil
Returns the current (innermost) span ID, or nil.
@spec merge_collectors([pid()]) :: :ok
Merges collectors from another process into the current stack.
Filters out dead processes and deduplicates while preserving order.
@spec parent_span_id() :: String.t() | nil
Returns the parent span ID (second element on the stack), or nil.
Pops the innermost collector and handler ID from the stack.
Returns {collector, handler_id} or nil if the stack is empty.
@spec pop_span() :: String.t() | nil
Pops the current span from the stack.
Pushes a collector and its handler ID onto the stack.
Pushes a span ID onto the stack. Returns the parent span ID (previous top).
Stores a child execution result for pass-through.
Removes a specific collector from the stack (not necessarily the top).
Returns {collector, handler_id} if found, or nil.
@spec set_parent_span(String.t() | nil) :: :ok
Sets the initial parent span for this process (for cross-process propagation).
Only sets if the span stack is empty (does not override existing context).
Returns the span context map with :span_id and :parent_span_id.
Takes (gets and deletes) the child execution result. One-shot read.
Returns {trace_id, step} or nil if no child result is stored.