mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-12 23:01:41 +00:00
fix(otel): emit litellm_request span when caller parent span already ended
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
a947019eb0
commit
e7ce773008
2 changed files with 16 additions and 8 deletions
|
|
@ -1213,9 +1213,12 @@ class OpenTelemetry(OTELGenAISemconvMixin, CustomLogger):
|
|||
ctx = None
|
||||
|
||||
# Decide whether to create a primary span
|
||||
# Always create if no parent span exists (backward compatibility)
|
||||
# Always create if no parent span exists (backward compatibility), or if the
|
||||
# parent already ended, since writes to it would be dropped by the SDK
|
||||
# OR if USE_OTEL_LITELLM_REQUEST_SPAN is explicitly enabled
|
||||
should_create_primary_span: Final = parent_span is None or get_secret_bool("USE_OTEL_LITELLM_REQUEST_SPAN")
|
||||
should_create_primary_span: Final = (
|
||||
parent_span is None or not is_recording(parent_span) or get_secret_bool("USE_OTEL_LITELLM_REQUEST_SPAN")
|
||||
)
|
||||
|
||||
if should_create_primary_span:
|
||||
# Create a new litellm_request span
|
||||
|
|
@ -1231,9 +1234,8 @@ class OpenTelemetry(OTELGenAISemconvMixin, CustomLogger):
|
|||
from opentelemetry.trace import Status, StatusCode
|
||||
|
||||
span = None
|
||||
if is_recording(parent_span):
|
||||
parent_span.set_status(Status(StatusCode.OK))
|
||||
self.set_attributes(parent_span, kwargs, response_obj)
|
||||
parent_span.set_status(Status(StatusCode.OK))
|
||||
self.set_attributes(parent_span, kwargs, response_obj)
|
||||
# Raw-request as direct child of parent_span
|
||||
self._maybe_log_raw_request(kwargs, response_obj, start_time, end_time, parent_span)
|
||||
|
||||
|
|
|
|||
|
|
@ -6047,9 +6047,15 @@ class TestEndedParentSpanNotWritten(unittest.TestCase):
|
|||
finally:
|
||||
otel_context.detach(token)
|
||||
|
||||
exported_server_spans = [s for s in span_exporter.get_finished_spans() if s.name == "POST /chat"]
|
||||
self.assertEqual(len(exported_server_spans), 1)
|
||||
self.assertNotIn("gen_ai.request.model", exported_server_spans[0].attributes or {})
|
||||
exported = span_exporter.get_finished_spans()
|
||||
server_spans = [s for s in exported if s.name == "POST /chat"]
|
||||
self.assertEqual(len(server_spans), 1)
|
||||
self.assertNotIn("gen_ai.request.model", server_spans[0].attributes or {})
|
||||
|
||||
litellm_spans = [s for s in exported if s.name == "litellm_request"]
|
||||
self.assertEqual(len(litellm_spans), 1, "attributes must land on a fresh child span, not be dropped")
|
||||
self.assertIn("gen_ai.request.model", litellm_spans[0].attributes or {})
|
||||
self.assertEqual(litellm_spans[0].parent.span_id, server_spans[0].context.span_id)
|
||||
|
||||
def test_safe_set_attribute_skips_ended_span(self):
|
||||
tracer_provider = TracerProvider()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue