From c0007bd418b5e46c516eb8b1f7b861e8a35e7c83 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Thu, 22 Jan 2026 05:40:16 +0900 Subject: [PATCH 1/2] fix: Send litellm_trace_id to Langfuse to link LiteLLM logs with Langfuse logs --- litellm/integrations/langfuse/langfuse.py | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/litellm/integrations/langfuse/langfuse.py b/litellm/integrations/langfuse/langfuse.py index 7e62613a7e4..8087c17cafe 100644 --- a/litellm/integrations/langfuse/langfuse.py +++ b/litellm/integrations/langfuse/langfuse.py @@ -593,30 +593,10 @@ def _log_langfuse_v2( # noqa: PLR0915 trace_id = clean_metadata.pop("trace_id", None) # Use standard_logging_object.trace_id if available (when trace_id from metadata is None) # This allows standard trace_id to be used when provided in standard_logging_object - # However, we skip standard_logging_object.trace_id if it's a UUID (from litellm_trace_id default), - # as we want to fall back to litellm_call_id instead for better traceability. - # Note: Users can still explicitly set a UUID trace_id via metadata["trace_id"] (highest priority) if trace_id is None and standard_logging_object is not None: - standard_trace_id = cast( + trace_id = cast( Optional[str], standard_logging_object.get("trace_id") ) - # Only use standard_logging_object.trace_id if it's not a UUID - # UUIDs are 36 characters with hyphens in format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - # We check for this specific pattern to avoid rejecting valid trace_ids that happen to have hyphens - # This primarily filters out default litellm_trace_id UUIDs, while still allowing user-provided - # trace_ids via metadata["trace_id"] (which is checked first and not affected by this logic) - if standard_trace_id is not None: - # Check if it's a UUID: 36 chars, 4 hyphens, specific pattern - is_uuid = ( - len(standard_trace_id) == 36 - and standard_trace_id.count("-") == 4 - and standard_trace_id[8] == "-" - and standard_trace_id[13] == "-" - and standard_trace_id[18] == "-" - and standard_trace_id[23] == "-" - ) - if not is_uuid: - trace_id = standard_trace_id # Fallback to litellm_call_id if no trace_id found if trace_id is None: trace_id = litellm_call_id From 898cc3ff4ff1a911b772bc04eec2dc3a8f3d9e54 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Thu, 22 Jan 2026 06:19:43 +0900 Subject: [PATCH 2/2] test: update langfuse trace_id tests to use litellm_trace_id --- tests/litellm_utils_tests/test_utils.py | 4 ++-- tests/logging_callback_tests/test_alerting.py | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/litellm_utils_tests/test_utils.py b/tests/litellm_utils_tests/test_utils.py index e1751c8e2f8..f585aadbfcb 100644 --- a/tests/litellm_utils_tests/test_utils.py +++ b/tests/litellm_utils_tests/test_utils.py @@ -973,11 +973,11 @@ def test_logging_trace_id(langfuse_trace_id, langfuse_existing_trace_id): litellm_logging_obj._get_trace_id(service_name="langfuse") == langfuse_trace_id ) - ## if existing_trace_id exists + ## if no trace_id or existing_trace_id is provided, use litellm_trace_id else: assert ( litellm_logging_obj._get_trace_id(service_name="langfuse") - == litellm_call_id + == litellm_logging_obj.litellm_trace_id ) diff --git a/tests/logging_callback_tests/test_alerting.py b/tests/logging_callback_tests/test_alerting.py index 8a691e7618d..524cc00d5f7 100644 --- a/tests/logging_callback_tests/test_alerting.py +++ b/tests/logging_callback_tests/test_alerting.py @@ -866,11 +866,9 @@ async def test_langfuse_trace_id(): assert trace_url is not None - returned_trace_id = int(trace_url.split("/")[-1]) + returned_trace_id = trace_url.split("/")[-1] - assert returned_trace_id == int( - litellm_logging_obj._get_trace_id(service_name="langfuse") - ) + assert returned_trace_id == litellm_logging_obj._get_trace_id(service_name="langfuse") @pytest.mark.asyncio