o
    ưif,                     @   s  U 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m	Z	 d dl
mZ d dlmZ dZedu r>ed	 eed
dZeddZeee Zeed< e Zee dede	eeef  fddZdede	eeef  fddZdefddZe Z G dd deZ!dd Z"ere#e!  e"e!  nejdddZ$e#e$ e%dZ&e%dZ'e%dZ(e')e e&)e e()e d d! Z*e*  e% e(e'e&gZ+d"d# Z,d$ej-fd%d&Z.d'd( Z/d)d* Z0d+d, Z1d-d. Z2d/d0 Z3d1d2 Z4defd3d4Z5dS )5    N)datetime)	Formatter)AnyDictOptional)
safe_dumps)safe_json_loadsFTze`litellm.set_verbose` is deprecated. Please set `os.environ['LITELLM_LOG'] = 'DEBUG'` for debug logs.Z	JSON_LOGSZLITELLM_LOGDEBUGnumeric_levelmessagereturnc                 C   sX   | rt | ts	dS |  }|ds|dsdS t| dd}|du s(t |ts*dS |S )z
    Try to parse a log message as JSON. Returns parsed dict if valid, else None.
    Handles messages that are entirely valid JSON (e.g. json.dumps output).
    Uses shared safe_json_loads for consistent error handling.
    N{[)default)
isinstancestrstrip
startswithr   dict)r   Zmsg_strippedparsed r   G/home/app/Keep/.python/lib/python3.10/site-packages/litellm/_logging.py_try_parse_json_message   s   r   c                 C   s  | rt | trd| vrdS d}|t| k r| d|}|dkr"	 dS d}t|t| D ]I}| | }|dkr:|d7 }q+|dkrt|d8 }|dkrt| ||d  }zt|}t |trdt|dkrd|W   S W n tt	t
fyq   Y nw  nq+|d }|t| k sdS )a6  
    Try to find and parse a Python dict repr (e.g. str(d) or repr(d)) embedded in
    the message. Handles patterns like:
    "get_available_deployment for model: X, Selected deployment: {'model_name': '...', ...} for model: X"
    Uses ast.literal_eval for safe parsing. Returns the parsed dict or None.
    r   Nr      })r   r   lenfindrangeastliteral_evalr   
ValueErrorSyntaxError	TypeError)r   istartdepthjcsubstrresultr   r   r   _try_parse_embedded_python_dict+   s<   


r+   c                
   C   s    t tdddddddj S )z]Standard LogRecord attribute names - excludes extra keys from logger.debug(..., extra={...}). r   r   N)	frozensetlogging	LogRecord__dict__keysr   r   r   r   _get_standard_record_attrsO   s    r2   c                       s.   e Zd Z fddZdddZdd Z  ZS )	JsonFormatterc                    s   t t|   d S N)superr3   __init__)self	__class__r   r   r6   X   s   zJsonFormatter.__init__Nc                 C   s   t |j}| S r4   )r   fromtimestampcreated	isoformat)r7   recorddatefmtdtr   r   r   
