Observe Claude Code with OpenTelemetry

Claude Code exports its own usage data over OpenTelemetry: metrics for sessions, tokens, and cost, structured events for prompts, tool calls, and API errors, and optional traces for individual interactions. Point that export at Better Stack to see how your team uses Claude Code, what it costs, and where it fails, with no extra instrumentation.

Prerequisites

You need Claude Code installed and authenticated, and a Better Stack Telemetry source to receive the data.

Create one in Telemetry β†’ Sources β†’ Connect source, or read more in the Quick start guide. Select the OpenTelemetry platform, then copy the source token and ingesting host shown for the source.

Use the ingesting host from your source

Copy the ingesting host exactly as shown for your source. It already points to your team's data region, so your metrics and logs land in the right place.

Connect Claude Code to Better Stack

There are two ways to send the data. Use the settings file to keep telemetry on across sessions, or shell variables to turn it on for a single terminal session. Either way, replace $INGESTING_HOST and $SOURCE_TOKEN with the values from your source.

Keep telemetry on across sessions

Add the variables to your Claude Code settings file. ~/.claude/settings.json applies to every project, while a project's .claude/settings.json applies to that project and can be committed to source control.

~/.claude/settings.json
{
  "env": {
    "CLAUDE_CODE_ENABLE_TELEMETRY": "1",
    "OTEL_METRICS_EXPORTER": "otlp",
    "OTEL_LOGS_EXPORTER": "otlp",
    "OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf",
    "OTEL_EXPORTER_OTLP_ENDPOINT": "https://$INGESTING_HOST",
    "OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer $SOURCE_TOKEN"
  }
}


Turn telemetry on for one session

Export the variables in your shell before starting Claude Code. They apply only to that terminal session.

Enable telemetry for one session
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=otlp
export OTEL_LOGS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=https://$INGESTING_HOST
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer $SOURCE_TOKEN"


Better Stack ingests OpenTelemetry over HTTP, so with the http/protobuf protocol Claude Code appends the per-signal paths /v1/metrics and /v1/logs to the endpoint for you.

Claude Code reads telemetry configuration only at startup, so restart it after any change.

Verify the data is arriving

Start Claude Code:

Start Claude Code
claude

At the prompt, give it a small task so it exercises the model and a tool. For example:

Example prompt
Create a file called hello.py that prints "Hello from Better Stack", then run it.

Approve the action when Claude Code asks. This one task produces a claude_code.user_prompt, one or more claude_code.api_request events, a claude_code.tool_decision and claude_code.tool_result for the file it writes and runs, and a claude_code.assistant_response.

Open Live tail in Better Stack. Within a minute you should see those claude_code.* events.

Live tail showing Claude Code events arriving in Better Stack

Can't see any data?

Run claude --debug and look for OpenTelemetry export errors. Check that the ingesting host and source token match your source, and remember that Claude Code reads telemetry configuration only at startup.

What Claude Code exports

Claude Code emits these metrics, each attributable by user, team, and model:

  • claude_code.session.count: sessions started
  • claude_code.cost.usage: estimated spend in USD
  • claude_code.token.usage: tokens used, with a type label of input, output, cacheCreation, or cacheRead
  • claude_code.lines_of_code.count: lines added or removed
  • claude_code.commit.count: git commits created
  • claude_code.pull_request.count: pull requests opened
  • claude_code.code_edit_tool.decision: edit permission decisions, with a decision label of accept or reject
  • claude_code.active_time.total: active time in seconds

For the full list of metrics, events, and attributes, see the Claude Code monitoring documentation.

Capture prompts, tool calls, and traces

Claude Code redacts prompt text and tool details by default. To include them, add these variables to the env block:

Capture prompt and tool content
{
  "env": {
    "OTEL_LOG_USER_PROMPTS": "1",
    "OTEL_LOG_TOOL_DETAILS": "1"
  }
}

Review the privacy impact first

These variables send prompt text, commands, file paths, and other potentially sensitive content to your source. Enable them only where that is acceptable.

Claude Code can also export distributed traces that link each prompt to the API requests and tool executions it triggers. This capability is currently in beta. To turn it on, add "CLAUDE_CODE_ENHANCED_TELEMETRY_BETA": "1" and "OTEL_TRACES_EXPORTER": "otlp" to the same env block. Traces reach Better Stack at the same endpoint. See Tracing for how to explore them.

What to do next

Need help?

Please let us know at hello@betterstack.com.
We're happy to help! πŸ™