From 1915cd326cac149a190704496efaf92264adf426 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 7 Jun 2024 14:48:16 -0700 Subject: [PATCH 1/2] v0 - log proxy server exceptions on OTEL --- litellm/integrations/opentelemetry.py | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/litellm/integrations/opentelemetry.py b/litellm/integrations/opentelemetry.py index 5a5b6d14dda..089b67368a4 100644 --- a/litellm/integrations/opentelemetry.py +++ b/litellm/integrations/opentelemetry.py @@ -9,10 +9,13 @@ from typing import Union, Optional, TYPE_CHECKING, Any if TYPE_CHECKING: from opentelemetry.trace import Span as _Span + from litellm.proxy.proxy_server import UserAPIKeyAuth as _UserAPIKeyAuth Span = _Span + UserAPIKeyAuth = _UserAPIKeyAuth else: Span = Any + UserAPIKeyAuth = Any LITELLM_TRACER_NAME = os.getenv("OTEL_TRACER_NAME", "litellm") @@ -111,6 +114,31 @@ class OpenTelemetry(CustomLogger): service_logging_span.set_status(Status(StatusCode.OK)) service_logging_span.end(end_time=self._to_ns(end_time)) + async def async_post_call_failure_hook( + self, original_exception: Exception, user_api_key_dict: UserAPIKeyAuth + ): + from opentelemetry.trace import Status, StatusCode + from opentelemetry import trace + + parent_otel_span = user_api_key_dict.parent_otel_span + if parent_otel_span is not None: + parent_otel_span.set_status(Status(StatusCode.ERROR)) + _span_name = "Failed Proxy Server Request" + + # Exception Logging Child Span + exception_logging_span = self.tracer.start_span( + name=_span_name, + context=trace.set_span_in_context(parent_otel_span), + ) + exception_logging_span.set_attribute( + key="exception", value=str(original_exception) + ) + exception_logging_span.set_status(Status(StatusCode.ERROR)) + exception_logging_span.end(end_time=self._to_ns(datetime.now())) + + # End Parent OTEL Sspan + parent_otel_span.end(end_time=self._to_ns(datetime.now())) + def _handle_sucess(self, kwargs, response_obj, start_time, end_time): from opentelemetry.trace import Status, StatusCode From 15c0d334e852819f0cce800cd8b1fae472b53e53 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 7 Jun 2024 15:10:05 -0700 Subject: [PATCH 2/2] fix logic for deep copying otel spans / traces --- litellm/proxy/utils.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index db6eefc926d..e89aae6ad26 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -83,15 +83,13 @@ def safe_deep_copy(data): if isinstance(data, dict): # remove litellm_parent_otel_span since this is not picklable if "metadata" in data and "litellm_parent_otel_span" in data["metadata"]: - data["metadata"].pop("litellm_parent_otel_span") + litellm_parent_otel_span = data["metadata"].pop("litellm_parent_otel_span") new_data = copy.deepcopy(data) # Step 2: re-add the litellm_parent_otel_span after doing a deep copy if isinstance(data, dict): - if "metadata" in data and "litellm_parent_otel_span" in data["metadata"]: - data["metadata"]["litellm_parent_otel_span"] = data["metadata"][ - "litellm_parent_otel_span" - ] + if "metadata" in data: + data["metadata"]["litellm_parent_otel_span"] = litellm_parent_otel_span return new_data