Skip to content

Claude Code OpenTelemetry: metrics to Grafana or Datadog

How to turn on Claude Code's OpenTelemetry export, which environment variables to set, every metric and event it sends, and how to roll it out to a whole team with managed settings.

Short answer: Claude Code can export its own usage as OpenTelemetry metrics and events. Set CLAUDE_CODE_ENABLE_TELEMETRY=1, choose an exporter with OTEL_METRICS_EXPORTER and OTEL_LOGS_EXPORTER, point OTEL_EXPORTER_OTLP_ENDPOINT at your collector, and sessions, tokens, cost, lines of code, commits and tool decisions start arriving in Grafana, Datadog, Honeycomb or any backend that speaks OTLP.

It is off by default, and prompt text is not included unless you ask for it.

What is the minimal setup?

export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=otlp
export OTEL_LOGS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
claude

To check it works before you have a collector, use the console exporter and a short interval:

export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=console
export OTEL_METRIC_EXPORT_INTERVAL=10000
claude

The metrics are printed to the terminal every ten seconds.

Which environment variables matter?

VariableWhat it does
CLAUDE_CODE_ENABLE_TELEMETRY1 turns the export on. Nothing is sent without it
OTEL_METRICS_EXPORTERotlp, prometheus or console
OTEL_LOGS_EXPORTERotlp or console, for the events
OTEL_EXPORTER_OTLP_PROTOCOLgrpc, http/json or http/protobuf
OTEL_EXPORTER_OTLP_ENDPOINTWhere your collector listens
OTEL_EXPORTER_OTLP_HEADERSAuthentication, such as Authorization=Bearer <token>
OTEL_METRIC_EXPORT_INTERVALMilliseconds between metric exports (60 seconds by default)
OTEL_RESOURCE_ATTRIBUTESYour own labels, such as team.id=platform,department=eng
OTEL_LOG_USER_PROMPTS1 includes prompt text in events. Leave it off unless you need it

What metrics does Claude Code export?

MetricWhat it countsUseful attributes
claude_code.session.countSessions startedsession.id
claude_code.lines_of_code.countLines added and removedtype, model
claude_code.pull_request.countPull requests created
claude_code.commit.countGit commits created
claude_code.cost.usageCost in US dollarsmodel
claude_code.token.usageTokenstype (input, output, cacheRead, cacheCreation), model
claude_code.code_edit_tool.decisionEdits accepted or rejectedtool_name, decision, language
claude_code.active_time.totalActive time in secondstype

Every metric also carries standard attributes such as the session id, the organization and a hashed user account id, so you can group by person without exporting names.

What events does it send?

Events go through the logs exporter, one per thing that happened:

  • claude_code.user_prompt: a prompt was submitted (its length, and its text only with OTEL_LOG_USER_PROMPTS=1)
  • claude_code.api_request: a call to the model, with model, tokens, cost and duration
  • claude_code.api_error: a failed call, with the error and status code
  • claude_code.tool_result: a tool finished, with its name, success and duration
  • claude_code.tool_decision: a tool call was accepted or rejected, and by whom

Metrics answer "how much"; events answer "what exactly happened, and how long did it take".

How do I turn it on for the whole team?

Put the variables in the env block of the managed settings file, so every developer's Claude Code exports to the same collector and nobody has to remember to set them:

{
  "env": {
    "CLAUDE_CODE_ENABLE_TELEMETRY": "1",
    "OTEL_METRICS_EXPORTER": "otlp",
    "OTEL_LOGS_EXPORTER": "otlp",
    "OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
    "OTEL_EXPORTER_OTLP_ENDPOINT": "https://otel.example.com:4317",
    "OTEL_RESOURCE_ATTRIBUTES": "team.id=platform"
  }
}

Managed settings override what users set themselves. See Claude Code managed settings for where the file lives on each system.

Which charts are worth building first?

Start with the four that answer real questions:

  1. Cost per day by model, from claude_code.cost.usage. The model mix is usually the biggest lever on spend.
  2. Active people per week, from distinct user ids on claude_code.session.count. That is adoption.
  3. Commits, pull requests and lines added, from the three counters. That is output, not volume.
  4. Edit acceptance rate, from claude_code.code_edit_tool.decision. A falling rate means Claude's edits are being thrown away.

Keep team dashboards at the level of groups, not people. A rule many teams use: never show a group smaller than five.

What if I have no collector?

OpenTelemetry only records from the day you turn it on, and it needs somewhere to send the data. Claude Code already keeps every past session in ~/.claude/projects (see where Claude Code keeps your history), with the same tokens, cost, tool calls and decisions.

Usage Insights for Claude Code reads that folder in your browser, with nothing uploaded, and draws the charts above without any collector: cost by model, tokens, commits, kept edits, turn times, API errors and tool health. Its Catalog view lists the OpenTelemetry names next to every metric, so you can rebuild any chart in Grafana or Datadog later. The lesson Is Claude Code working well? walks through the telemetry side.

Where can you check this?

What is the short version?

  • CLAUDE_CODE_ENABLE_TELEMETRY=1 plus an exporter and an endpoint.
  • Eight metrics: sessions, lines, PRs, commits, cost, tokens, edit decisions, active time.
  • Events for prompts, model calls, errors, tool results and decisions.
  • Roll it out with the env block of managed settings; keep prompt text off.
The tool

Do it in your browser.

Claude Code

Usage Insights for Claude Code

See what you and your team did with Claude: activity, what you built, the tools and skills you used, cost and telemetry, from your Claude Code history, in your browser.

Keep reading

More from the blog.

Every post

Contact