mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-11 03:38:38 +00:00
Merge b6aad94707 into 635085ac14
This commit is contained in:
commit
40f6a955de
2 changed files with 76 additions and 2 deletions
|
|
@ -2162,6 +2162,15 @@ class OpenTelemetry(OTELGenAISemconvMixin, CustomLogger):
|
|||
# OR if USE_OTEL_LITELLM_REQUEST_SPAN is explicitly enabled
|
||||
should_create_primary_span: Final = parent_otel_span is None or get_secret_bool("USE_OTEL_LITELLM_REQUEST_SPAN")
|
||||
|
||||
standard_logging_payload: Final[StandardLoggingPayload | None] = kwargs.get("standard_logging_object")
|
||||
error_information: Final = (
|
||||
standard_logging_payload.get("error_information") if standard_logging_payload else None
|
||||
)
|
||||
error_message: Final = (error_information.get("error_message") if error_information else None) or (
|
||||
standard_logging_payload.get("error_str") if standard_logging_payload else None
|
||||
)
|
||||
error_status: Final = Status(StatusCode.ERROR, error_message if isinstance(error_message, str) else None)
|
||||
|
||||
span = None
|
||||
if should_create_primary_span:
|
||||
# Span 1: Request sent to litellm SDK
|
||||
|
|
@ -2174,7 +2183,7 @@ class OpenTelemetry(OTELGenAISemconvMixin, CustomLogger):
|
|||
if self._gen_ai_semconv_latest_experimental:
|
||||
span_kwargs["kind"] = self.span_kind.CLIENT
|
||||
span = otel_tracer.start_span(**span_kwargs)
|
||||
span.set_status(Status(StatusCode.ERROR))
|
||||
span.set_status(error_status)
|
||||
self.set_attributes(span, kwargs, response_obj)
|
||||
|
||||
# Record exception information using OTEL standard method
|
||||
|
|
@ -2187,7 +2196,7 @@ class OpenTelemetry(OTELGenAISemconvMixin, CustomLogger):
|
|||
# Only set attributes if the span is still recording (not closed)
|
||||
# Note: parent_otel_span is guaranteed to be not None here
|
||||
if parent_otel_span.is_recording():
|
||||
parent_otel_span.set_status(Status(StatusCode.ERROR))
|
||||
parent_otel_span.set_status(error_status)
|
||||
self.set_attributes(parent_otel_span, kwargs, response_obj)
|
||||
self._record_exception_on_span(span=parent_otel_span, kwargs=kwargs)
|
||||
|
||||
|
|
|
|||
|
|
@ -3558,6 +3558,71 @@ class TestOpenTelemetrySemanticConventions138(unittest.TestCase):
|
|||
error_spans = [s for s in spans if s.status.status_code == StatusCode.ERROR]
|
||||
self.assertTrue(error_spans, "Expected at least one span with ERROR status")
|
||||
|
||||
@parameterized.expand(
|
||||
[
|
||||
(
|
||||
"own_span_error_information",
|
||||
False,
|
||||
{
|
||||
"error_str": "litellm.ServiceUnavailableError: upstream returned 503",
|
||||
"error_information": {
|
||||
"error_class": "ServiceUnavailableError",
|
||||
"error_message": "upstream returned 503",
|
||||
},
|
||||
},
|
||||
"upstream returned 503",
|
||||
),
|
||||
(
|
||||
"own_span_error_str_only",
|
||||
False,
|
||||
{"error_str": "litellm.ServiceUnavailableError: upstream returned 503"},
|
||||
"litellm.ServiceUnavailableError: upstream returned 503",
|
||||
),
|
||||
(
|
||||
"parent_span_error_information",
|
||||
True,
|
||||
{
|
||||
"error_information": {
|
||||
"error_class": "ServiceUnavailableError",
|
||||
"error_message": "upstream returned 503",
|
||||
}
|
||||
},
|
||||
"upstream returned 503",
|
||||
),
|
||||
]
|
||||
)
|
||||
def test_handle_failure_error_status_carries_the_error_message(
|
||||
self, _name: str, has_parent_span: bool, error_fields: dict, expected_description: str
|
||||
):
|
||||
span_exporter = InMemorySpanExporter()
|
||||
tracer_provider = TracerProvider()
|
||||
tracer_provider.add_span_processor(SimpleSpanProcessor(span_exporter))
|
||||
otel = OpenTelemetry(tracer_provider=tracer_provider)
|
||||
otel.tracer = tracer_provider.get_tracer("litellm")
|
||||
active_parent_span = (
|
||||
trace.use_span(tracer_provider.get_tracer("proxy").start_span("parent_span"), end_on_exit=True)
|
||||
if has_parent_span
|
||||
else contextlib.nullcontext()
|
||||
)
|
||||
start = datetime.now(timezone.utc)
|
||||
end = start + timedelta(seconds=1)
|
||||
kwargs = {
|
||||
"model": "gpt-4",
|
||||
"messages": [{"role": "user", "content": "Hello"}],
|
||||
"optional_params": {},
|
||||
"litellm_params": {"custom_llm_provider": "openai"},
|
||||
"standard_logging_object": {"id": "test-id", "call_type": "completion", "metadata": {}, **error_fields},
|
||||
"exception": Exception("upstream returned 503"),
|
||||
}
|
||||
|
||||
with patch.dict(os.environ, {"USE_OTEL_LITELLM_REQUEST_SPAN": "false"}), active_parent_span:
|
||||
otel._handle_failure(kwargs, None, start, end)
|
||||
|
||||
error_spans = [s for s in span_exporter.get_finished_spans() if s.status.status_code == trace.StatusCode.ERROR]
|
||||
self.assertEqual(len(error_spans), 1)
|
||||
self.assertEqual(error_spans[0].name, "parent_span" if has_parent_span else "litellm_request")
|
||||
self.assertEqual(error_spans[0].status.description, expected_description)
|
||||
|
||||
|
||||
class TestRawSpanAttributeIsolation(unittest.TestCase):
|
||||
"""Issue #3: raw_gen_ai_request span should only contain provider-specific
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue