Jido.Signal.Trace (Jido Signal v2.2.2)

View Source

Helper functions for distributed trace management.

Provides utilities for creating and propagating trace contexts across signal boundaries. Uses the correlation extension (Jido.Signal.Ext.Trace) for storage.

Trace Hierarchy

  • trace_id - Constant across entire workflow (16-byte hex)
  • span_id - Unique per signal (8-byte hex)
  • parent_span_id - Links child to parent signal
  • causation_id - Signal ID that triggered this signal

W3C Trace Context Compatibility

IDs are generated in W3C-compatible format:

  • trace_id: 32 hex chars (128-bit)
  • span_id: 16 hex chars (64-bit)

Examples

# Create a new root trace
ctx = Jido.Signal.Trace.new_root()

# Create child context for emitted signal
child_ctx = Jido.Signal.Trace.child_of(parent_ctx, parent_signal.id)

# Add trace to signal
{:ok, traced_signal} = Jido.Signal.Trace.put(signal, ctx)

# Get trace from signal
ctx = Jido.Signal.Trace.get(signal)

# Ensure signal has trace (add root if missing)
{:ok, signal, ctx} = Jido.Signal.Trace.ensure(signal)

Summary

Types

Trace context struct containing W3C-compatible trace information.

Functions

Parses a W3C traceparent header and creates a child context.

Creates a child trace context that continues the parent's trace.

Ensures a signal has trace context.

Parses a W3C traceparent header into trace context.

Extracts trace context from a signal.

Creates a new root trace context.

Adds trace context to a signal.

Adds trace context to a signal, raising on error.

Formats trace context as W3C traceparent header value.

Checks if a trace context is valid.

Types

trace_context()

@type trace_context() :: Jido.Signal.Trace.Context.t()

Trace context struct containing W3C-compatible trace information.

Functions

child_from_traceparent(traceparent, opts \\ [])

@spec child_from_traceparent(
  String.t(),
  keyword()
) :: Jido.Signal.Trace.Context.t() | nil

Parses a W3C traceparent header and creates a child context.

This is useful when receiving an external request with trace headers and you want to create a new span as a child of that trace.

Returns nil if parsing fails.

Options

  • :causation_id - Optional causation ID for the child span
  • :tracestate - Optional tracestate to associate with the child

Examples

child = Trace.child_from_traceparent(
  "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
  causation_id: "http-request-123"
)

child_of(parent, causation_id)

@spec child_of(Jido.Signal.Trace.Context.t() | nil, String.t() | nil) ::
  Jido.Signal.Trace.Context.t()

Creates a child trace context that continues the parent's trace.

The child:

  • Shares the parent's trace_id
  • Gets a new unique span_id
  • Sets parent_span_id to the parent's span_id
  • Sets causation_id to the causing signal's ID
  • Inherits tracestate

Examples

parent_ctx = Trace.get(parent_signal)
child_ctx = Trace.child_of(parent_ctx, parent_signal.id)

ensure(signal, opts \\ [])

@spec ensure(
  Jido.Signal.t(),
  keyword()
) :: {:ok, Jido.Signal.t(), Jido.Signal.Trace.Context.t()}

Ensures a signal has trace context.

If the signal already has a trace, returns it unchanged. If not, creates a new root trace and adds it.

Returns {:ok, signal, trace_context}.

Options

  • :causation_id - Optional causation reference for new root traces
  • :tracestate - Optional W3C tracestate for new root traces

Examples

{:ok, signal, ctx} = Trace.ensure(signal)
{:ok, signal, ctx} = Trace.ensure(signal, causation_id: "req-123")

from_traceparent(traceparent)

@spec from_traceparent(String.t()) :: Jido.Signal.Trace.Context.t() | nil

Parses a W3C traceparent header into trace context.

Returns nil if parsing fails (invalid format, wrong lengths).

Examples

Trace.from_traceparent("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01")
#=> %Context{trace_id: "4bf92f3577b34da6a3ce929d0e0e4736", span_id: "00f067aa0ba902b7", ...}

Trace.from_traceparent("invalid")
#=> nil

get(signal)

@spec get(Jido.Signal.t()) :: Jido.Signal.Trace.Context.t() | nil

Extracts trace context from a signal.

Returns nil if the signal has no trace extension.

Examples

ctx = Trace.get(signal)
case Trace.get(signal) do
  nil -> "no trace"
  %Context{trace_id: tid} -> "traced: #{tid}"
end

new_root(opts \\ [])

@spec new_root(keyword()) :: Jido.Signal.Trace.Context.t()

Creates a new root trace context.

Generates new W3C-compatible trace_id (32 hex chars) and span_id (16 hex chars).

Options

  • :causation_id - Optional causation reference (e.g., external request ID)
  • :tracestate - Optional W3C tracestate string for vendor-specific data

Examples

ctx = Trace.new_root()
ctx = Trace.new_root(causation_id: "external-123")
ctx = Trace.new_root(tracestate: "vendor1=value1")

put(signal, ctx)

@spec put(Jido.Signal.t(), Jido.Signal.Trace.Context.t()) ::
  {:ok, Jido.Signal.t()} | {:error, term()}

Adds trace context to a signal.

Uses the correlation extension namespace to store trace data.

Examples

ctx = Trace.new_root()
{:ok, traced} = Trace.put(signal, ctx)

put!(signal, ctx)

Adds trace context to a signal, raising on error.

Examples

traced = Trace.put!(signal, ctx)

to_traceparent(ctx)

@spec to_traceparent(Jido.Signal.Trace.Context.t()) :: String.t()

Formats trace context as W3C traceparent header value.

Format: {version}-{trace-id}-{span-id}-{flags}

Version is always "00" (current W3C spec). Flags is "01" (sampled).

Examples

Trace.to_traceparent(ctx)
#=> "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"

valid?(ctx)

@spec valid?(Jido.Signal.Trace.Context.t() | nil) :: boolean()

Checks if a trace context is valid.

A valid trace context has:

  • trace_id that is 32 lowercase hex characters
  • span_id that is 16 lowercase hex characters

Examples

Trace.valid?(ctx) #=> true
Trace.valid?(nil) #=> false