OpenTelemetry (OTel)
CNCF-graduated open-source observability framework for distributed systems. Provides a vendor-neutral standard for collecting and exporting traces, metrics, and logs. Key property: instrument once, export anywhere. Instrumentation code is backend-agnostic; the export destination is a configuration decision, not a code decision. Repo: https://opentelemetry.ioSpec: https://opentelemetry.io/docs/specs/otel/
GenAI SIG: https://github.com/open-telemetry/semantic-conventions/tree/main/docs/gen-ai
Three Signals
Traces — distributed request flows. A trace is one complete user interaction; it contains spans in a parent-child tree. Each span represents one unit of work: an LLM call, a retrieval operation, a tool execution. Metrics — numeric time-series. Counters, histograms, gauges. Aggregate trends (token burn rate, p99 latency, error rate). Logs — structured log records with trace context correlation. For AI systems, prompt/completion content lives here (as span events, not attributes).Core Concepts
Span
Unit of work in a trace. Contains:trace_id— shared across all spans in one user requestspan_id— unique to this operationparent_span_id— creates the tree structurename— e.g.,"anthropic chat","vector-retrieval","agent.tool_call"start_time/end_timeattributes— key-value metadata (GenAI attributes go here)status—OK,ERROR, orUNSETevents— timestamped moments within a span (e.g.,gen_ai.user.message)
TracerProvider
Global singleton that createsTracer instances. Configure once at startup with: resource (service name/version), span processors, and exporters. Must call instrument() on auto-instrumentation packages before creating any SDK clients.
Collector
Standalone process (sidecar or gateway) that receives spans, applies processors (sampling, enrichment, batching), and routes to multiple backends. Decouples application from observability backends. Two modes:- Agent: runs alongside each app instance, low latency, good for smaller deployments
- Gateway: centralized tier, enables sophisticated routing and tail sampling, preferred at scale
Context Propagation
W3Ctraceparent header carries {version}-{trace_id}-{parent_span_id}-{flags} across HTTP service boundaries. When HTTP clients are instrumented (HTTPXClientInstrumentor, RequestsInstrumentor), propagation is automatic. For message queues (Kafka, Celery, SQS): must manually inject(headers) at producer and extract(headers) at consumer — queues don’t use HTTP headers.
GenAI Semantic Conventions
Defined by the OTel GenAI Special Interest Group. Status: incubating (experimental but rapidly stabilizing as of 2026). Organizations should use abstraction layers to insulate against attribute changes.Key Attributes
Standard Metric Names
Instrumentation Approaches
1. Auto-Instrumentation
Fastest path. Wraps SDK calls automatically without modifying business logic.instrument() at startup, before creating any SDK clients:
2. Manual SDK Instrumentation
Required for: custom retrieval steps, tool calls, evaluation scores, business logic, or any framework without an existing instrumentor.3. OpenLLMetry (traceloop-sdk)
Third-party wrapper with broader framework support and simpler initialization:4. OpenLIT
Zero-code CLI option; TypeScript support; broadest framework coverage including newer frameworks (AG2, Dynamiq, Mem0):Collector Configuration (Minimal)
Sampling
Head sampling — decision at trace start, before any work.TraceIdRatioBased(0.10) = keep 10% randomly. Fast, low overhead, but can’t consider outcome (drops errors at same rate as successes).
Tail sampling — decision after trace completes. Buffer all spans for decision_wait seconds, then decide based on: error status, latency threshold, user tier, attribute values. Higher memory cost but captures what matters. Always use for AI production workloads.
Compatible Backends
OTel exports to any OTLP-compatible backend via gRPC (port 4317) or HTTP (port 4318):- Arize Phoenix — local dev, AI-specific analysis, UMAP embeddings visualization
- LangSmith — AI observability, prompt versioning, dataset curation (OTel endpoint available)
- Langfuse — open-source AI observability alternative to LangSmith
- Grafana Tempo — open-source distributed tracing backend
- Jaeger — open-source tracing, good for local dev
- Datadog — enterprise APM with GenAI semantic convention support
- Honeycomb — high-cardinality event analytics
- Dynatrace — enterprise APM, OTLP ingestion, AI observability app
- Uptrace — open-source APM on ClickHouse, native
gen_ai.*support
Python SDK Setup (Minimal)
provider.force_flush() and provider.shutdown() before process exit. BatchSpanProcessor buffers async — Lambda functions may terminate before flush, silently dropping all traces.
Language Support
- Python:
opentelemetry-sdk, OpenInference instrumentors for Anthropic/OpenAI/LangChain/LlamaIndex - JavaScript/TypeScript:
@opentelemetry/sdk-node, OpenInference JS instrumentors - Go:
go.opentelemetry.io/otel - Java:
io.opentelemetry:opentelemetry-sdk(OpenInference has strong Java support) - Ruby: OpenLLMetry supports Ruby
Common Pitfalls
- Don’t send to multiple backends directly from app — use Collector for routing/fan-out; direct multi-export adds latency and coupling
- Don’t store prompt content in span attributes — always indexed, no size limit, PII risk; use span events
- Don’t use custom attribute names — use
gen_ai.*conventions or pre-built dashboards won’t work - Don’t forget to instrument HTTP clients — context propagation breaks at uninstrumented boundaries
- Thread pool workers don’t inherit context — capture
otel_context.get_current()in main thread, pass to workers, alwaysdetach(token)infinally
Related Pages
- LLM Observability — full observability patterns for LLM and agent systems
- Agent Harness — orchestration systems where OTel trace correlation matters
- Context Degradation Patterns — failure modes that OTel helps diagnose