Claude Code OpenTelemetry: Track Usage and Cost (Setup)

David IyaDavid Iya November 1, 2026 9 min read

What Claude Code OpenTelemetry gives you

Claude Code OpenTelemetry export sends usage data from every session to a collector you run. Metrics arrive as time series: sessions, lines changed, commits, pull requests, tokens, estimated cost and active time. Events arrive through the logs protocol: each prompt, API request, API error, tool result and permission decision. Traces are available as a beta. Nothing is exported until someone turns it on.

Team and Enterprise plans already get an analytics dashboard with active users, sessions, accept rates and contribution metrics. That covers adoption. OpenTelemetry is what you add when you need per-user token counts and cost estimates in your own monitoring stack, alerts on spend spikes, or a breakdown by team, cost center, skill or model that the dashboard does not give you. My take: if you are paying for Claude Code across more than a handful of people, you want this on before the first surprise bill, not after.

Quick setup on one machine

Test on your own machine before you roll anything out. You need a collector that accepts OTLP, running locally or somewhere your laptop can reach. Then set these variables in your shell or in the env block of ~/.claude/settings.json:

  1. CLAUDE_CODE_ENABLE_TELEMETRY=1. Nothing is exported without it.
  2. OTEL_METRICS_EXPORTER=otlp and OTEL_LOGS_EXPORTER=otlp. Metrics also accept prometheus or console, and either can be none.
  3. OTEL_EXPORTER_OTLP_PROTOCOL set to grpc, http/json or http/protobuf. Claude Code has no default protocol, so leaving this out is the most common reason nothing arrives.
  4. OTEL_EXPORTER_OTLP_ENDPOINT set to your collector, such as http://localhost:4317 for gRPC.
  5. OTEL_EXPORTER_OTLP_HEADERS if your collector needs a token, in the form Authorization=Bearer your-token.

Metrics export every 60 seconds by default and logs every 5 seconds. While testing, drop OTEL_METRIC_EXPORT_INTERVAL to 10000 so you are not waiting a minute for each check, then set it back for production. Start a session in the desktop app or the terminal and look for claude_code.session.count in your backend. For a logs-only setup, send a prompt and look for the claude_code.user_prompt event.

Roll it out to a team with managed settings

For a company, do not ask every developer to edit their shell. Put the same variables in the env block of your managed settings file and push it with your device management. The desktop app's Code tab reads managed settings too, so desktop users are covered alongside terminal users. The settings.json guide covers where each settings file lives and which one wins.

Managed settings also lock the destination. When you set OTEL_EXPORTER_OTLP_ENDPOINT there, Claude Code removes any per-signal endpoint a developer set, so nobody can quietly send one signal to a different collector. Setting headers or client certificates there removes developer-set endpoints too, because your credentials should only ever reach the collector you chose. The exporter selectors are the exception: a developer can still switch a signal to none or console unless you set OTEL_METRICS_EXPORTER and OTEL_LOGS_EXPORTER in managed settings as well. Set all of them.

Repositories cannot interfere in the other direction. Claude Code ignores the OpenTelemetry exporter variables in a repo's .claude/settings.json and .claude/settings.local.json, so a cloned project cannot switch telemetry on, choose where it goes or capture content. A repo can only turn a signal off by setting its exporter to none, and only when managed settings have not already set that variable.

The metrics that matter

Claude Code OpenTelemetry metrics and what to use them for

MetricWhat it countsUse it for
claude_code.session.countSessions started, with a start_type of fresh, resume or continueAdoption over time
claude_code.cost.usageEstimated cost in USD after each API requestSpend by person, team, model, skill or subagent
claude_code.token.usageTokens by type: input, output, cacheRead, cacheCreationSpotting heavy sessions and cache behavior
claude_code.lines_of_code.countLines added and removed, by modelRough output volume
claude_code.commit.countCommits created through Claude CodeWorkflow impact
claude_code.pull_request.countPull and merge requests createdWorkflow impact
claude_code.code_edit_tool.decisionAccept or reject decisions on Edit, Write and NotebookEditTrust and review habits by language
claude_code.active_time.totalActive seconds, split into user and cli timeReal usage, not idle sessions left open

The cost metric is an estimate. For billing, your API provider's own records are the source of truth. Use claude_code.cost.usage for trends and alerts, not for invoices. The useful part is the breakdown: cost and token metrics carry model, effort level and query_source, which tells you whether spend came from the main conversation, subagents or background requests.

The three alerts I would set first are a cost spike per user per day, unusual token volume, and a jump in session count from one account. All three come straight from these metrics. If you are trying to bring spend down after you see it, how to cut Claude Code token usage and the effort levels guide are the two levers that move it most.

Split usage by team and cost center

