litellm/tests/test_litellm/integrations/otel
Yassin Kortam abd239f903
fix(otel): label retrieval and agent metrics correctly and emit gen_ai.provider.name (#35151)
* fix(otel): label retrieval and agent metrics correctly and emit gen_ai.provider.name

The GenAI metric attribute builder mapped only chat, text completion, embedding,
responses and MCP tool calls to an operation name, so vector-store searches and
A2A agent sends fell through to the "chat" default. Their duration and cost then
landed in the same series a Grafana GenAI dashboard reads chat latency off, with
no way to tell them apart. Both now map to the operation names the convention
defines for them, retrieval and invoke_agent, and an unmapped call type says so
at debug instead of silently becoming chat.

The provider label used gen_ai.system, which the convention deprecated in favor
of gen_ai.provider.name; the dashboards built on that vocabulary find nothing
under the old key. Metrics now carry gen_ai.provider.name with the semconv
provider value (bedrock -> aws.bedrock) via the resolve_provider helper the span
path already uses, and keep dual-emitting gen_ai.system with its raw value so a
dashboard already querying it keeps matching. A request litellm cannot attribute
to a provider gets no provider label at all rather than a placeholder "Unknown"
that minted a permanent series nobody can act on.

Resolves LIT-4954
Resolves LIT-4959

* fix(otel): map the rest of the vector-store call types off the chat default

Mapping only the search left the store lifecycle (create, retrieve, list,
update, delete) and the file operations (create, list, retrieve, content,
update, delete) falling through to chat, so vector-store admin traffic kept
polluting the same series a dashboard reads chat latency off. A live run
confirmed it: all 20 metric datapoints from a create, retrieve, list, file-list
and delete came out labelled chat.

The convention names no operation for vector-store management, so these take
vendor values under the litellm. prefix, litellm.vector_store_management and
litellm.vector_store_file_management, one per REST resource. Its note on
gen_ai.operation.name directs instrumentation to use a system-specific name
when no predefined value applies, which is the same allowance resolve_provider
already relies on for unmapped providers. Excluding them from the GenAI metrics
altogether was the alternative; it deletes series an operator may be watching
today and is far harder to reverse than a rename, so it stays available as a
follow-up rather than being decided here. Mapping them onto the semconv memory
store family was rejected: litellm vector stores hold documents, not agent
memory records, and borrowing those names would put document admin calls into
whatever charts agent-memory operations, which is the bug this fixes.

/rag/query reaches the same recorder and is the same operation as a vector-store
search, so query and aquery map to retrieval too; leaving them would have left
the defect alive on a second retrieval surface. /rag/ingest is a write with no
semconv equivalent and no retrieval or agent confusion, so it is left for the
RAG owners to name.

Resolves LIT-4954

* fix(otel): give the streaming A2A path a call type so it labels as invoke_agent

The streaming logging object is built by hand and never runs through
update_environment_variables, the only place call_type reaches
model_call_details, so every streamed agent turn arrived at the recorder
with no call type and fell back to chat. Stamp it, and map the streaming
spelling alongside the non-streaming ones.
2026-07-30 13:48:59 -07: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 fix(otel): make OTLP export work against Grafana Cloud (#35060) 2026-07-29 13:43:33 -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): cap tool-definition attributes so they cannot evict gen_ai.* from the LLM span (#34828) 2026-07-30 12:01:10 -07:00
test_otel_v2_logger.py fix(otel): make OTLP export work against Grafana Cloud (#35060) 2026-07-29 13:43:33 -07:00
test_otel_v2_metrics.py fix(otel): label retrieval and agent metrics correctly and emit gen_ai.provider.name (#35151) 2026-07-30 13:48:59 -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 fix(otel): label retrieval and agent metrics correctly and emit gen_ai.provider.name (#35151) 2026-07-30 13:48:59 -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