
    AHj~                    ,   d dl Z d dlmZ d dlmZ d dlmZmZmZmZm	Z	m
Z
mZ d dlZd dlmZ d dlmZmZ d dlmZ d dlmZ d d	lmZmZ d d
lmZ d dlmZmZmZmZm Z m!Z! erOd dl"m#Z$ d dl%m&Z' d dl%m(Z) d dl%m*Z+ d dl,m-Z. d dl/m0Z1 e
e)ef   Z(e
e+ef   Z*e
e'ef   Z&e
e$ef   Z#e
e1ef   Z0e
e.ef   Z-neZ(eZ*eZ#eZ0eZ-eZ& e jd                  dd      Z3 e jd                  dd      Z4 e jd                  dd      Z5dZ6dZ7dZ8e G d d             Z9 G d de      Z:y)    N)	dataclass)datetime)TYPE_CHECKINGAnyDictListOptionalUnioncast)verbose_logger)OpenInferenceSpanKindValuesSpanAttributes)CustomLogger)
safe_dumps)get_secret_boolstr_to_bool)ServiceLoggerPayload)ChatCompletionMessageToolCallCostBreakdownFunctionLLMResponseTypesStandardCallbackDynamicParamsStandardLoggingPayload)SpanExporter)Context)Span)Tracer) ManagementEndpointLoggingPayload)UserAPIKeyAuthOTEL_TRACER_NAMElitellmLITELLM_METER_NAMELITELLM_LOGGER_NAMEzReceived Proxy Server Requestraw_gen_ai_requestlitellm_requestc                       e Zd ZU dZeeef   ed<   dZe	e   ed<   dZ
e	e   ed<   dZeed<   dZeed<   dZe	e   ed	<   dZe	e   ed
<   dZe	e   ed<   dZe	e   ed<   ddZed        Zy)OpenTelemetryConfigconsoleexporterNendpointheadersFenable_metricsenable_eventsservice_namedeployment_environmentmodel_idignore_context_propagationc                    | j                   r0t        | j                  t              r| j                  dk(  rd| _        | j                  st        j                  dd      | _        | j                  st        j                  dd      | _        | j                  s%t        j                  d| j                        | _        | j                  $t        t        j                  d            | _	        y y )	Nr(   	otlp_httpOTEL_SERVICE_NAMEr!   OTEL_ENVIRONMENT_NAME
productionOTEL_MODEL_IDOTEL_IGNORE_CONTEXT_PROPAGATION)r*   
isinstancer)   strr.   osgetenvr/   r0   r1   r   )selfs    Z/root/tools/cai/cai_env/lib/python3.12/site-packages/litellm/integrations/opentelemetry.py__post_init__z!OpenTelemetryConfig.__post_init__I   s     MM4==#.*'DM   "		*=y ID***,))'+D' }}IIot7H7HIDM**2.9		;</D+ 3    c           
      l   ddl m} t        j                  dt        j                  dd            }t        j                  dt        j                  d            }t        j                  dt        j                  d	            }t        j                  d
d      j	                         dk(  }t        j                  dd      j	                         dk(  }t        j                  dd      }t        j                  dd      }t        j                  d|      }	|dk(  r |  |             S  | ||||||||	      S )z
        OTEL_HEADERS=x-honeycomb-team=B85YgLm9****
        OTEL_EXPORTER="otlp_http"
        OTEL_ENDPOINT="https://api.honeycomb.io/v1/traces"

        OTEL_HEADERS gets sent as headers = {"x-honeycomb-team": "B85YgLm96******"}
        r   )InMemorySpanExporterOTEL_EXPORTER_OTLP_PROTOCOLOTEL_EXPORTERr(   OTEL_EXPORTER_OTLP_ENDPOINTOTEL_ENDPOINTOTEL_EXPORTER_OTLP_HEADERSOTEL_HEADERS'LITELLM_OTEL_INTEGRATION_ENABLE_METRICSfalsetrue&LITELLM_OTEL_INTEGRATION_ENABLE_EVENTSr4   r!   r5   r6   r7   	in_memory)r)   )r)   r*   r+   r,   r-   r.   r/   r0   )6opentelemetry.sdk.trace.export.in_memory_span_exporterrB   r;   r<   lower)
clsrB   r)   r*   r+   r,   r-   r.   r/   r0   s
             r>   from_envzOpenTelemetryConfig.from_envb   s   	
 99)299_i+P
 99:BIIo<VW))("))N*C
 II?IOOQ 	
 II>HNNP 	 yy!4i@!#+BL!Q99_l;{" 4 677)'%#9	
 		
r@   )returnN)__name__
__module____qualname__r)   r
   r:   r   __annotations__r*   r	   r+   r,   boolr-   r.   r/   r0   r1   r?   classmethodrQ    r@   r>   r'   r'   =   s    )2HeC%&2"Hhsm"!GXc]! ND M4"&L(3-&,0HSM0"Hhsm"1552 *
 *
r@   r'   c                       e Zd Z	 	 	 	 	 d_dee   dee   dee   dee   dee   f
 fdZedefd       Z	d Z
	 d`d	ed
efdZd Zd Zd Zd Zd Zd Zd Z	 	 	 	 dadedee   deeeef      deeeef      dee   f
dZ	 	 	 	 	 dbdedee   dee   deeeef      deeeef      dee   fdZ	 dcdedededee   fdZd eded!efd"Z d#ed$e!fd%Z"d$ee   fd&Z#d'efd(Z$d)e%d$ee   fd*Z&d+ Z'd, Z(d- Z)d. Z*ed/eeeeef      d$ee   fd0       Z+d#ed1efd2Z,d#ed3ee   ded4ed1ef
d5Z-d#edeeef   d1efd6Z.d7efd8Z/ed7ee   d9ee   d:ee   d$ee   fd;       Z0d#ee   d<ee1   fd=Z2d> Z3d7ed#efd?Z4d7efd@Z5d$eeee6ef   fdAZ7edBe8e9   d$e:eef   fdC       Z;d7ed3ee   fdDZ<d$eeee6ef   fdEZ=d7edFedGefdHZ>dIee8e   ef   d$e8e   fdJZ?dKe8e   d$e8e   fdLZ@d7efdMZAdN ZBdO ZCdP ZDdcdQee   fdRZEdcd'ee   fdSZFdT ZGdU ZHdVee   dWed$ee   fdXZIedYeeeef      d$e:eef   fdZ       ZJ	 dcd[eKdee   fd\ZL	 dcd[eKdee   fd]ZMdedYed$ee   fd^ZN xZOS )dOpenTelemetryconfigcallback_nametracer_providerlogger_providermeter_providerc                    |t         j                         }|| _        || _        | j                  j                  | _        | j                  j                  | _        | j                  j                  | _	        i | _
        | j                  |       t        t        j                  dd            j                         }|dk(  radd l}|j#                  |j$                         |j'                  t(               |j'                  d      }	|	j+                  |j$                         t-        
| \  di | | j1                  |       | j3                  |       | j5                          y )N
DEBUG_OTELFalserK   r   )levelzopentelemetry.sdk.trace.exportrY   )r'   rQ   r\   r]   r)   rD   r*   rF   r+   rH   _tracer_provider_cache_init_tracingr:   r;   r<   rO   loggingbasicConfigDEBUG	getLoggerrS   setLevelsuper__init___init_metrics
_init_logs"_init_otel_logger_on_litellm_proxy)r=   r\   r]   r^   r_   r`   kwargs_debug_otelrg   otel_exporter_logger	__class__s             r>   rm   zOpenTelemetry.__init__   s    >(113F*![[11![[11 KK//68#?+"))L':;AAC& gmm4h' $+#4#45U#V  ))'--8 	"6">*(//1r@   c                     ddl m}m} | j                  | j                  | j
                  xs | j                  d}|j                  |      } |       }|j                         }|j                  |      S )z>Create an OpenTelemetry Resource using config-driven defaults.r   )OTELResourceDetectorResource)zservice.namezdeployment.environmentr0   )	opentelemetry.sdk.resourcesrv   rw   r.   r/   r0   createdetectmerge)r\   rv   rw   base_attributesbase_resourceotel_resource_detectorenv_resources          r>   _get_litellm_resourcez#OpenTelemetry._get_litellm_resource   sm     	O #//&,&C&C>6+>+>5
 !8!5!7-446""<00r@   c                    	 ddl m} dt
        j                  vr?t        d t
        j                  D              rt
        j                  j                  |        t        |d|        y# t        $ r t        j                  d       Y yw xY w)z
        Initializes OpenTelemetry for litellm proxy server

        - Adds Otel as a service callback
        - Sets `proxy_server.open_telemetry_logger` to self
        r   )proxy_serverzEProxy Server is not installed. Skipping OpenTelemetry initialization.Notelc              3   >   K   | ]  }t        |t                 y wN)r9   r[   ).0cbs     r>   	<genexpr>zCOpenTelemetry._init_otel_logger_on_litellm_proxy.<locals>.<genexpr>   s      :
