- which tools they called
- how long each model request took
- how many tokens were spent
- where failures occurred
How telemetry flows from the SDK
The Agent SDK runs the Claude Code CLI as a child process and communicates with it over a local pipe. The CLI has OpenTelemetry instrumentation built in: it records spans around each model request and tool execution, emits metrics for token and cost counters, and emits structured log events for prompts and tool results. The SDK does not produce telemetry of its own. Instead, it passes configuration through to the CLI process, and the CLI exports directly to your collector. Configuration is passed as environment variables. By default, the child process inherits your application’s environment, so you can configure telemetry in either of two places:- Process environment: set the variables in your shell, container, or orchestrator before your application starts. Every
query()call picks them up automatically with no code change. This is the recommended approach for production deployments. - Per-call options: set the variables in
ClaudeAgentOptions.env(Python) oroptions.env(TypeScript). Use this when different agents in the same process need different telemetry settings. In Python,envis merged on top of the inherited environment. In TypeScript,envreplaces the inherited environment entirely, so include...process.envin the object you pass.
For the complete list of metric names, event names, and attributes, see the Claude Code Monitoring reference. The Agent SDK emits the same data because it runs the same CLI. Span names are listed in Read agent traces below.
Enable telemetry export
Telemetry is off until you setCLAUDE_CODE_ENABLE_TELEMETRY=1 and choose at least one exporter. The most common configuration sends all three signals over OTLP HTTP to a collector.
The following example sets the variables in a dictionary and passes them through options.env. The agent runs a single task, and the CLI exports spans, metrics, and events to the collector at collector.example.com while the loop consumes the response stream:
options.env entirely.
To confirm that export is working, check your collector’s logs for incoming spans, metrics, and log events after the task completes. The CLI fails silently on export errors by default: if the endpoint is unreachable or rejects the data, the agent still runs normally and the CLI drops the telemetry without surfacing an error in your application. To surface exporter errors, set CLAUDE_CODE_OTEL_DIAG_STDERR=1 alongside the exporter variables and read the diagnostics through the SDK’s stderr callback (Python) or stderr option (TypeScript). Requires Claude Code v2.1.179 or later.
The
console exporter writes telemetry to standard output, which the SDK uses
as its message channel. Do not set console as an exporter value when running
through the SDK. To inspect telemetry locally, point
OTEL_EXPORTER_OTLP_ENDPOINT at a local collector or an all-in-one Jaeger
container instead.