llm-integration.eu

Claude Code Telemetry: OpenTelemetry Setup for Teams

Claude Code telemetry with OpenTelemetry: the 8 metrics, privacy defaults, a managed-settings file, a collector that strips user IDs, and Bedrock or Vertex setups.

Updated 11 min readFacts verified on 1 October 2026

TL;DR

Claude Code telemetry is off until you set CLAUDE_CODE_ENABLE_TELEMETRY=1 and an OpenTelemetry exporter. It then sends 8 metrics (sessions, tokens, cost, lines, commits, PRs, edit decisions, active time) and optional events to your collector. Prompts stay redacted by default. On Bedrock and Vertex, OpenTelemetry is the only usage view you get. Aggregate per team, not per person.

What does Claude Code telemetry export?

Claude Code telemetry is OpenTelemetry data that Claude Code sends to a collector you choose. Metrics go out as time series, events go out through the logs protocol, and traces are an optional beta. Nothing reaches your backend until you enable it: CLAUDE_CODE_ENABLE_TELEMETRY=1 is required, and each signal needs an exporter such as otlp, prometheus or console.

The monitoring documentation lists eight metrics. Metric export runs every 60,000 ms by default, logs every 5,000 ms. The meter name is com.anthropic.claude_code, and service.name is claude-code for terminal sessions and claude-code-desktop for the Code tab in the desktop app. Filter on both, or desktop usage disappears from your dashboards.

Metric What it counts Useful attributes
claude_code.session.count Sessions started start_type (fresh, resume, continue)
claude_code.token.usage Tokens, unit tokens type (input, output, cacheRead, cacheCreation), model
claude_code.cost.usage Estimated cost, unit USD model, query_source, effort
claude_code.lines_of_code.count Lines added or removed type, model
claude_code.commit.count Git commits created standard attributes
claude_code.pull_request.count PRs or MRs created standard attributes
claude_code.code_edit_tool.decision Accepted or rejected Edit, Write, NotebookEdit decision, language
claude_code.active_time.total Active time, unit s type (user, cli)

Events are the detail layer: claude_code.user_prompt, claude_code.api_request (with cost_usd, duration_ms and token counts per call), claude_code.tool_result, claude_code.tool_decision, claude_code.api_error and more than twenty others. They carry a prompt.id that ties every API call and tool run back to one prompt. For a cost dashboard you need the metrics. For a security audit or SIEM you need the events.

How do you enforce telemetry for the whole organization?

Put the telemetry variables into the managed settings file on every developer machine. Managed settings outrank user settings, and Claude Code ignores OpenTelemetry exporter variables in a repository’s .claude/settings.json, so a repo cannot switch telemetry on, redirect it, or start capturing prompts. Developers can still turn a signal off unless you also set the exporter selector centrally.

The file lives in a fixed system path per OS, documented on the managed settings page: /Library/Application Support/ClaudeCode/managed-settings.json on macOS, /etc/claude-code/managed-settings.json on Linux and WSL, and C:\Program Files\ClaudeCode\managed-settings.json on Windows. If another team already owns that file, drop a separate 10-telemetry.json into the managed-settings.d/ directory next to it. Claude Code merges the main file first, then every *.json in that directory in alphabetical order.

{
  "env": {
    "CLAUDE_CODE_ENABLE_TELEMETRY": "1",
    "OTEL_METRICS_EXPORTER": "otlp",
    "OTEL_LOGS_EXPORTER": "none",
    "OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
    "OTEL_EXPORTER_OTLP_ENDPOINT": "https://otel.example.internal:4317",
    "OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer REPLACE_ME",
    "OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE": "cumulative",
    "OTEL_METRICS_INCLUDE_ACCOUNT_UUID": "false",
    "OTEL_METRICS_INCLUDE_SESSION_ID": "false",
    "OTEL_RESOURCE_ATTRIBUTES": "department=engineering,team.id=platform,cost_center=eng-123"
  }
}