24
2}--:
s   open_telemetry_logger)
litellm.proxyr   ImportErrorr   warningr!   service_callbackallappendsetattr)r=   r   s     r>   rp   z0OpenTelemetry._init_otel_logger_on_litellm_proxy   s~    	2 111c :
8?8P8P:
 7
 $$++D15t<  	""W 		s   A' 'BBprovider_nameskip_set_globalc                    |+t        j                  dt        |      j                         |S 	  |       }t	        ||      r.t        j                  d|t        |      j                         |}|S t        j                  d|        |       }|s
 ||       |S t        j
                  d|       	 |S # t        $ r<}	t        j                  d|t        |	              |       }|s ||       Y d}	~	|S d}	~	ww xY w)a  
        Generic helper to get or create an OpenTelemetry provider (Tracer, Meter, or Logger).

        Args:
            provider: The provider instance passed to the init function (can be None)
            provider_name: Name for logging (e.g., "TracerProvider")
            get_existing_provider_fn: Function to get the existing global provider
            sdk_provider_class: The SDK provider class to check for (e.g., TracerProvider from SDK)
            create_new_provider_fn: Function to create a new provider instance
            set_provider_fn: Function to set the provider globally
            skip_set_global: If True, don't set the provider globally (for dynamic-only providers)

        Returns:
            The provider to use (either existing, new, or explicitly provided)
        Nz0OpenTelemetry: Using provided TracerProvider: %sz$OpenTelemetry: Using existing %s: %szOpenTelemetry: Creating new %sz^OpenTelemetry: Created %s but NOT setting it globally (will use dynamic providers per-request)zCOpenTelemetry: Exception checking existing %s, creating new one: %s)r   debugtyperS   r9   info	Exceptionr:   )
r=   providerr   get_existing_provider_fnsdk_provider_classcreate_new_provider_fnset_provider_fnr   existing_provideres
             r>   _get_or_create_providerz%OpenTelemetry._get_or_create_provider   s   2    BX'' O!	* 8 : +-?@$$:!*+44
 -0 ) $$%E}U13&#H-"  #''x%   		*  UA
 ./H")		*s#   ?B2 0'B2 B2 2	C7;1C22C7c           	          ddl m} ddlm ddlm}  fd}t         d      xr  j                  dk(  } j                  |d|j                  ||j                  |	      }|j                  t               _        | _        y )
Nr   traceTracerProvider)SpanKindc                       j                  j                              } | j                  j                                | S Nresource)r   r\   add_span_processor_get_span_processor)r   r   r=   s    r>   create_tracer_providerz;OpenTelemetry._init_tracing.<locals>.create_tracer_provider-  s8    %t/I/I$++/VWH''(@(@(BCOr@   r]   langfuse_otelr   )r   r   r   r   r   r   r   )opentelemetryr   opentelemetry.sdk.tracer   opentelemetry.tracer   hasattrr]   r   get_tracer_providerset_tracer_provider
get_tracerLITELLM_TRACER_NAMEtracer	span_kind)r=   r^   r   r   r   skip_globalr   s   `     @r>   rf   zOpenTelemetry._init_tracing(  s    ':0	 D/*Tt/A/A_/T 	 66$*%*%>%>-#9!55' 7 
 &001DE!r@   c                 Z     j                   j                  s+d  _        d  _        d  _        d  _        d  _        d  _        y ddlm	} ddl
m  fd} j                  |d|j                  ||j                        }|j                  t               }|j#                  ddd	
       _        |j#                  ddd
       _        |j#                  ddd
       _        |j#                  ddd	
       _        |j#                  ddd	
       _        |j#                  ddd	
       _        y )Nr   )metrics)MeterProviderc                  l    j                         }  | gj                  j                              S )N)metric_readersr   )_get_metric_readerr   r\   )metric_readerr   r=   s    r>   create_meter_providerz:OpenTelemetry._init_metrics.<locals>.create_meter_providerS  s5     335M  -33DKK@ r@   r   r   r   r   r   r   r   z gen_ai.client.operation.durationzGenAI operation durations)namedescriptionunitzgen_ai.client.token.usagezGenAI token usagez{token}zgen_ai.client.token.costzGenAI request costUSDz*gen_ai.client.response.time_to_first_tokenz*Time to first token for streaming requestsz,gen_ai.client.response.time_per_output_tokenzCAverage time per output token (generation time / completion tokens)zgen_ai.client.response.durationz9Total LLM API generation time (excludes LiteLLM overhead))r\   r,   _operation_duration_histogram_token_usage_histogram_cost_histogram_time_to_first_token_histogram _time_per_output_token_histogram_response_duration_histogramr   r   opentelemetry.sdk.metricsr   r   get_meter_providerset_meter_provider	get_meterrS   create_histogram)r=   r`   r   r   meterr   s   `    @r>   rn   zOpenTelemetry._init_metricsF  si   {{))15D.*.D'#'D 26D/48D104D-);	 55#)%,%?%?,#8#66 6 
 ((2-2-C-C32 .D .
*
 ',&<&<,+ '= '
#
  %55+,  6  

 /4.D.D=D /E /
+
 160F0F?] 1G 1
-
 -2,B,B2S -C -
)r@   c                       j                   j                  sy ddlm}m} ddlm ddlm  fd} j                  |d|||       y )Nr   )get_logger_providerset_logger_provider)LoggerProvider)BatchLogRecordProcessorc                       j                  j                              } j                         }| j                   |             | S r   )r   r\   _get_log_exporteradd_log_record_processor)r   log_exporterr   OTLoggerProviderr=   s     r>   create_logger_providerz8OpenTelemetry._init_logs.<locals>.create_logger_provider  sL    '33DKK@H  113L--'5 Or@   r   r   )
r\   r-   opentelemetry._logsr   r   opentelemetry.sdk._logsr   opentelemetry.sdk._logs.exportr   r   )r=   r_   r   r   r   r   r   s   `    @@r>   ro   zOpenTelemetry._init_logs  sH    {{((PNJ	 	$$$*%8/#9/ 	% 	
r@   c                 ,    | j                  ||||       y r   _handle_successr=   rq   response_obj
start_timeend_times        r>   log_success_eventzOpenTelemetry.log_success_event      V\:xHr@   c                 ,    | j                  ||||       y r   _handle_failurer   s        r>   log_failure_eventzOpenTelemetry.log_failure_event  r   r@   c                 4   K   | j                  ||||       y wr   r   r   s        r>   async_log_success_eventz%OpenTelemetry.async_log_success_event       V\:xH   c                 4   K   | j                  ||||       y wr   r   r   s        r>   async_log_failure_eventz%OpenTelemetry.async_log_failure_event  r   r   payloadparent_otel_spanr   r   event_metadatac                   K   ddl m} ddlm}m} d}	d}
t        |t              rt        |dz        }	n| j                  |      }	t        |t              rt        |dz        }
n| j                  |      }
||j                  }| j                  j                  ||j                  |      |	      }| j                  |d|j                         | j                  |d|j                  j                         |rL|j!                         D ]9  \  }}|d	}t        |t"              r	 t%        |      }| j                  |||       ; |j)                   ||j*                               |j-                  |
       y y # t&        $ r d
}Y Xw xY ww)Nr   r   Status
StatusCode    eAr   contextr   	call_typespankeyvalueserviceNonez0litellm logging error - could_not_json_serializer   )r   r   r   r   r   r9   floatint_to_nsr  r   
start_spanset_span_in_contextsafe_set_attributer   r  itemsdictr:   r   
set_statusOKend)r=   r   r   r   r   r   r   r   r   _start_time_ns_end_time_ns
_span_nameservice_logging_spanr  r  s                  r>   async_service_success_hookz(OpenTelemetry.async_service_success_hook  s     	(:j%( c!12N![[4Nh&x#~.L;;x0L' J#';;#9#9112BC) $: $ 
 ##)'' $ 
 ##)oo++ $  "0"6"6"8 JC} &!%.W$'JE ++1# ,  !++F:==,AB $$l$;C (2  ) W$VEWs+   D!F$E:/AF:FFFFerrorc                 b  K   ddl m} ddlm}m}	 d}
d}t        |t              rt        t        |      dz        }
n| j                  |      }
t        |t              rt        t        |      dz        }n| j                  |      }||j                  }| j                  j                  ||j                  |      |
      }| j                  |d|j                         | j                  |d|j                  j                         |r| j                  |d	|       |rH|j!                         D ]5  \  }}t        |t"              r	 t%        |      }| j                  |||       7 |j)                   ||	j*                               |j-                  |       y y # t&        $ r d
}Y Xw xY ww)Nr   r   r   r   r   r   r   r  r  z/litllm logging error - could_not_json_serializer  )r   r   r   r   r   r9   r  r  r  r  r   r	  r
  r  r   r  r  r  r:   r   r  ERRORr  )r=   r   r  r   r   r   r   r   r   r   r  r  r  r  r  r  s                   r>   async_service_failure_hookz(OpenTelemetry.async_service_failure_hook  s     	(:j%( Z3!67N![[4Nh&s8}s23L;;x0L' J#';;#9#9112BC) $: $ 
 ##)'' $ 
 ##)oo++ $ 
 ''- ( 
 "0"6"6"8 
JC!%.V$'JE ++1# , 
 !++F:3C3C,DE $$l$;K (8  ) V$UEVs+   EF/FAF/F,)F/+F,,F/request_dataoriginal_exceptionuser_api_key_dicttraceback_strc                 ,  K   ddl m} ddlm}m} |j
                  }||j                   ||j                               d}	| j                  j                  |	|j                  |            }
