o
    bb.                     @   s  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edefddZdededefddZedfde
e de
e dedefddZ e fdedee
e gef de
e fddZ!G dd deZ"dedeeef defd d!Z#dedefd"d#Z$d$edefd%d&Z%dedefd'd(Z&d)d)d)e fded*e'd+e'd,e'deegef defd-d.Z(d/S )0z&
Tools for formatting logging events.
    )Mapping)datetime)AnyCallableIteratorr   OptionalUnioncast)NamedConstant)FixedOffsetTimeZone)Failure)	safe_repr   )
aFormatter
flatFormat)LogEventz%Y-%m-%dT%H:%M:%S%zeventreturnc                 C   s   t | d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)r    r   8/usr/lib/python3/dist-packages/twisted/logger/_format.pyformatEvent   s   r   errorc                 C   sV   zdj | |dW S  ty*   t }ddd |  D }dj t|||d Y S 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   r   z, c                 s   s*    | ]\}}d  t|t|fV  qdS )z = N)joinr   ).0keyvaluer   r   r   	<genexpr>B   s
    
z+formatUnformattableEvent.<locals>.<genexpr>zrMESSAGE LOST: unformattable object logged: {error}
Recoverable data: {text}
Exception during formatting:
{failure})r   failuretext)formatBaseExceptionr   r   itemsr   )r   r   r!   r"   r   r   r   formatUnformattableEvent,   s   


r&   -when
timeFormatdefaultc                 C   s8   |du s| du r
|S t | }t| |}t||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.
    N)r   fromLocalTimeStampDateTimefromtimestampstrstrftime)r(   r)   r*   tzr   r   r   r   
formatTimeP   s
   
r1   c                 C   s(   t | |d}|s
dS |dd}|d 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.
    )r1   N
z
	)r   replace)r   r1   	eventTextr   r   r   formatEventAsClassicLogTextr   s
   /r5   c                   @   sX   e Zd ZdZdeeef ddfddZdefddZ	de
fd	d
ZdedefddZdS )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}.
    
submappingr   Nc                 C   s
   || _ dS )zo
        @param submapping: Another read-only mapping which will be used to look
            up items.
        N)_submapping)selfr7   r   r   r   __init__   s   
zCallMapping.__init__c                 C   
   t | jS N)iterr8   r9   r   r   r   __iter__      
zCallMapping.__iter__c                 C   r;   r<   )lenr8   r>   r   r   r   __len__   r@   zCallMapping.__len__r   c                 C   s6   | d}|r|dd n|}| j| }|r| }|S )z|
        Look up an item in the submapping for this L{CallMapping}, calling it
        if C{key} ends with C{"()"}.
        z()N)endswithr8   )r9   r   callitrealKeyr   r   r   r   __getitem__   s   

zCallMapping.__getitem__)__name__
__module____qualname____doc__r   r.   r   r:   r   r?   intrB   rG   r   r   r   r   r6      s    r6   formatStringmappingc                 C   s   t t| 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   )r.   r   vformatr6   )rM   rN   r   r   r   formatWithCall   s   rP   c              
   C   s   z=d| v r
t | W S tttttf  | dd}|du r W dS t|tr&nt|tr1|d}nt	d|t
|| W S  tyT } zt| |W  Y d}~S d}~w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   r.   bytesget
isinstancedecode	TypeErrorrP   r$   r&   )r   r#   er   r   r   _formatEvent   s    


rZ   r!   c              
   C   sB   z|   }W |S  ty  } zdt| }W Y d}~|S d}~w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$   r.   )r!   	tracebackrY   r   r   r   _formatTraceback  s   
r]   c                 C   s   t tt | dd}|du r4t tt | dd}|du r!d}n|j}djt t| dd|d}|S zt|}W |S  tyG   d}Y |S 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   r.   rU   r
   namer#   	Exception)r   systemrb   	levelNamer   r   r   _formatSystem  s$   	
rh   Tr   r   r   c           
   	   C   s   t | }|rd| v r| d }t|}d||f}|s|S d}|r1d|tt| dddg}d}	|r@ddt| ddg}	d	j||	|d
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_failurer2   rS   log_timeN []z{timeStamp}{system}{eventText})	timeStamprf   r4   )rZ   r]   r   r	   floatrU   rh   r#   )
r   r   r   r   r1   r4   fr\   rn   rf   r   r   r   r   7  s$   * r   N))rK   collections.abcr   
MappingABCr   r,   typingr   r   r   r   r   r	   
constantlyr
   twisted.python._tzhelperr   twisted.python.failurer   twisted.python.reflectr   _flattenr   r   _interfacesr   timeFormatRFC3339r.   r   r$   r&   ro   r1   r5   r6   rP   rZ   r]   rh   boolr   r   r   r   r   <module>   sl   $&
#
6""!