mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
fix(langfuse_otel): prevent empty proxy request spans from being sent to Langfuse
When using langfuse_otel callback, empty traces were being sent to Langfuse for requests that didn't result in actual LLM calls (e.g., auth operations, health checks, failed requests). These traces contained only internal proxy operations (auth, postgres, proxy_pre_call) with no useful LLM data. Root cause: LangfuseOtelLogger extends OpenTelemetry, which sets itself as the proxy's open_telemetry_logger. This caused create_litellm_proxy_request_started_span to be called for every request, creating a parent span that was sent to Langfuse even when no LLM call occurred. Fix: Override create_litellm_proxy_request_started_span in LangfuseOtelLogger to return None, preventing the creation of empty parent spans. This is consistent with the existing overrides for async_service_success_hook and async_service_failure_hook which already prevent service-level logs from being sent to Langfuse. Fixes: Empty traces in Langfuse v3 when using langfuse_otel callback
This commit is contained in:
parent
169c9dae79
commit
52372dcbe9
2 changed files with 45 additions and 0 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import base64
|
||||
import json # <--- NEW
|
||||
import os
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING, Any, Optional, Union
|
||||
|
||||
from litellm._logging import verbose_logger
|
||||
|
|
@ -353,6 +354,22 @@ class LangfuseOtelLogger(OpenTelemetry):
|
|||
|
||||
return dynamic_headers
|
||||
|
||||
def create_litellm_proxy_request_started_span(
|
||||
self,
|
||||
start_time: datetime,
|
||||
headers: dict,
|
||||
) -> Optional[Span]:
|
||||
"""
|
||||
Override to prevent creating empty proxy request spans.
|
||||
|
||||
Langfuse should only receive spans for actual LLM calls, not for
|
||||
internal proxy operations (auth, postgres, proxy_pre_call, etc.).
|
||||
|
||||
By returning None, we prevent the parent span from being created,
|
||||
which in turn prevents empty traces from being sent to Langfuse.
|
||||
"""
|
||||
return None
|
||||
|
||||
async def async_service_success_hook(self, *args, **kwargs):
|
||||
"""
|
||||
Langfuse should not receive service success logs.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import os
|
||||
import sys
|
||||
import unittest
|
||||
from datetime import datetime
|
||||
from unittest.mock import patch, AsyncMock, MagicMock
|
||||
|
||||
# Add the project root to sys.path
|
||||
|
|
@ -41,6 +42,33 @@ class TestServiceLoggerOTEL(unittest.IsolatedAsyncioTestCase):
|
|||
"LangfuseOtelLogger.async_service_failure_hook",
|
||||
)
|
||||
|
||||
@patch("litellm.integrations.opentelemetry.OpenTelemetry._init_tracing")
|
||||
@patch("litellm.integrations.opentelemetry.OpenTelemetry._init_metrics")
|
||||
@patch("litellm.integrations.opentelemetry.OpenTelemetry._init_logs")
|
||||
async def test_langfuse_otel_does_not_create_proxy_request_span(
|
||||
self, mock_logs, mock_metrics, mock_tracing
|
||||
):
|
||||
"""
|
||||
Test that LangfuseOtelLogger returns None for create_litellm_proxy_request_started_span.
|
||||
|
||||
This prevents empty proxy request spans from being sent to Langfuse when
|
||||
requests don't result in actual LLM calls (e.g., auth failures, health checks).
|
||||
"""
|
||||
logger = LangfuseOtelLogger()
|
||||
|
||||
# Verify the method is overridden
|
||||
self.assertEqual(
|
||||
logger.create_litellm_proxy_request_started_span.__qualname__,
|
||||
"LangfuseOtelLogger.create_litellm_proxy_request_started_span",
|
||||
)
|
||||
|
||||
# Verify it returns None
|
||||
result = logger.create_litellm_proxy_request_started_span(
|
||||
start_time=datetime.now(),
|
||||
headers={"Authorization": "Bearer test"},
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
@patch("litellm.integrations.opentelemetry.OpenTelemetry._init_tracing")
|
||||
@patch("litellm.integrations.opentelemetry.OpenTelemetry._init_metrics")
|
||||
@patch("litellm.integrations.opentelemetry.OpenTelemetry._init_logs")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue