
    h5                         d 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mZm	Z	m
Z
mZmZ ddl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 dd	lmZmZ dd
l ddlmZmZ  G d dee      Zy)z
Implements logging integration with Datadog's LLM Observability Service


API Reference: https://docs.datadoghq.com/llm_observability/setup/api/?tab=example#api-standards

    N)datetime)AnyDictListLiteralOptionalUnion)verbose_logger)CustomBatchLogger)DataDogLogger)>handle_any_messages_to_chat_completion_str_messages_conversion)get_async_httpx_clienthttpxSpecialProvider)*)	CallTypesStandardLoggingPayloadc            
           e Zd Zd Zd Zd Zdedededede	f
d	Z
d
edefdZdedee   fdZdee   ded   fdZdeeeee   eeef   f      dee   fdZd
edefdZy)DataDogLLMObsLoggerc                    	 t        j                  d       t        j                  dd       t	        d      t        j                  dd       t	        d      t        t        j                        | _        t        j                  d      | _	        t        j                  d      | _
        d| j                   d| _        t        j                  d	      }|r
| d| _        t        j                  | j                                t        j                         | _        g | _        t%        j&                  | fi |d
| j                   i y # t        $ r(}t        j(                  dt+        |              |d }~ww xY w)Nz"DataDogLLMObs: Initializing logger
DD_API_KEYz*DD_API_KEY is not set, set 'DD_API_KEY=<>'DD_SITEzGDD_SITE is not set, set 'DD_SITE=<>', example sit = `us5.datadoghq.com`)llm_providerzhttps://api.z"/api/intake/llm-obs/v1/trace/spansDD_BASE_URL
flush_lockz$DataDogLLMObs: Error initializing - )r
   debugosgetenv	Exceptionr   r   LoggingCallbackasync_clientr   r   
intake_urlasynciocreate_taskperiodic_flushLockr   	log_queuer   __init__	exceptionstr)selfkwargsdd_base_urles       h/var/www/Befach/backend/env/lib/python3.12/site-packages/litellm/integrations/datadog/datadog_llm_obs.pyr'   zDataDogLLMObsLogger.__init__"   s?   	  !EFyyt,4 LMMyyD)1]  !71AA!D !ii5DO99Y/DLt||n,NO O
 ))M2K%0M1S"T 3 3 56%llnDO24DN&&tRvR$//R 	$$'KCPQF8%TUG	s   EE
 
	E;#E66E;c                   K   	 t        j                  d|j                  dd              | j                  ||||      }t        j                  d|        | j                  j                  |       t        | j                        | j                  k\  r| j                          d {    y y 7 # t        $ r+}t        j                  dt        |              Y d }~y d }~ww xY ww)Nz/DataDogLLMObs: Logging success event for model modelunknownzDataDogLLMObs: Payload: z-DataDogLLMObs: Error logging success event - )r
   r   getcreate_llm_obs_payloadr&   appendlen