Four choices in that file are deliberate:

  1. OTEL_LOGS_EXPORTER is none. Metrics answer the cost and adoption questions. Events carry per-prompt identity and belong in a separate, access-restricted pipeline if you need them at all.
  2. Setting OTEL_EXPORTER_OTLP_ENDPOINT centrally locks the destination. Since v2.1.217, Claude Code removes every developer-set per-signal endpoint at startup, so nobody can point metrics at a private collector.
  3. cumulative temporality is what we set for a Prometheus pipeline. The default is delta, and the docs say to switch when your backend expects cumulative values.
  4. OTEL_RESOURCE_ATTRIBUTES tags every datapoint with team and cost center. Values cannot contain spaces: write org.name=Platform_Team, not Platform Team. Quotes do not escape spaces, they become part of the value.

To verify, start a session and look for claude_code.session.count in your backend. If nothing arrives, run claude --debug-file /tmp/cc.log and search the log for [3P telemetry] errors. Lines tagged [Anthropic telemetry] are Anthropic’s own operational telemetry and say nothing about your setup.

Which collector setup keeps the data aggregated?

Run an OpenTelemetry Collector that receives OTLP, deletes the identity attributes, and only then exports to Prometheus or your observability backend. Claude Code always attaches user.id, attaches user.email whenever the user is signed in with a Claude account, and adds account UUIDs unless you disable them. Strip these at the collector, before they reach any storage that a manager can query.

The attributes processor works on traces, metrics and logs, at beta stability. It supports delete and hash. Hashing uses SHA1, which keeps a stable per-person key. That is pseudonymisation, not anonymisation, so a hashed email is still personal data. For a team dashboard we delete. The memory limiter and batch processor follow the collector configuration reference, and the Prometheus exporter requires only an endpoint.

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

processors:
  memory_limiter:
    check_interval: 5s
    limit_mib: 512
  attributes/strip_identity:
    actions:
      - { key: user.email, action: delete }
      - { key: user.id, action: delete }
      - { key: user.account_uuid, action: delete }
      - { key: user.account_id, action: delete }
      - { key: session.id, action: delete }
      - { key: enduser.id, action: delete }
  resource/strip_identity:
    attributes:
      - { key: user.email, action: delete }
      - { key: enduser.id, action: delete }
  batch: {}

exporters:
  prometheus:
    endpoint: 0.0.0.0:8889

service:
  pipelines:
    metrics:
      receivers: [otlp]
      processors: [memory_limiter, attributes/strip_identity, resource/strip_identity, batch]
      exporters: [prometheus]

What remains per datapoint: team.id, department, cost_center, model, type, organization.id and the OS resource attributes. That is enough for every KPI below. We would also refuse dashboard filters that resolve to fewer than five people. A “team” of two is an individual report with extra steps. Five is our editorial threshold, not a legal number.

Without a collector, Claude Code can expose a Prometheus scrape endpoint itself at http://localhost:9464/metrics with OTEL_METRICS_EXPORTER=prometheus. That works for one machine. For a team it means scraping laptops, which nobody should do.

Which dashboard KPIs answer the cost and adoption questions?

Five KPIs cover what budget owners and engineering leads ask: active sessions per team, tokens by type and model, estimated cost per team, accepted versus rejected edits, and lines changed. Build all of them from metrics, grouped by team.id or cost_center, over weeks rather than days. Then reconcile cost with the invoice, because the telemetry cost figure is an estimate.

KPI Source metric Aggregation What it tells you
Adoption claude_code.session.count Sessions per team per week, excluding start_type="agents_view" Whether the rollout is used
Token mix claude_code.token.usage Sum by type and model Cache read share, Opus versus Sonnet share
Cost per team claude_code.cost.usage Sum by cost_center per month Budget burn before the invoice
Edit acceptance claude_code.code_edit_tool.decision accept / (accept + reject) by language Where suggestions fail
Output claude_code.lines_of_code.count, claude_code.commit.count Sum by team per sprint Trend, not productivity score

Anthropic’s own cost guide gives a baseline for alerts: across enterprise deployments, about $13 per developer per active day and $150-250 per developer per month, with 90% of users under $30 per active day. We would alert when a team’s daily cost exceeds its active headcount times $30, which flags a runaway loop without naming anyone.

