
    Ϫf4                    \   d Z ddl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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mZ dZddZddZedf	 	 	 	 	 	 	 d dZef	 	 	 	 	 d!dZd"dZ G d de       Z! G d de	e"ef         Z#d#dZ$ddZ%d$dZ&ddZ'dddef	 	 	 	 	 	 	 	 	 	 	 d%dZ(y)&z&
Tools for formatting logging events.
    )annotations)datetime)AnyCallableIteratorMappingOptionalUnioncast)NamedConstant)FixedOffsetTimeZone)Failure)	safe_repr   )
aFormatter
flatFormat)LogEventz%Y-%m-%dT%H:%M:%S%zc                     t        | ddd      S )aa  
    Formats an event as text, using the format in C{event["log_format"]}.

    This implementation should never raise an exception; if the formatting
    cannot be done, the returned string will describe the event generically so
    that a useful message is emitted regardless.

    @param event: A logging event.

    @return: A formatted string.
    F)includeTracebackincludeTimestampincludeSystem)eventAsText)events    8/usr/lib/python3/dist-packages/twisted/logger/_format.pyformatEventr      s     	     c                    	 dj                  | |      S # t        $ rP t               }dj                  d | j	                         D              }dj                  t        |      ||      cY S w xY w)z
    Formats an event as text that describes the event generically and a
    formatting error.

    @param event: A logging event.
    @param error: The formatting error.

    @return: A formatted string.
    z)Unable to format event {event!r}: {error})r   errorz, c              3  l   K   | ],  \  }}d j                  t        |      t        |      f       . yw)z = N)joinr   ).0keyvalues      r   	<genexpr>z+formatUnformattableEvent.<locals>.<genexpr>C   s3      
U JJ	#	%(89:
s   24zrMESSAGE LOST: unformattable object logged: {error}
Recoverable data: {text}
Exception during formatting:
{failure})r   failuretext)formatBaseExceptionr   r    itemsr   )r   r   r%   r&   s       r   formatUnformattableEventr*   -   s    
:AAu B 
 	
  
 )yy 
#kkm
 
66<f&d 7= 7	

s    AA.-A.-c                    || |S t        j                  |       }t        j                  | |      }t	        |j                  |            S )a  
    Format a timestamp as text.

    Example::

        >>> from time import time
        >>> from twisted.logger import formatTime
        >>>
        >>> t = time()
        >>> formatTime(t)
        u'2013-10-22T14:19:11-0700'
        >>> formatTime(t, timeFormat="%Y/%W")  # Year and week number
        u'2013/42'
        >>>

    @param when: A timestamp.
    @param timeFormat: A time format.
    @param default: Text to return if C{when} or C{timeFormat} is L{None}.

    @return: A formatted time.
    )r   fromLocalTimeStampDateTimefromtimestampstrstrftime)when
timeFormatdefaulttzr   s        r   
formatTimer6   Q   sK    4 T\ 33D9))$38$$Z011r   c                P    t        | |      }|sy|j                  dd      }|dz   S )a&  
    Format an event as a line of human-readable text for, e.g. traditional log
    file output.

    The output format is C{"{timeStamp} [{system}] {event}\n"}, where:

        - C{timeStamp} is computed by calling the given C{formatTime} callable
          on the event's C{"log_time"} value

        - C{system} is the event's C{"log_system"} value, if set, otherwise,
          the C{"log_namespace"} and C{"log_level"}, joined by a C{"#"}.  Each
          defaults to C{"-"} is not set.

        - C{event} is the event, as formatted by L{formatEvent}.

    Example::

        >>> from time import time
        >>> from twisted.logger import formatEventAsClassicLogText
        >>> from twisted.logger import LogLevel
        >>>
        >>> formatEventAsClassicLogText(dict())  # No format, returns None
        >>> formatEventAsClassicLogText(dict(log_format="Hello!"))
        u'- [-#-] Hello!\n'
        >>> formatEventAsClassicLogText(dict(
        ...     log_format="Hello!",
        ...     log_time=time(),
        ...     log_namespace="my_namespace",
        ...     log_level=LogLevel.info,
        ... ))
        u'2013-10-22T17:30:02-0700 [my_namespace#info] Hello!\n'
        >>> formatEventAsClassicLogText(dict(
        ...     log_format="Hello!",
        ...     log_time=time(),
        ...     log_system="my_system",
        ... ))
        u'2013-11-11T17:22:06-0800 [my_system] Hello!\n'
        >>>

    @param event: an event.
    @param formatTime: A time formatter

    @return: A formatted event, or L{None} if no output is appropriate.
    )r6   N