batch_sizeasync_send_batchr   r(   r)   )r*   r+   response_obj
start_timeend_timepayloadr-   s          r.   async_log_success_eventz+DataDogLLMObsLogger.async_log_success_eventB   s     	  A&**WV_B`Aab 11j(G   #;G9!EFNN!!'*4>>"doo5++--- 6- 	$$?AxH 	sA   C(B$B1 (B/)B1 -C(/B1 1	C%:!C C( C%%C(c           	        K   	 | j                   sy t        j                  dt        | j                          d       dt	        dt        | j                         | j                         g| j                               i}t        j                  dt        j                  |d	             | j                  j                  | j                  || j                  d
d       d {   }|j                  dk7  r%t        d|j                   d|j                          t        j                  d|j                          | j                   j#                          y 7 u# t$        j&                  $ r6}t        j(                  d|j*                  j                           Y d }~y d }~wt        $ r+}t        j(                  dt-        |              Y d }~y d }~ww xY ww)NzDataDogLLMObs: Flushing z eventsdataspan)ml_apptagsspans)type
attributesz
payload %s   )indentzapplication/json)z
DD-API-KEYzContent-Type)urljsonheaders   z2DataDogLLMObs: Unexpected response - status_code: z, text: z6DataDogLLMObs: Successfully sent batch - status_code: z%DataDogLLMObs: Error sending batch - )r&   r
   r   r5   DDIntakePayloadDDSpanAttributes_get_datadog_service_get_datadog_tagsrH   dumpsr    postr!   r   status_coder   textclearhttpxHTTPStatusErrorr(   responser)   )r*   r;   rV   r-   s       r.   r7   z$DataDogLLMObsLogger.async_send_batchT   s    +	W>>  *3t~~+>*?wG /#88:"4467"nn 	G   tzz'!/LM!..33OO"&//$6 4  H ##s*HI]I]H^^fgogtgtfuv    HI]I]H^_ NN  "#$ $$ 	$$7

7HI   	W$$'LSQRVH%UVV	Ws^   GE GCE "E#A4E GE G-,FGG*!GGGGr+   r8   r9   r:   returnc                 2   |j                  d      }|t        d      |d   }| j                  |      }|j                  di       j                  di       }t        t	        |            }t        | j                  |            }	t        | j                  |j                  d            ||	| j                  |            }
t        t        |j                  d	d
            t        |j                  dd
            t        |j                  dd
            t        |j                  dd
            | j                  |            }t        |j                  dd      |j                  dt        t        j                                      |j                  dt        t        j                                      |j                  dd      |
t#        |j%                         dz        t#        ||z
  j'                         dz        || j)                  |      g	      S )Nstandard_logging_objectz1DataDogLLMObs: standard_logging_object is not setmessages)rZ   litellm_paramsmetadata	call_type)kindinputoutputr\   prompt_tokensr   completion_tokenstotal_tokensresponse_cost)input_tokensoutput_tokensrc   
total_costtime_to_first_token	parent_id	undefinedtrace_idspan_idnamelitellm_llm_callg    eA)rY   )	ri   rk   rl   rm   metastart_nsdurationmetricsrA   )r2   r   _ensure_string_content	InputMetar   
OutputMeta_get_response_messagesMeta_get_datadog_span_kind _get_dd_llm_obs_payload_metadata
LLMMetricsfloat _get_time_to_first_token_secondsLLMObsPayloadr)   uuiduuid4int	timestamptotal_secondsrN   )r*   r+   r8   r9   r:   standard_logging_payloadrZ   r\   
input_metaoutput_metaro   rr   s               r.   r3   z*DataDogLLMObsLogger.create_llm_obs_payload   s    FLZZ%F
  $+OPP+J7...A::.377
BGS


 !$*E*El*ST,,-E-I-I+-VW::;ST	
 7;;OQOP 8 < <=PRS TU7;;NANO599/1MN $ E EF^ _
 ll;<-11*c$**,>OPLLC

,=>f&89--/#56(Z/>>@3FG&&?W&X
 	
    r   c                     |j                  d      }|j                  d      }|j                  d      }||||z
  S ||||z
  S y)z
        Get the time to first token in seconds

        CompletionStartTime - StartTime = Time to first token

        For non streaming calls, CompletionStartTime is time we get the response back
        	startTimecompletionStartTimeendTimeg        )r2   )r*   r   r9   completion_start_timer:   s        r.   r|   z4DataDogLLMObsLogger._get_time_to_first_token_seconds   se     '?&B&B;&O
1I1M1MNc1d$<$@$@$K ,1G(:55!j&<j((r   c                 n    t        |t        j                        r|d   d   d   j                         gS g S )z}
        Get the messages from the response object

        for now this handles logging /chat/completions responses
        choicesr   message)
isinstancelitellmModelResponserH   )r*   r8   s     r.   rv   z*DataDogLLMObsLogger._get_response_messages   s:     lG$9$9: +A.y9>>@AA	r   r]   )llmtooltask	embedding	retrievalc                    |y|t         j                  j                  t         j                  j                  fv ry|t         j                  j                  t         j
                  j                  t         j                  j                  t         j                  j                  t         j                  j                  t         j                  j                  t         j                  j                  t         j                  j                  t         j                  j                  f	v ry|t         j                  j                  fv ry|t         j                  j                  t         j                  j                  t         j                   j                  t         j"                  j                  t         j$                  j                  t         j&                  j                  t         j(                  j                  t         j*                  j                  t         j,                  j                  t         j.                  j                  t         j0                  j                  t         j2                  j                  t         j4                  j                  t         j6                  j                  t         j8                  j                  t         j:                  j                  t         j<                  j                  t         j>                  j                  t         j@                  j                  fv ry|g t         jB                  j                  t         jD                  j                  t         jF                  j                  t         jH                  j                  t         jJ                  j                  t         jL                  j                  t         jN                  j                  t         jP                  j                  t         jR                  j                  t         jT                  j                  t         jV                  j                  t         jX                  j                  t         jZ                  j                  t         j\                  j                  t         j^                  j                  t         j`                  j                  t         jb                  j                  t         jd                  j                  t         jf                  j                  t         jh                  j                  t         jj                  j                  t         jl                  j                  t         jn                  j                  t         jp                  j                  t         jr                  j                  t         jt                  j                  t         jv                  j                  t         jx                  j                  t         jz                  j                  t         j|                  j                  t         j~                  j                  t         j                  j                  t         j                  j                  t         j                  j                  t         j                  j                  t         j                  j                  v ryy)z
        Map liteLLM call_type to appropriate DataDog LLM Observability span kind.
        
        Available DataDog span kinds: "llm", "tool", "task", "embedding", "retrieval"
        r   r   r   r   r   )Er   r   value