The monitoring page states plainly that cost metrics are approximations and that official billing comes from your provider: Claude Console, Amazon Bedrock or Google Cloud. Use telemetry for allocation and early warning. Use the cloud bill for the number that goes to finance. Our Claude Code pricing for teams breaks down what the invoice side looks like on seats versus API tokens.

Two upgrade effects distort trend lines. Before v2.1.214, gateways that streamed usage across several frames inflated cost.usage and token.usage by about one extra request per extra frame. Before v2.1.222, the mcp_server.name attribute was set on every request after an MCP call, so MCP shares drop after upgrading. Annotate those versions on your charts.

What changes on Bedrock and Vertex?

On Amazon Bedrock and Google Cloud, OpenTelemetry is the only per-team usage view. Anthropic’s analytics dashboards and the Claude Code Analytics API do not cover cloud-provider usage. There is also no Claude account in the session, so user.email never appears. Server-managed settings do not reach these sessions either, so telemetry must ship through managed settings files or MDM.

The data usage page says Anthropic’s own operational metrics, error reports and /feedback uploads are off by default when CLAUDE_CODE_USE_BEDROCK or CLAUDE_CODE_USE_VERTEX is set. Session quality surveys and the WebFetch domain check still run. So on a cloud provider, the only usage data that leaves the laptop is what you configure in OpenTelemetry. Google Cloud’s offering appears as “Agent Platform” in the current Claude Code docs.

Claude Team / Enterprise Bedrock or Vertex
Built-in dashboard claude.ai/analytics/claude-code (Admins, Owners) None from Anthropic
User identity in telemetry user.email, account IDs Only user.id and session.id
Delivery of telemetry config Server-managed or file-based settings File-based settings or MDM only
Billing truth Claude invoice or spend report AWS or Google Cloud bill

Because identity is missing, the docs suggest adding it yourself through OTEL_RESOURCE_ATTRIBUTES per user. For a team dashboard we would not: set team.id and cost_center per machine image and leave the person out.

AWS publishes a monitoring guidance for Claude Code on Bedrock with two modes. Central mode runs an ADOT collector on ECS Fargate with 0.25 vCPU and 0.5 GB behind a load balancer, for roughly $30-50 a month, and exports to CloudWatch. Sidecar mode sends directly from each machine to the CloudWatch OTLP endpoint for $0 in infrastructure. Note that its dashboards include top users and cost by user, keyed on user.email from an identity helper, and that CloudWatch PromQL queries are limited to a 7-day range. Deploy it in an EU region, and switch off the per-user panels if your works agreement says team level only. Setup of Claude Code itself on Bedrock is in our Claude Code on Bedrock EU guide.

Is Claude Code telemetry employee monitoring under GDPR?

Yes, as soon as data can be tied to a person. user.email, account IDs and even the random user.id are personal data for the employer, and session counts or accepted edits per person describe work behaviour. That needs a legal basis, a purpose limited to cost and capacity planning, a short retention period, and often a works council agreement.

The defaults help. Prompt text is not collected, only prompt_length. Assistant responses are replaced with <REDACTED>. Tool arguments, Bash commands and file paths stay out unless someone sets OTEL_LOG_TOOL_DETAILS=1. Raw file contents are never in metrics or events. The data goes only to the endpoint you configure, not to Anthropic. Each of OTEL_LOG_USER_PROMPTS, OTEL_LOG_ASSISTANT_RESPONSES, OTEL_LOG_TOOL_DETAILS and OTEL_LOG_RAW_API_BODIES widens collection sharply. Raw API bodies contain the full conversation history. We would allow none of them in the cost pipeline.

The analytics dashboard for Team and Enterprise is the bigger risk. It has a leaderboard of the top 10 contributors, a CSV export of all users, and, with the GitHub app, attribution of merged PR lines to Claude Code sessions from 21 days before to 2 days after the merge. That is individual performance data by design. Decide who may open it before you enable it. Contribution metrics are unavailable on Zero Data Retention organizations.

In Germany, section 87(1) no. 6 BetrVG gives the works council co-determination over technical systems designed to monitor employee behaviour or performance. In France, the CNIL says the CSE must be consulted before any monitoring system is introduced in private companies with 50 or more employees. Our German and French versions cover those rules in detail.