z
	)r   replace)r   r6   	eventTexts      r   formatEventAsClassicLogTextr;   s   s4    ^ Ej9I!!$/Itr   PotentialCallWrapperc                n    | j                  d      }|r| dd n| } ||      }|r |       }t        |      S )at  
    Check to see if C{key} ends with parentheses ("C{()}"); if not, wrap up the
    result of C{get} in a L{PotentialCallWrapper}.  Otherwise, call the result
    of C{get} first, before wrapping it up.

    @param key: The last dotted segment of a formatting key, as parsed by
        L{Formatter.vformat}, which may end in C{()}.

    @param getter: A function which takes a string and returns some other
        object, to be formatted and stringified for a log.

    @return: A L{PotentialCallWrapper} that will wrap up the result to allow
        for subsequent usages of parens to defer execution to log-format time.
    z()N)endswithr<   )r"   gettercallitrealKeyr#   s        r   keycallrC      s?     \\$F c#2hcG7OE&&r   c                  @    e Zd ZdZd	dZd
dZd
dZddZddZddZ	y)r<   z
    Object wrapper that wraps C{getattr()} so as to process call-parentheses
    C{"()"} after a dotted attribute access.
    c                    || _         y N)_wrapped)selfwrappeds     r   __init__zPotentialCallWrapper.__init__   s	    r   c                B    t        || j                  j                        S rF   )rC   rG   __getattribute__)rH   names     r   __getattr__z PotentialCallWrapper.__getattr__   s    tT]];;<<r   c                6    | j                   |   }t        |      S rF   )rG   r<   )rH   rM   r#   s      r   __getitem__z PotentialCallWrapper.__getitem__   s     d##E**r   c                8    | j                   j                  |      S rF   )rG   
__format__)rH   format_specs     r   rR   zPotentialCallWrapper.__format__   s    }}''44r   c                6    | j                   j                         S rF   )rG   __repr__rH   s    r   rU   zPotentialCallWrapper.__repr__   s    }}%%''r   c                6    | j                   j                         S rF   )rG   __str__rV   s    r   rX   zPotentialCallWrapper.__str__   s    }}$$&&r   N)rI   objectreturnNone)rM   r0   rZ   rY   )rS   r0   rZ   r0   )rZ   r0   )
__name__
__module____qualname____doc__rJ   rN   rP   rR   rU   rX    r   r   r<   r<      s%    
 =+5('r   c                  0    e Zd ZdZddZddZd	dZd
dZy)CallMappingz
    Read-only mapping that turns a C{()}-suffix in key names into an invocation
    of the key rather than a lookup of the key.

    Implementation support for L{formatWithCall}.
    c                    || _         y)zo
        @param submapping: Another read-only mapping which will be used to look
            up items.
        N)_submapping)rH   
submappings     r   rJ   zCallMapping.__init__   s    
 &r   c                ,    t        | j                        S rF   )iterrd   rV   s    r   __iter__zCallMapping.__iter__   s    D$$%%r   c                ,    t        | j                        S rF   )lenrd   rV   s    r   __len__zCallMapping.__len__   s    4##$$r   c                B    t        || j                  j                        S )z|
        Look up an item in the submapping for this L{CallMapping}, calling it
        if C{key} ends with C{"()"}.
        )rC   rd   rP   )rH   r"   s     r   rP   zCallMapping.__getitem__   s    
 sD,,8899r   N)re   Mapping[str, Any]rZ   r[   )rZ   zIterator[Any])rZ   int)r"   r0   rZ   r   )r\   r]   r^   r_   rJ   rh   rk   rP   r`   r   r   rb   rb      s    &&%:r   rb   c           	     T    t        t        j                  | dt        |                  S )a  
    Format a string like L{str.format}, but:

        - taking only a name mapping; no positional arguments

        - with the additional syntax that an empty set of parentheses
          correspond to a formatting item that should be called, and its result
          C{str}'d, rather than calling C{str} on the element directly as
          normal.

    For example::

        >>> formatWithCall("{string}, {function()}.",
        ...                dict(string="just a string",
        ...                     function=lambda: "a function"))
        'just a string, a function.'

    @param formatString: A PEP-3101 format string.
    @param mapping: A L{dict}-like object to format.

    @return: The string with formatted values interpolated.
    r`   )r0   r   vformatrb   )formatStringmappings     r   formatWithCallrs      s#    . z!!,K4HIJJr   c                n   	 d| v rt        |       S t        t        t        t        t
        f      | j                  dd            }|yt        |t              rn0t        |t
              r|j                  d      }nt        d|      t        ||       S # t        $ r}t        | |      cY d}~S d}~ww xY w)ae  
    Formats an event as a string, using the format in C{event["log_format"]}.

    This implementation should never raise an exception; if the formatting
    cannot be done, the returned string will describe the event generically so
    that a useful message is emitted regardless.

    @param event: A logging event.

    @return: A formatted string.
    log_flattened
log_formatN zutf-8zLog format must be str, not )r   r   r	   r
   r0   bytesget
isinstancedecode	TypeErrorrs   r(   r*   )r   r'   es      r   _formatEventr~     s    2e#e$$huS%Z01599\43PQ> fc"&]]7+F:6*EFFfe,, 2'q112s)   B 6B AB 	B4B/)B4/B4c                r    	 | j                         }|S # t        $ r}dt        |      z   }Y d}~|S d}~ww xY w)a^  
    Format a failure traceback, assuming UTF-8 and using a replacement
    strategy for errors.  Every effort is made to provide a usable
    traceback, but should not that not be possible, a message and the
    captured exception are logged.

    @param failure: The failure to retrieve a traceback from.

    @return: The formatted traceback.
    z((UNABLE TO OBTAIN TRACEBACK FROM EVENT):N)getTracebackr(   r0   )r%   	tracebackr}   s      r   _formatTracebackr   5  sF    H((*	   H>QG	Hs    	616c           	     j   t        t        t           | j                  dd            }|kt        t        t           | j                  dd            }|d}n|j
                  }dj                  t        t        | j                  dd            |      }|S 	 t        |      }|S # t        $ r d}Y |S w xY w)	a  
    Format the system specified in the event in the "log_system" key if set,
    otherwise the C{"log_namespace"} and C{"log_level"}, joined by a C{"#"}.
    Each defaults to C{"-"} is not set.  If formatting fails completely,
    "UNFORMATTABLE" is returned.

    @param event: The event containing the system specification.

    @return: A formatted string representing the "log_system" key.
    
log_systemN	log_levelr+   z{namespace}#{level}log_namespace)	namespacelevelUNFORMATTABLE)r   r	   r0   ry   r   rM   r'   	Exception)r   systemr   	levelNames       r   _formatSystemr   G  s     (3-<!>?F~Xm,eiiT.JK=I

I&--3		/3 ?@ . 
 M		%[F M  	%$FM	%s   B# #B21B2Tc                T   t        |       }|r'd| v r#| d   }t        |      }dj                  ||f      }|s|S d}|r7dj                   |t        t        | j                  dd                  dg      }d}	|rdj                  dt        |       ddg      }	d	j                  ||	|
      S )ah  
    Format an event as text.  Optionally, attach timestamp, traceback, and
    system information.

    The full output format is:
    C{"{timeStamp} [{system}] {event}\n{traceback}\n"} where:

        - C{timeStamp} is the event's C{"log_time"} value formatted with
          the provided C{formatTime} callable.

        - C{system} is the event's C{"log_system"} value, if set, otherwise,
          the C{"log_namespace"} and C{"log_level"}, joined by a C{"#"}.  Each
          defaults to C{"-"} is not set.

        - C{event} is the event, as formatted by L{formatEvent}.

        - C{traceback} is the traceback if the event contains a
          C{"log_failure"} key.  In the event the original traceback cannot
          be formatted, a message indicating the failure will be substituted.

    If the event cannot be formatted, and no traceback exists, an empty string
    is returned, even if includeSystem or includeTimestamp are true.

    @param event: A logging event.
    @param includeTraceback: If true and a C{"log_failure"} key exists, append
        a traceback.
    @param includeTimestamp: If true include a formatted timestamp before the
        event.
    @param includeSystem:  If true, include the event's C{"log_system"} value.
    @param formatTime: A time formatter

    @return: A formatted string with specified options.

    @since: Twisted 18.9.0
    log_failurer8   rw   log_timeN []z{timeStamp}{system}{eventText})	timeStampr   r:   )r~   r   r    r   floatry   r   r'   )
r   r   r   r   r6   r:   fr   r   r   s
             r   r   r   f  s    T U#IMU2- $Q'	IIy)45	IGGZUEIIj$4O(PQSVWX	F#}U3S#>?+22 3  r   N)r   r   rZ   r0   )r   r   r   r(   rZ   r0   )r2   zOptional[float]r3   Optional[str]r4   r0   rZ   r0   )r   r   r6   z Callable[[Optional[float]], str]rZ   r   )r"   r0   r@   zCallable[[str], Any]rZ   r<   )rq   r0   rr   rm   rZ   r0   )r%   r   rZ   r0   )r   r   r   boolr   r   r   r   r6   zCallable[[float], str]rZ   r0   ))r_   
__future__r   r   r.   typingr   r   r   r   r	   r
   r   
constantlyr   twisted.python._tzhelperr   twisted.python.failurer   twisted.python.reflectr   _flattenr   r   _interfacesr   timeFormatRFC3339r   r*   r6   r;   rC   rY   r<   r0   rb   rs   r~   r   r   r   r`   r   r   <module>r      s  
 # ) J J J $ 8 * , , !) (!
L !22
22 2 		2F EO33!A33l'.'6 '8:'#s(# ::K42D$B "!)3??? ? 	?
 '? 	?r   