aembedding
completionacompletiontext_completionatext_completiongenerate_contentagenerate_contentgenerate_content_streamagenerate_content_streamanthropic_messagescall_mcp_toolget_assistantsaget_assistants
get_threadaget_threadget_messagesaget_messagesafile_retrievefile_retrieve
afile_list	file_listafile_contentfile_contentretrieve_batcharetrieve_batchretrieve_fine_tuning_jobaretrieve_fine_tuning_job	responses
aresponsesalist_input_itemscreate_batchacreate_batchcreate_fine_tuning_jobacreate_fine_tuning_jobcancel_fine_tuning_jobacancel_fine_tuning_joblist_fine_tuning_jobsalist_fine_tuning_jobscreate_assistantsacreate_assistantsdelete_assistantadelete_assistantcreate_threadacreate_threadadd_messagea_add_message
run_threadarun_threadrun_thread_streamarun_thread_streamfile_deleteafile_deletecreate_fileacreate_fileimage_generationaimage_generation
image_editaimage_edit
moderationamoderationtranscriptionatranscriptionspeechaspeechrerankarerank)r*   r]   s     r.   rx   z*DataDogLLMObsLogger._get_datadog_span_kind   sW     ,,22I4H4H4N4NOO   &&!!''%%++&&,,&&,,''----33..44((..

 

  006677 $$**%%++  &&!!''""((##))$$**##))  &&%%##))""(($$**%%++..44//55%%  &&''--'
 
*   %
""((%
##))%
 ,,22%
 --33	%

 ,,22%
 --33%
 ++11%
 ,,22%
 ''--%
 ((..%
 &&,,%
 ''--%
 ##))%
 $$**%
 !!''%
  ##))!%
"   &&#%
$ !!''%%
& ''--'%
( ((..)%
* !!''+%
, ""((-%
. !!''/%
0 ""((1%
2 &&,,3%
4 ''--5%
6   &&7%
8 !!''9%
:   &&;%
< !!''=%
> ##))?%
@ $$**A%
B ""C%
D ##E%
F ""G%
H ##I%
 %
L  r   rZ   c                     |g S t        |t              r|gS t        |t              r|D cg c]  }| c}S t        |t              rt        |j	                  dd            gS g S c c}w )Ncontent )r   r)   listdictr2   )r*   rZ   r   s      r.   rs   z*DataDogLLMObsLogger._ensure_string_content6  si     Ih$:$'+34G44$'Y3455	 5s   	A&c           
      Z   |j                  dd      |j                  dd      |j                  dd      |j                  dd      |j                  dd      |j                  dd      |j                  dd	      d
}t        |j                  di             xs i }|j                  |       |S )zh
        Fields to track in DD LLM Observability metadata from litellm standard logging payload
        r0   r1   custom_llm_provideridrk   	cache_hit	cache_keysaved_cache_costr   )
model_namemodel_providerr   rk   r   r   r   r\   )r2   r   update)r*   r   	_metadata_standard_logging_metadatas       r.   ry   z4DataDogLLMObsLogger._get_dd_llm_obs_payload_metadataC  s     366w	J6::%y +..tY?044ZK155k9M155k9M 8 < <=OQR S

	 )--j"=>D" 	# 	34r   N)__name__
__module____qualname__r'   r<   r7   r   r   r   r}   r3   r   r{   r|   r   rv   r   r)   r   rx   r	   rs   ry    r   r.   r   r   !   s    @$,W\1
1
*-1
;C1
OW1
	1
fI_ di (3 49 a a'JyBz aF sDItCH~'E!FG	c(>	r   r   )__doc__r"   rH   r   r~   r   typingr   r   r   r   r   r	   rT   r   litellm._loggingr
   (litellm.integrations.custom_batch_loggerr   $litellm.integrations.datadog.datadogr   8litellm.litellm_core_utils.prompt_templates.common_utilsr   &litellm.llms.custom_httpx.http_handlerr   r   *litellm.types.integrations.datadog_llm_obslitellm.types.utilsr   r   r   r   r   r.   <module>r      sS      	   < <   + F > 9 Aw-): wr   