Every metric and event already carries a session ID, your organization ID, account identifiers and, when signed in, the user's email. To add your own grouping, set OTEL_RESOURCE_ATTRIBUTES with comma-separated key=value pairs, for example department=engineering,team.id=platform,cost_center=eng-123. Those keys become labels on every metric and event, so you can build a dashboard per team or charge spend back to a cost center.

  • No spaces in values. Use underscores, camelCase or percent-encoding. Wrapping a value in quotes keeps the quotes in the value, it does not escape the space.
  • Every custom key is a new label on every series, so high-cardinality values raise your storage cost. If you only need them on the resource block, set OTEL_METRICS_INCLUDE_RESOURCE_ATTRIBUTES=false.
  • Session IDs and account IDs are on by default. Version, entrypoint and repository attributes are off by default and each has its own OTEL_METRICS_INCLUDE flag.
  • Desktop app sessions report service.name as claude-code-desktop, not claude-code. If your dashboards filter on claude-code, add the desktop value or you will miss everyone using the app.

What stays private by default

This is the question every security team asks first, and the defaults are sensible. Raw file contents and code snippets are never in metrics or events. Prompt text is not collected, only prompt length. Response text is not collected, only its length. Tool arguments like Bash commands and file paths are not logged. All of it goes only to the endpoint you configure.

Content flags and what each one adds

FlagWhat it addsDefault
OTEL_LOG_USER_PROMPTS=1Prompt text on user_prompt eventsOff
OTEL_LOG_ASSISTANT_RESPONSES=1Response text on assistant_response events. Falls back to the prompts flag when unsetOff
OTEL_LOG_TOOL_DETAILS=1Bash commands, file paths, URLs, and real skill, plugin and MCP namesOff
OTEL_LOG_TOOL_CONTENT=1Tool output in trace spans, such as file contents and command outputOff, needs tracing
OTEL_LOG_RAW_API_BODIESFull API request and response bodies, including the whole conversationOff

My advice: leave the content flags off for the first rollout. Usage and cost answer most of what a team lead wants to know, and turning on prompt or tool content changes the conversation with your developers and your legal team. If you need it later for audits, turn it on deliberately and filter it in your collector. If you set OTEL_LOG_ASSISTANT_RESPONSES=0 explicitly, you can collect prompts without collecting responses.

Free Claude Code drops, straight to your inbox

Short, practical drops on skills, MCP, agents, prompts, and more. No spam, unsubscribe anytime.

Frequently asked questions

How do I enable OpenTelemetry in Claude Code?

Set CLAUDE_CODE_ENABLE_TELEMETRY=1, set OTEL_METRICS_EXPORTER and OTEL_LOGS_EXPORTER to otlp, set OTEL_EXPORTER_OTLP_PROTOCOL and OTEL_EXPORTER_OTLP_ENDPOINT for your collector, and add OTEL_EXPORTER_OTLP_HEADERS if it needs a token. Then check your backend for the claude_code.session.count metric.

Does Claude Code OpenTelemetry send my prompts or code?

Not by default. Metrics and events never include raw file contents or code snippets, and prompt and response text are recorded only as lengths unless you set OTEL_LOG_USER_PROMPTS or OTEL_LOG_ASSISTANT_RESPONSES. Everything goes only to the endpoint you configure.

How do I turn on Claude Code telemetry for my whole team?

Put the variables in the env block of your managed settings file and deploy it to every machine. An endpoint or credential set in managed settings removes conflicting developer-set endpoints. Set the exporter selectors there too so developers cannot switch a signal off.

Is the Claude Code cost metric accurate enough for billing?

No. claude_code.cost.usage is an estimate meant for trends, alerts and attribution. Use your API provider's billing records for actual charges.

Why is no Claude Code telemetry arriving at my collector?

The usual causes are a missing OTEL_EXPORTER_OTLP_PROTOCOL, since Claude Code has no default, a wrong endpoint, or a collector your machine cannot reach. Start Claude Code with claude --debug-file and a path, then look for [3P telemetry] errors in that file.

Last reviewed by David Iya on November 1, 2026

David Iya

Written by

David Iya

Forbes 30 Under 30 · Y Combinator

Keep reading

Claude CodeSetup

Claude Code with GitHub Enterprise Server: Setup and Limits

Claude Code works with GitHub Enterprise Server on Team and Enterprise plans. An Owner connects your GHES instance once from Organization settings > Git providers, installs the GitHub App it creates, and then developers get cloud sessions, Code Review and GHES-hosted plugin marketplaces with no per-repo setup. Here is the setup, what works and what does not, and the fixes for the errors you will hit.

David Iya 9 min
Read article
Claude CodeSetup

Claude Code Behind a Corporate Proxy: Proxy, CA Certs and Fixes

To run Claude Code behind a corporate proxy, set HTTPS_PROXY to the proxy's URL, trust your company's CA with NODE_EXTRA_CA_CERTS if the proxy inspects TLS, and allow the hosts Claude Code needs. Put all of it in ~/.claude/settings.json so the desktop app, the terminal and background agents all see it. Here is the setup, the hosts to allowlist, and the fixes for the errors you will hit.

David Iya 9 min
Read article

Ready to build it yourself?

Join Claude Code Club, the #1 community for learning claude code, for $9/month.

← Back to the blog