Ë
    tPêjk'  ã                   óÒ  — 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mZ  ej                   «       Zeed<   dadada ej                   «       Zeed<   daedz  ed	<    ej                   «       Zeed
<   i Zeeeef      ed<   dedefd„Zdeddfd„Zdedefd„Z de
ddfd„Z!ddefd„Z"dd„Z#dededefd„Z$dedefd„Z%d dedz  ddfd„Z&d dedz  ddfd„Z'y)!aD  
Performance utilities for LiteLLM proxy server.

This module provides performance monitoring and profiling functionality for endpoint
performance analysis using cProfile with configurable sampling rates, and line_profiler
for line-by-line profiling.

See performance_utils.md for detailed usage examples and documentation.
é    N)ÚCallable)ÚPath)ÚAnyÚFinal)Úverbose_proxy_loggerÚ_profile_lockÚ_sample_counter_lockÚ_line_profilerÚ_line_profiler_lockÚ_wrapped_functionsÚprofile_sampling_rateÚreturnc                 ó˜   — | dk\  ry| dk  ryt         5  t        dz  at        t        d| z  «      z  dk(  }|cddd«       S # 1 sw Y   yxY w)zFDetermine if current request should be sampled based on sampling rate.ç      ð?Tg        Fé   r   N)r	   Ú_sample_counterÚint)r   Úshould_samples     úq/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/common_utils/performance_utils.pyÚ_should_sampler   #   sZ   € à Ò#ØØ	 #Ò	%Øô 
ñ Ü˜1Ñˆä /´#°cÐ<QÑ6QÓ2RÑ RÐWXÑXˆØ÷	÷ ò ús   “#A Á A	c                 óÂ   — t         5  t        €>t        j                  «       at        j	                  «        t        j                  d| «       ddd«       y# 1 sw Y   yxY w)z'Start cProfile profiling once globally.Nz(Profiling started with sampling rate: %s)r   Ú	_profilerÚcProfileÚProfileÚenabler   Úinfo©r   s    r   Ú_start_profilingr   3   sR   € ô 
ñ iÜÐÜ ×(Ñ(Ó*ˆIÜ×ÑÔÜ ×%Ñ%Ð&PÐRgÔh÷	i÷ iñ iús   ‡AAÁAc                 ó2   — t        | «      rt        | «       yy)z<Start profiling for a specific request (if sampling allows).TF)r   r   r   s    r   Ú_start_profiling_for_requestr    =   s   € äÐ+Ô,ÜÐ.Ô/ØØó    Úprofile_filec                 ó¶  — t         5  t        €
	 ddd«       y	 t        j                  «        t        j                  t	        | «      «       t        j                  «        t        j                  d| «       ddd«       y# t        $ rE}t        j                  d|«       	 t        j                  «        n# t        $ r Y nw xY wY d}~ŒRd}~ww xY w# 1 sw Y   yxY w)z$Save current stats directly to file.NzProfiling stats saved to %sz Error saving profiling stats: %s)
