
    k7i$                         S r SSKrSSKrSSKrSSKJr  SSKJr  SSKJr  SSK	r	SSK
JrJrJr  S\S	\4S
 jr " S S\5      r " S S\5      r " S S\5      rS\S	\4S jrg)z5Comprehensive logging middleware for FastMCP servers.    N)Callable)Logger)Any   )CallNext
MiddlewareMiddlewareContextdatareturnc                 P    [         R                  " U [        S9R                  5       $ )z>The default serializer for Payloads in the logging middleware.)fallback)pydantic_coreto_jsonstrdecode)r
   s    [/home/james-whalen/.local/lib/python3.13/site-packages/fastmcp/server/middleware/logging.pydefault_serializerr      s      4;;==    c                      \ rS rSr% Sr\\S'   \\S'   \\S'   \\S'   \\S'   \S-  \S	'   \	\
   S-  \S
'   \\S'   \\/\
4   S-  \S'   S\\   S\
4S jrS\\
\
\-  4   S\
4S jrS\\   S\\
\
\-  4   4S jrS\\   S\S\S\\
\
\-  \-  4   4S jrS\\   S\S\\
\
\-  \-  4   4S jr SS\\
\
\-  \-  4   S\S-  4S jjrS\\   S\\\4   S\4S jrSrg)BaseLoggingMiddleware   z"Base class for logging middleware.logger	log_levelinclude_payloadsinclude_payload_lengthestimate_payload_tokensNmax_payload_lengthmethodsstructured_loggingpayload_serializercontextr   c                 t   U R                   (       d  [        UR                  5      nU$  U R                  UR                  5      nU$ ! [         af  nU R                  R                  SU SUR                   SUR                   SUR                   S3	5        [        UR                  5      n S nAU$ S nAff = f)Nz#Failed to serialize payload due to z:  .)	r    r   message	Exceptionr   warningtypemethodsource)selfr!   payloades       r   _serialize_payload(BaseLoggingMiddleware._serialize_payload!   s     &&(9G >11'//B   >##9!Bw||nAgnnM]]^_f_m_m^nnop -W__=>s   A 
B7AB22B7r%   c           	          U R                   (       a  [        R                  " U5      $ SR                  UR	                  5        VVs/ s H  u  p#U SU 3PM     snn5      $ s  snnf )zFormat a message for logging.r#   =)r   jsondumpsjoinitems)r+   r%   kvs       r   _format_message%BaseLoggingMiddleware._format_message1   sM    ""::g&&88GMMODODAs!A3ZODEEDs   A!
c                    UR                   S-   UR                  =(       d    SUR                  S.nU R                  (       d"  U R                  (       d  U R
                  (       a  U R                  U5      nU R                  (       d  U R
                  (       a:  [        U5      nUS-  nU R
                  (       a  XRS'   U R                  (       a  XBS'   U R                  (       a+  [        U5      U R                  :  a  US U R                   S-   nU R                  (       a&  X2S'   [        UR                  5      R                  US	'   U$ )
N_startunknown)eventr)   r*      payload_tokenspayload_lengthz...r,   payload_type)r(   r)   r*   r   r   r   r.   lenr   r%   __name__)r+   r!   r%   r,   r@   r?   s         r   _create_before_message,BaseLoggingMiddleware._create_before_message8   s     \\H,nn1	nn
 !!**++--g6G**d.J.J!$W!/1!4//0>,-..0>,-&&3w<$:Q:Q+Q!";D$;$;<uD$$%,	"*.w*?*H*H'r   
start_timeerrorc                     [        U5      nUR                  S-   UR                  =(       d    SUR                  U[	        US9S.nU$ )N_errorr<   )object)r=   r)   r*   duration_msrG   )_get_duration_msr(   r)   r*   r   )r+   r!   rF   rG   rK   r%   s         r   _create_error_message+BaseLoggingMiddleware._create_error_messageY   sF     .j9\\H,nn1	nn&&
 r   c                 ~    [        U5      nUR                  S-   UR                  =(       d    SUR                  US.nU$ )N_successr<   )r=   r)   r*   rK   )rL   r(   r)   r*   )r+   r!   rF   rK   r%   s        r   _create_after_message+BaseLoggingMiddleware._create_after_messagei   s>    
 .j9\\J.nn1	nn&	
 r   c                     U R                   R                  U=(       d    U R                  U R                  U5      5        g N)r   logr   r8   )r+   r%   r   s      r   _log_message"BaseLoggingMiddleware._log_messagew   s*     		3T^^T5I5I'5RSr   	call_nextc                   #    U R                   (       a*  UR                  U R                   ;  a  U" U5      I Sh  vN $ U R                  U R                  U5      5        [        R
                  " 5       n U" U5      I Sh  vN nU R                  U R                  X5      5        U$  Nl N(! [         a6  nU R                  U R                  XU5      [        R                  5        e SnAff = f7f)z$Log messages for configured methods.N)r   r)   rV   rD   timeperf_counterrQ   r&   rM   loggingERROR)r+   r!   rX   rF   resultr-   s         r   
on_message BaseLoggingMiddleware.on_message|   s     
 <<GNN$,,>"7+++$55g>?&&(

	$W--Fd88MNM , .
  	**7BGMM 		sE   7C-B&9C-4B* ?B( %B* %C-(B* *
C*41C%%C**C- rT   )rC   
__module____qualname____firstlineno____doc__r   __annotations__intboollistr   r   r   r	   r.   dictr8   rD   floatr&   rM   rQ   rV   r   r_   __static_attributes__ra   r   r   r   r      s   ,NN  !!d
"#Y #,t33*;C*@ S  FtCsN'; F F(-	c39n	B"3'  	
 
c39u$$	% "3'  
c39u$$	%	 NRTCsU!223T@Cd
T
(-:B38:L	r   r   c                       \ rS rSrSrS\R                  SSSSSSS.S\R                  S-  S\S	\	S
\	S\	S\S\
\   S-  S\\/\4   S-  4S jjrSrg)LoggingMiddleware   a  Middleware that provides comprehensive request and response logging.

Logs all MCP messages with configurable detail levels. Useful for debugging,
monitoring, and understanding server usage patterns.

Example:
    ```python
    from fastmcp.server.middleware.logging import LoggingMiddleware
    import logging

    # Configure logging
    logging.basicConfig(level=logging.INFO)

    mcp = FastMCP("MyServer")
    mcp.add_middleware(LoggingMiddleware())
    ```
NF  )r   r   r   r   r   r   r   r    r   r   r   r   r   r   r   r    c                    U=(       d    [         R                  " S5      U l        X l        X0l        X@l        XPl        X`l        Xpl        Xl	        SU l
        g)a  Initialize logging middleware.

Args:
    logger: Logger instance to use. If None, creates a logger named 'fastmcp.requests'
    log_level: Log level for messages (default: INFO)
    include_payloads: Whether to include message payloads in logs
    include_payload_length: Whether to include response size in logs
    estimate_payload_tokens: Whether to estimate response tokens
    max_payload_length: Maximum length of payload to log (prevents huge logs)
    methods: List of methods to log. If None, logs all methods.
    payload_serializer: Callable that converts objects to a JSON string for the
        payload. If not provided, uses FastMCP's default tool serializer.
zfastmcp.middleware.loggingFN)r\   	getLoggerr   r   r   r   r   r   r   r    r   )	r+   r   r   r   r   r   r   r   r    s	            r   __init__LoggingMiddleware.__init__   sL    2 %W(9(9:V(W"&6,B#-D$'9)0?Q(-r   	r   r   r   r   r   r   r   r    r   rC   rb   rc   rd   re   r\   INFOr   rg   rh   ri   r   r   r   rs   rl   ra   r   r   rn   rn      s    * )- !&',(-"&$(:>!. %!. 	!.
 !. !%!. "&!.  !. cT!!. %cUCZ047!. !.r   rn   c                       \ rS rSrSrS\R                  SSSSSS.S\R                  S-  S\S\	S	\	S
\	S\
\   S-  S\\/\4   S-  4S jjrSrg)StructuredLoggingMiddleware   a  Middleware that provides structured JSON logging for better log analysis.

Outputs structured logs that are easier to parse and analyze with log
aggregation tools like ELK stack, Splunk, or cloud logging services.

Example:
    ```python
    from fastmcp.server.middleware.logging import StructuredLoggingMiddleware
    import logging

    mcp = FastMCP("MyServer")
    mcp.add_middleware(StructuredLoggingMiddleware())
    ```
NF)r   r   r   r   r   r   r    r   r   r   r   r   r   r    c                    U=(       d    [         R                  " S5      U l        X l        X0l        X@l        XPl        X`l        Xpl        SU l	        SU l
        g)ao  Initialize structured logging middleware.

Args:
    logger: Logger instance to use. If None, creates a logger named 'fastmcp.structured'
    log_level: Log level for messages (default: INFO)
    include_payloads: Whether to include message payloads in logs
    include_payload_length: Whether to include payload size in logs
    estimate_payload_tokens: Whether to estimate token count using length // 4
    methods: List of methods to log. If None, logs all methods.
    payload_serializer: Callable that converts objects to a JSON string for the
        payload. If not provided, uses FastMCP's default tool serializer.
z%fastmcp.middleware.structured_loggingNT)r\   rr   r   r   r   r   r   r   r    r   r   )r+   r   r   r   r   r   r   r    s           r   rs   $StructuredLoggingMiddleware.__init__   sT    . % 
(9(93)
 (&6,B#-D$)0?Q.2(,r   ru   rv   ra   r   r   ry   ry      s    $ )- !&',(-$(:>!- %!- 	!-
 !- !%!- "&!- cT!!- %cUCZ047!- !-r   ry   rF   c                H    [        [        R                  " 5       U -
  S-  SS9$ )Nrp      )numberndigits)roundrZ   r[   )rF   s    r   rL   rL      s"    **,z9TA1MMr   )re   r2   r\   rZ   collections.abcr   r   typingr   r   
middlewarer   r   r	   r   r   r   rn   ry   rk   rL   ra   r   r   <module>r      sw    ;    $    ? ?>S >S >
}J }@4.- 4.n1-"7 1-hN Ne Nr   