[BUG] OTel gen_ai.client.token.usage exported as Counter, not Histogram
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 bygen_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
- Enable Claude Code telemetry: CLAUDE_CODE_ENABLE_TELEMETRY=1, OTEL_METRICS_EXPORTER=otlp,
OTEL_TRACES_EXPORTER=otlp, pointed at an OTel Collector.
- Forward metrics/traces to an OTel-GenAI-compliant backend (e.g. Splunk Observability
Cloud via the signalfx exporter with send_otlp_histograms: true).
- Confirm traces/spans and claude_code.token.usage arrive correctly (they do).
- Add a collector metricstransform processor that republishes claude_code.token.usage
under the name gen_ai.client.token.usage.
- Observe that AI-agent-monitoring token/cost tiles in the backend still stay empty.
- 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.