| j                  |
dt        |             |
j                   ||j                               |
j                  | j                  t        j                                       |j                  | j                  t        j                                       y y w)	Nr   r   r   zFailed Proxy Server Request)r   r   	exceptionr   r  )r   r   r   r   r   r   r  r  r   r	  r
  r  r:   r  r  r   now)r=   r  r  r  r  r   r   r   r   r  exception_logging_spans              r>   async_post_call_failure_hookz*OpenTelemetry.async_post_call_failure_hook'  s      	(:,=='''z/?/?(@A6J &*[[%;%;112BC &< &" ##+,- $ 
 #--fZ5E5E.FG"&&HLLN0K&L   $++hlln*E F% (s   DDdataresponsec                    K   ddl m} |j                  d      }|Mt        ||      rA|j                  }|j
                  }| j                  ||      \  }}	| j                  ||       |S w)Nr   )Logginglitellm_logging_obj)default_spanrq   r   )*litellm.litellm_core_utils.litellm_loggingr&  getr9   model_call_detailsr   _get_span_context_create_guardrail_span)
r=   r#  r  r$  LiteLLMLoggingr'  rq   parent_spanctx_s
             r>   async_post_call_success_hookz*OpenTelemetry.async_post_call_success_hookF  sy      	Y"hh'<=*z0
 );;F+<<K++F+MFC ''vs'Cs   A)A+rq   rR   c                    | j                  |      }|)| j                  |      }t        j                  d|       |S t	        | d      r| j
                  dk(  rv| j                  r| j                  | j                        ni }|r(| j                  |      }t        j                  d       |S | j                  }t        j                  d       |S | j                  }t        j                  d       |S )a  
        Get the tracer to use for this request

        If dynamic headers are present, a temporary tracer is created with the dynamic headers.
        Otherwise, the default tracer is used.

        Returns:
            Tracer: The tracer to use for this request
        z2[OTEL DEBUG] Using DYNAMIC tracer with headers: %sr]   r   zM[OTEL DEBUG] Using env var credentials for langfuse_otel (master key request)z7[OTEL DEBUG] No credentials available for langfuse_otelz5[OTEL DEBUG] Using GLOBAL tracer (no dynamic headers))	%_get_dynamic_otel_headers_from_kwargs _get_tracer_with_dynamic_headersr   r   r   r]   rH   _get_headers_dictionaryr   )r=   rq   dynamic_headerstracer_to_useenv_var_headerss        r>   get_tracer_to_use_for_requestz+OpenTelemetry.get_tracer_to_use_for_request`  s    DDVL& AA/RM  Do> 5 t_-$2D2D2W (( 001B1BC  
 #$($I$I'%M #((g  %)KKM"((Q  !%$$K r@   c                 Z    |j                  d      }|sy| j                  |      }|r|S dS )z1Extract dynamic headers from kwargs if available. standard_callback_dynamic_paramsN)r=  )r+  construct_dynamic_otel_headers)r=   rq   r=  r8  s       r>   r5  z3OpenTelemetry._get_dynamic_otel_headers_from_kwargs  sE     JJ9: 	) 0==-M > 
 #2;t;r@   r8  c                    ddl m} t        t        |j	                                     }|| j
                  v r"| j
                  |   j                  t              S  || j                  | j                              }|j                  | j                  |             || j
                  |<   |j                  t              S )zECreate a temporary tracer with dynamic headers for this request only.r   r   r   )r8  )r   r   r:   sortedr  re   r   r   r   r\   r   r   )r=   r8  r   	cache_keytemp_providers        r>   r6  z.OpenTelemetry._get_tracer_with_dynamic_headers  s    : 44678	333..y9DD# 
 '0J0J4;;0WX(($$_$E	

 2?##I.''(;<<r@   r=  c                      y)a  
        Construct dynamic headers from standard callback dynamic params

        Note: You just need to override this method in Arize, Langfuse Otel if you want to allow team/key based logging.

        Returns:
            dict: A dictionary of dynamic headers
        NrY   )r=   r=  s     r>   r>  z,OpenTelemetry.construct_dynamic_otel_headers  s     r@   c                 >   t        j                  d|| j                         | j                  |      \  }}| j                  j                  rd }d }|d u xs t        d      }|r+| j                  |||||      }| j                  |||||       n_ddlm	}	m
}
 d }t        |d      r4|j                   |	|
j                               | j                  |||       | j                  |||||       | j                  |||      }| j!                  ||       | j#                  ||||       | j                  j$                  r||n|}|| j'                  |||       |Ct        |d      r6|j(                  t*        k(  r"|j-                  | j/                  |      	       y y y y )
NzAOpenTelemetry Logger: Logging kwargs: %s, OTEL config settings=%sUSE_OTEL_LITELLM_REQUEST_SPANr   r   r  r   r0  fallback_ctxr)  r   r  )r   r   r\   r-  r1   r   _start_primary_span_maybe_log_raw_requestr   r   r   r   r  r  set_attributes_resolve_guardrail_contextr.  _record_metricsr-   _emit_semantic_logsr   LITELLM_PROXY_REQUEST_SPAN_NAMEr  r  )r=   rq   r   r   r   r1  r0  should_create_primary_spanr   r   r   guardrail_ctxlog_spans                r>   r   zOpenTelemetry._handle_success  s   OKK	

  11&9[;;11KC
 &1D%8 &
O+=
" &++j(CD ''j(D ?D {L1&&vjmm'<=##KF''j(K 77;S 8 
 	##6=#I 	V\:xH ;;$$#/t[H#((xH #V,  $CCOOT[[%:O; D - $r@   c                 F   ddl m}m} | j                  |      }|j	                  | j                  |      | j                  |      |      }	|	j                   ||j                               | j                  |	||       |	j                  | j                  |             |	S )Nr   r   r   r   r   r  )r   r   r   r;  r	  _get_span_namer  r  r  rJ  r  )
r=   rq   r   r   r   r   r   r   otel_tracerr   s
             r>   rH  z!OpenTelemetry._start_primary_span  s     	;"@@H %%$$V,{{:. & 
 	z}}-.D&,7$++h/0r@   c                    ddl m} ddlm}m} t
        j                  s| j                  sy |j                  di       }	|	j                  d      xs i }
|
j                  d      }|r|nt        }| j                  |      }|j                  || j                  |      |j                  |            }|j                   ||j                               | j!                  |||       |j#                  | j                  |             y )	Nr   r   r   litellm_paramsmetadatageneration_namerS  r  )r   r   r   r   r   r!   turn_off_message_loggingmessage_loggingr+  RAW_REQUEST_SPAN_NAMEr;  r	  r  r
  r  r  set_raw_request_attributesr  )r=   rq   r   r   r   r0  r   r   r   rW  rX  rY  raw_span_namerU  raw_spans                  r>   rI  z$OpenTelemetry._maybe_log_raw_request(  s     	(: ++43G3G$4b9!%%j17R",,'89+:@U"@@H)){{:.--k: * 

 	F:==12''&,Gdkk(34r@   c                 (   ||z
  j                         }|j                  d      xs i }|j                  dd      }d||j                  d      dd}|j                  d      }	t        |	d	d       xs |	xs i j                  d	i       }
d
D ](  }|
j                  |      t        |
|         |d| <   * t        |	dd       xs |	xs i j                  di       }|rt	        |      |d<   | j
                  r| j
                  j                  ||       |r|j                  d      x}rv| j                  rji |ddi}i |ddi}| j                  j                  |j                  dd      |       | j                  j                  |j                  dd      |       |j                  d      }| j                  r|r| j                  j                  ||       | j                  ||       | j                  |||||       | j                  |||       y )NrW  custom_llm_providerUnknownchatmodelr!   )zgen_ai.operation.namegen_ai.systemzgen_ai.request.modelzgen_ai.frameworkstandard_logging_objectrX  )user_api_key_hashuser_api_key_aliasuser_api_key_team_iduser_api_key_org_iduser_api_key_user_iduser_api_key_team_aliasuser_api_key_user_emailspend_logs_metadatarequester_ip_addressrequester_metadatauser_api_key_end_user_idprompt_management_metadataapplied_guardrailsmcp_tool_call_metadatavector_store_request_metadataz	metadata.hidden_params
attributesusagezgen_ai.token.typeinputoutputprompt_tokensr   completion_tokensresponse_cost)total_secondsr+  getattrr:   r   r   recordr   r   "_record_time_to_first_token_metric$_record_time_per_output_token_metric _record_response_duration_metric)r=   rq   r   r   r   
duration_sparamsr   common_attrsstd_logmdr  rv  ry  in_attrs	out_attrscosts                    r>   rL  zOpenTelemetry._record_metricsB  s?   +::<
,-3::3Y? &,%$*JJw$7 )	
 **67Wj$/VGMr3F3FzSU3V
 	?C" vvc{&25bg,y./%	?*  $? 
GMrCVCVRD
 ,6},EL)--..55| 6  *..w77U7//IlI,?IK|K-@(K	++22IIoq1h 3  ++22II115) 3  zz/*D  '''F 	//E11L(J	
 	--fhMr@   valc                 \   | yt        | t              r| j                         S t        | t        t        f      rt	        |       S 	 t        j
                  | d      j                         S # t        $ r8 	 t        j
                  | d      j                         cY S # t        $ r Y Y yw xY ww xY w)z+Convert datetime/float/string to timestamp.Nz%Y-%m-%d %H:%M:%S.%fz%Y-%m-%d %H:%M:%S)r9   r   	timestampr  r  strptime
ValueError)r  s    r>   _to_timestampzOpenTelemetry._to_timestamp  s    
 ;c8$==?"cC<(:	$$S*@AKKMM 	((.ABLLNN 	s0   #A* *	B+4#BB+	B'#B+&B''B+r  c                 P   |j                  di       }|j                  dd      }| j                  r|sy|j                  dd      }|j                  dd      }|M|J| j                  |      }| j                  |      }||y||z
  }	| j                  j                  |	|       yyy)z@Record Time to First Token (TTFT) metric for streaming requests.optional_paramsstreamFNapi_call_start_timecompletion_start_timerw  )r+  r   r  r  )
r=   rq   r  r  is_streamingr  r  api_call_start_tscompletion_start_tstime_to_first_token_secondss
             r>   r  z0OpenTelemetry._record_time_to_first_token_metric  s     **%6;&**8U;33 %jj)>E &

+BD I*/D/P $ 2 23F G"&"4"45J"K (,?,G*=@Q*Q'//66+ 7  0Q*r@   r   r  c                    | j                   syd}|r$|j                  d      x}r|j                  d      }||dk  ry|j                  dd      }|j                  dd      }	| j                  |      }
|
*|}|dkD  r"||z  }| j                   j                  ||       y|| j                  |      }||}n&|
|z
  }n |	| j                  |	      }||}n|
|z
  }n|}|dkD  r#||z  }| j                   j                  ||       yy)a2  Record Time Per Output Token (TPOT) metric.

        Calculated as: generation_time / completion_tokens
        - For streaming: uses end_time - completion_start_time (time to generate all tokens after first)
        - For non-streaming: uses end_time - api_call_start_time (total generation time)
        Nry  r}  r   r  r  rw  )r   r+  r  r  )r=   rq   r   r   r  r  r}  ry  r  r  end_time_tsgeneration_time_secondstime_per_output_token_secondsr  r  s                  r>   r  z2OpenTelemetry._record_time_per_output_token_metric  sq    44 !l&6&6w&??U? %		*= >$(9Q(> !'

+BD I$jj)>E ((2&0#&*+.?? . 55<<1l =   , #'"4"45J"K"**4'*58K*K' , $ 2 23F G (*4'*58I*I' '1#"Q&,CFW,W)1188-, 9  'r@   c                 <   | j                   sy|j                  dd      }|y|j                  d      xs |}|t        j                         }| j	                  |      }| j	                  |      }||y||z
  }|dkD  r| j                   j                  ||       yy)a  Record Total Generation Time (response duration) metric.

        Measures pure LLM API generation time: end_time - api_call_start_time
        This excludes LiteLLM overhead and measures only the LLM provider's response time.
        Works for both streaming and non-streaming requests.

        Mirrors Prometheus's litellm_llm_api_latency_metric.
        Uses kwargs.get("end_time") with fallback to parameter for consistency with Prometheus.
        Nr  r   r   rw  )r   r+  r   r   r  r  )	r=   rq   r   r  r  	_end_timer  r  response_duration_secondss	            r>   r  z.OpenTelemetry._record_response_duration_metric  s     00$jj)>E&
 JJz*6h	 I !../BC((3$(;$/2C$C!$q(--44)l 5  )r@   r   c                 &   | j                   j                  sy ddlm}m} 	 ddlm}  |t              }|j                         }|j                  d      xs i j                  dd      }	|j                  dg       D ]  }
|
j                  dd	      }d
|	d}|dk(  r|
j                  d      r|
d   |d<   | j                  r|
j                  d      r|
d   |d<    || j                  t        j                               |j                   |j"                  |j$                  |j&                  d|
j)                         |      }|j+                  |        t-        |j                  dg             D ]  \  }}d|	||j                  d      d}|j                  di       }| j                  r|j                  d      r|d   |d<   ||j                  d      d|j                  dd      id}| j                  r|j                  d      r|d   |d   d<    || j                  t        j                               |j                   |j"                  |j$                  |j&                  d||      }|j+                  |        y # t        $ r
 ddlm} Y hw xY w)Nr   )SeverityNumber
get_logger)	LogRecordrW  ra  rb  messagesroleuserzgen_ai.content.prompt)
event_namere  toolidcontentzgen_ai.promptINFO)r  trace_idspan_idtrace_flagsseverity_numberseverity_textbodyrx  choiceszgen_ai.content.completionfinish_reason)r  re  indexr  messagezmessage.content	assistant)r  r  r  )r\   r-   r   r  r  r   r  r   !opentelemetry.sdk._logs._internalr#   get_span_contextr+  r[  r  r   r   r  r  r  r  copyemit	enumerate)r=   rq   r   r   r  r  SdkLogRecordotel_logger
parent_ctxr   msgr  attrs
log_recordidxchoicebody_msgr  s                     r>   rM  z!OpenTelemetry._emit_semantic_logs'  s{   {{(( 	C	 !!45**,
JJ/06B;;!9

 ::j"- 	)C7766*D5!)E v~#''$-!$id##	(:),Yo&%++hlln5#,,"**&22 . 3 3$XXZ 	J Z(+	)0 %\%5%5i%DE 	)KC9!)!'O!<	E zz)R0H##Y(?+3I+>'(!'O!<"HLL$EFD
 ##Y(?-5i-@Y	*%++hlln5#,,"**&22 . 3 3$ 	J Z(9	)K  	 	s   I= =JJr0  rG  c                 ^    ddl m} | |j                  |       S ||j                  |      S |S )u1  
        Return a valid OTEL context for guardrail child spans so they are
        never orphaned (Issue #5).  Priority:
          1. The litellm_request span that was just created
          2. The parent proxy-request span
          3. The original fallback context (may be None — last resort)
        r   r   )r   r   r
  )r   r0  rG  _traces       r>   rK  z(OpenTelemetry._resolve_guardrail_context}  s;     	2--d33"--k::r@   r   c                    |xs i }|j                  d      }|y|j                  d      }|sy|D cg c]  }t        |t              r| }}|sy| j                  |      }|D ]  }|j                  d      }	|j                  d      }
t	        j
                         }|	t	        j                  |	      }t	        j
                         }|
t	        j                  |
      }|j                  d| j                  |      |      }| j                  |t        j                  t        j                  j                         | j                  |d	|j                  d	             | j                  |d
|j                  d
             |j                  d      }||j                  dt!        |             | j                  |d|j                  d             |j#                  | j                  |              yc c}w )zr
        Creates a span for Guardrail, if any guardrail information is present in standard_logging_object
        rf  Nguardrail_informationr   r   	guardrailrS  r   guardrail_nameguardrail_modemasked_entity_countguardrail_responser  )r+  r9   r  r;  r   r   fromtimestampr	  r  r  r   OPENINFERENCE_SPAN_KINDr   	GUARDRAILr  set_attributer   r  )r=   rq   r   standard_logging_payloadguardrail_information_datainformationguardrail_information_listrU  r  start_time_floatend_time_floatstart_time_datetimeend_time_datetimeguardrail_spanr  s                  r>   r.  z$OpenTelemetry._create_guardrail_span  s/    2EKZZ%F
  $+%=%A%A#&
" *  :&
+t, &
" &
 *"@@H%? .	H!488F266zBN"*,,.+&.&<&<=M&N# ()$,$:$:>$J!(33 ;;':; 4 N ###"::1;;AA $  ###$+//0@A $  ###$+//0@A $  #8";";<Q"R".,,):6I+J ###(+//0DE $  4E(FG].	H&
s   G9c                    ddl m}m} t        j                  d|| j
                         | j                  |      \  }}| j
                  j                  rd }d }|d u xs t        d      }	d }
|	r| j                  |      }|j                  | j                  |      | j                  |      |      }
|
j                   ||j                               | j                  |
||       | j!                  |
|       |
j#                  | j                  |             nW|j%                         rG|j                   ||j                               | j                  |||       | j!                  ||       | j'                  |
||      }| j)                  ||	       |Ct+        |d
      r6|j,                  t.        k(  r"|j#                  | j                  |             y y y y )Nr   r   zPOpenTelemetry Logger: Failure HandlerLogging kwargs: %s, OTEL config settings=%srE  rS  )r   rq   r  rF  r)  r   )r   r   r   r   r   r\   r-  r1   r   r;  r	  rT  r  r  r  rJ  _record_exception_on_spanr  is_recordingrK  r.  r   r   rN  )r=   rq   r   r   r   r   r   _parent_contextr   rO  r   rU  rP  s                r>   r   zOpenTelemetry._handle_failure  s   :^KK	

 -1,B,B6,J));;11#"O
 &6%= &
+B
" %"&"D"DV"LK))((0;;z2' * D
 OOF:#3#345fl; **V*DHHdkk(3H4  ,,. ++F:3C3C,DE##$4flK..4DV.T 77#3/ 8 
 	##6=#I ((&1 %%)HH  $++h*? @ I 2 )r@   c                 l   	 ddl m} |j                  d      }||j                  |       |j                  d      }|y|j                  d      }|2|j                  d      }|r| j	                  ||j
                  |       y|j                  d	      r!| j	                  ||j                  |d	          |j                  d
      r!| j	                  ||j                  |d
          |j                  d      r!| j	                  ||j
                  |d          |j                  d      r!| j	                  ||j                  |d          |j                  d      r"| j	                  ||j                  |d          yy# t        $ r)}t        j                  dt        |             Y d}~yd}~ww xY w)aQ  
        Record exception information on the span using OTEL standard methods.

        This extracts error information from StandardLoggingPayload and:
        1. Uses span.record_exception() for the actual exception object (OTEL standard)
        2. Sets structured error attributes from StandardLoggingPayloadErrorInformation
        r   )ErrorAttributesr  Nrf  error_information	error_strr   
error_codeerror_classerror_messagellm_provider	tracebackz4OpenTelemetry: Error recording exception on span: %s)*litellm.integrations._types.open_inferencer  r+  record_exceptionr  ERROR_MESSAGE
ERROR_CODE
ERROR_TYPEERROR_LLM_PROVIDERERROR_STACK_TRACEr   r   r  r:   )	r=   r   rq   r  r  r  r  r  r   s	            r>   r  z'OpenTelemetry._record_exception_on_span   s   I	
 

;/I $%%i0 JP)J$ (/ !9 < <=P Q (488E	++!+99' , 
  !$$\2'''22+L9 (  !$$]3'''22+M: (  !$$_5'''55+O< (  !$$^4'''::+N; (  !$$[1'''99+K8 (  2  	$$FA 	s%   =F  AF C:F 	F3
F..F3c           
         dd l }ddlm} |sy 	 t        |      D ]  \  }}|j	                  d      }|s|j
                  j                   d| }| j                  || d|j	                  d             | j                  || d|j	                  d	             | j                  || d
|j                  |j	                  d                    y # t        $ r)}	t        j                  dt        |	             Y d }	~	y d }	~	ww xY w)Nr   r   function.z.namer   r   z.descriptionr   z.parameters
parametersz1OpenTelemetry: Error setting tools attributes: %s)jsonlitellm.proxy._typesr   r  r+  LLM_REQUEST_FUNCTIONSr  r  dumpsr   r   r  r:   )
r=   r   toolsr  r   ir  r  prefixr   s
             r>   set_tools_attributesz"OpenTelemetry.set_tools_attributess  s   7	$U+ 488J/*@@FFGqL''!(%(",,v. ( 
 ''!(,/",,}5 ( 
 ''!(+.**X\\,%?@ ( !*  	  CSV 		s   CC 	DD  Dc                     |yt        |t        t        t        t        f      r|S 	 t        |      S # t
        $ r Y yw xY wz
        Casts the value to a primitive OTEL type if it is not already a primitive type.

        OTEL supports - str, bool, int, float

        If it's not a primitive type, then it's converted to a string
         r9   r:   rW   r  r  r   r=   r  s     r>   cast_as_primitive_value_typez*OpenTelemetry.cast_as_primitive_value_type  E     =ec4e45L	u: 		   
2 	>>
tool_callsc           	         ddl m} i }t        |       D ]s  \  }}|j                  d      }|st        j
                  j                         }|D ]7  }|j                  |      }|s|||j                  j                   d| d| <   9 u |S )Nr   r  r  r  z.function_call.)	r  r   r  r+  r   rV   keysLLM_COMPLETIONSr  )	r  r   kv_pairsr  	tool_call	_functionr	  r  _values	            r>   _tool_calls_kv_pairz!OpenTelemetry._tool_calls_kv_pair  s     	8#%'
3 	NC!j1I++002D "s+  )99??@#oVYUZ[	 r@   c           
         	 | j                   dk(  rddlm}  |       j                  |||       y | j                   dk(  rddlm} |j                  |||       y | j                   dk(  rddlm}  ||||       y ddl	m
} |j                  d	i       }|j                  d
i       xs i }	|j                  d      }
|
t        d      |
d   }|j                         D ](  \  }}| j                  |dj                  |      |       * t!        |
dd       xs |
xs i j                  di       }|r| j                  |dt#        |             |
j                  d      }|r2|j                         D ]  \  }}|	| j                  |d| |       ! |j                  d      r7| j                  ||j$                  j&                  |j                  d             | j                  ||j(                  j&                  |
d          | j                  ||j*                  j&                  |	j                  dd             |j                  d      r7| j                  ||j,                  j&                  |j                  d             |j                  d      r7| j                  ||j.                  j&                  |j                  d             |j                  d      r7| j                  ||j0                  j&                  |j                  d             | j                  ||j2                  j&                  t5        |j                  dd                   |j                  d      r7| j                  ||j6                  j&                  |j                  d             |r|j                  d      nd xs |
j                  d      }|r| j                  |d|       |rH|j                  d      r7| j                  ||j8                  j&                  |j                  d             |xr |j                  d      }|r| j                  ||j:                  j&                  |j                  d              | j                  ||j<                  j&                  |j                  d!             | j                  ||j>                  j&                  |j                  d"             t@        jB                  d#u ry | jD                  d#ury |j                  d$      r|d$   }| jG                  ||       |j                  d%      rQ| jI                  |j                  d%            }| j                  ||jJ                  j&                  t#        |             |j                  d&      rQ| jI                  |j                  d&            }| j                  ||jL                  j&                  t#        |             | j                  ||jN                  j&                  |
j                  d      d'k(  rd(n|
j                  d      xs d(       |
j                  d)      r7| j                  ||jP                  j&                  |
j                  d)             ||j                  d*      ru| jS                  |j                  d*            }| j                  ||jT                  j&                  t#        |             g }tW        |j                  d*            D ]7  \  }}|j                  d+      s|jY                  |j                  d+             9 |r1| j                  ||jZ                  j&                  t#        |             tW        |j                  d*            D ]}  \  }}|j                  d+      s|j                  d,      }|j                  d-      }|s=t\        j_                  |      }|j                         D ]  \  }}| j                  |||         y y y # t`        $ rI}| jc                  | j                   xs d./       te        jf                  d0t5        |             Y d }~y d }~ww xY w)1N	langtracer   )LangtraceAttributesr   )LangfuseOtelLogger
weave_otel)set_weave_otel_attributesr  r  rW  rf  z+standard_logging_object not found in kwargsrX  zmetadata.{}r   rv  cost_breakdownzgen_ai.cost.rd  r   ra  rb  
max_tokenstemperaturetop_pr  Fr  r  zgen_ai.response.idry  total_tokensr}  r|  Tr  r  system_instructions
completionrc  
request_idr  r  r  r  r   )r]   z0OpenTelemetry logging error in set_attributes %s)4r]   litellm.integrations.langtracer  set_langtrace_attributes+litellm.integrations.langfuse.langfuse_otelr  set_langfuse_otel_attributes%litellm.integrations.weave.weave_otelr  r  r   r+  r  r  r  formatr  r   LLM_REQUEST_MODELr  LLM_REQUEST_TYPE
LLM_SYSTEMLLM_REQUEST_MAX_TOKENSLLM_REQUEST_TEMPERATURELLM_REQUEST_TOP_PLLM_IS_STREAMINGr:   LLM_USERLLM_RESPONSE_MODELGEN_AI_USAGE_TOTAL_TOKENSGEN_AI_USAGE_OUTPUT_TOKENSGEN_AI_USAGE_INPUT_TOKENSr!   rZ  r[  r  0_transform_messages_to_otel_semantic_conventionsGEN_AI_INPUT_MESSAGESGEN_AI_SYSTEM_INSTRUCTIONSGEN_AI_OPERATION_NAMEGEN_AI_REQUEST_ID/_transform_choices_to_otel_semantic_conventionsGEN_AI_OUTPUT_MESSAGESr  r   GEN_AI_RESPONSE_FINISH_REASONSr[   r  r   handle_callback_failurer   r  )r=   r   rq   r   r  r  r  r   r  rW  r  rX  r  r  rv  r  response_idry  r  transformed_messagestransformed_system_instructionstransformed_choicesfinish_reasonsr  r  r  r  r  r   s                                r>   rJ  zOpenTelemetry.set_attributes  s   S	!![0N#%>>&, ##6 #??&, ##|3 *$E;$jj):B?O#ZZ(8"=CNIO)J$ (/ !NOO 0
;H&nn. 
U''=#7#7#<E (  $(/4 K*0b55orJ  '''$]3 (  7O6R6R 7N "0"6"6"8 JC(//!%".se 4"' 0  zz'"''&88>> **W- (  ##"3399.{; $  ##"--33$(()>	J $  ""<0''&==CC)--l; (  ""=1''&>>DD)--m< (  ""7+''&88>>)--g6 (  ##"3399/--h>? $  ""6*''&//55)--f5 (  +7  &D4)--d3  '',% (   0 0 9''&99??&**73 (  !>\%5%5g%>E''&@@FF))N3 (  ''&AAGG))$78 (  ''&@@FF))O4 (  //47##4/""7+'0))$6zz*%II

:. %
 ''&<<BB$%9: (  zz/0II

#89 0
 ''&AAGG$%DE (  ##"88>> 033K@LP 155kBLf $  (++L9''&88>>266|D (  '##I.LL(,,Y7 (
 ++!*AAGG()<= ,  &(N'01A1A)1L'M OV!::o6*11&**_2MNO &//!% . M M S S",^"< 0  (11A1A)1L'M &V!::o6&,jj&;G)0\)BJ)+8+L+LZ+X2:..2B !&JC$($;$;-1,/.3 %< %&!&&1 / (L  	(("00CO )  $$BCF 		sQ   -` (` ` 9C;` 5M;` 1`  H` B` &$` A` 	a#?aa#c                     |yt        |t        t        t        t        f      r|S 	 t        |      S # t
        $ r Y yw xY wr   r  r  s     r>   _cast_as_primitive_value_typez+OpenTelemetry._cast_as_primitive_value_type  r  r  r  r  c                 J    | j                  |      }|j                  ||       y)z_
        Safely sets an attribute on the span, ensuring the value is a primitive type.
        N)r?  r  )r=   r   r  r  primitive_values        r>   r  z OpenTelemetry.safe_set_attribute  s$     <<UC30r@   r  c                    t        |t              r
dd|dgdgS g }|D ]  }|j                  dd      }|j                  dd      }g }t        |t              r|j                  d|d       nVt        |t              rF|D ]A  }t        |t
              r|j                  |       %|j                  dt        |      d       C ||d}d	|v r|d	   |d	<   d
|v r|d
   |d
<   d|v r|d   |d<   |j                  |        |S )z
        Transforms LiteLLM/OpenAI style messages into OTEL GenAI 1.38 compliant format.
        OTEL expects a 'parts' array instead of a single 'content' string.
        systemtext)r   r  )r  partsr  r  r  r  r  r  tool_call_id)r9   r:   r+  r   listr  )	r=   r  transformedr  r  r  rE  parttransformed_msgs	            r>   r0  z>OpenTelemetry._transform_messages_to_otel_semantic_conventions  s.    h$ %'-(CD   	0C7766*Dggi,GE'3'fABGT*# MD!$-T*fT%KL	M (,e<Os{(+D	%s"03L0A-$25n2E//-	00 r@   r  c                     g }|D ]U  }|j                  d      xs i }|j                  d      }| j                  |g      d   }|r||d<   |j                  |       W |S )z_
        Transforms choices into OTEL GenAI 1.38 compliant format for output.messages.
        r  r  r   )r+  r0  r   )r=   r  rH  r  r  r  rJ  s          r>   r5  z=OpenTelemetry._transform_choices_to_otel_semantic_conventions  s{      
	0Fjj+1rG"JJ7M"SS	O 3@0/
	0 r@   c                    	 |j                  di       xs i }|j                  dd      }|j                  d      }|j                  di       xs i }|j                  d      }|rBt        |t              r2|j                         D ]  \  }	}
