anthropics / anthropics/claude-code

OTEL: add W3C Trace Context (traceparent) propagation on outbound API requests

Open
#95,626 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area:api enhancement
Dominant language
TypeScript
Stars
147k
Forks
24k
PR merge metrics
PR metrics pending

Description

Description

Claude Code exports rich OTEL traces internally (claude_code.interaction, claude_code.llm_request, claude_code.tool, etc.) and sends them to the configured OTLP endpoint. However, it does not inject a traceparent header (W3C Trace Context) on its outbound HTTP requests to ANTHROPIC_BASE_URL.

This means gateways that sit between Claude Code and the backend provider cannot link their spans as children of Claude Code's spans. The result is two disconnected trace trees in the observability backend:

Tree 1: claude-code
  claude_code.interaction (1m 9s)
    claude_code.llm_request (4.7s)    <-- no traceparent sent here
    claude_code.tool (2.8s)
    claude_code.llm_request (4.1s)    <-- or here
    ...

Tree 2: model-gateway (separate, unlinked)
  gateway.messages (0.55s)
  gateway.messages (2.18s)

With traceparent, these would be a single tree:

claude_code.interaction (1m 9s)
  claude_code.llm_request (4.7s)
    gateway.messages (0.55s)          <-- child span via traceparent
  claude_code.tool (2.8s)
  claude_code.llm_request (4.1s)
    gateway.messages (2.18s)          <-- child span via traceparent

Environment

  • Claude Code v2.1.276+
  • OTEL configured via settings.json env vars:
    • OTEL_TRACES_EXPORTER=otlp
    • OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
    • OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
  • Gateway at ANTHROPIC_BASE_URL=http://localhost:9090/anthropic
  • Aspire Dashboard for local trace visualization

Evidence

Headers Claude Code sends on API requests (from gateway debug logs):

Accept, Accept-Encoding, Anthropic-Beta, Anthropic-Dangerous-Direct-Browser-Access,
Anthropic-Version, Connection, Content-Length, Content-Type, User-Agent,
X-Api-Key, X-App, X-Claude-Code-Session-Id, X-Stainless-*

No traceparent or tracestate header is present, despite OTEL being active and traces being exported.

Current workaround

X-Claude-Code-Session-Id can be used for manual correlation (the gateway records it as session.id on its spans), but this requires manual filtering in the UI rather than automatic parent-child linking.

Expected behavior

When OTEL tracing is enabled, Claude Code should inject traceparent (and optionally tracestate) headers on its outbound HTTP requests to the API endpoint, following the W3C Trace Context specification. The gateway compatibility guide already documents that gateways should forward headers unchanged, so this would work end-to-end without gateway changes.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the outbound HTTP request path to ANTHROPIC_BASE_URL and the existing OTEL tracing setup. Verify how trace context is represented when OTEL is enabled, then confirm that API requests carry W3C traceparent propagation and that gateway spans appear as children in the resulting trace.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, observability
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
50/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.