formatTime[   s   zJsonFormatter.formatTimec                 C   s   |  }||j| |d}t|}|d u rt|}|d ur/| D ]\}}||vr.|||< q"|j D ]\}}|tvrD||vrD|||< q4|jrP| 	|j|d< t
|S )N)r   level	timestampZ
stacktrace)
getMessage	levelnamer@   r   r+   itemsr0   _STANDARD_RECORD_ATTRSexc_infoformatExceptionr   )r7   r=   Zmessage_strZjson_recordr   keyvaluer   r   r   format`   s(   zJsonFormatter.formatr4   )__name__
__module____qualname__r6   r@   rK   __classcell__r   r   r8   r   r3   W   s    
r3   c                    sb   t    |   fdd}|t_zdd l} fdd}| | W d S  ty0   Y d S w )Nc              
      s2   t jdt jddt|d| ||fd} | d S )NLiteLLMr,   r   r   namerA   pathnamelinenomsgargsrG   )r.   r/   ERRORr   handle)exc_type	exc_valueexc_tracebackr=   Zerror_handlerr   r   json_excepthook   s   	z7_setup_json_exception_handlers.<locals>.json_excepthookr   c              	      sH   | d}|rtjdtjddt|dd d} | d S | | d S )N	exceptionrP   r,   r   r   rQ   )getr.   r/   rW   r   rX   default_exception_handler)loopcontextr^   r=   r\   r   r   async_json_exception_handler   s   
	zD_setup_json_exception_handlers.<locals>.async_json_exception_handler)	r.   StreamHandlersetFormattersys
excepthookasyncioget_event_loopset_exception_handler	Exception)	formatterr]   rh   rc   r   r\   r   _setup_json_exception_handlers}   s   
rm   zT[92m%(asctime)s - %(name)s:%(levelname)s[0m: %(filename)s:%(lineno)s - %(message)sz%H:%M:%S)r>   zLiteLLM ProxyzLiteLLM RouterrP   c                  C   sF   t d} | t j t d}|t j t d}|t j dS )z$Suppress noisy loggers at INFO levelZhttpxzapscheduler.executors.defaultzapscheduler.schedulerN)r.   	getLoggersetLevelWARNING)Zhttpx_loggerZapscheduler_executors_loggerZapscheduler_scheduler_loggerr   r   r   _suppress_loggers   s   


rq   c                  C   sD   ddl } tt}ddh}t| j| j }||@ r |td |S )z
    Get all loggers that should be initialized with the JSON handler.

    Includes third-party integration loggers (like langfuse) if they are
    configured as callbacks.
    r   NZlangfuseZlangfuse_otel)	litellmlistALL_LOGGERSsetZsuccess_callbackZfailure_callbackappendr.   rn   )rr   loggersZlangfuse_callbacksZall_callbacksr   r   r   _get_loggers_to_initialize   s   rx   handlerc                 C   s*   t  D ]}|j  ||  d|_qdS )z
    Initialize all loggers with a handler

    - Adds a handler to each logger
    - Prevents bubbling to parent/root (critical to prevent duplicate JSON logs)
    FN)rx   handlersclear
addHandler	propagate)ry   Zlgr   r   r    _initialize_loggers_with_handler   s
   


r~   c               
   C   sp   d} t  }ddd| id| id| iddddd	d
ddd	ddg|dddg|ddd
g|dddd}|S )z
    Generate a uvicorn log_config dictionary that applies JSON formatting to all loggers.

    This ensures that uvicorn's access logs, error logs, and all application logs
    are formatted as JSON when json_logs is enabled.
    zlitellm._logging.JsonFormatterr   Fz())jsonr   accessr   zlogging.StreamHandlerzext://sys.stdout)rl   classstreamr   )r   r   r   )rz   rA   r}   )Zuvicornzuvicorn.errorzuvicorn.access)versiondisable_existing_loggers
formattersrz   rw   )	log_levelupper)Zjson_formatter_classZuvicorn_log_levelZ
log_configr   r   r   _get_uvicorn_json_log_config   sF   -r   c                  C   s*   t  } | t  t|  tt  dS )zJ
    Turn on JSON logging

    - Adds a JSON formatter to all loggers
    N)r.   rd   re   r3   r~   rm   )ry   r   r   r   _turn_on_json5  s   r   c                   C   s.   t jtjd tjtjd tjtjd d S )N)rA   )verbose_loggerro   r.   r	   verbose_router_loggerverbose_proxy_loggerr   r   r   r   _turn_on_debugB  s   r   c                   C      dt _dt_dt_d S )NTr   disabledr   r   r   r   r   r   _disable_debuggingH     
r   c                   C   r   )NFr   r   r   r   r   _enable_debuggingN  r   r   c                 C   s.   zt r
t|  W d S W d S  ty   Y d S w r4   )set_verboseprintrk   )Zprint_statementr   r   r   print_verboseT  s   r   c                   C   s   t tjp	tdu S )z)
    Returns True if debugging is on
    T)r   isEnabledForr.   r	   r   r   r   r   r   _is_debugging_on\  s   r   )6r   r.   osrf   r   r   typingr   r   r   Z*litellm.litellm_core_utils.safe_json_dumpsr   Z*litellm.litellm_core_utils.safe_json_loadsr   r   warningboolgetenvZ	json_logsr   getattrr   r
   r   __annotations__rd   ry   ro   r   r+   r-   r2   rF   r3   rm   re   rl   rn   r   r   r   r|   rq   rt   rx   Handlerr~   r   r   r   r   r   r   r   r   r   r   r   <module>   sn   
 
$&.






<