| j	                  |d| d|	 |
	       ! |rZt        |t
              rId
d l}	 |j                  |      }|j                         D ]  \  }	}
| j	                  |d| d|	 |
	       ! y y y # |j                  $ r? t        j                  dj                  |             | j	                  |d| d|	       Y y w xY w# t        $ r)}t        j                  dt        |             Y d }~y d }~ww xY w)NrW  ra  rb  original_responseadditional_argscomplete_input_dictzllm.r  r   r   zglitellm.integrations.opentelemetry.py::set_raw_request_attributes() - raw_response not json string - {}z.stringified_raw_responsez<OpenTelemetry logging error in set_raw_request_attributes %s)r+  r9   r  r  r  r:   r  loadsJSONDecodeErrorr   r   r#  r   r  )r=   r   rq   r   rW  ra  _raw_response_additional_argsrO  paramr  r  r   s                r>   r]  z(OpenTelemetry.set_raw_request_attributes-  s   7	
 $ZZ(8"=CN"0"4"45JI"V"JJ':;M%zz*;R@FB"2"6"67L"M #z2Et'L"5";";"= JE3++!"#6"7q@! ,  M3!?$(JJ}$=M&3&9&9&; 
s//!%"&':&;1UG D"% 0  "@} ++ "(( B  I  I) ++!"#6"77PQ+ ,   	$$NA 	s8   B:E =AD AEE EE 	FFFc                 :    t        |j                         dz        S )Nr   )r  r  )r=   dts     r>   r  zOpenTelemetry._to_nsg  s    2<<>C'((r@   c                     |j                  di       }|j                  d      xs i }|j                  d      }|r|S t        S )NrW  rX  rY  )r+  LITELLM_REQUEST_SPAN_NAME)r=   rq   rW  rX  rY  s        r>   rT  zOpenTelemetry._get_span_namej  sF    $4b9!%%j17R",,'89""((r@   c                 |    |y |j                  dd       }|y ddlm}  |       }d|i}|j                  |      }|S )Ntraceparentr   TraceContextTextMapPropagatorcarrier)r+  ,opentelemetry.trace.propagation.tracecontextr\  extract)r=   r+   _traceparentr\  
propagatorr^  r  s          r>   get_traceparent_from_headerz)OpenTelemetry.get_traceparent_from_headert  sU    ?{{=$7	
 34
 ,/$,,W,=r@   r(  c           	         ddl m}m} ddlm} |j                  di       xs i }|j                  di       xs i }|j                  di       xs i }|j                  dd       }	|j                  di       xs i }
