OTel Configuration by Harness¶
Each agent harness configures OpenTelemetry differently based on the agent CLI's telemetry implementation. The local OTLP collector accepts all signals (metrics, logs, traces) regardless of harness -- the differences are in what the agent exports and what env vars control it.
For the full telemetry architecture (collector, trace completeness, MLflow pipeline), see OTEL Architecture.
Claude Code¶
Claude Code has its own telemetry system that exports via the standard OTLP protocol.
| Variable | Value | Purpose |
|---|---|---|
CLAUDE_CODE_ENABLE_TELEMETRY |
1 |
Master switch for telemetry export |
OTEL_METRICS_EXPORTER |
otlp |
Export metrics (token counts, cost) |
OTEL_LOGS_EXPORTER |
otlp |
Export log events (API requests, tool decisions) |
OTEL_TRACES_EXPORTER |
otlp |
Export trace spans (tool calls, LLM requests) |
OTEL_EXPORTER_OTLP_PROTOCOL |
http/json |
OTLP wire format |
OTEL_EXPORTER_OTLP_ENDPOINT |
http://...:{port} |
Collector address |
OTEL_BSP_SCHEDULE_DELAY |
1000 |
Flush spans every 1s. Reduces span loss on container crash vs the default 5s. |
OTEL_METRIC_EXPORT_INTERVAL |
10000 |
Export metrics every 10s. Controls Claude Code's OTel metrics SDK export frequency. |
CLAUDE_CODE_ENHANCED_TELEMETRY_BETA |
1 |
Rich span hierarchy with tool nesting and subagent spans |
OTEL_LOG_USER_PROMPTS |
1 |
Include user prompt text in spans |
OTEL_LOG_TOOL_DETAILS |
1 |
Include tool input parameters in spans |
OTEL_LOG_TOOL_CONTENT |
1 |
Include tool output/results in spans |
TRACEPARENT |
00-{trace_id}-{span_id}-01 |
W3C Trace Context. If the agent's OTEL SDK respects it, spans parent under the orchestrator's root span. |
OpenCode¶
OpenCode uses the Vercel AI SDK's OpenTelemetry integration. OTel must
be enabled in opencode.json (experimental.openTelemetry: true) in
addition to the env vars — the harness writes this config automatically
via write_sandbox_config().
| Variable | Value | Purpose |
|---|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT |
http://...:{port} |
Collector address |
OTEL_EXPORTER_OTLP_PROTOCOL |
http/json |
OTLP wire format |
OTEL_BSP_SCHEDULE_DELAY |
0 |
Flush spans immediately. Required because OpenCode calls process.exit() which kills the Node.js process before the OTel batch span processor can drain its queue. Without this, spans are lost. |
TRACEPARENT |
00-{trace_id}-{span_id}-01 |
W3C Trace Context. Same as Claude Code. |
Not set:
CLAUDE_CODE_ENABLE_TELEMETRY— Claude-specific, not used by OpenCodeOTEL_METRICS_EXPORTER/OTEL_LOGS_EXPORTER— OpenCode doesn't export metrics or logs via OTel. Cost and token data come from JSON stdout events (step_finishtype), not from the OTel pipeline.OTEL_METRIC_EXPORT_INTERVAL— no OTel metrics to exportOTEL_LOG_USER_PROMPTS/OTEL_LOG_TOOL_*— Claude-specific flags
Codex¶
Codex configures OTel through its [otel] configuration rather than standard
OTel environment variables. For each run, the Codex harness passes -c
overrides for three OTLP/HTTP JSON exporters:
| Signal | Endpoint |
|---|---|
| Logs | http://...:{port}/v1/logs |
| Metrics | http://...:{port}/v1/metrics |
| Traces | http://...:{port}/v1/traces |
| Variable | Value | Purpose |
|---|---|---|
TRACEPARENT |
00-{trace_id}-{span_id}-01 |
W3C Trace Context. Codex parents its exec root span under it, so its spans join the agentic-ci root trace. Spans Codex spawns without context propagation (auth, code_mode.broker.invoke_tool) still start their own traces. |
The log stream includes API requests, response events with token counts, tool decisions/results, and redacted prompt metadata. User prompt content remains disabled by default. The metrics stream includes Codex API, streaming, and tool counters and duration histograms. Exporters flush when Codex shuts down.
Codex reports token usage rather than dollar cost. agentic-ci estimates USD
cost from a generated snapshot of LiteLLM's OpenAI model-price map, including
cache and priority/flex service-tier rates. make update-cost-map resolves
LiteLLM main to an immutable commit SHA, fetches the map from that revision,
and records the SHA alongside the generated pricing data. Set
AGENTIC_CI_LITELLM_COST_MAP to a path containing a LiteLLM-format JSON map to
override the bundled snapshot. Token usage is still shown when a model has no
known price; the cost table omits that model.
The endpoint host is backend-specific: loopback for local and host-networked
Podman runs, and host.openshell.internal for OpenShell.
Sandbox config¶
The opencode.json config is written by write_sandbox_config() and
mounted into the container by the backend:
- Podman: mounted as a read-only volume via
sandbox_config_mounts() - OpenShell: uploaded and moved into place via
_upload_sandbox_config()
Claude Code and Codex do not require a mounted sandbox config for OTel. Claude Code uses environment variables; Codex receives per-run CLI config overrides.