r   r   ÚdisableÚ
dump_statsÚstrr   r   ÚdebugÚ	ExceptionÚerror)r"   Úes     r   Ú_save_statsr+   E   s¹   € ä	ñ ÜÐØ÷ð ð	ä×ÑÔÜ× Ñ ¤ \Ó!2Ô3ä×ÑÔÜ ×&Ñ&Ð'DÀlÔS÷ð øô ò 	Ü ×&Ñ&Ð'IÈ1ÔMðÜ× Ñ Õ"øÜò Ùðÿûð	ú÷ð úsS   ‡C™AA>Á>	CÂCÂB3Â2CÂ3	B?Â<CÂ>B?Â?CÃCÃCÃCÃCÚsampling_ratec                 ó   ‡ — ˆ fd„}|S )a8  Decorator to sample endpoint hits and save to a profile file.

    Args:
        sampling_rate: Rate of requests to profile (0.0 to 1.0)
                      - 1.0: Profile all requests (100%)
                      - 0.1: Profile 1 in 10 requests (10%)
                      - 0.0: Profile no requests (0%)
    c                 óÎ   •‡ ‡— dt         dd fd„Št        j                  ‰ «      r!t        j                  ‰ «      ˆ ˆˆfd„«       }|S t        j                  ‰ «      ˆ ˆˆfd„«       }|S )NÚpathr   c                 ó   — | a y ©N)Ú_last_profile_file_path)r/   s    r   Úset_last_profile_pathzBprofile_endpoint.<locals>.decorator.<locals>.set_last_profile_pathe   s   € à&*Ñ#r!   c               Ÿ   óÂ   •K  — t        ‰«      }t        d«      } ‰|«       	  ‰| i |¤Žƒ d {  –—† }|rt        |«       |S 7 Œ# t        $ r |rt        |«       ‚ w xY w­w©Nzendpoint_profile.pstat©r    ÚPathLibr+   r(   ©ÚargsÚkwargsÚis_samplingÚfile_path_objÚresultÚfuncr,   r3   s        €€€r   Úasync_wrapperz:profile_endpoint.<locals>.decorator.<locals>.async_wrapperk   so   øè ø€ ä%AÀ-Ó%P�Ü'.Ð/GÓ'H�Ù% mÔ4ðÙ*.°Ð*?¸Ñ*?×$?�FÙ"Ü# MÔ2Ø!�Mð %@ùô !ò Ù"Ü# MÔ2Øðüs,   ƒA£A ®A¯A ÁAÁA ÁAÁAc                  ó¦   •— t        ‰«      }t        d«      } ‰|«       	  ‰| i |¤Ž}|rt        |«       |S # t        $ r |rt        |«       ‚ w xY wr5   r6   r8   s        €€€r   Úsync_wrapperz9profile_endpoint.<locals>.decorator.<locals>.sync_wrapper}   sa   ø€ ä%AÀ-Ó%P�Ü'.Ð/GÓ'H�Ù% mÔ4ðÙ$(¨$Ð$9°&Ñ$9�FÙ"Ü# MÔ2Ø!�MøÜ ò Ù"Ü# MÔ2Øðús	   ¡8 ¸A)r7   ÚinspectÚiscoroutinefunctionÚ	functoolsÚwraps)r>   r?   rA   r3   r,   s   `  @€r   Ú	decoratorz#profile_endpoint.<locals>.decoratord   sn   ú€ ð	+¬ð 	+°Dó 	+ô ×&Ñ& tÔ,ä�_‰_˜TÓ"õó #ðð !Ð ô �_‰_˜TÓ"õó #ðð  Ðr!   © )r,   rF   s   ` r   Úprofile_endpointrH   Z   s   ø€ ô( ðT Ðr!   c                  óŠ   — ddl m}  t        5  t        € | «       at	        j
                  d«       ddd«       y# 1 sw Y   yxY w)z|Enable line_profiler for dynamic function wrapping.

    Raises:
        ImportError: If line_profiler is not available
    r   ©ÚLineProfilerNzLine profiler enabled)Úline_profilerrK   r   r
   r   r   rJ   s    r   Úenable_line_profilerrM   ‘   s;   € õ +ä	ñ ?ÜÐ!Ù)›^ˆNÜ ×%Ñ%Ð&=Ô>÷?÷ ?ñ ?ús	   �#9¹AÚmoduleÚfunction_namec                 ó˜  — 	 t        «        t        €y	 t        | |d«      }|€"t	        j
                  d|| j                  «       y|t        vr	|t        |<   t        |«      }t        | ||«       t	        j                  d| j                  |«       y# t        $ r Y yw xY w# t        $ r!}t	        j                  d||«       Y d}~yd}~ww xY w)zíDynamically wrap a function with line_profiler.

    Args:
        module: The module containing the function
        function_name: Name of the function to wrap

    Returns:
        True if wrapping was successful, False otherwise
    FNz"Function %s not found in module %sz Wrapped %s.%s with line_profilerTz(Error wrapping %s with line_profiler: %s)rM   ÚImportErrorr
   Úgetattrr   ÚwarningÚ__name__r   Úsetattrr   r(   r)   )rN   rO   Úoriginal_functionÚprofiled_functionr*   s        r   Ú wrap_function_with_line_profilerrX       s×   € ðÜÔô ÐØðÜ#*¨6°=À$Ó#GÐØÐ$Ü ×(Ñ(Ð)MÈ}Ð^d×^mÑ^mÔnØð Ô 2Ñ2Ø0AÔ˜}Ñ-ô $2Ð2CÓ#DÐÜ�˜Ð'8Ô9ä×!Ñ!Ð"DÀfÇoÁoÐWdÔeØøô+ ò Ùðûô, ò Ü×"Ñ"Ð#MÈ}Ð^_Ô`Üûðús/   ‚
B ”0B ÁA
B Â	BÂBÂ	C	Â(CÃC	r>   c                 ó>  — ddl }t        «        t        €t        d«      ‚|j	                  «       5  |j                  ddt        ¬«       t        j                  | «       t        | «      }ddd«       t        j                  d| j                  «       S # 1 sw Y   Œ+xY w)aá  Wrap a function directly with line_profiler.

    This is the recommended way to profile functions, especially closures or
    functions created dynamically (like wrapper_async in litellm/utils.py).

    Args:
        func: The function to wrap

    Returns:
        The wrapped function that will be profiled when called

    Raises:
        ImportError: If line_profiler is not available
        RuntimeError: If line_profiler cannot be enabled or function cannot be wrapped
    r   Nz!Line profiler was not initializedÚignorez.*__wrapped__.*)ÚmessageÚcategoryz&Wrapped function %s with line_profiler)ÚwarningsrM   r
   ÚRuntimeErrorÚcatch_warningsÚfilterwarningsÚUserWarningÚadd_functionr   r   rT   )r>   r]   rW   s      r   Úwrap_function_directlyrc   Ç   sŽ   € ó  äÔäÐÜÐ>Ó?Ð?ð 
