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""!ûÿþýüûú