mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-16 23:41:43 +00:00
fix(proxy): keep caller metadata.trace_id ahead of the OTel fallback on litellm_metadata routes
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
898fbd37a7
commit
3628025aae
2 changed files with 31 additions and 3 deletions
|
|
@ -124,7 +124,8 @@ def add_otel_trace_id_to_request(
|
|||
if data.get("litellm_trace_id"):
|
||||
return
|
||||
metadata: Final = data.get(_metadata_variable_name)
|
||||
if isinstance(metadata, dict) and metadata.get("trace_id"):
|
||||
requester_metadata: Final = data.get("metadata")
|
||||
if any(isinstance(m, dict) and m.get("trace_id") for m in (metadata, requester_metadata)):
|
||||
return
|
||||
trace_id: Final = _trace_id_from_otel_span(parent_otel_span)
|
||||
if trace_id is None:
|
||||
|
|
|
|||
|
|
@ -3561,7 +3561,9 @@ async def test_add_litellm_data_to_request_defaults_trace_id_to_otel_server_span
|
|||
of the proxy's server span, so a trace in the OTel backend can be looked up
|
||||
in the Logs UI and vice versa."""
|
||||
otel_trace_id: Final = 0x4BF92F3577B34DA6A3CE929D0E0E4736
|
||||
user_api_key_dict: Final = UserAPIKeyAuth(api_key="hashed-key", parent_otel_span=_otel_span_with_trace_id(otel_trace_id))
|
||||
user_api_key_dict: Final = UserAPIKeyAuth(
|
||||
api_key="hashed-key", parent_otel_span=_otel_span_with_trace_id(otel_trace_id)
|
||||
)
|
||||
|
||||
data: Final = await add_litellm_data_to_request(
|
||||
data={"model": "gpt-5.6", "messages": [{"role": "user", "content": "hi"}]},
|
||||
|
|
@ -3605,6 +3607,29 @@ async def test_add_litellm_data_to_request_otel_span_does_not_override_caller_tr
|
|||
assert from_body["metadata"]["trace_id"] == "body-trace"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize("path", ["/v1/responses", "/v1/messages"])
|
||||
async def test_add_litellm_data_to_request_otel_span_does_not_override_body_trace_id_on_litellm_metadata_routes(path):
|
||||
"""On routes that keep LiteLLM state in litellm_metadata, the caller's body
|
||||
metadata.trace_id is only promoted into litellm_metadata later in the
|
||||
pipeline, so the OTel fallback must look at the requester metadata too or
|
||||
it would claim the slot first and the caller's id would be lost."""
|
||||
request_mock: Final = _request_mock_without_trace_headers()
|
||||
request_mock.url.path = path
|
||||
request_mock.url.__str__.return_value = f"http://localhost{path}"
|
||||
data: Final = await add_litellm_data_to_request(
|
||||
data={"model": "gpt-5.6", "metadata": {"trace_id": "body-trace"}},
|
||||
request=request_mock,
|
||||
user_api_key_dict=UserAPIKeyAuth(
|
||||
api_key="hashed-key", parent_otel_span=_otel_span_with_trace_id(0x4BF92F3577B34DA6A3CE929D0E0E4736)
|
||||
),
|
||||
proxy_config=MagicMock(),
|
||||
general_settings={},
|
||||
)
|
||||
assert "litellm_trace_id" not in data
|
||||
assert data["litellm_metadata"]["trace_id"] == "body-trace"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize("empty_trace_id", [None, ""])
|
||||
async def test_add_litellm_data_to_request_otel_span_fills_empty_body_trace_id(empty_trace_id):
|
||||
|
|
@ -3614,7 +3639,9 @@ async def test_add_litellm_data_to_request_otel_span_fills_empty_body_trace_id(e
|
|||
data: Final = await add_litellm_data_to_request(
|
||||
data={"model": "gpt-5.6", "litellm_trace_id": empty_trace_id},
|
||||
request=_request_mock_without_trace_headers(),
|
||||
user_api_key_dict=UserAPIKeyAuth(api_key="hashed-key", parent_otel_span=_otel_span_with_trace_id(otel_trace_id)),
|
||||
user_api_key_dict=UserAPIKeyAuth(
|
||||
api_key="hashed-key", parent_otel_span=_otel_span_with_trace_id(otel_trace_id)
|
||||
),
|
||||
proxy_config=MagicMock(),
|
||||
general_settings={},
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue