Ë
    tPêj£…  ã                   óŠ  — U d Z ddlZddlZddlZddlZddlZddlmZ ddlmZ ddl	m
Z
mZ ddlZddlmZ ddlZddlmZ ddlmZ dd	lmZ dd
lmZmZmZmZ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$ 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/m0Z0m1Z1 ddl2m3Z3 ddl4m5Z5 e1jl                  gZ7ee8d<   de9fd„Z: G d„ dee5«      Z;y)ay  
DataDog Integration - sends logs to /api/v2/log

DD Reference API: https://docs.datadoghq.com/api/latest/logs

`async_log_success_event` - used by litellm proxy to send logs to datadog
`log_success_event` - sync version of logging to DataDog, only used on litellm Python SDK, if user opts in to using sync functions

async_log_success_event:  will store batch of DD_MAX_BATCH_SIZE in memory and flush to Datadog once it reaches DD_MAX_BATCH_SIZE or every 5 seconds

async_service_failure_hook: Logs failures from Redis, Postgres (Adjacent systems), as 'WARNING' on DataDog

For batching specific details see CustomBatchLogger class
é    N)ÚSequence)Údatetime)ÚAnyÚFinal)ÚResponse)Úverbose_logger)Úuuid)ÚCustomBatchLogger)Úget_datadog_base_url_from_envÚget_datadog_hostnameÚget_datadog_serviceÚget_datadog_sourceÚget_datadog_tags)Úcreate_mock_datadog_clientÚshould_use_datadog_mock)Útracer)ÚMaskedHTTPStatusErrorÚ_get_httpx_clientÚget_async_httpx_clientÚhttpxSpecialProvider)ÚIntegrationHealthCheckStatus)Ú	DD_ERRORSÚDD_MAX_BATCH_SIZEÚDD_MAX_PAYLOAD_SIZE_BYTESÚDatadogInitParamsÚDatadogPayloadÚ"DatadogProxyFailureHookJsonMessageÚDataDogStatus)ÚServiceLoggerPayloadÚServiceTypes)ÚStandardLoggingPayloadé   )ÚAdditionalLoggingUtilsÚDD_LOGGED_SUCCESS_SERVICE_TYPESÚreturnc                  óè   — t        j                  d«      } | €t        S 	 t        | «      }t        dt        |t        «      «      S # t        $ r$ t        j                  d| t        «       t        cY S w xY w)NÚDD_BATCH_SIZEz4Datadog: ignoring invalid DD_BATCH_SIZE=%r, using %sé   )	ÚosÚgetenvr   ÚintÚ
ValueErrorr   ÚwarningÚmaxÚmin)ÚrawÚvalues     úi/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/integrations/datadog/datadog.pyÚ_resolve_dd_batch_sizer3   J   sp   € Ü—‘˜?Ó+€CØ
€{Ü Ð ð!Ü˜3“xˆô ˆq”#�eÔ.Ó/Ó0Ð0øô ò !Ü×ÑØBØÜô	
ô
 !Ò ð!ús   ŸA Á*A1Á0A1c                   ó*  ‡ — e Zd Z	 	 	 	 	 d6dedz  dedz  dedz  dedz  def
ˆ fd„Zdefd	„Z	 	 	 d7dededz  dedz  deddf
d
„Z	 	 	 d7dedz  dedz  deddfd„Z	d„ Z
d„ Z	 d8dededededz  dedz  f
d„Zd„ Zdedefd„Zededee   defd„«       Zedee   defd„«       Zd„ Zd„ Zd„ Zdededefd„Zd eez  d!ed"ej:                  d#ej:                  def
d$„Zd%edefd&„Z 	 	 	 	 	 d9d'e!d(edz  d)edz  d"e"e#z  dz  d#e#e"z  dz  d*edz  fd+„Z$	 	 	 	 	 d9d'e!d(edz  d)edz  d"e"e#z  dz  d#e#e"z  dz  d*edz  fd,„Z%d eez  d!ed"ej:                  d#ej:                  def
d-„Z&d.eddfd/„Z'deeef   dz  fd0„Z(de)fd1„Z*d2ed3e"dz  d4e"dz  dedz  fd5„Z+ˆ xZ,S ):ÚDataDogLoggerNÚ
dd_api_keyÚdd_siteÚdd_agent_hostÚdd_agent_portÚallow_env_credentialsc                 ó  •— 	 t        j                  d«       t        «       | _        | j                  rt	        «        t        j                  d«       | j                  «       }|j                  |«       t        t        j                  ¬«      | _
        |xs t        j                  d«      }|r| j                  ||||¬«       n| j                  |||¬«       t        «       }	|	r
|	› d�| _        t#        «       | _        t'        j(                  | j+                  «       «       t'        j,                  «       | _        t1        ‰| �d  di |¤| j.                  t5        «       dœ¤Ž y
# t6        $ r}
t        j8                  d	|
«       |
‚d
}
~
ww xY w)a‹  
        Initializes the datadog logger, checks if the correct env variables are set

        Args:
            dd_api_key: Datadog API key. Falls back to DD_API_KEY env var when allow_env_credentials is True.
            dd_site: Datadog site (e.g. "us5.datadoghq.com"). Falls back to DD_SITE env var.
            dd_agent_host: Hostname or IP of DataDog agent. Falls back to LITELLM_DD_AGENT_HOST env var.
            dd_agent_port: Port of DataDog agent (default: 10518). Falls back to LITELLM_DD_AGENT_PORT env var.
            allow_env_credentials: When False, the API key is never read from DD_API_KEY env var. Set to
                False for team/key-scoped loggers whose destination (dd_agent_host/dd_site) is caller-supplied,
                so the proxy's global DD_API_KEY is never sent to an untrusted host.

        Required environment variables (Direct API) when kwargs not provided:
        `DD_API_KEY` - your datadog api key
        `DD_SITE` - your datadog site, example = `"us5.datadoghq.com"`

        Optional environment variables (DataDog Agent):
        `LITELLM_DD_AGENT_HOST` - hostname or IP of DataDog agent, example = `"localhost"`
        `LITELLM_DD_AGENT_PORT` - port of DataDog agent (default: 10518 for logs)

        Note: We use LITELLM_DD_AGENT_HOST instead of DD_AGENT_HOST to avoid conflicts
        with ddtrace which automatically sets DD_AGENT_HOST for APM tracing.
        zDatadog: in init datadog loggerz6[DATADOG MOCK] Datadog logger initialized in mock mode)Úllm_providerÚLITELLM_DD_AGENT_HOST)r8   r9   r6   r:   )r6   r7   r:   ú/api/v2/logs)Ú
flush_lockÚ
batch_sizez0Datadog: Got exception on init Datadog client %sN© )r   Údebugr   Úis_mock_moder   Ú_get_datadog_paramsÚupdater   r   ÚLoggingCallbackÚasync_clientr)   r*   Ú_configure_dd_agentÚ_configure_dd_direct_apir   Ú
intake_urlr   Úsync_clientÚasyncioÚcreate_taskÚperiodic_flushÚLockr?   ÚsuperÚ__init__r3   Ú	ExceptionÚ	exception)Úselfr6   r7   r8   r9   r:   ÚkwargsÚdict_datadog_paramsÚresolved_agent_hostÚdd_base_urlÚeÚ	__class__s              €r2   rQ   zDataDogLogger.__init___   sd  ø€ ð@0	Ü× Ñ Ð!BÔCä 7Ó 9ˆDÔà× Ò Ü*Ô,Ü×$Ñ$Ð%]Ô^ð
 *.×)AÑ)AÓ)CÐØ�M‰MÐ-Ô.ä 6ÔDX×DhÑDhÔ iˆDÔð *7Ò)\¼"¿)¹)ÐD[Ó:\ÐÙ"Ø×(Ñ(Ø"5Ø"/Ø)Ø*?ð	 )õ ð ×-Ñ-Ø)Ø#Ø*?ð .ô ô "?Ó!@ˆKÙØ%0 M°Ð">�”Ü0Ó2ˆDÔÜ×Ñ × 3Ñ 3Ó 5Ô6Ü%Ÿl™l›nˆDŒOÜ‰GÑñ ØðàŸ?™?Ü1Ó3õøô
 ò 	Ü×$Ñ$Ð%WÐYZÔ[ØˆGûð	ús   ƒEE Å	FÅ(F Æ Fr%   c                 ó0  — i }t         j                  �ƒt        t         j                  t        «      r t         j                  j	                  «       }|S t        t         j                  t
        «      r't        di t         j                  ¤Žj	                  «       }|S )z§
        Get the datadog_params from litellm.datadog_params

        These are params specific to initializing the DataDogLogger e.g. turn_off_message_logging
        rA   )ÚlitellmÚdatadog_paramsÚ
isinstancer   Ú
model_dumpÚdict)rT   rV   s     r2   rD   z!DataDogLogger._get_datadog_params±   sy   € ð %'ÐÜ×!Ñ!Ð-Üœ'×0Ñ0Ô2CÔDÜ&-×&<Ñ&<×&GÑ&GÓ&IÐ#ð #Ð"ô œG×2Ñ2´DÔ9ä&7Ñ&Q¼'×:PÑ:PÑ&Q×&\Ñ&\Ó&^Ð#Ø"Ð"ó    c                 óØ   — |xs t        j                  dd«      }d|› d|› d�| _        |xs |rt        j                  d«      nd| _        t	        j
                  d| j                  «       y)	aÞ  
        Configure DataDog Agent for log forwarding

        Args:
            dd_agent_host: Hostname or IP of DataDog agent
            dd_agent_port: Port of DataDog agent. Falls back to LITELLM_DD_AGENT_PORT env var (default: 10518).
            dd_api_key: Datadog API key. Falls back to DD_API_KEY env var when allow_env_credentials is True. Optional when using agent.
            allow_env_credentials: When False, never read the API key from DD_API_KEY env var.
        ÚLITELLM_DD_AGENT_PORTÚ10518zhttp://ú:r>   Ú
DD_API_KEYNzDatadog: Using DD Agent at %s)r)   r*   rJ   rf   r   rB   )rT   r8   r9   r6   r:   Úresolved_ports         r2   rH   z!DataDogLogger._configure_dd_agentÀ   sg   € ð   -Ò[´·	±	Ð:QÐSZÓ0[ˆØ# M ?°!°M°?À,ÐOˆŒØ$ò 
Ù'<ŒB�I‰I�lÔ#À$ð 	Œô 	×ÑÐ<¸d¿o¹oÕNra   c                 óÈ   — |xs |rt        j                  d«      nd}|xs t        j                  d«      }|€t        d«      ‚|€t        d«      ‚|| _        d|› d�| _        y)a½  
        Configure direct DataDog API connection

        Args:
            dd_api_key: Datadog API key. Falls back to DD_API_KEY env var when allow_env_credentials is True.
            dd_site: Datadog site. Falls back to DD_SITE env var.
            allow_env_credentials: When False, never read the API key from DD_API_KEY env var.

        Raises:
            Exception: If required credentials are not provided via args or env vars
        rf   NÚDD_SITEz)DD_API_KEY is not set, set 'DD_API_KEY=<>z+DD_SITE is not set in .env, set 'DD_SITE=<>zhttps://http-intake.logs.r>   )r)   r*   rR   rf   rJ   )rT   r6   r7   r:   Úresolved_api_keyÚresolved_sites         r2   rI   z&DataDogLogger._configure_dd_direct_api×   sl   € ð" #-Ò"lÑLa´·±¸<Ô1HÐgkÐØ&Ò>¬"¯)©)°IÓ*>ˆàÐ#ÜÐGÓHÐHØÐ ÜÐIÓJÐJà*ˆŒØ5°m°_ÀLÐQˆ�ra   c              ƒ   óô   K  — 	 t        j                  d|«       | j                  ||||«      ƒ d{  –—†  y7 Œ# t        $ r3}t        j                  d|t        j                  «       «       Y d}~yd}~ww xY w­w)aF  
        Async Log success events to Datadog

        - Creates a Datadog payload
        - Adds the Payload to the in memory logs queue
        - Payload is flushed every 10 seconds or when batch size is greater than 100


        Raises:
            Raises a NON Blocking verbose_logger.exception if an error occurs
        ú7Datadog: Logging - Enters logging function for model %sNúDatadog Layer Error - %s
%s©r   rB   Ú_log_async_eventrR   rS   Ú	tracebackÚ
format_exc©rT   rU   Úresponse_objÚ
start_timeÚend_timerY   s         r2   Úasync_log_success_eventz%DataDogLogger.async_log_success_eventó   sh   è ø€ ð	`Ü× Ñ Ð!ZÐ\bÔcØ×'Ñ'¨°¸jÈ(ÓS×SÒSùäò 	`Ü×$Ñ$Ð%CÀQÌ	×H\ÑH\ÓH^×_Ñ_ûð	`üó7   ‚A8„-9 ±7²9 ¶A8·9 ¹	A5Á)A0Á+A8Á0A5Á5A8c              ƒ   óô   K  — 	 t        j                  d|«       | j                  ||||«      ƒ d {  –—†  y 7 Œ# t        $ r3}t        j                  d|t        j                  «       «       Y d }~y d }~ww xY w­w)Nrm   rn   ro   rs   s         r2   Úasync_log_failure_eventz%DataDogLogger.async_log_failure_event  sh   è ø€ ð	`Ü× Ñ Ð!ZÐ\bÔcØ×'Ñ'¨°¸jÈ(ÓS×SÒSùäò 	`Ü×$Ñ$Ð%CÀQÌ	×H\ÑH\ÓH^×_Ñ_ûð	`ürx   Úrequest_dataÚoriginal_exceptionÚuser_api_key_dictÚtraceback_strc              ƒ   ó  K  — 	 ddl m} ddlm} |j	                  ||¬«      }|j                  d«      xs d}d}	|r2t        |«      j                  «       j                  «       rt        |«      }	i }
	 ddl
m} |j                  |¬	«      }t        |t        «      rt        |«      n|}
|j                  d«      xs t        |«      |j                  d«      xs |j$                  j&                  |	|j                  d«      xs d|
dœ}t)        t+        «       dj-                  t/        «       «      t1        «        ||«      t3        «       t4        j6                  ¬«      }| j9                  |¬«       | j:                  j=                  |«       t?        | j:                  «      | j@                  k\  r| jC                  «       ƒ d{  –—†  y# t        $ rt t!        |d
«      rt#        |d
d«      |
d
<   t!        |d«      rt#        |dd«      |
d<   t!        |d«      rt#        |dd«      |
d<   t!        |d«      rt#        |dd«      |
d<   Y �Œ–w xY w7 Œ…# t        $ r3}tE        jF                  d|tI        jJ                  «       «       Y d}~yd}~ww xY w­w)a  
        Log proxy-level failures (e.g. 401 auth, DB connection errors) to Datadog.

        Ensures failures that occur before or outside the LLM completion flow
        (e.g. ConnectError during auth when DB is down) are visible in Datadog
        alongside Prometheus.
        r   )ÚStandardLoggingPayloadSetup©Ú
safe_dumps)r|   r~   Ú
error_codeÚ N)ÚLiteLLMProxyRequestSetup)r}   Úrequest_routeÚteam_idÚuser_idÚend_user_idÚerror_messageÚerror_classrq   )rS   r‹   Ústatus_coderq   r}   ú,©ÚddsourceÚddtagsÚhostnameÚmessageÚserviceÚstatus©Ú
dd_payloadz-Datadog: async_post_call_failure_hook - %s
%s)&Ú*litellm.litellm_core_utils.litellm_loggingr€   Ú*litellm.litellm_core_utils.safe_json_dumpsr‚   Úget_error_informationÚgetÚstrÚstripÚisdigitr+   Ú$litellm.proxy.litellm_pre_call_utilsr…   Ú'get_sanitized_user_information_from_keyr^   r`   rR   ÚhasattrÚgetattrrZ   Ú__name__r   r   Újoinr   r   r   r   ÚERRORÚ_add_trace_context_to_payloadÚ	log_queueÚappendÚlenr@   Úflush_queuer   rS   rq   rr   )rT   r{   r|   r}   r~   r€   r‚   Úerror_informationÚ_coderŒ   Úuser_contextr…   Ú_metaÚmessage_payloadr–   rY   s                   r2   Úasync_post_call_failure_hookz*DataDogLogger.async_post_call_failure_hook  sr  è ø€ ð;	rõõ Nà'B×'XÑ'XØ#5Ø+ð (Yó (Ðð -×0Ñ0°Ó>ÒDÀ"ˆEØ&*ˆKÙœ˜U›×)Ñ)Ó+×3Ñ3Ô5Ü! %›j�ð ,.ˆLðbõð  8×_Ñ_Ø&7ð  `ó  �ô /9¸ÄÔ.Eœt Eœ{È5�ð /×2Ñ2°?ÓCÒ^ÄsÐK]ÓG^Ø0×4Ñ4°]ÓCÒlÐGY×GcÑGc×GlÑGlØ*Ø.×2Ñ2°;Ó?ÒEÀ2Ø%1ñJˆOô !/Ü+Ó-Ø—x‘xÔ 0Ó 2Ó3Ü-Ó/Ù" ?Ó3Ü+Ó-Ü$×*Ñ*ô!ˆJð ×.Ñ.¸*Ð.ÔEØ�N‰N×!Ñ! *Ô-ä�4—>‘>Ó" d§o¡oÒ5Ø×&Ñ&Ó(×(Ð(ð øôE ò 	bäÐ,¨oÔ>Ü4;Ð<MÈÐ`dÓ4e�L Ñ1ÜÐ,¨iÔ8Ü.5Ð6GÈÐTXÓ.Y�L Ñ+ÜÐ,¨iÔ8Ü.5Ð6GÈÐTXÓ.Y�L Ñ+ÜÐ,¨mÔ<Ü29Ð:KÈ]Ð\`Ó2a�L Ñ/úð	búð> )ùÜò 	rÜ×$Ñ$Ð%UÐWXÔZc×ZnÑZnÓZp×qÐqØûð	rüsa   ‚J„A,I Á15G  Â&DI Æ:I Æ;I Æ?JÇ A9H=È9I È<H=È=I É	I>É)I9É4JÉ9I>É>Jc              ƒ   ót  K  — | j                   st        j                  d«       y| j                   dd }g | _         	 t        j                  dt	        |«      | j
                  «       | j                  rt        j                  d«       | j                  |«      ƒ d{  –—† }|r|| j                   z   | _         | j                  r t        j                  dt	        |«      «       yy7 ŒG# t        $ rG}|| j                   z   | _         t        j                  d|t        j                  «       «       Y d}~yd}~ww xY w­w)zþ
        Sends the in memory logs queue to datadog api

        Logs sent to /api/v2/logs

        DD Ref: https://docs.datadoghq.com/api/latest/logs/

        Raises:
            Raises a NON Blocking verbose_logger.exception if an error occurs
        z!Datadog: log_queue does not existNz(Datadog - about to flush %s events on %sz@[DATADOG MOCK] Mock mode enabled - API calls will be interceptedz5[DATADOG MOCK] Batch of %s events successfully mockedz'Datadog Error sending batch API - %s
%s)r¦   r   rS   rB   r¨   rJ   rC   Ú_send_with_413_splitrR   rq   rr   )rT   Úbatch_to_sendÚundeliveredrY   s       r2   Úasync_send_batchzDataDogLogger.async_send_batchZ  s  è ø€ ð �~Š~Ü×$Ñ$Ð%HÔIØà#Ÿ~™~©aÐ0ˆØˆŒð	lÜ× Ñ Ø:Ü�MÓ"Ø—‘ôð × Ò Ü×$Ñ$Ð%gÔhà'+×'@Ñ'@ÀÓ'O×!OˆKÙØ!,¨t¯~©~Ñ!=�”à× Ò Ü×$Ñ$Ð%\Ô^aÐboÓ^pÕqð !ð	 "Pùô ò 	lØ*¨T¯^©^Ñ;ˆDŒNÜ×$Ñ$Ð%OÐQRÔT]×ThÑThÓTj×kÑkûð	lüsB   ‚9D8¼AC% ÂC#ÂAC% Ã!D8Ã#C% Ã%	D5Ã.=D0Ä+D8Ä0D5Ä5D8Úbatchc              ƒ   ó  K  — |g}|�r‹|j                  «       }|sŒt        |«      dkD  rH| j                  |«      r7t        |«      dz  }|j                  ||d «       |j                  |d| «       Œl	 | j	                  |«      ƒ d{  –—† }|j                  dk(  rtt        |«      dk(  r.t        j                  t        j                  j                   «       ŒÑt        |«      dz  }|j                  ||d «       |j                  |d| «       �Œ	|j                  dk7  r=t        j                  d|j                  |j"                  «       | j                  ||«      S t        j$                  dt        |«      |j                  |j"                  «       |r�Œ‹g S 7 �Œ# t
        $ rd}t        |t        «      r|j                  dk(  r|j                  }n-t        j                  d|«       | j                  ||«      cY d}~S Y d}~�Œud}~ww xY w­w)	a   
        Send a batch, halving any sub-batch that exceeds Datadog's intake limits before
        sending, and halving again on a 413 (payload too large) response, since Datadog
        enforces a 5MB uncompressed limit per request. The proactive split avoids paying
        a serialize + gzip + round trip for a payload the intake is guaranteed to reject.

        A 413 surfaces as a raised MaskedHTTPStatusError (httpx raise_for_status), not a
        returned response, so both paths are handled. A lone event that still 413s is
        dropped to avoid wedging the queue on an undeliverable payload. Returns the events
        that could not be delivered because of a non-413 (transient) error, so the caller
        re-queues only those and never the events already accepted by Datadog.
        r(   r"   Ni�  z$Datadog Error sending batch API - %séÊ   z4Datadog: unexpected response status_code=%s, text=%sz5Datadog: delivered %s events, status_code=%s, text=%s)Úpopr¨   Ú_exceeds_intake_limitsr§   Úasync_send_compressed_datarR   r^   r   rŒ   Úresponser   rS   Ú_undeliveredÚerrorr   ÚDATADOG_413_ERRORr1   ÚtextrB   )rT   rµ   ÚpendingÚchunkÚmidr»   rY   s          r2   r±   z"DataDogLogger._send_with_413_split�  sË  è ø€ ð ', WˆÚØ—K‘K“MˆEÙØÜ�5‹z˜AŠ~ $×"=Ñ"=¸eÔ"DÜ˜%“j A‘o�Ø—‘˜u S T˜{Ô+Ø—‘˜u T c˜{Ô+Øð=Ø!%×!@Ñ!@ÀÓ!G×G�ð ×#Ñ# sÒ*Ü�u“: ’?Ü"×(Ñ(¬×)DÑ)D×)JÑ)JÔKØÜ˜%“j A‘o�Ø—‘˜u S T˜{Ô+Ø—‘˜u T c˜{Ô+Ùà×#Ñ# sÒ*Ü×$Ñ$ØJØ×(Ñ(Ø—M‘Môð
 ×(Ñ(¨°Ó8Ð8ä× Ñ ØGÜ�E“
Ø×$Ñ$Ø—‘ô	óG ðR ˆ	ð? HúÜò =Ü˜aÔ!6Ô7¸A¿M¹MÈSÒ<PØ Ÿz™z‘Hä"×,Ñ,Ð-SÐUVÔWØ×,Ñ,¨U°GÓ<Õ<õ ûð=üsP   ‚A0H	Á3F ÂFÂF ÂDH	ÆH	ÆF Æ	HÆ"AHÇ5HÇ6H	ÈHÈH	rÁ   rÀ   c                 óX   — | t        |«      D ��cg c]  }|D ]  }|‘Œ Œ c}}z   S c c}}w ©N)Úreversed)rÁ   rÀ   Ú	remainingÚevents       r2   r¼   zDataDogLogger._undeliveredº  s,   € à¬x¸Ó/@×X )ÈiÒXÀUšÐX˜ÓXÑXÐXùÓXs   �&c                 ó†   — ddl m} t        | «      t        kD  ryt         || «      j	                  d«      «      }|t
        kD  S )a5  
        True when a chunk would breach Datadog's log intake limits: more than
        DD_MAX_BATCH_SIZE events per payload, or a serialized size above
        DD_MAX_PAYLOAD_SIZE_BYTES (held under Datadog's 5MB uncompressed cap so
        the batch is split before the intake rejects it with a 413).
        r   r�   Túutf-8)r˜   r‚   r¨   r   Úencoder   )rÁ   r‚   Úpayload_size_bytess      r2   r¹   z$DataDogLogger._exceeds_intake_limits¾  s?   € õ 	Jäˆu‹:Ô)Ò)ØÜ$'©
°5Ó(9×(@Ñ(@ÀÓ(IÓ$JÐØ!Ô$=Ñ=Ð=ra   c              ƒ   óŠ  K  — | j                   €y | j                   4 ƒd {  –—†  | j                  rft        j                  dt	        | j                  «      «       | j                  «       ƒ d {  –—†  | j                  st        j                  «       | _        d d d «      ƒd {  –—†  y 7 Œ‡7 Œ<7 Œ	# 1 ƒd {  –—†7  sw Y   y xY w­w)Nz$Datadog: Flushing batch of %s events)r?   r¦   r   rB   r¨   r´   ÚtimeÚlast_flush_time)rT   s    r2   r©   zDataDogLogger.flush_queueÍ  sš   è ø€ Ø�?‰?Ð"Øà—?‘?÷ 	7ñ 	7Ø�~Š~Ü×$Ñ$Ð%KÌSÐQU×Q_ÑQ_ÓM`ÔaØ×+Ñ+Ó-×-Ð-Ø—~’~Ü+/¯9©9«;�DÔ(÷	7÷ 	7ñ 	7øð .øð	7ø÷ 	7÷ 	7ñ 	7üsW   ‚C B(¡C¤A	B.Á-B*Á.)B.ÂCÂ"B,Â#CÂ*B.Â,CÂ.C Â4B7Â5C Â<Cc                 óf  — 	 t         j                  du r| j                  ||||¬«      }n| j                  ||||¬«      }i }| j                  r| j                  |d<   | j
                  j                  | j                  ||¬«      }|j                  «        |j                  dk7  r%t        d|j                  › d|j                  › �«      ‚t        j                  d|j                  |j                  «       y
# t        $ r3}t        j                  d	|t        j                   «       «       Y d
}~y
d
}~ww xY w)z
        Sync Log success events to Datadog

        - Creates a Datadog payload
        - instantly logs it on DD API
        T©rU   rt   ru   rv   ú
DD-API-KEY)ÚurlÚjsonÚheadersr·   z'Response from datadog API status_code: z, text: z<Datadog: Response from datadog API status_code: %s, text: %srn   N)r\   Údatadog_use_v1Ú_create_v0_logging_payloadÚcreate_datadog_logging_payloadrf   rK   ÚpostrJ   Úraise_for_statusrŒ   rR   r¿   r   rB   rS   rq   rr   )	rT   rU   rt   ru   rv   r–   rÔ   r»   rY   s	            r2   Úlog_success_eventzDataDogLogger.log_success_eventØ  s8  € ð'	`Ü×%Ñ%¨Ñ-Ø!×<Ñ<Ø!Ø!-Ø)Ø%ð	 =ó ‘
ð "×@Ñ@Ø!Ø!-Ø)Ø%ð	 Aó �
ð  ˆGà�ŠØ(,¯©�˜Ñ%à"×.Ñ.×3Ñ3Ø—O‘OØØð 4ó ˆHð ×%Ñ%Ô'Ø×#Ñ# sÒ*ÜÐ"IÈ(×J^ÑJ^ÐI_Ð_gÐhp×huÑhuÐgvÐ wÓxÐxä× Ñ ØNØ×$Ñ$Ø—‘õøô ò 	`Ü×$Ñ$Ð%CÀQÌ	×H\ÑH\ÓH^×_Ñ_ûð	`ús   ‚C1C4 Ã4	D0Ã=)D+Ä+D0c              ƒ   ó&  K  — | j                  ||||¬«      }| j                  j                  |«       t        j                  d| j
                  «       t        | j                  «      | j                  k\  r| j                  «       ƒ d {  –—†  y y 7 Œ­w)NrÐ   z:Datadog, event added to queue. Will flush in %s seconds...)	r×   r¦   r§   r   rB   Úflush_intervalr¨   r@   r©   )rT   rU   rt   ru   rv   r–   s         r2   rp   zDataDogLogger._log_async_event  sƒ   è ø€ Ø ×?Ñ?ØØ%Ø!Øð	 @ó 
ˆ
ð 	�‰×Ñ˜jÔ)Ü×ÑÐYÐ[_×[nÑ[nÔoäˆt�~‰~Ó $§/¡/Ò1Ø×"Ñ"Ó$×$Ñ$ð 2Ø$ús   ‚BBÂBÂ	BÚstandard_logging_objectr”   c                 óö   — ddl m}  ||«      }t        j                  d|«       t	        t        «       dj                  t        |¬«      «      t        «       |t        «       |¬«      }| j                  |¬«       |S )Nr   r�   ú&Datadog: Logger - Logging payload = %sr�   )rÝ   rŽ   r•   )r˜   r‚   r   rB   r   r   r£   r   r   r   r¥   )rT   rÝ   r”   r‚   Újson_payloadr–   s         r2   Ú&_create_datadog_logging_payload_helperz4DataDogLogger._create_datadog_logging_payload_helper  sr   € õ
 	Já(Ð)@ÓAˆÜ×ÑÐEÀ|ÔTÜ*Ü'Ó)Ø—8‘8Ô,ÐE\Ô]Ó^Ü)Ó+Ø Ü'Ó)Øô
ˆ
ð 	×*Ñ*°jÐ*ÔAØÐra   rU   rt   ru   rv   c                 óô   — |j                  dd«      }|€t        d«      ‚t        j                  }|j                  d«      dk(  rt        j                  }| j                  |«       | j                  ||¬«      }|S )a�  
        Helper function to create a datadog payload for logging

        Args:
            kwargs (Union[dict, Any]): request kwargs
            response_obj (Any): llm api response
            start_time (datetime.datetime): start time of request
            end_time (datetime.datetime): end time of request

        Returns:
            DatadogPayload: defined in types.py
        rÝ   Nz+standard_logging_object not found in kwargsr”   Úfailure©rÝ   r”   )rš   r,   r   ÚINFOr¤   Ú)truncate_standard_logging_payload_contentrá   )rT   rU   rt   ru   rv   rÝ   r”   r–   s           r2   r×   z,DataDogLogger.create_datadog_logging_payload*  s‰   € ð( IOÏ
É
ÐSlÐnrÓHsÐØ"Ð*ÜÐJÓKÐKä×#Ñ#ˆØ"×&Ñ& xÓ0°IÒ=Ü"×(Ñ(ˆFð 	×6Ñ6Ð7NÔOà ×GÑGØ$;Øð Hó 
ˆ
ð Ðra   Údatac              ƒ   ó  K  — ddl }ddlm} |j                   ||«      j	                  d«      «      }dddœ}| j
                  r| j
                  |d<   | j                  j                  | j                  ||¬	«      ƒ d{  –—† }|S 7 Œ­w)
a;  
        Async helper to send compressed data to datadog self.intake_url

        Datadog recommends using gzip to compress data
        https://docs.datadoghq.com/api/latest/logs/

        "Datadog recommends sending your logs compressed. Add the Content-Encoding: gzip header to the request when sending"
        r   Nr�   rÉ   Úgzipzapplication/json)zContent-EncodingzContent-TyperÑ   )rÒ   rç   rÔ   )	ré   r˜   r‚   ÚcompressrÊ   rf   rG   rØ   rJ   )rT   rç   ré   r‚   Úcompressed_datarÔ   r»   s          r2   rº   z(DataDogLogger.async_send_compressed_dataO  s‹   è ø€ ó 	åIà!%§¡©z¸$Ó/?×/FÑ/FÀwÓ/OÓ!Pˆð !'Ø.ñ
ˆð �?Š?Ø$(§O¡OˆG�LÑ!à $× 1Ñ 1× 6Ñ 6Ø—‘Ø Øð !7ó !
÷ 
ˆð
 ˆð
ús   ‚A<BÁ>BÁ?BÚpayloadr½   Úparent_otel_spanÚevent_metadatac              ƒ   óž  K  — 	 |j                  «       }|j                  |xs i «       ddlm}  ||«      }	t	        t        «       dj                  t        «       «      t        «       |	t        «       t        j                  ¬«      }
| j                  j                  |
«       y# t        $ r }t        j                   d|«       Y d}~yd}~ww xY w­w)z¬
        Logs failures from Redis, Postgres (Adjacent systems), as 'WARNING' on DataDog

        - example - Redis is failing / erroring, will be logged on DataDog
        r   r�   r�   rŽ   ú=Datadog: Logger - Exception in async_service_failure_hook: %sN)r_   rE   r˜   r‚   r   r   r£   r   r   r   r   ÚWARNr¦   r§   rR   r   rS   ©rT   rì   r½   rí   ru   rv   rî   Ú_payload_dictr‚   Ú_dd_message_strÚ_dd_payloadrY   s               r2   Úasync_service_failure_hookz(DataDogLogger.async_service_failure_hookp  s¬   è ø€ ð	iØ#*×#5Ñ#5Ó#7ˆMØ× Ñ  Ò!5°2Ô6ÝMá%/°Ó%>ˆOÜ!/Ü+Ó-Ø—x‘xÔ 0Ó 2Ó3Ü-Ó/Ø'Ü+Ó-Ü$×)Ñ)ô"ˆKð �N‰N×!Ñ! +Õ.øäò 	iÜ×$Ñ$Ð%dÐfg×hÑhûð	iüs/   ‚C„BB! Â CÂ!	C
Â*CÃ CÃC
Ã
Cc              ƒ   óÄ  K  — 	 |j                   t        vry|j                  «       }|j                  |xs i «       ddlm}  ||«      }	t        t        «       dj                  t        «       «      t        «       |	t        «       t        j                  ¬«      }
| j                  j                  |
«       y# t         $ r }t#        j$                  d|«       Y d}~yd}~ww xY w­w)zÏ
        Logs success from Redis, Postgres (Adjacent systems), as 'INFO' on DataDog

        No user has asked for this so far, this might be spammy on datatdog. If need arises we can implement this
        Nr   r�   r�   rŽ   rð   )r“   r$   r_   rE   r˜   r‚   r   r   r£   r   r   r   r   rå   r¦   r§   rR   r   rS   rò   s               r2   Úasync_service_success_hookz(DataDogLogger.async_service_success_hook’  s¼   è ø€ ð	ià�‰Ô&EÑEØà#*×#5Ñ#5Ó#7ˆMØ× Ñ  Ò!5°2Ô6åMá%/°Ó%>ˆOÜ!/Ü+Ó-Ø—x‘xÔ 0Ó 2Ó3Ü-Ó/Ø'Ü+Ó-Ü$×)Ñ)ô"ˆKð �N‰N×!Ñ! +Õ.øäò 	iÜ×$Ñ$Ð%dÐfg×hÑhûð	iüs9   ‚C „B4 –C —BB4 Â3C Â4	CÂ=CÃC ÃCÃC c                 óº  — |j                  di «      }|j                  di «      xs i }|j                  d«      }|j                  di «      }|j                  dd«      }	|j                  dd«      }
|d	   }|j                  d
t        t        j                  «       «      «      }t	        |«      }	 ||z
  j                  «       dz  }	 t	        |«      }i }t        |t        «      r"|j                  «       D ]  \  }}|dv rŒ|||<   Œ ||	|
||||j                  dd«      |j                  dd«      ||j                  dd«      ||||dœ}ddl	m
}  ||«      }t        j                  d|«       t        t        «       dj                  t!        «       «      t#        «       |t%        «       t&        j(                  ¬«      }|S # t        $ r d}Y �Œw xY w# t        $ r |}Y �Œ	w xY w)z¨
        Note: This is our V1 Version of DataDog Logging Payload


        (Not Recommended) If you want this to get logged set `litellm.datadog_use_v1 = True`
        Úlitellm_paramsÚmetadataÚmessagesÚoptional_paramsÚ	call_typezlitellm.completionÚ	cache_hitFÚusageÚidiè  N)ÚendpointÚcaching_groupsÚprevious_modelsÚmodelr„   ÚuserÚresponse_costr   )r  rþ   rÿ   ru   rv   Úresponse_timer  r  Úmodel_parametersÚspendrü   r»   r   rû   r�   rß   r�   rŽ   )rš   r›   r	   Úuuid4r`   Útotal_secondsrR   r^   Úitemsr˜   r‚   r   rB   r   r   r£   r   r   r   r   rå   )rT   rU   rt   ru   rv   rú   rû   rü   rý   rþ   rÿ   r   r  r  Úclean_metadataÚkeyr1   rì   r‚   rà   r–   s                        r2   rÖ   z(DataDogLogger._create_v0_logging_payload¹  sð  € ð !'§
¡
Ð+;¸RÓ @ˆØ(×,Ñ,¨Z¸Ó<ÒBÀˆØ Ÿ*™* ZÓ0ˆØ!'§¡Ð,=¸rÓ!BˆØ!Ÿ:™: kÐ3GÓHˆ	Ø!Ÿ:™: k°5Ó9ˆ	Ø˜WÑ%ˆØ ×$Ñ$ T¬3¬t¯z©z«|Ó+<Ó=ˆÜ�U“ˆð	!Ø%¨
Ñ2×AÑAÓCÀdÑJˆMð	(Ü Ó-ˆLð !#ˆÜ�h¤Ô%Ø&Ÿn™nÓ.ò 	0‘
��Uàð ñ ð
 à*/�N 3Ò'ð	0ð Ø"Ø"Ø$Ø Ø*Ø—Z‘Z ¨Ó,Ø—J‘J˜v rÓ*Ø /Ø—Z‘Z °Ó3Ø Ø$ØØ&ñ
ˆõ" 	Já(¨Ó1ˆä×ÑÐEÀ|ÔTä*Ü'Ó)Ø—8‘8Ô,Ó.Ó/Ü)Ó+Ø Ü'Ó)Ü ×%Ñ%ô
ˆ
ð Ðøôq ò 	!Ø ‹Mð	!ûô
 ò 	(Ø'‹Lð	(ús$   Â.F9 ÃG Æ9GÇGÇGÇGr–   c                 ó¶   — 	 | j                  «       }|€y|d   |d<   |j                  d«      }|�||d<   yy# t        $ r t        j                  d«       Y yw xY w)z2Attach Datadog APM trace context if one is active.NÚtrace_idzdd.trace_idÚspan_idz
dd.span_idz2Datadog: Failed to attach trace context to payload)Ú_get_active_trace_contextrš   rR   r   rS   )rT   r–   Útrace_contextr  s       r2   r¥   z+DataDogLogger._add_trace_context_to_payload  ss   € ð
	[Ø#'×#AÑ#AÓ#CˆMØÐ$Øà(5°jÑ(AˆJ�}Ñ%Ø*×.Ñ.¨yÓ9ˆGØÐ"Ø+2�
˜<Ò(ð #øäò 	[Ü×$Ñ$Ð%YÖZð	[ús   ‚7 • 7 ·AÁAc                 ó^  — 	 d }t        t        dd «      }t        |«      r |«       }|€#t        t        dd «      }t        |«      r |«       }|€y t        |dd «      }|€y t        |dd «      }dt        |«      i}|�t        |«      |d<   |S # t        $ r t        j                  d«       Y y w xY w)NÚcurrent_spanÚcurrent_root_spanr  r  z<Datadog: Failed to retrieve active trace context from tracer)r¡   r   Úcallabler›   rR   r   rS   )rT   r  Úcurrent_span_fnÚcurrent_root_span_fnr  r  r  s          r2   r  z'DataDogLogger._get_active_trace_context  sÉ   € ð	ØˆLÜ%,¬V°^ÀTÓ%JˆOÜ˜Ô(Ù.Ó0�àÐ#Ü.5´fÐ>QÐSWÓ.XÐ$ÜÐ0Ô1Ù#7Ó#9�LàÐ#Øä% l°JÀÓEˆHØÐØä$ \°9¸dÓCˆGØ4>ÄÀHÃÐ3NˆMØÐ"Ü+.¨w«<�˜iÑ(Ø Ð øÜò 	Ü×$Ñ$Ð%cÔdÙð	ús   ‚AB ÁB Á+B ÂB,Â+B,c              ƒ   ó®  K  — ddl m}  |«       }| j                  |t        j                  ¬«      }|g}| j                  |«      ƒ d{  –—† }	 |j                  «        t        dd¬«      S 7 Œ"# t        j                  $ r+}t        d|j                  j                  ¬«      cY d}~S d}~wt        $ r }t        dt        |«      ¬«      cY d}~S d}~ww xY w­w)z1
        Check if the service is healthy
        r   )Ú%create_dummy_standard_logging_payloadrä   NÚhealthy)r”   rŠ   Ú	unhealthy)r—   r  rá   r   rå   rº   rÙ   r   ÚhttpxÚHTTPStatusErrorr»   r¿   rR   r›   )rT   r  rÝ   r–   r¦   r»   rY   s          r2   Úasync_health_checkz DataDogLogger.async_health_check:  sÓ   è ø€ õ	
ñ *OÓ)PÐØ ×GÑGØ$;Ü ×%Ñ%ð Hó 
ˆ
ð '˜<ˆ	Ø $× ?Ñ ?À	Ó J×Jˆð	Ø×%Ñ%Ô'Ü/Ø Ø"ôð ð Kùô ×$Ñ$ò 	Ü/Ø"ØŸj™jŸo™oôõ ûô ò 	Ü/Ø"Ü! !›fôõ ûð	üsZ   ‚ACÁA+Á	CÁA- Á*CÁ-CÂ  B&Â CÂ!CÂ&CÂ2CÃCÃCÃCÃCÚ
request_idÚstart_time_utcÚend_time_utcc              ƒ   ó   K  — y ­wrÄ   rA   )rT   r"  r#  r$  s       r2   Úget_request_response_payloadz*DataDogLogger.get_request_response_payloadZ  s   è ø€ ð 	ùs   ‚)NNNNT)NNTrÄ   )r„   NNNN)-r¢   Ú
__module__Ú__qualname__r›   ÚboolrQ   r`   rD   rH   rI   rw   rz   rR   r   r¯   r´   Úlistr±   Ústaticmethodr¼   r   r   r¹   r©   rÚ   rp   r!   r   rá   r   r×   r   rº   r   ÚdatetimeObjÚfloatrö   rø   rÖ   r¥   r  r   r!  r&  Ú__classcell__)rZ   s   @r2   r5   r5   Z   s  ø„ ð "&Ø"Ø$(Ø$(Ø&*ñPà˜$‘JðPð �t‘ðPð ˜T‘zð	Pð
 ˜T‘zðPð  $õPðd# Tó #ð$ %)Ø!%Ø&*ñOàðOð ˜T‘zðOð ˜$‘Jð	Oð
  $ðOð 
óOð2 "&Ø"Ø&*ñ	Rà˜$‘JðRð �t‘ðRð  $ð	Rð
 
óRò8`ò&`ð %)ñJàðJð &ðJð ð	Jð
 ˜T‘zðJð 
ˆt‰óJòX%lðN7°ð 7¸ó 7ðr ðY˜Dð Y¨4°©:ð Y¸$ò Yó ðYð ð> h¨~Ñ&>ð >À4ò >ó ð>ò	7ò.`ò`%ðà!7ðð ðð 
ó	ð(#à�s‘
ð#ð ð#ð ×%Ñ%ð	#ð
 ×#Ñ#ð#ð 
ó#ðJ°Tð ¸hó ðH Ø'+Ø15Ø/3Ø&*ñ ià%ð ið �T‰zð ið  ™*ð	 ið
   %Ñ'¨$Ñ.ð ið ˜+Ñ%¨Ñ,ð ið ˜t™ó iðJ Ø'+Ø15Ø/3Ø&*ñ%ià%ð%ið �T‰zð%ið  ™*ð	%ið
   %Ñ'¨$Ñ.ð%ið ˜+Ñ%¨Ñ,ð%ið ˜t™ó%iðNQà�s‘
ðQð ðQð ×%Ñ%ð	Qð
 ×#Ñ#ðQð 
óQðf[à"ð[ð 
ó[ð$¨4°°S°©>¸DÑ+@ó ð8Ð*Fó ð@àðð $ dÑ*ðð " DÑ(ð	ð
 
�‰÷ra   r5   )<Ú__doc__rL   r   r)   rÍ   rq   Úcollections.abcr   r,  Útypingr   r   r  r   r\   Úlitellm._loggingr   Úlitellm._uuidr	   Ú(litellm.integrations.custom_batch_loggerr
   Ú,litellm.integrations.datadog.datadog_handlerr   r   r   r   r   Ú0litellm.integrations.datadog.datadog_mock_clientr   r   Ú%litellm.litellm_core_utils.dd_tracingr   Ú&litellm.llms.custom_httpx.http_handlerr   r   r   r   Ú,litellm.types.integrations.base_health_checkr   Ú"litellm.types.integrations.datadogr   r   r   r   r   r   r   Úlitellm.types.servicesr   r    Úlitellm.types.utilsr!   Úadditional_logging_utilsr#   ÚRESET_BUDGET_JOBr$   Ú__annotations__r+   r3   r5   rA   ra   r2   ú<module>r@     s­   ðòó Û Û 	Û Û Ý $Ý ,ß ã Ý ã Ý +Ý Ý F÷õ ÷õ 9÷ó õ V÷÷ ñ ÷ FÝ 6å =ð ×!Ñ!ð*Ð  ó ð
1 ó 1ô FØØõFra   