|
j                  d	d       }|(t        j                  d
       |j                  |      |fS |	2t        j                  d       d|	i} |       j                  |      d fS 	 |j                         }|}|j                         }|j                  rat        j                  d|t        |j                  d      t        |j                  d      |j!                                |j#                         |fS t        j                  d       y# t$        $ r)}t        j                  dt'        |             Y d }~Cd }~ww xY w)Nr   )r   r   r[  rW  proxy_server_requestr+   rZ  rX  litellm_parent_otel_spanz7OpenTelemetry: Using explicit parent span from metadataz?OpenTelemetry: Using traceparent header for context propagationr]  zcOpenTelemetry: Using active span from global context: %s (trace_id=%s, span_id=%s, is_recording=%s)032x016xz-OpenTelemetry: Error getting current span: %sz:OpenTelemetry: No parent context found, creating root span)NN)r   r   r   r_  r\  r+  r   r   r
  r`  get_current_spanr  is_validr#  r  r  r  get_currentr   r:   )r=   rq   r(  r   r   r\  rW  re  r+   rZ  	_metadatar   r^  current_spanspan_contextr   s                   r>   r-  zOpenTelemetry._get_span_context  s   0	
  $4b9?R-112H"MSQS&**9b9?Rkk-6"&&z26<"	$==)CTJ '  I ,,-=>@PPP "  Q %k2G-/777H 	 113L'+<<>(("((}$|44f=|33V<$113 #..0,>> 	H	
   	  ?Q 	s   *BF 	GF<<Gc                    ddl m}m}m}m} t        j                  d| j                  | j                  | j                         t        j                  |xs | j                        }|rXt        j                  d|j                         D ci c]'  \  }}|t        t        |            dkD  r|d d dz   n|) c}}       nt        j                  d       t        | j                  d	      r<t        j                  d
| j                          |t!        || j                              S | j                  dk(  r-t        j                  d| j                          | |             S | j                  dk(  s| j                  dk(  s| j                  dk(  rS	 ddlm}	 t        j                  d| j                         | j)                  | j                  d      } | |	||            S | j                  dk(  s| j                  dk(  rS	 ddlm} t        j                  d| j                         | j)                  | j                  d      } | |||            S t        j                  d| j                          | |             S c c}}w # t&        $ r}
t'        d      |
d }
~
ww xY w# t&        $ r}
t'        d      |
d }
~
ww xY w)Nr   )BatchSpanProcessorConsoleSpanExporterSimpleSpanProcessorr   zvOpenTelemetry Logger, initializing span processor 
self.OTEL_EXPORTER: %s
self.OTEL_ENDPOINT: %s
self.OTEL_HEADERS: %sr+   z=[OTEL DEBUG] Creating span processor with DYNAMIC headers: %s   z...z8[OTEL DEBUG] Creating span processor with GLOBAL headersexportzDOpenTelemetry: intiializing SpanExporter. Value of OTEL_EXPORTER: %sr(   zHOpenTelemetry: intiializing console exporter. Value of OTEL_EXPORTER: %sr3   http/protobuf	http/json)OTLPSpanExporterzmOpenTelemetry OTLP HTTP exporter is not available. Install `opentelemetry-exporter-otlp` to enable OTLP HTTP.zEOpenTelemetry: intiializing http exporter. Value of OTEL_EXPORTER: %stracesr*   r+   	otlp_grpcgrpcz{OpenTelemetry OTLP gRPC exporter is not available. Install `opentelemetry-exporter-otlp` and `grpcio` (or `litellm[grpc]`).zEOpenTelemetry: intiializing grpc exporter. Value of OTEL_EXPORTER: %s)opentelemetry.sdk.trace.exportrp  rq  rr  r   r   r   rD   rF   rH   r[   r7  r  lenr:   r   r   5opentelemetry.exporter.otlp.proto.http.trace_exporterrx  r   _normalize_otel_endpoint5opentelemetry.exporter.otlp.proto.grpc.trace_exporter)r=   r8  rp  rq  rr  r   _split_otel_headerskvOTLPSpanExporterHTTPexcnormalized_endpointOTLPSpanExporterGRPCs                r>   r   z!OpenTelemetry._get_span_processor  s   	
 	
 	 H		
 ,CC#8t'8'8 D 
   O !4 9 9 ;1 SVr)9q"v~q@   J 
   V"" 'tL$:L:L'MNN*  Z"" &&9&;<<+-!!_4!![0   W"" #'"?"?""H# &$0:M 
 ;.$2D2D2N   W"" #'"?"?""H# &$0:M    Z"" &&9&;<<aD  !I .  !W s6   ,JJ J% 	J"JJ"%	J?.J::J?c                 F   t        j                  d| j                  | j                  | j                         t
        j                  | j                        }| j                  | j                  d      }t        j                  d| j                  |       t        | j                  d      r,t        j                  d| j                         | j                  S t        j                  d      }| j                  dk(  s|dk(  r-dd	lm} t        j                  d
| j                          |       S | j                  dk(  s| j                  dk(  s| j                  dk(  r1ddlm} t        j                  d| j                  |        |||      S | j                  dk(  s| j                  dk(  r2	 ddlm} t        j                  d| j                  |        |||      S t        j"                  d| j                         dd	lm}  |       S # t         $ r}t!        d      |d}~ww xY w)zN
        Get the appropriate log exporter based on the configuration.
        ztOpenTelemetry Logger, initializing log exporter 
self.OTEL_EXPORTER: %s
self.OTEL_ENDPOINT: %s
self.OTEL_HEADERS: %slogsz4OpenTelemetry: Log endpoint normalized from %s to %sru  zDOpenTelemetry: Using custom log exporter. Value of OTEL_EXPORTER: %sOTEL_LOGS_EXPORTERr(   r   )ConsoleLogExporterzEOpenTelemetry: Using console log exporter. Value of OTEL_EXPORTER: %sr3   rv  rw  )OTLPLogExporterzPOpenTelemetry: Using HTTP log exporter. Value of OTEL_EXPORTER: %s, endpoint: %srz  r{  r|  zOpenTelemetry OTLP gRPC log exporter is not available. Install `opentelemetry-exporter-otlp` and `grpcio` (or `litellm[grpc]`).NzPOpenTelemetry: Using gRPC log exporter. Value of OTEL_EXPORTER: %s, endpoint: %sziOpenTelemetry: Unknown log exporter '%s', defaulting to console. Supported: console, otlp_http, otlp_grpc)r   r   rD   rF   rH   r[   r7  r  r   r;   r<   r   r  4opentelemetry.exporter.otlp.proto.http._log_exporterr  4opentelemetry.exporter.otlp.proto.grpc._log_exporterr   r   )r=   r  r  otel_logs_exporterr  r  r  s          r>   r   zOpenTelemetry._get_log_exporter$  s     	 F		
 ,CCDDUDUV #;;D<N<NPVWB	
 4%%x0  V"" %%%YY';<*.@I.MI  W"" &''+-!!_4!![0   b""#
 #,6I  ;.$2D2D2N   b""#
 #,6I  ""{"" J%''+  !W s   (H 	H HH c                    ddl m} ddlm}m}m} t        j                  d| j                  | j                  | j                         t        j                  | j                        }| j                  | j                  d      }| j                  dk(  r |       } ||d      S | j                  d	k(  s| j                  d
k(  s| j                  dk(  r'ddlm}  |||||j                   i      } ||d      S | j                  dk(  s| j                  dk(  r(	 ddlm}  |||||j                   i      } ||d      S t        j&                  d| j                          |       } ||d      S # t$        $ r}	t%        d      |	d}	~	ww xY w)zO
        Get the appropriate metric reader based on the configuration.
        r   )	Histogram)AggregationTemporalityConsoleMetricExporterPeriodicExportingMetricReaderztOpenTelemetry Logger, initializing metric reader
self.OTEL_EXPORTER: %s
self.OTEL_ENDPOINT: %s
self.OTEL_HEADERS: %sr   r(   i  )export_interval_millisr3   rv  rw  )OTLPMetricExporter)r*   r+   preferred_temporalityr{  r|  zOpenTelemetry OTLP gRPC metric exporter is not available. Install `opentelemetry-exporter-otlp` and `grpcio` (or `litellm[grpc]`).NzlOpenTelemetry: Unknown metric exporter '%s', defaulting to console. Supported: console, otlp_http, otlp_grpc)r   r   opentelemetry.sdk.metrics.exportr  r  r  r   r   rD   rF   rH   r[   r7  r  6opentelemetry.exporter.otlp.proto.http.metric_exporterr  DELTA6opentelemetry.exporter.otlp.proto.grpc.metric_exporterr   r   )
r=   r  r  r  r  r  r  r)   r  r  s
             r>   r   z OpenTelemetry._get_metric_readerx  s    	8	
 	
 	 F		
 ,CCDDUDUV";;	
 *,.H0RVWW +-!!_4!![0 *,+'02H2N2N&OH
 1RVWW;.$2D2D2N *,+'02H2N2N&OH
 1RVWW ""~"" -.H0RVWW'  !W s   E- -	F6FFr*   signal_typec                 f   |s|S h d}||vrt        j                  d||       |S |j                  d      }d| }|j                  |      r|S ||hz
  }|D ]7  }d| }|j                  |      s|j	                  dd      d   d| z   }|c S  |j                  d      s||z   }|S |d| z   }|S )a  
        Normalize the endpoint URL for a specific OpenTelemetry signal type.

        The OTLP exporters expect endpoints to use signal-specific paths:
        - traces: /v1/traces
        - metrics: /v1/metrics
        - logs: /v1/logs

        This method ensures the endpoint has the correct path for the given signal type.

        Args:
            endpoint: The endpoint URL to normalize
            signal_type: The telemetry signal type ('traces', 'metrics', or 'logs')

        Returns:
            Normalized endpoint URL with the correct signal path

        Examples:
            _normalize_otel_endpoint("http://collector:4318/v1/traces", "logs")
            -> "http://collector:4318/v1/logs"

            _normalize_otel_endpoint("http://collector:4318", "traces")
            -> "http://collector:4318/v1/traces"

            _normalize_otel_endpoint("http://collector:4318/v1/logs", "metrics")
            -> "http://collector:4318/v1/metrics"
        >   r  ry  r   znInvalid signal_type '%s' provided to _normalize_otel_endpoint. Valid values: %s. Returning endpoint unchanged./z/v1/   r   z/v1)r   r   rstripendswithrsplit)r=   r*   r  valid_signalstarget_pathother_signalsother_signal
other_paths           r>   r  z&OpenTelemetry._normalize_otel_endpoint  s   < O 6m+""B	 O ??3' [M*[)O &5) 	 L~.J  ,#??3215!K=8II		    '+-H   Ak]"33Hr@   r+   c                     i }| rVt        | t              r4| j                  d      }|D ]  }|j                  dd      \  }}|||<    |S t        | t              r| }|S )zY
        Convert a string or dictionary of headers into a dictionary of headers.
        ,=r  )r9   r:   splitr  )r+   r  rE  rI  r  r  s         r>   r7  z%OpenTelemetry._get_headers_dictionary	  su     /1'3'  c*! 5D!%C!3JC/4',5
 #" GT*&-#""r@   logging_payloadc                   K   ddl m} ddlm}m} d}d}|j
                  }|j                  }	t        |t              rt        |dz        }n| j                  |      }t        |	t              rt        |	dz        }n| j                  |	      }||j                  }
| j                  j                  |
|j                  |      |      }|j                  }|/|j!                         D ]  \  }}| j#                  |d| |        |j$                  }|/|j!                         D ]  \  }}| j#                  |d| |        |j'                   ||j(                               |j+                  |	       y y w)
Nr   r   r   r   r   request.r   z	response.r  )r   r   r   r   r   r   r   r9   r  r  r  router   r	  r
  r  r  r  r$  r  r  r  )r=   r  r   r   r   r   r  r  r   r   r  management_endpoint_span_request_datar  r  	_responses                   r>   &async_management_endpoint_success_hookz4OpenTelemetry.async_management_endpoint_success_hook	  s    
 	(:$//
"++j%( c!12N![[4Nh&x#~.L;;x0L'(..J'+{{'='=112BC) (> ($ ,88M("/"5"5"7 JC++5&se,# ,  (00I$"+//"3 JC++5'u-# ,  %//z}}0EF$((,(?7 (s   E5E7c                   K   ddl m} ddlm}m} d}d}|j
                  }|j                  }	t        |t              rt        t        |      dz        }n| j                  |      }t        |	t              rt        t        |	      dz        }n| j                  |	      }||j                  }
| j                  j                  |
|j                  |      |      }|j                  }|/|j!                         D ]  \  }}| j#                  |d| |        |j$                  }| j#                  |dt'        |             |j)                   ||j*                               |j-                  |	       y y w)
Nr   r   r   r   r   r  r   r  r  )r   r   r   r   r   r   r   r9   r  r  r  r  r   r	  r
  r  r  r  r  r:   r  r  r  )r=   r  r   r   r   r   r  r  r   r   r  r  r  r  r  
_exceptions                   r>   &async_management_endpoint_failure_hookz4OpenTelemetry.async_management_endpoint_failure_hookJ	  st    
 	(:$//
"++j%( Z3!67N![[4Nh&s8}s23L;;x0L'(..J'+{{'='=112BC) (> ($ ,88M("/"5"5"7 JC++5&se,# ,  )22J##-*o $ 
 %//z7G7G0HI$((,(?1 (s   E3E5c                     | j                   j                  t        | j                  |      | j	                  |      | j
                  j                        S )zF
        Create a span for the received proxy server request.
        rs  )r   r   r   kind)r   r	  rN  r  rc  r   SERVER)r=   r   r+   s      r>   )create_litellm_proxy_request_started_spanz7OpenTelemetry.create_litellm_proxy_request_started_span|	  sM     {{%%0{{:.44W4E&&	 & 
 	
r@   )NNNNN)F)NNNN)r  NNNNr   )PrS   rT   rU   r	   r'   r:   r   rm   staticmethodr   rp   rW   r   rf   rn   ro   r   r   r   r   r   r   r
   r   r  r  r  r  r   r   r"  r   r3  r   r;  r5  r6  r   r>  r   rH  rI  rL  r  r  r  r  rM  rK  r   r.  r   r  r  r  r  r   r   r   r  rJ  r?  r  r0  r5  r]  r  rT  rc  r-  r   r   r   r  r7  r   r  r  r  __classcell__)rt   s   @r>   r[   r[      s    15'+)-)-(,&2,-&2  }&2
 "#&2 "#&2 !&2P 1&9 1 1=< !&G G GR"<<
|
8IIII ,07;59)-9<%9< #4.9< U8U?34	9<
 55129< !9<|  "+/7;59)-><%>< }>< #4.	><
 U8U?34>< 512>< !><J (,GG &G *	G
  }G> * #	4.D .V .`<x~ <= =,0M	$"G<R254DNL eHeS012	% & T 4DD smD 	D
 D DL)) %() 	)VT)d T)l smc] sm 
