Kipt

Claude Code OpenTelemetry: monitor usage, costs and tool activity

Set up Claude Code OpenTelemetry: enable telemetry, choose exporters, enforce it with managed settings, and use the metrics, events and traces it exports.

By the Kipt team · Updated 24 October 2026

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.json and .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_request and claude_code.api_error: each model call, with model, estimated cost, duration and token counts, and terminal errors after retries.
  • claude_code.tool_result and claude_code.tool_decision: which tools ran, whether they succeeded, and whether each call was accepted or rejected.
  • claude_code.permission_mode_changed, claude_code.auth and claude_code.mcp_server_connection: useful for security audits.
  • claude_code.skill_activated, claude_code.plugin_loaded and claude_code.hook_execution_complete: what extensions did.
  • claude_code.compaction and claude_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=1 adds it.
  • Assistant response text is not collected; OTEL_LOG_ASSISTANT_RESPONSES=1 adds it. When unset, it follows OTEL_LOG_USER_PROMPTS.
  • Tool arguments such as Bash commands and file paths are not logged; OTEL_LOG_TOOL_DETAILS=1 adds them.
  • user.email is 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.

Questions

How do I enable OpenTelemetry in Claude Code?

Set CLAUDE_CODE_ENABLE_TELEMETRY=1, choose exporters with OTEL_METRICS_EXPORTER and OTEL_LOGS_EXPORTER, and point OTEL_EXPORTER_OTLP_ENDPOINT and OTEL_EXPORTER_OTLP_PROTOCOL at your collector. Then start claude and look for the claude_code.session.count metric in your backend.

Does Claude Code telemetry include my prompts or code?

Not by default. Metrics and events never include raw file contents or code snippets, and prompts and responses are recorded only as lengths. You must opt in with OTEL_LOG_USER_PROMPTS, OTEL_LOG_ASSISTANT_RESPONSES or OTEL_LOG_TOOL_DETAILS to send that content, and it goes only to the endpoint you configure.

What metrics does Claude Code export?

Eight metrics: session count, lines of code, pull requests, commits, cost in USD, token usage, code edit tool decisions and active time. Each carries standard attributes such as session.id, organization.id and user.account_uuid, and cost and token metrics also carry the model.

Can a repository turn on Claude Code telemetry?

No. Claude Code ignores the OpenTelemetry exporter variables in a repository's .claude/settings.json and .claude/settings.local.json. Set them in managed settings, your shell, or ~/.claude/settings.json. A repository can still turn a signal off.

Are Claude Code OpenTelemetry cost numbers exact?

No. The docs call cost metrics approximations. Use your API provider's billing, such as the Claude Console, Amazon Bedrock or Google Cloud's Agent Platform, for official numbers.

More in Claude Code

All guides

Keep your prompts and skills in one place, in your own GitHub. Install every skill with one command.

Get started

Kipt is an independent product, not affiliated with or endorsed by Anthropic, OpenAI, Cursor or GitHub. Claude, ChatGPT, Codex, Cursor and GitHub are trademarks of their owners.