litellm/tests/test_litellm/integrations/otel
Yassin Kortam 502d3609af
fix(otel): stamp an MCP tool failure on the request that carried it (#34551)
A failed MCP tool call aimed its error.* attributes at request_root_span(),
a ContextVar written on the ASGI request task. A stateful streamable-HTTP
session runs every message on the single task the session's initialize POST
spawned, so inside the message handler that ContextVar still holds the
initialize request's SERVER span. That span ended long ago, so the SDK
dropped every write (five 'Setting attribute on ended span' warnings plus
set_status and _add_event per failed call) and the POST that actually
failed carried no error at all. The identity attributes seeded onto the
server span went the same way.

Publish the live transport span on the ASGI scope of the request being
handled and read it back in the message handler through req_ctx.request,
the Request the streamable-HTTP transport attaches to each message. That
replaces the session-scoped field with a per-message one: a JSON-RPC
response POST deliberately skips the per-session lock, since it can arrive
while the tool call awaiting it is still in flight, so a field on the
shared auth object could be overwritten mid-call and send the tool call's
telemetry to the response's request. A scope also dies with its request
rather than holding a finished span on idle session state.

Publishing re-anchors the request root for the message so guardrail spans
and identity seeding follow, and only a transport still open for writes is
anchored or stamped: a notification POST can answer before the session task
is done, and moving dropped writes from one finished span to another is no
fix. Live capture goes from seven ended-span warnings and an unmarked
transaction to zero warnings and ERROR on the POST that carried the call.
2026-07-25 17:32:53 +00:00
..
test_otel_v2_baggage.py feat(otel): allowlist team_metadata sub-keys promoted to baggage (#29442) 2026-06-01 14:02:23 -07:00
test_otel_v2_components.py feat(otel): emit the gen_ai.client.operation.exception event on failed LLM calls (#32655) 2026-07-10 16:08:10 -07:00
test_otel_v2_config_baggage_parenting_guardrails.py feat(otel): typed semconv-aligned OpenTelemetry instrumentation (#28909) 2026-05-29 23:15:27 -07:00
test_otel_v2_dynamic.py fix(otel): one v2 logger owns the global provider; scope tenant OTLP creds per exporter (#30590) 2026-06-19 11:15:29 -07:00
test_otel_v2_emitter.py fix(otel): restore proxy-level error.* attributes on v2 failure spans (LIT-4179) (#33664) 2026-07-18 10:52:27 -07:00
test_otel_v2_logger.py fix(otel): stamp an MCP tool failure on the request that carried it (#34551) 2026-07-25 17:32:53 +00:00
test_otel_v2_metrics.py fix(otel): export v2 gen_ai client metrics to the configured meter provider (#30549) 2026-06-16 12:15:26 -07:00
test_otel_v2_mount.py perf(otel): resolve LITELLM_OTEL_V2 flag once instead of rebuilding settings per call (#30989) 2026-06-22 11:26:42 -07:00
test_otel_v2_multibackend.py feat(otel): typed semconv-aligned OpenTelemetry instrumentation (#28909) 2026-05-29 23:15:27 -07:00
test_otel_v2_presets.py fix(otel): point AgentOps OTLP exporter at otlp.agentops.ai (#31490) 2026-06-26 20:39:39 -07:00
test_otel_v2_sources_of_truth.py refactor(otel): move litellm error detail keys under the litellm.* namespace (#32591) 2026-07-09 00:51:37 -07:00
test_otel_v2_vendor_mappers.py feat(otel): typed semconv-aligned OpenTelemetry instrumentation (#28909) 2026-05-29 23:15:27 -07:00
test_runtime.py perf(otel): memoize per-request lazy import of otel runtime hooks (#31707) 2026-06-30 10:26:20 -07:00