claude-otel

OpenTelemetry-compliant tracing for Claude Code sessions.
Overview
claude-otel is a Claude Code plugin that captures every session, turn, tool call, and LLM invocation as hierarchical OpenTelemetry traces. It exports them via OTLP/HTTP JSON to any compatible backend (Jaeger, Grafana Tempo, Honeycomb, Datadog, etc.) or to a local JSONL file for offline analysis.
All hooks run asynchronously -- they never block your Claude Code session.
Dependencies
| Tool | Purpose | Notes |
|---|
bash 4.0+ | Hook scripts | Pre-installed on macOS and Linux |
jq | JSON processing | brew install jq / apt install jq |
uuidgen | Trace and span ID generation | Pre-installed on macOS; apt install uuid-runtime on Linux |
curl | HTTP export mode | Pre-installed on most systems; only needed for CLAUDE_OTEL_EXPORT=http |
Quick Start
-
Add the marketplace and install the plugin
claude plugin marketplace add whizzzkid/claude-otel
claude plugin install claude-otel@claude-otel
-
Set environment variables (HTTP mode with a local Jaeger)
export CLAUDE_OTEL_EXPORT=http
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
-
Use Claude Code normally. Traces appear in your backend automatically.
Configuration
| Variable | Required | Default | Description |
|---|
CLAUDE_OTEL_EXPORT | Yes | (unset -- tracing disabled) | Export mode: http or file |
OTEL_EXPORTER_OTLP_ENDPOINT | For http | -- | OTLP HTTP endpoint base URL (e.g., http://localhost:4318) |
OTEL_EXPORTER_OTLP_HEADERS | No | -- | Comma-separated key=value headers sent with every HTTP request |
OTEL_SERVICE_NAME | No | claude-code | Value of service.name in the resource block |
OTEL_RESOURCE_ATTRIBUTES | No | -- | Comma-separated key=value pairs added to the resource |
CLAUDE_OTEL_SPAN_ATTRIBUTES | No | -- | Comma-separated key=value pairs added to every span |
CLAUDE_OTEL_LOG_FILE | No | ~/.claude/state/otel_traces.jsonl | Output path for file export mode |
CLAUDE_OTEL_DEBUG | No | false | Enable debug logging to ~/.claude/state/otel_hook.log |
TRACEPARENT | No | -- | W3C Trace Context header for trace propagation |
Export Modes
HTTP
Sends OTLP/HTTP JSON to $OTEL_EXPORTER_OTLP_ENDPOINT/v1/traces via curl. Requires curl to be installed.
export CLAUDE_OTEL_EXPORT=http
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
With authentication headers (e.g., Honeycomb):
export OTEL_EXPORTER_OTLP_HEADERS="x-honeycomb-team=your-api-key"
File
Appends one OTLP JSON document per line to a JSONL file. Useful for debugging, offline analysis, or piping into another tool.
export CLAUDE_OTEL_EXPORT=file
export CLAUDE_OTEL_LOG_FILE=/tmp/claude-traces.jsonl # optional, has sensible default
Custom Attributes
Resource Attributes
Add metadata to the resource block of every export. These typically describe the environment.
export OTEL_RESOURCE_ATTRIBUTES="deployment.environment=staging,service.version=1.2.3"
Span Attributes
Add metadata to every span. These are useful for tagging traces with project or team info.
export CLAUDE_OTEL_SPAN_ATTRIBUTES="team=platform,project=api-migration"
Trace Propagation
Set TRACEPARENT to attach Claude Code traces as children of an external trace (e.g., from a CI pipeline):
export TRACEPARENT="00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
# ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^
# ver trace-id parent-id flags
When TRACEPARENT is set, the session span inherits the trace ID and sets its parentSpanId to the given parent. When unset, a fresh trace ID is generated and the session span becomes the trace root.
Trace Hierarchy
A single Claude Code session produces a trace shaped like this: