Skip to main content

Overview

Claude Code is Anthropic’s CLI coding agent. It emits OpenTelemetry traces that Fiddler natively ingests and maps to the Fiddler schema, giving you observability over coding agent sessions — including user prompts, LLM calls, tool invocations, token usage, and permission decisions. No Fiddler SDK is required. Claude Code’s built-in OTel instrumentation sends traces directly to Fiddler’s OTLP ingestion endpoint.
Beta telemetry. Claude Code’s OpenTelemetry tracing requires the CLAUDE_CODE_ENHANCED_TELEMETRY_BETA flag and is subject to change between versions. Several content attributes (LLM responses, tool input/output) are not available in trace spans. See Known Limitations for full details.

Prerequisites

  • Claude Code v2.1.138 or later
  • A Fiddler application with a valid application.id

Quick Start

Step 1 — Enable Claude Code telemetry

Set the following environment variables before launching Claude Code:

Step 2 — Launch Claude Code

Use Claude Code normally. Every interaction generates OTel traces that flow to Fiddler.

Step 3 — Verify traces in Fiddler

Navigate to your application in the Fiddler UI. You should see traces appearing within 30 seconds, with:
  • Agent spans for each user interaction (prompt → reasoning → tool calls → response)
  • LLM spans for each model call (Sonnet, Haiku) with token counts and latency
  • Tool spans for each tool invocation (Bash, Read, Write, MCP tools, WebSearch)

Managed Deployment via Settings File

For enterprise or managed deployments, you can configure telemetry via Claude Code’s settings file instead of environment variables. This ensures consistent telemetry across all developers without requiring them to set env vars manually. Create or update .claude/settings.json (project-level) or ~/.claude/settings.json (user-level):
Do not commit API keys to version control. The OTEL_EXPORTER_OTLP_HEADERS value contains your Fiddler API key. If using project-level .claude/settings.json, add it to .gitignore to prevent accidental exposure. For CI/CD or shared environments, prefer setting credentials via environment variables instead of the settings file.
Settings in .claude/settings.json (project-level) take precedence over environment variables. Settings in the user-level ~/.claude/settings.json apply to all projects unless overridden.

What Gets Captured

Span Hierarchy

Each user interaction produces a trace with the following span structure:

Span Type Mapping

Captured Attributes by Span Type

Agent Spans (claude_code.interaction)

LLM Spans (claude_code.llm_request)

LLM response content is not available in traces. Claude Code emits LLM output via OTel log records, not trace span attributes. This mapper processes trace spans only. See Known Limitations.

Tool Spans (claude_code.tool)

Tool input/output content is not available in traces. Despite the OTEL_LOG_TOOL_CONTENT=1 env var, Claude Code does not currently emit tool.output span events on tool spans. See Known Limitations.

Permission Decision Spans (claude_code.tool.blocked_on_user)


Session Grouping

Claude Code assigns a session.id to each coding session. Fiddler maps this to gen_ai.conversation.id, enabling session-level grouping in the UI. All spans within a session share the same session.id, allowing you to:
  • View the full timeline of a coding session
  • Correlate LLM calls with tool invocations
  • Track interaction sequences within a session
When session.id is absent (rare), Fiddler falls back to using the OTel trace_id as the conversation ID.

Enrichment Setup

Fiddler can automatically score Claude Code user prompts using Prompt Safety (powered by the Centor Model for Safety) or other evaluators. To configure:
  1. Navigate to your application in the Fiddler UI.
  2. Create an evaluator rule with:
    • Span type: agent
    • Text field: user_prompt
    • Evaluator: Prompt Safety (or any custom evaluator)
  3. New claude_code.interaction spans will be scored automatically as they arrive.
Enrichment requires the user_prompt attribute to be populated. Set OTEL_LOG_USER_PROMPTS=1 to enable content capture. When disabled, user_prompt contains <REDACTED> and enrichment will score the redaction placeholder instead of the actual prompt.

Configuration Reference

Environment Variables

Required

Content Logging

Optional


Troubleshooting

Traces not appearing in Fiddler

  1. Verify telemetry is enabled:
  2. Verify the OTLP endpoint, protocol, and headers are set:
  3. Verify application.id in OTEL_RESOURCE_ATTRIBUTES is a valid UUID for an existing Fiddler application. Spans with an invalid or missing application.id are dropped during ingestion.
  4. Verify the endpoint URL is the base URL (the SDK appends /v1/traces automatically) and OTEL_EXPORTER_OTLP_PROTOCOL is set to http/protobuf.