×	 Ñ	 Ó	"ñ 8Ø×Ñ Ð2CÌkÐÔZä×#Ñ# DÔ)Ü#1°$Ó#7Ð÷	8ô ×ÑÐFÈÏÉÔVØÐ÷8ð 8ús   °9BÂBÚoutput_filec                 óø  — t         5  t        €t        j                  d«       	 ddd«       y	 | r@t	        | «      }t        j                  t        |«      «       t        j                  d|«       nKddlm	}  |«       }t        j                  |¬«       |j                  «       }t        j                  d|z   «       ddd«       y# t        $ r }t        j                  d|«       Y d}~Œ-d}~ww xY w# 1 sw Y   yxY w)	a  Collect and save line_profiler statistics.

    This can be called manually to collect stats at any time, or it's
    automatically called on shutdown if register_shutdown_handler() was used.

    Args:
        output_file: Optional path to save stats. If None, prints to stdout.
    Nz-Line profiler not enabled, nothing to collectzLine profiler stats saved to %sr   )ÚStringIO)ÚstreamzLine profiler stats:
z(Error collecting line profiler stats: %s)r   r
   r   r'   r7   r%   r&   r   Úiorf   Úprint_statsÚgetvaluer(   r)   )rd   Úoutput_pathrf   rg   Ústats_outputr*   s         r   Úcollect_line_profiler_statsrm   é   sç   € ô 
ñ VÜÐ!Ü ×&Ñ&Ð'VÔWØ÷Vð Vð
	VÙä%,¨[Ó%9�Ü×)Ñ)¬#¨kÓ*:Ô;Ü$×)Ñ)Ð*KÈ[ÕYõ (á (£
�Ü×*Ñ*°&Ð*Ô9Ø&,§o¡oÓ&7�Ü$×)Ñ)Ð*BÀ\Ñ*QÔR÷%Vð Vøô& ò 	VÜ ×&Ñ&Ð'QÐST×UÑUûð	Vú÷'Vð Vús/   ‡C0®BCÃ	C-ÃC(Ã#C0Ã(C-Ã-C0Ã0C9c                 ón   ‡ — ‰ €dŠ ˆ fd„}t        j                  |«       t        j                  d‰ «       y)aw  Register a shutdown handler to collect line_profiler stats.

    This registers an atexit handler that will automatically save profiling
    statistics when the Python process exits. Safe to call multiple times
    (only registers once).

    Args:
        output_file: Optional path to save stats on shutdown.
                     Defaults to 'line_profile_stats.lprof'
    Nzline_profile_stats.lprofc                  ó   •— t        ‰ ¬«       y )N©rd   )rm   rp   s   €r   Úshutdown_handlerz3register_shutdown_handler.<locals>.shutdown_handler  s   ø€ Ü#°Ö<r!   z0Registered line_profiler shutdown handler for %s)ÚatexitÚregisterr   r'   )rd   rq   s   ` r   Úregister_shutdown_handlerrt     s6   ø€ ð ÐØ0ˆô=ô ‡O�OÐ$Ô%Ü×ÑÐQÐS^Õ_r!   )r   )r   Nr1   )(Ú__doc__rr   r   rD   rB   Ú	threadingÚcollections.abcr   Úpathlibr   r7   Útypingr   r   Úlitellm._loggingr   ÚLockr   Ú__annotations__r   r2   r   r	   r
   r   r   Údictr&   ÚfloatÚboolr   r   r    r+   rH   rM   rX   rc   rm   rt   rG   r!   r   ú<module>r€      sb  ðòó Û Û Û Û Ý $Ý #ß å 1ð &�y—~‘~Ó'€ˆuÓ 'Ø€	ØÐ Ø€Ø,˜iŸn™nÓ.Ð �eÓ .ð "€��d‘
Ó !Ø+˜YŸ^™^Ó-Ð �UÓ -Ø13Ð �E˜$˜s H˜}Ñ-Ñ.Ó 3ð¨%ð °Dó ð i¨Eð i°dó ið¸ð À$ó ð˜gð ¨$ó ñ*4 Eó 4ón?ð$¨Sð $Àð $Èó $ðN ð ¨hó ñDV¨S°4©Zð VÀ4ó VñD`¨3°©:ð `Àô `r!   