Run it yourself or outsource?

Running Claude Code telemetry in-house means operating one more production service: a collector that must stay reachable from every laptop, TLS certificates, a bearer token or mTLS, a metrics store, and dashboards that break when Claude Code renames attributes. Outsourcing makes sense when you have no observability team. Keep it in-house when you already run Prometheus or Grafana.

Recurring work we see on this topic, effort figures are our estimate:

  1. Collector operation: version upgrades, certificate renewal, token rotation, capacity. Under one day per month once stable.
  2. Dashboard upkeep: Claude Code ships frequent releases and documents attribute changes per version. Someone has to read those notes and fix panels. About half a day per month.
  3. Privacy governance: retention configuration, the attribute strip list, access reviews, the works agreement. Mostly at setup, then quarterly.

If you outsource, demand these specifics: an EU-hosted backend and named region; a DPA that lists telemetry data, including emails if you keep them; the full subprocessor list; an access model where the provider’s staff cannot query per-user series; retention under your control; an SLA on ingestion, not only on the dashboard UI; and an exit clause that hands over the collector config and raw metrics in OTLP or Prometheus format. If the provider insists on receiving unstripped data, run the stripping collector yourself and send them only the aggregated stream.

FAQ

Is Claude Code telemetry on by default?

No. Export to your own backend is opt-in and requires CLAUDE_CODE_ENABLE_TELEMETRY=1 plus an exporter. Separately, Anthropic’s operational telemetry is on by default with the Claude API and off by default on Bedrock, Vertex and Foundry. DISABLE_TELEMETRY=1 turns it off.

What does Claude Code telemetry cost to run?

The data is free. You pay for the collector and storage. The AWS guidance estimates about $30-50 a month for a central collector on ECS Fargate, or $0 infrastructure in sidecar mode, plus CloudWatch charges. A self-hosted Prometheus on an existing cluster adds little.

Does Claude Code telemetry record prompts or code?

Not by default. Events record prompt length, and response text is redacted. Raw file contents are never in metrics or events. Prompt text, responses, tool arguments and raw API bodies appear only if an administrator sets the matching OTEL_LOG_* variable.

OpenTelemetry versus the Claude analytics dashboard: which one?

Use the dashboard if you are on Team or Enterprise and want adoption and PR attribution with no setup. Use OpenTelemetry if you run Claude Code on Bedrock or Vertex, need per-team cost, or want the data in your own EU backend. On cloud providers the dashboard shows nothing.

How do I tag usage per team?

Set OTEL_RESOURCE_ATTRIBUTES, for example team.id=platform,cost_center=eng-123, in managed settings per machine group. The keys become labels on every metric. Avoid spaces in values and avoid per-person values, which raise storage cost and turn the dashboard into individual tracking.

Can a developer switch Claude Code telemetry off?

Partly. A repository cannot turn telemetry on, redirect it or enable content capture, but a repository or a developer can set an exporter to none. Setting OTEL_METRICS_EXPORTER and OTEL_LOGS_EXPORTER in managed settings closes that gap. Managed endpoints and credentials cannot be redirected.

Sources

  1. Claude Code docs: Monitoring (OpenTelemetry) (1 October 2026)
  2. Claude Code docs: Track team usage with analytics (1 October 2026)
  3. Claude Code docs: Data usage (1 October 2026)
  4. Claude Code docs: Manage costs effectively (1 October 2026)
  5. Claude Code docs: Deploy managed settings (1 October 2026)
  6. Claude Code docs: Model configuration (surface coverage) (1 October 2026)
  7. OpenTelemetry Collector: configuration (1 October 2026)
  8. OpenTelemetry Collector Contrib: attributes processor (1 October 2026)
  9. OpenTelemetry Collector Contrib: Prometheus exporter (1 October 2026)
  10. Betriebsverfassungsgesetz section 87 (1 October 2026)
  11. CNIL: contrôle de l'activité des personnes employées (1 October 2026)
  12. AWS Solutions Library: Claude Code monitoring on Amazon Bedrock (1 October 2026)

Related guides