diff --git a/litellm/integrations/opentelemetry.py b/litellm/integrations/opentelemetry.py index 803cc012982..12465377b51 100644 --- a/litellm/integrations/opentelemetry.py +++ b/litellm/integrations/opentelemetry.py @@ -3093,10 +3093,6 @@ class OpenTelemetry(OTELGenAISemconvMixin, CustomLogger): if signal_type == "traces" and "/v2/trace/otlp" in endpoint: return endpoint - # Langtrace ingests traces at /api/trace (a complete path, not an OTLP base). Do not rewrite. - if signal_type == "traces" and endpoint.endswith("/api/trace"): - return endpoint - # Check if endpoint already ends with the correct signal path target_path = f"/v1/{signal_type}" if endpoint.endswith(target_path): diff --git a/litellm/litellm_core_utils/litellm_logging.py b/litellm/litellm_core_utils/litellm_logging.py index b624108d670..9e7222660e7 100644 --- a/litellm/litellm_core_utils/litellm_logging.py +++ b/litellm/litellm_core_utils/litellm_logging.py @@ -3992,9 +3992,9 @@ def _init_custom_logger_compatible_class( otel_config = OpenTelemetryConfig( exporter="otlp_http", - endpoint="https://app.langtrace.ai/api/trace", + endpoint="https://langtrace.ai/api/trace", ) - os.environ["OTEL_EXPORTER_OTLP_TRACES_HEADERS"] = f"x-api-key={os.getenv('LANGTRACE_API_KEY')}" + os.environ["OTEL_EXPORTER_OTLP_TRACES_HEADERS"] = f"api_key={os.getenv('LANGTRACE_API_KEY')}" for callback in _in_memory_loggers: if isinstance(callback, OpenTelemetry) and callback.callback_name == "langtrace": return callback # type: ignore diff --git a/tests/test_litellm/integrations/test_opentelemetry.py b/tests/test_litellm/integrations/test_opentelemetry.py index 2e7424526c8..7ffd09b931f 100644 --- a/tests/test_litellm/integrations/test_opentelemetry.py +++ b/tests/test_litellm/integrations/test_opentelemetry.py @@ -1928,21 +1928,12 @@ class TestOpenTelemetryEndpointNormalization(unittest.TestCase): "https://example.com/prefix/v2/trace/otlp", "https://example.com/prefix/v2/trace/otlp", ), - ( - "https://app.langtrace.ai/api/trace", - "https://app.langtrace.ai/api/trace", - ), - ( - "https://app.langtrace.ai/api/trace/", - "https://app.langtrace.ai/api/trace", - ), ] ) def test_normalize_traces_nonstandard_otlp_ingest_urls_unchanged( self, input_url: str, expected: str ) -> None: - """Vendor full-path ingest URLs (Splunk /v2/trace/otlp, Langtrace /api/trace) - must not get /v1/traces appended — that 404s.""" + """Splunk-style /v2/trace/otlp endpoints must not get /v1/traces appended.""" otel = OpenTelemetry() self.assertEqual( otel._normalize_otel_endpoint(input_url, "traces"), @@ -5861,45 +5852,3 @@ class TestOpenTelemetryMetricAttributeFiltering(unittest.TestCase): exporter="console", attributes=attributes ) ) - - -class LangtraceV1ConfigTest(unittest.TestCase): - def test_langtrace_uses_live_host_and_x_api_key_header(self): - """Regression: litellm hardcoded the stale https://langtrace.ai/api/trace (now 404) - with header ``api_key=``. The live ingest is https://app.langtrace.ai/api/trace and - the auth header is ``x-api-key``. Pins both so the stale values can't return.""" - import litellm - import litellm.litellm_core_utils.litellm_logging as ll - from litellm.integrations.opentelemetry import OpenTelemetry - from litellm.integrations.otel.model.config import is_otel_v2_enabled - - saved = { - k: os.environ.get(k) - for k in ( - "LANGTRACE_API_KEY", - "LITELLM_OTEL_V2", - "OTEL_EXPORTER_OTLP_TRACES_HEADERS", - ) - } - try: - ll._in_memory_loggers.clear() # force a fresh build, not a cached logger - os.environ["LANGTRACE_API_KEY"] = "lt-test" - os.environ.pop("LITELLM_OTEL_V2", None) - is_otel_v2_enabled.cache_clear() - litellm.credential_list = [] - logger = ll._init_custom_logger_compatible_class("langtrace", None, None) - assert isinstance(logger, OpenTelemetry) - self.assertEqual( - logger.config.endpoint, "https://app.langtrace.ai/api/trace" - ) - self.assertEqual( - os.environ["OTEL_EXPORTER_OTLP_TRACES_HEADERS"], "x-api-key=lt-test" - ) - finally: - is_otel_v2_enabled.cache_clear() - ll._in_memory_loggers.clear() - for key, value in saved.items(): - if value is None: - os.environ.pop(key, None) - else: - os.environ[key] = value