Claude Code exports OpenTelemetry data when you set CLAUDE_CODE_ENABLE_TELEMETRY=1 and choose an exporter: metrics go out over the standard metrics protocol, events over the logs protocol, and distributed traces are available as a beta. You point it at any OTLP collector, or at Prometheus, and get sessions, tokens, cost, commits and tool activity per user and team.
This guide covers the setup, the variables that matter, how admins enforce it, what each metric means and what stays private. It is based on the official Claude Code monitoring documentation, read on 24 October 2026.
How do you turn on OpenTelemetry in Claude Code?
Telemetry is off until you opt in. The quick start from the docs:
# 1. Enable telemetry
export CLAUDE_CODE_ENABLE_TELEMETRY=1
# 2. Choose exporters
export OTEL_METRICS_EXPORTER=otlp # otlp, prometheus, console, none
export OTEL_LOGS_EXPORTER=otlp # otlp, console, none
# 3. Point at your collector
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
# 4. Authentication, if your collector needs it
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer your-token"
claude
Claude Code has no default OTLP protocol, so set OTEL_EXPORTER_OTLP_PROTOCOL (or the per-signal version) for each otlp exporter you turn on. Valid values are grpc, http/json and http/protobuf.
To verify, check your backend for claude_code.session.count, which Claude Code emits when a session starts. For a logs-only setup, send a prompt and look for the claude_code.user_prompt event. If nothing arrives, start Claude Code with claude --debug-file <path> and read the log. Failures from your exporters show up as [3P telemetry] errors; lines marked [Anthropic telemetry] are about Anthropic's separate operational telemetry, not your setup.
For local testing, OTEL_METRICS_EXPORTER=console with OTEL_METRIC_EXPORT_INTERVAL=1000 prints metrics every second. With prometheus as the exporter, metrics are scraped from http://localhost:9464/metrics.
Which configuration variables matter most?
| Variable | What it does | Default |
|---|---|---|
CLAUDE_CODE_ENABLE_TELEMETRY |
Turns telemetry on (required) | Off |
OTEL_METRICS_EXPORTER |
Metrics exporters, comma-separated | None |
OTEL_LOGS_EXPORTER |
Events exporters, comma-separated | None |
OTEL_EXPORTER_OTLP_ENDPOINT |
Collector for all signals | None |
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT / _LOGS_ENDPOINT |
Per-signal collector, overrides the generic one | None |
OTEL_METRIC_EXPORT_INTERVAL |
Metrics export interval in ms | 60000 |
OTEL_LOGS_EXPORT_INTERVAL |
Events export interval in ms | 5000 |
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE |
delta or cumulative |
delta |
OTEL_RESOURCE_ATTRIBUTES |
Custom attributes such as team or cost center | None |
You can send metrics and events to different backends by setting the per-signal endpoint and protocol variables. For mTLS, the client certificate variables depend on the protocol: CLAUDE_CODE_CLIENT_CERT and CLAUDE_CODE_CLIENT_KEY for HTTP, and OTEL_EXPORTER_OTLP_CLIENT_KEY and OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE for gRPC.
If your collector needs short-lived tokens, the otelHeadersHelper setting runs a script that prints a JSON object of headers. It runs at startup and every 29 minutes by default, and only applies to the HTTP protocols.
How do administrators enforce telemetry for everyone?
Put the same variables in the env block of managed settings, which take precedence over each developer's own configuration:
{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_LOGS_EXPORTER": "otlp",
"OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://collector.example.com:4317",
"OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer example-token"
}
}
When managed settings set an OTEL_EXPORTER_OTLP_* endpoint, protocol or credential, Claude Code removes conflicting developer-set variables at startup, so nobody can redirect one signal to a different collector. Exporter selectors such as OTEL_LOGS_EXPORTER follow normal precedence, though, so set them in managed settings too if you need them locked.
Two details catch people out:
- Claude Code ignores the exporter variables in a repository's
.claude/settings.jsonand.claude/settings.local.json. A repo cannot turn telemetry on, choose where it goes or capture content, though it can turn a signal off. - Claude Code does not pass
OTEL_*variables to the subprocesses it starts, including Bash commands, hooks and MCP servers.
Cloud sessions run on Anthropic's infrastructure, not on developer machines, so they need the variables in server-managed settings or in the cloud environment's variables. Don't put collector tokens in environment variables, because anyone who uses the environment can read them. The enterprise guide explains each delivery method.
What metrics does Claude Code export?
| Metric | What it counts | Unit |
|---|---|---|
claude_code.session.count |
Sessions started | none |
claude_code.lines_of_code.count |
Lines added or removed | none |
claude_code.pull_request.count |
Pull requests created | none |
claude_code.commit.count |
Git commits created | none |
claude_code.cost.usage |
Session cost | USD |
claude_code.token.usage |
Tokens, split by input, output, cacheRead, cacheCreation |
tokens |
claude_code.code_edit_tool.decision |
Accept or reject decisions for Edit, Write and NotebookEdit | none |
claude_code.active_time.total |
Active time, excluding idle | s |
Every metric carries standard attributes, including session.id, organization.id, user.account_uuid, user.email when available and terminal.type. Cost and token metrics also carry model, query_source (main, subagent or auxiliary), effort, and attribution attributes such as skill.name, plugin.name and agent.name.
The docs are explicit that cost metrics are approximations. For official billing, use your API provider's data. On Bedrock, Agent Platform or Foundry that means your cloud's cost tools.
What events can you collect?
With OTEL_LOGS_EXPORTER set, Claude Code sends events through the logs protocol. A prompt.id attribute ties every event from one user prompt together. Useful ones include:
claude_code.user_prompt: a prompt was submitted (text redacted by default).claude_code.api_requestandclaude_code.api_error: each model call, with model, estimated cost, duration and token counts, and terminal errors after retries.claude_code.tool_resultandclaude_code.tool_decision: which tools ran, whether they succeeded, and whether each call was accepted or rejected.claude_code.permission_mode_changed,claude_code.authandclaude_code.mcp_server_connection: useful for security audits.claude_code.skill_activated,claude_code.plugin_loadedandclaude_code.hook_execution_complete: what extensions did.claude_code.compactionandclaude_code.subagent_completed: context and subagent activity.
Claude Code retries failed API requests internally and logs one claude_code.api_error only after it gives up, so that event is the signal a request truly failed.
What does Claude Code send, and what stays private?
OpenTelemetry export is opt-in, and the data goes only to the endpoint you configure, never to Anthropic. By default:
- Raw file contents and code snippets are not included in metrics or events.
- Prompt content is not collected; only prompt length.
OTEL_LOG_USER_PROMPTS=1adds it. - Assistant response text is not collected;
OTEL_LOG_ASSISTANT_RESPONSES=1adds it. When unset, it followsOTEL_LOG_USER_PROMPTS. - Tool arguments such as Bash commands and file paths are not logged;
OTEL_LOG_TOOL_DETAILS=1adds them. user.emailis included when you sign in with OAuth. Filter it in your backend if that is a concern.
OTEL_LOG_RAW_API_BODIES emits full API request and response bodies, which include the whole conversation, so treat it as consent to everything the other flags would reveal.
This is separate from Anthropic's own operational telemetry. That is controlled by DISABLE_TELEMETRY, DISABLE_ERROR_REPORTING or CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, as described on the data usage page, and it is off by default on Bedrock, Agent Platform and Foundry.
How do you split usage by team or repository?
Add custom attributes with OTEL_RESOURCE_ATTRIBUTES. They appear on every metric and event, so you can filter by department, team or cost center:
export OTEL_RESOURCE_ATTRIBUTES="department=engineering,team.id=platform,cost_center=eng-123"
Values cannot contain spaces. Use underscores or percent-encoding instead, because quotes do not escape them. Each custom key becomes a label on every metric series, which raises storage cost, so set OTEL_METRICS_INCLUDE_RESOURCE_ATTRIBUTES=false if you want them in the resource block only.
Set OTEL_METRICS_INCLUDE_REPOSITORY=true to tag data with the repository from its origin remote, such as vcs.repository.name. Other switches control cardinality: OTEL_METRICS_INCLUDE_SESSION_ID and OTEL_METRICS_INCLUDE_ACCOUNT_UUID default to true, while OTEL_METRICS_INCLUDE_VERSION and OTEL_METRICS_INCLUDE_ENTRYPOINT default to false.
Can you export traces from Claude Code?
Yes, as a beta. Set CLAUDE_CODE_ENABLE_TELEMETRY=1 and CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1, then choose OTEL_TRACES_EXPORTER. Spans link each prompt to the API requests and tool runs it triggered, so one request shows as a single trace.
Spans redact prompt text, tool input and tool content by default. While tracing is active, Bash and PowerShell subprocesses inherit a TRACEPARENT variable, so scripts Claude runs can attach their own spans to the same trace.
How do skills and plugins show up in the data?
Cost and token metrics carry skill.name, plugin.name and agent.name, so you can see which skills and subagents drive spend. Built-in, bundled and user-defined skill names appear as-is, while third-party plugin skill names are replaced with third-party unless you set OTEL_LOG_TOOL_DETAILS=1.
That makes OpenTelemetry a practical way to see which shared skills a team really uses. If you keep those skills in Kipt, they sit as Markdown in a private GitHub repo you own and install into Claude Code with one npx skills add command, and the metrics then tell you which ones earn their place. For a starter dashboard, Anthropic's Claude Code ROI measurement guide includes Docker Compose, Prometheus and OpenTelemetry setups.