Fix Langfuse trace_id mapping for failed logs and prioritize session_id

This fix addresses Bug 1 where failed LiteLLM logs were using request_id instead of session_id for Langfuse trace mapping, breaking trace correlation.

Changes:
1. Fix kwargs inconsistency in failure path (litellm_logging.py:2956)
   - Changed from passing self.model_call_details to passing local kwargs variable
   - Matches success path behavior and excludes original_response (potentially a coroutine)

2. Prioritize session_id as trace_id fallback (langfuse.py:607-615)
   - When no explicit trace_id is provided, now uses session_id from metadata
   - This ensures traces with the same session_id are grouped together in Langfuse
   - Maintains backward compatibility: only activates when session_id is set

Testing:
- All 28 existing Langfuse tests pass (excluding pre-existing test_langfuse_e2e_sync which fails due to missing API key)
- Specifically verified trace_id resolution tests still pass

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Harshit28j 2026-02-28 17:22:01 +05:30
parent 290ecf88f8
commit 7e9930cc3b
2 changed files with 5 additions and 2 deletions

View file

@ -604,9 +604,12 @@ class LangFuseLogger:
session_id = clean_metadata.pop("session_id", None)
trace_name = cast(Optional[str], clean_metadata.pop("trace_name", None))
trace_id = clean_metadata.pop("trace_id", None)
# If session_id is provided, use it as trace_id for consistent trace mapping
if trace_id is None and session_id is not None:
trace_id = session_id
# 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
if trace_id is None and standard_logging_object is not None:
elif trace_id is None and standard_logging_object is not None:
trace_id = cast(
Optional[str], standard_logging_object.get("trace_id")
)

View file

@ -2953,7 +2953,7 @@ class Logging(LiteLLMLoggingBaseClass):
user_id=kwargs.get("user", None),
status_message=str(exception),
level="ERROR",
kwargs=self.model_call_details,
kwargs=kwargs,
)
if _response is not None and isinstance(_response, dict):
_trace_id = _response.get("trace_id", None)