[BUG] OTel gen_ai.client.token.usage exported as Counter, not Histogram

Open 💬 0 comments Opened Jul 14, 2026 by syrac88

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Claude Code's OTel telemetry exports token usage exclusively via claude_code.token.usage,
implemented as a Counter instrument. There is no native gen_ai.client.token.usage metric,
and even collector-side republishing of the counter under that name doesn't fix it, because
downstream platforms check the actual OTel instrument type, not just the metric name.

The OpenTelemetry GenAI Semantic Conventions specify gen_ai.client.token.usage as a
Histogram (with defined bucket boundaries) specifically so per-call distributions can be
computed — not just a running total.

This breaks any dashboard built strictly against the semconv shape. Concretely: Splunk
Observability Cloud's "AI Agent Monitoring" / AI Overview pages require histogram-typed
metrics to populate their token/cost tiles; with only a Counter available, those tiles stay
permanently empty even though traces, spans, and every other signal from Claude Code arrive
correctly.

What Should Happen?

In addition to the existing claude_code.token.usage Counter (kept for backwards
compatibility), Claude Code should record token usage per LLM call through a proper OTel
Histogram instrument named gen_ai.client.token.usage (unit {token}), dimensioned by
gen_ai.token.type (input/output/cache_read/cache_creation), gen_ai.request.model,
gen_ai.operation.name, and gen_ai.provider.name, per the GenAI semantic conventions.

This is small and additive — a second instrument alongside the existing counter — and would
make Claude Code's native telemetry immediately compatible with any GenAI-semconv-compliant
dashboard, no collector-side workarounds required.

Error Messages/Logs

No error is logged; the metric simply never appears with the correct type. Confirmed via
Splunk's /v2/metric API that the org's registered type for gen_ai.client.token.usage (after
a collector-side metricstransform republish of claude_code.token.usage) is COUNTER, not
HISTOGRAM — renaming a counter doesn't change its instrument type.

Steps to Reproduce

  1. Enable Claude Code telemetry: CLAUDE_CODE_ENABLE_TELEMETRY=1, OTEL_METRICS_EXPORTER=otlp,

OTEL_TRACES_EXPORTER=otlp, pointed at an OTel Collector.

  1. Forward metrics/traces to an OTel-GenAI-compliant backend (e.g. Splunk Observability

Cloud via the signalfx exporter with send_otlp_histograms: true).

  1. Confirm traces/spans and claude_code.token.usage arrive correctly (they do).
  2. Add a collector metricstransform processor that republishes claude_code.token.usage

under the name gen_ai.client.token.usage.

  1. Observe that AI-agent-monitoring token/cost tiles in the backend still stay empty.
  2. Query the backend's metric catalog API directly and confirm gen_ai.client.token.usage

is registered as COUNTER, confirming the type mismatch is the root cause, not a naming
or pipeline issue.

Claude Model

None

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.175 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

Related issues:

  • #68771 — missing gen_ai.usage.* span attributes (attribute naming, not instrument type —

related but distinct gap)

  • #67852 — claude_code.cost.usage also behaves inconsistently as a Counter; the same fix

(a proper Histogram, or per-call recording) would likely resolve both.

View original on GitHub ↗