User prompts showing as <REDACTED>

Set OTEL_LOG_USER_PROMPTS=1 in the environment before launching Claude Code. This is disabled by default for privacy.

Tool details missing from spans

Tool spans only include tool_name and duration_ms by default. Setting OTEL_LOG_TOOL_DETAILS=1 adds file_path (for Read/Edit/Write tools) and full_command (for Bash tools). However, tool input/output content is not currently available in trace spans — see Known Limitations.

Enrichment worker skipping spans

If you see warnings like Missing fiddler.span.system.gen_ai.agent.name in span.attributes, the Fiddler mapper automatically sets this to "claude-code" on all spans. Ensure you are running the latest version of the external OTel consumer that includes the Claude Code mapper.

Spans classified as chain instead of expected types

Only three span types have specific classifications: claude_code.interaction (agent), claude_code.llm_request (llm), and claude_code.tool (tool). All other spans — including tool.blocked_on_user and tool.execution — are classified as chain. This is expected behavior.

Known Claude Code Upstream Limitations

Claude Code’s OpenTelemetry tracing is currently in beta and has several limitations that affect what data is available in Fiddler. These are not Fiddler issues — they are limitations of Claude Code’s OTel instrumentation. Fiddler captures and maps every attribute that Claude Code emits.

LLM response content not available in traces

Claude Code does not emit LLM response text as a trace span attribute. Response content is only available via OTel log records (controlled by OTEL_LOGS_EXPORTER and OTEL_LOG_RAW_API_BODIES), not trace spans. Additionally, OTel log records are currently emitted without trace_id or span_id, making log-to-trace correlation impossible. Impact: Session views in Fiddler show user prompts (input) but not Claude’s responses (output). Evaluators that require both input and output (e.g., response faithfulness) cannot run on Claude Code traces.

Tool input/output not emitted in trace spans

Claude Code’s documentation states that OTEL_LOG_TOOL_CONTENT=1 records a tool.output span event with tool input and output bodies. In practice, tool spans have empty event arrays — the tool.output event is not emitted. Tool spans only carry tool_name and duration_ms. Impact: Cannot see what arguments were passed to tools or what they returned. This limits visibility into MCP tool interactions and debugging tool failures.

Tracing is beta and requires opt-in

Claude Code’s OTel tracing requires the CLAUDE_CODE_ENHANCED_TELEMETRY_BETA flag. The trace schema (span names, attribute names, hierarchy) may change between Claude Code versions without notice. Impact: Fiddler’s mapper may need updates when Claude Code’s trace schema changes. Pin Claude Code versions in managed deployments to avoid unexpected schema changes.

No distributed tracing to LLM providers

Claude Code does not send W3C traceparent headers when making LLM API calls. If Claude Code is routed through a proxy (e.g., LiteLLM), the proxy creates a new trace root rather than continuing Claude Code’s trace. Claude Code traces and proxy traces are separate trace trees. Claude Code does propagate TRACEPARENT to Bash subprocesses (e.g., when running shell commands), enabling trace correlation for subprocess-initiated LLM calls in non-interactive mode. Impact: End-to-end distributed traces (user → coding agent → LLM proxy → LLM provider) require joining on session.id or x-claude-code-session-id at query time rather than native trace propagation.

Content redaction is all-or-nothing per category

Content capture is controlled by three separate env vars (OTEL_LOG_USER_PROMPTS, OTEL_LOG_TOOL_DETAILS, OTEL_LOG_TOOL_CONTENT). Each controls an entire category — there is no per-attribute or per-tool-type granularity. You cannot, for example, capture user prompts while keeping tool content redacted within a single category.

Thinking and reasoning content not available

There is no env var to export Claude’s extended thinking or reasoning steps in OTel telemetry. Only metadata (token counts, model, latency) is available for the reasoning process, not the content.

ScopeName and ScopeVersion empty in collected traces

Despite using instrumentation scope com.anthropic.claude_code.tracing 1.0.0, traces may show empty ScopeName and ScopeVersion fields. This does not affect span routing or processing — service.name and span name prefixes are used for detection.

Summary