CloudCodeTree LogoCloudCodeTree
AI NewsTutorialsAbout
CloudCodeTree Logo
CloudCodeTree
  • AI News
  • Tutorials
  • About
← Back to AI News
Ship Agent Telemetry in Three Env Vars: Claude Agent SDK's Built-in OpenTelemetry

Ship Agent Telemetry in Three Env Vars: Claude Agent SDK's Built-in OpenTelemetry

Chris Harper

3 min read

Jun 29, 2026 · 20:05 UTC

AI
Workflow
Claude Code
Agents

TL;DR: Three env vars activate the Agent SDK's built-in OpenTelemetry export — every tool call, model request, and token cost becomes a span in Grafana, Honeycomb, Datadog, or Jaeger without an extra library.

Every production service needs metrics, traces, and logs. If you're deploying agents via the Claude Agent SDK's query() API, you have all three — the CLI backing each call has OpenTelemetry instrumentation built in. No extra library; just env vars.

Enable telemetry

CLAUDE_CODE_ENABLE_TELEMETRY=1
CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1   # required for span traces
OTEL_TRACES_EXPORTER=otlp
OTEL_METRICS_EXPORTER=otlp
OTEL_LOGS_EXPORTER=otlp
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_ENDPOINT=http://your-collector:4318

Set these in your shell, Dockerfile, or Kubernetes manifest and every query() call exports automatically. Or inject them per-call when different agents in the same process need different settings:

from claude_agent_sdk import query, ClaudeAgentOptions

options = ClaudeAgentOptions(env={
    "CLAUDE_CODE_ENABLE_TELEMETRY": "1",
    "CLAUDE_CODE_ENHANCED_TELEMETRY_BETA": "1",
    "OTEL_TRACES_EXPORTER": "otlp",
    "OTEL_METRICS_EXPORTER": "otlp",
    "OTEL_LOGS_EXPORTER": "otlp",
    "OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf",
    "OTEL_EXPORTER_OTLP_ENDPOINT": "http://your-collector:4318",
})

async for message in query("Summarize the diff in git HEAD", options=options):
    print(message)

What you get

SignalContents
MetricsToken counters, cost, session counts, lines-of-code, tool decisions
Log eventsStructured records per prompt, API request, API error, tool result
Tracesclaude_code.interaction → child spans for each llm_request and tool

Traces give the most detail: one turn produces a parent claude_code.interaction span with child spans for every model call and tool invocation. When an agent spawns a subagent via the Task tool, the subagent's spans nest under the parent's claude_code.tool span — the full delegation chain appears as one connected tree.

Linked to your application's traces

The SDK automatically propagates W3C trace context (TRACEPARENT) into the CLI subprocess. Call query() while an active OpenTelemetry span exists in your application and the agent's spans appear as children of your span — one connected trace, not two disconnected roots. This is the key advantage over external plugins: the agent run shows up inside your API request's trace, not as a separate stream.

For short-lived processes

By default, metrics export every 60 seconds. Shorten the interval for batch jobs or CI steps so data isn't lost before the process exits:

OTEL_METRIC_EXPORT_INTERVAL=1000   # milliseconds
OTEL_LOGS_EXPORT_INTERVAL=1000
OTEL_TRACES_EXPORT_INTERVAL=1000

Content your agent reads and writes is not recorded by default — only structure (durations, model names, token counts). Set OTEL_LOG_USER_PROMPTS=1 or OTEL_LOG_TOOL_DETAILS=1 to opt in if your pipeline is approved to store that data.

Sources: Observability with OpenTelemetry — Claude Agent SDK Docs | Monitoring reference | Agent SDK overview