Observing LangChain apps with OpenTelemetry means instrumenting the framework so every chain, LLM call, tool and retriever becomes a span carrying model, token, cost and latency attributes over OTLP, giving you a full trace of an LLM workflow you own, rather than only what a proprietary tool shows..
Observing LangChain apps with OpenTelemetry means instrumenting the framework so every chain, LLM call, tool and retriever becomes a span carrying model, token, cost and latency attributes over OTLP, giving you a full trace of an LLM workflow you own, rather than only what a proprietary tool shows.
A LangChain application is a graph of steps: chains that call other chains, LLM invocations, tool calls, and, in retrieval apps, retrievers that fetch context. The signals worth capturing map onto that structure: a span per chain and step, and, for each LLM call, the model, prompt and completion tokens (which drive cost), latency and any error or rate-limit response. The value of tracing the whole graph is that a slow or expensive request is rarely the LLM alone; it is a particular chain, a retriever, or a tool call, and only the trace shows which.
OpenTelemetry has emerging GenAI semantic conventions for LLM and agent spans, and libraries such as OpenLLMetry and OpenInference instrument the popular frameworks to emit them, with token, model and cost attributes, over OTLP. For LangChain specifically, the instrumentation hooks into the framework's callback system, so chains, LLM calls, tools and retrievers are captured automatically once the instrumentation is loaded, with an OTLP exporter pointing at your Collector. LangChain has a native tool in LangSmith, but it is proprietary; instrumenting with OpenTelemetry keeps your traces portable and in the same backend as the rest of your telemetry, so an LLM workflow is observed alongside the services around it.
The signals that explain most LangChain incidents:
| Signal | Source | What it tells you / watch for |
|---|---|---|
gen_ai.usage.input_tokens / output_tokens | LLM instrumentation | Tokens per call by model; the direct driver of cost. Watch the per-request distribution, not just the total. |
gen_ai.client.operation.duration | LLM instrumentation | Model call latency and time-to-first-token; large contexts and long outputs push it up. |
chain / step span duration | LangChain instrumentation | Where a request spends its time across the chain graph; isolates a slow step from a slow model. |
retriever span latency / result count | LangChain instrumentation | For retrieval chains, whether retrieval is slow or returning too little, the usual cause of a poor answer. |
tool call duration and errors | LangChain instrumentation | Latency and failures of tools the chain calls; a failing tool breaks the workflow silently. |
error / rate-limit rate | LLM instrumentation | 429s and provider errors; rate-limit responses predict failed requests and degraded experience. |
A LangChain dashboard keeps cost and experience side by side. Row one is cost: tokens and estimated cost per request by model, with the per-request token distribution so a creeping prompt size is caught before the bill is. Row two is latency: model call latency and total chain latency, so you can see whether the LLM or the surrounding steps dominate. Row three, for retrieval chains and tools: retriever latency and result counts, and tool call errors.
# tokens per request by model (rising = prompt bloat or bigger outputs)
gen_ai.usage.input_tokens + gen_ai.usage.output_tokens by (gen_ai.request.model)
# chain latency vs model latency (is the LLM or the chain slow?)
histogram_quantile(0.95, chain.span.duration) by (chain.name)
# rate-limit (429) rate by model
rate(gen_ai_errors{type="rate_limit"}[5m]) by (gen_ai.request.model)
Spend jumps without a matching jump in traffic, because tokens per request grew, a prompt template expanded or context is being stuffed. The per-request token distribution reveals it, and the trace of one expensive request shows which chain or retriever ballooned the context. Trim prompts and cap retrieved context.
End-to-end latency rises but the LLM call is fast; the time is in a retriever, a tool, or a nested chain. The chain span breakdown points at the exact step, which a model-only view would miss entirely.
429s climb as you approach the provider's tokens-per-minute limit, and requests start failing or retrying. The rate-limit rate by model is the signal. Spread load, request higher quota, add backoff, or route overflow to a secondary model.
Starting thresholds to tune:
| Condition | Signal | Meaning |
|---|---|---|
| tokens per request > baseline x2 for 10m | cost | Prompt bloat inflating spend. |
| rate-limit rate > 1% for 5m | errors | Approaching provider quota; requests failing. |
| p95 chain latency > SLO for 10m | latency | A chain or step regressed. |
| retriever result count near zero | retrieval | Retrieval returning nothing; answers will degrade. |
Ops Singularity's AI/ML and Agent Ops pillar operates LangChain apps in production, ingesting this OpenTelemetry data, watching cost, latency and retrieval quality, and taking governed action when a chain or model degrades. Explore AI/ML and Agent Ops and TelemetryOps.
Yes. Instrumentation such as OpenLLMetry or OpenInference hooks LangChain's callback system so chains, LLM calls, tools and retrievers become spans with gen_ai attributes, exported over OTLP.
No. LangSmith is LangChain's proprietary option; OpenTelemetry instrumentation keeps your traces portable and in the same backend as the rest of your telemetry.
Capture prompt and completion tokens per call as gen_ai.usage attributes and multiply by the model's price. Because the tokens are on every span, cost rolls up per model, per feature and per request.
Bring a real incident. We will show you Sentinel investigate, act and verify end to end, with every action reversible and audited.