AURA exports OpenTelemetry spans via OTLP when OTEL_EXPORTER_OTLP_ENDPOINT
is set. Spans follow the OpenInference
taxonomy so they render correctly in Phoenix, Jaeger, and similar tools.
Every request produces two traces:
- HTTP trace — covers the request/response lifecycle
- Agent trace — covers the LLM/tool execution
The agent trace is rooted at agent.stream with parent: None so Phoenix
sees it as an independent trace root with all LLM I/O attributes.
chat_completions (CHAIN)
└── streaming_completion (CHAIN)
agent.stream (AGENT, ROOT)
└── agent.turn (LLM)
├── execute_tool (TOOL)
│ └── mcp.tool_call (TOOL)
└── execute_tool (TOOL)
└── mcp.tool_call (TOOL)
agent.stream (AGENT, ROOT)
└── orchestration (CHAIN)
├── orchestration.planning (CHAIN)
│ └── agent.turn (LLM) → execute_tool → mcp.tool_call
└── orchestration.iteration (CHAIN)
└── orchestration.worker (AGENT)
└── agent.turn (LLM) → execute_tool → mcp.tool_call
user.id, session.id, metadata, input.value, output.value,
llm.token_count.prompt, llm.token_count.completion, llm.token_count.total
| Span | Attributes |
|---|---|
orchestration |
orchestration.goal, orchestration.max_iterations, orchestration.routing (direct/clarification/orchestrated) |
orchestration.planning |
orchestration.phase |
orchestration.iteration |
orchestration.iteration, orchestration.task_count, orchestration.quality_score, orchestration.will_replan |
orchestration.worker |
orchestration.task_id, orchestration.worker, orchestration.task |
Token usage (llm.token_count.*) is recorded on all orchestration phase
spans (planning, worker).
Span kind is inferred from the span name by the custom exporter in
openinference_exporter.rs:
| Kind | Spans |
|---|---|
| LLM | chat_streaming, agent.turn |
| TOOL | execute_tool, mcp.tool_call |
| AGENT | agent.stream, orchestration.worker |
| CHAIN | chat_completions, streaming_completion, orchestration, orchestration.planning, orchestration.iteration |
agent.streamis created withparent: Noneto break the link from the HTTP handler trace, making it an independent trace root in Phoenix.- The
tokio::spawninhandlers.rsis instrumented withagent.streamso Rig'sagent.turnbecomes a direct child. - In orchestration mode,
Orchestrator::stream()instruments its spawned task with theagent.streamspan so all orchestration child spans nest under the trace root. ToolWrapper::callpropagates the current span into itstokio::spawnsomcp.tool_callnests under Rig'sexecute_tool.
When OTEL_RECORD_CONTENT=true, prompt/completion text and tool
arguments/results are recorded as span attributes, truncated to
OTEL_CONTENT_MAX_LENGTH (default 1000 bytes, rounded to a UTF-8 boundary).
- Tool error propagation: Tool errors are only recorded on the
mcp.tool_callchild span (bymcp_tool_execution.rs), not on Rig'sexecute_toolparent. This is intentional —mcp.tool_callis the canonical TOOL span for Phoenix.