OpenTelemetry Integration
JAATO integrates OpenTelemetry tracing via a plugin-based architecture. A TelemetryPlugin protocol abstracts OTel operations, with a zero-cost NullTelemetryPlugin default and a full OTelPlugin implementation. The span hierarchy — jaato.turn → gen_ai.chat → jaato.tool → jaato.permission_check — provides end-to-end visibility into agentic turns, model calls, tool executions, and permission decisions.
Span Hierarchy
Each agentic turn produces a tree of nested spans that capture the full execution flow:
| Span | Purpose | Key Attributes |
|---|---|---|
jaato.turn | Top-level turn orchestration | session_id, agent_type, turn_index, streaming, cancelled |
gen_ai.chat | Model API call (GenAI semantic conventions) | gen_ai.system, gen_ai.request.model, gen_ai.usage.* |
jaato.tool | Individual tool execution | tool.name, tool.plugin_type, tool.success, tool.duration_seconds |
jaato.permission_check | Permission decision | permission.tool, permission.decision, permission.scope |
jaato.gc | Garbage collection | gc.plugin, gc.tokens_freed, gc.trigger_reason |
Design Principles
- Zero-cost default — When telemetry is disabled,
NullTelemetryPluginprovides no-op implementations with zero overhead - Plugin-based — The
TelemetryPluginprotocol can be implemented by any backend, not just OpenTelemetry - Content redaction — Prompt and response content is redacted by default; opt-in via
JAATO_TELEMETRY_CAPTURE_CONTENT=true - GenAI semantic conventions — Follows the emerging OpenTelemetry GenAI semantic conventions for model interaction spans
Configuration
| Variable | Default | Description |
|---|---|---|
JAATO_TELEMETRY_ENABLED | false | Enable OpenTelemetry tracing |
OTEL_EXPORTER_OTLP_ENDPOINT | http://localhost:4317 | OTLP collector endpoint |
OTEL_SERVICE_NAME | jaato | Service name in traces |
JAATO_TELEMETRY_CAPTURE_CONTENT | false | Include prompt/response content in spans |
Thread Context Propagation
Parallel tool execution runs on a thread pool. The OTel plugin captures the parent span context before dispatching to threads and re-attaches it in each worker thread, ensuring tool spans are correctly parented under the jaato.turn span even during concurrent execution.