#	 (MHtnMH/7/@MH^=A~Qd QD Qf" "HU3c5;P5Q " 67	c3h *VV08VpeCsE<Q6R "1t 1# 1c 1)d4j#o.)	d)VDz	d(8t 8t))"6htn 6pe=8D> e=NR(hCXJB B47B	#BH #%T	*+#	c3h# #, ,03@93@ #4.3@p ,00@90@ #4.0@d

 
 
$	
r@   r[   );r;   dataclassesr   r   typingr   r   r   r   r	   r
   r   r!   litellm._loggingr   r  r   r   "litellm.integrations.custom_loggerr   *litellm.litellm_core_utils.safe_json_dumpsr   litellm.secret_managers.mainr   r   litellm.types.servicesr   litellm.types.utilsr   r   r   r   r   r   r}  r   _SpanExporterr   r   _Contextr   _Spanr   _Tracerr  r   !_ManagementEndpointLoggingPayloadlitellm.proxy.proxy_serverr   _UserAPIKeyAuthr<   r   r"   r#   rN  r\  rX  r'   r[   rY   r@   r>   <module>r     sH   	 !  H H H  + < A E 7  L715 MD7C< FHcM"G+,L?C/0N',-NPS-S'T$DFLN'*$Gbii 2I> RYY3Y? bii 5yA "A , -  O
 O
 O
dz#
L z#
r@   