The unified observability layer for the AI Control Plane.
AITrace provides instrumentation for capturing the complete causal chain of an AI agent's reasoning process.
Quick Start
defmodule MyAgent do
require AITrace
def handle_message(message) do
AITrace.trace "agent.handle_message" do
AITrace.add_event("Message received", %{text: message})
AITrace.span "reasoning_loop" do
# Perform reasoning
result = think_about(message)
AITrace.with_attributes(%{tokens: result.token_count})
result
end
end
end
endCore Concepts
- Trace: The complete record of a transaction, identified by a
trace_id - Span: A timed operation within a trace (can be nested)
- Event: A point-in-time annotation within a span
- Context: An immutable map carrying trace and span IDs through the call stack
Exporters
Configure exporters in your config:
config :aitrace,
exporters: [
{AITrace.Exporter.Console, verbose: true},
{AITrace.Exporter.File, directory: "./traces"}
]
Summary
Functions
Adds an event to the current span.
Clears process-local context.
Exports a fully materialized trace through the configured exporter pipeline.
Exports a fully materialized trace through an explicit export profile or exporter list.
Gets the current context from the process dictionary.
Restores process-local context, deleting it when the previous context was nil.
Runs a span with an explicit parent context argument.
Runs a trace with an explicit context argument.
Sets the current context in the process dictionary.
Creates a span within a trace.
Starts a new trace.
Adds attributes to the current span.
Functions
@spec add_event(String.t(), map()) :: :ok
@spec add_event(AITrace.Context.t(), String.t()) :: :ok
Adds an event to the current span.
Examples
AITrace.add_event("cache_hit", %{key: "user_123"})
AITrace.add_event("validation_passed")
@spec add_event(AITrace.Context.t(), String.t(), map()) :: :ok
@spec clear_current_context() :: :ok
Clears process-local context.
@spec export(AITrace.Trace.t()) :: :ok | {:error, term()}
Exports a fully materialized trace through the configured exporter pipeline.
This is the bridge-facing one-shot path for integrations that construct
completed AITrace.Trace values directly.
@spec export(AITrace.Trace.t(), AITrace.ExportProfile.t()) :: :ok | {:error, term()}
@spec export(AITrace.Trace.t(), [module() | {module(), keyword() | map()}]) :: :ok | {:error, term()}
Exports a fully materialized trace through an explicit export profile or exporter list.
Use this when a caller needs one-shot export behavior without relying on application-configured exporters.
Examples
trace = AITrace.Trace.new("trace-123")
AITrace.export(trace, [
{AITrace.Exporter.Console, verbose: true}
])
@spec get_current_context() :: AITrace.Context.t() | nil
Gets the current context from the process dictionary.
@spec restore_current_context(AITrace.Context.t() | nil) :: :ok
Restores process-local context, deleting it when the previous context was nil.
@spec run_span(AITrace.Context.t(), String.t(), (AITrace.Context.t() -> result)) :: result when result: var
Runs a span with an explicit parent context argument.
This path does not read or write process dictionary context.
@spec run_trace(String.t(), (AITrace.Context.t() -> result), keyword()) :: result when result: var
Runs a trace with an explicit context argument.
This path does not write to the process dictionary. It is the preferred production API when context must cross task or process boundaries.
@spec set_current_context(AITrace.Context.t()) :: :ok
Sets the current context in the process dictionary.
Creates a span within a trace.
The span macro creates a timed operation within the current trace.
Use AITrace.get_current_context() to access the current context.
Examples
AITrace.trace "request" do
AITrace.span "database_query" do
query_database()
end
endReturns the result of the block.
Starts a new trace.
The trace macro creates a new trace and stores the context in the
process dictionary. Use AITrace.get_current_context() to retrieve it.
Examples
require AITrace
AITrace.trace "user_request" do
process_request()
endReturns the result of the block.
@spec with_attributes(map()) :: :ok
@spec with_attributes(AITrace.Context.t(), map()) :: :ok
Adds attributes to the current span.
Examples
AITrace.with_attributes(%{user_id: 42, region: "us-west"})