Agent Observability with OpenTelemetry 2026
Instrument any agent stack (LangGraph, CrewAI, OpenAI Agents SDK, PydanticAI, AgentGuard) with OpenTelemetry so agent executions produce standard OTel traces for Jaeger, Grafana Tempo, Datadog, New Relic, and AgentOps.
Workflow Steps
- 1
Install the OpenTelemetry SDK for your language
- 2
Initialize the TracerProvider with an OTLP HTTP exporter
- 3
Instrument your agent framework with the OTel integration
- 4
Add custom agent spans tagged with agent.id, model, and intent
- 5
Tag every tool call with tool.name, tool.server, and result metadata
- 6
Deploy the OTel Collector with batch processor and your backend exporter
- 7
Build agent-specific dashboards: step latency, tool latency, token throughput, cost per run, failure rate, cross-agent coordination
- 8
Set up alerts on p95 latency, error rate spikes, cost spikes, and tool failures
Download
Documentation
Agent Observability with OpenTelemetry 2026
Overview
Agent observability became a first-class discipline in 2026, driven by the recognition that tracing agent executions with traditional application-monitoring tools is insufficient. This workflow shows how to instrument any agent stack (LangGraph, CrewAI, OpenAI Agents SDK, PydanticAI, AgentGuard) with OpenTelemetry so agent executions produce standard OTel traces that plug into any observability platform (Jaeger, Grafana Tempo, Datadog, New Relic).
Difficulty
Hard
Tools Required
- OpenTelemetry SDK ā Python 1.25+, TypeScript 1.25+, or Go 1.25+
- OpenTelemetry Collector ā for trace forwarding
- Observability backend ā Jaeger, Grafana Tempo, Datadog, New Relic, or AgentOps
- Agent framework ā LangGraph, CrewAI, OpenAI Agents SDK, PydanticAI, or AgentGuard
Workflow Steps
Step 1: Install the OTel SDK
# Python
pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp
# TypeScript
npm install @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/exporter-trace-otlp-http
# Go
go get go.opentelemetry.io/otel
Step 2: Initialize the Tracer
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace.export import BatchSpanExporter
trace.set_tracer_provider(TracerProvider())
exporter = OTLPSpanExporter(endpoint="http://localhost:4318/v1/traces")
trace.get_tracer_provider().add_span_processor(BatchSpanExporter(exporter))
tracer = trace.get_tracer("my-agent")
Step 3: Instrument the Agent
Most agent frameworks have OTel integrations. For LangGraph:
from langchain_core.tracers.langsmith import LangSmithTracer
from opentelemetry.instrumentation.langchain import LangChainInstrumentor
LangChainInstrumentor().instrument()
For OpenAI Agents SDK:
from openai.agents import Agent, Runner
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
OpenAIInstrumentor().instrument()
Step 4: Add Custom Agent Spans
For custom logic between agent steps:
with tracer.start_as_current_span("planner.step") as span:
span.set_attribute("agent.id", "agent:planner-v1")
span.set_attribute("planner.intent", "code_review")
result = await planner.run(task)
span.set_attribute("planner.output.tokens", len(result))
span.set_attribute("planner.tool_calls", result.tool_calls_count)
Step 5: Tag Tool Calls
with tracer.start_as_current_span("tool.call") as span:
span.set_attribute("tool.name", "read_file")
span.set_attribute("tool.server", "github-mcp")
span.set_attribute("agent.id", current_agent_id)
result = await call_tool("read_file", args)
span.set_attribute("tool.result.size", len(result))
span.set_attribute("tool.result.hash", hash(result))
Step 6: Forward to Your Backend
Deploy the OTel Collector:
# collector-config.yaml
receivers:
otlp:
protocols:
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 1s
send_batch_size: 1000
exporters:
otlp/jaeger:
endpoint: "jaeger-collector:4317"
tls:
insecure: true
otlp/datadog:
endpoint: "https://trace-api.datadoghq.com"
api_key: "${DD_API_KEY}"
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp/jaeger, otlp/datadog]
Step 7: Build Agent-Specific Dashboards
Key metrics for agent observability:
# Grafana dashboard variables
- agent_id (filter by agent)
- model (filter by model)
- tool_name (filter by tool)
- time_range
Visualize:
- Agent step latency ā p50, p95, p99 by agent
- Tool call latency ā per tool, per server
- Token throughput ā input vs output tokens per agent
- Cost per run ā dollars per execution
- Failure rate ā by agent, by tool, by error type
- Cross-agent coordination ā which agents call which other agents
Step 8: Alert on Anomalies
Set up alerts for:
alerts:
- name: agent_high_latency
condition: p95_step_latency > 5s for 5m
notify: #agent-alerts
- name: agent_error_spike
condition: error_rate > 5% for 3m
notify: #agent-alerts
- name: agent_cost_spike
condition: cost_per_run > $0.50 for 10m
notify: #finance
- name: agent_tool_failure
condition: tool_failure_rate > 10% for 5m
notify: #agent-alerts
Example Usage
A production agent deployment with full observability:
from openai.agents import Agent, Runner
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
OpenAIInstrumentor().instrument()
agent = Agent(
name="code-reviewer",
model="claude-opus-4-7",
instructions="You are a security-focused code reviewer.",
tools=[read_file, run_tests, post_comment],
)
# Each Runner.run() produces a root trace
# Each tool call produces a child span
# Cross-agent coordination produces linked traces
await Runner.run(agent, input=pr.diff)
The resulting trace looks like:
[code-reviewer.run]
āāā [tool.read_file] github-mcp @ src/auth.py
āāā [tool.run_tests] local @ auth tests
ā āāā [subspan] pytest collection
ā āāā [subspan] pytest execution
āāā [tool.post_comment] github-mcp @ PR #42
āāā [agent.planner.spawn] agent:summarizer-v1
āāā [summarizer.run]
āāā [tool.summarize] claude-opus-4-7
Pros
- ā Standard observability ā no custom telemetry format
- ā Works with every major observability backend
- ā Framework-agnostic ā instrument any agent framework
- ā Distributed tracing across agent + tool boundaries
- ā Industry-standard metrics, logs, and traces (the OpenTelemetry signal model)
Cons
- ā Steeper setup than purpose-built agent observability tools (AgentOps, LangSmith)
- ā Custom span tags need careful schema design
- ā Backend cost grows with trace volume
- ā Some frameworks' OTel instrumentation is still catching up
When to Use
- Production agent deployments needing enterprise observability
- Teams already invested in OpenTelemetry
- Multi-framework agent stacks needing unified observability
- Environments requiring audit-grade trace retention
