o
    NK&hP/                  
   @  sD  d dl mZ d dlZd dlZd dlZd dlmZmZ d dlm	Z	 d dlm
Z edZdZdZd	Zed
ZedZeedd dd dddj h dB ZG dd dejZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZ G dd  d eZ!G d!d" d"e!Z"dS )#    )annotationsN)is_atty
json_dumps)LEVEL_COLORS)Colorsz\033\[[0-9;]*\wz[1000D[{limit}Cz[1000D[{start}C[Kz[1000C[{right}D[Kz^(?P<exc>.*?): (?P<message>.*)$zCFile \"(?P<path>.*?)\", line (?P<line_num>\d+), in (?P<location>.*)  >   identrightasctimemessagec                      s   e Zd ZdZdZe Zej	dd
 dkZej	dd
 dkZej	ddp)dZd	Zd
ZdZej dej dZdZd# fddZd$ fddZd%ddZd&ddZd'd(dd Zd!d" Z  ZS ))AutoFormattera   
    Automatically sets up the formatter based on the environment.

    It will switch between the Debug and Production formatters based upon
    how the environment is set up. Additionally, it will automatically
    detect if the output is a TTY and colorize the output accordingly.
    FSANIC_NO_COLORfalsetrueSANIC_LOG_EXTRASANIC_WORKER_IDENTIFIERzMain z%Y-%m-%d %H:%M:%S %z   *   z%(ident)s{limit} %(asctime)s z%(levelname)s: {start}z%(message)sreturnNonec                   sp   t |}|s||   n|r|d s|  |d< t|dk r'|| j n	|d s0| j|d< t j|  d S )Nr         )listappend_make_formatlenDATE_FORMATsuper__init__)selfargs	args_list	__class__r   J/var/www/html/venv/lib/python3.10/site-packages/sanic/logging/formatter.pyr   5   s   
zAutoFormatter.__init__recordlogging.LogRecordstrc                   s6   | j |_| | t |}| jr|| |7 }|S N)IDENTr	   _set_levelnamer   format	LOG_EXTRA
_log_extra)r    r&   outputr#   r   r%   r,   B   s   
zAutoFormatter.formatc                 C  sB   | j r| jst|j }r| |j tj |_d S d S d S d S r)   )ATTYNO_COLORr   getlevelno	levelnamecEND)r    r&   colorr   r   r%   r+   J   s   zAutoFormatter._set_levelnamec                 C  sR   t j| jd}tj| jd}| j| j }|j||d}| jr!| jr't	
d|S |S )N)limit)start)r8   r9   r   )CONTROL_LIMIT_IDENTr,   IDENT_LIMITCONTROL_LIMIT_STARTMESSAGE_STARTPREFIX_FORMATMESSAGE_FORMATr0   r1   
CONTROL_REsub)r    r8   r9   base_formatfmtr   r   r%   r   R   s   zAutoFormatter._make_formatr   indentintc                 C  s@   dg}|j  D ]\}}|tvr|| ||| qd|S )Nr   
)__dict__itemsDEFAULT_FIELDSr   _format_key_valuejoin)r    r&   rD   extra_lineskeyvaluer   r   r%   r.   [   s   
zAutoFormatter._log_extrac           	   	   C  s   d| }| j r| js| dn| d}t|tr<|jt|ddg}| D ]\}}|| |||d  q&d	|S |jt||dS )N z   {c.YELLOW}{key}{c.END}={value}z{key}={value}r   )r5   rM   rN   r   rF   )
r0   r1   
isinstancedictr,   r5   rH   r   rJ   rK   )	r    rM   rN   rD   indentationtemplatenested_lines
nested_keynested_valuer   r   r%   rJ   d   s"   


zAutoFormatter._format_key_value)r   r   r&   r'   r   r(   r&   r'   r   r   )r   r(   )r   )r&   r'   rD   rE   r   r(   )__name__
__module____qualname____doc__SETUPr   r0   osenvironr2   lowerr1   r-   r*   r   r;   r=   r5   GREYr6   r>   r?   r   r,   r+   r   r.   rJ   __classcell__r   r   r#   r%   r      s&    

		r   c                      sX   e Zd ZdZdZdZdZd fd	d
Z fddZdddZ	dddZ
dddZ  ZS )DebugFormatterz
    The DebugFormatter is used for development and debugging purposes.

    It can be used directly, or it will be automatically selected if the
    environment is set up for development and is using the AutoFormatter.
    r      %H:%M:%Sr&   r'   r   r   c                   s.   t |jdkr|jd d |_t | d S )Nr      )r   r4   r   r+   r    r&   r#   r   r%   r+      s   zDebugFormatter._set_levelnamec                   s   t  |}| jr| jr|S g }| }t|D ]4\}}|dr'| |}n |dr2| |}nd|v sBd|v sBt	|d |krG| 
|}|| qd|S )Nz  Filez    Error	Exceptionr   rF   )r   formatExceptionr0   r1   
splitlines	enumerate
startswith_color_file_line_color_code_liner   _color_exception_liner   rK   )r    eiorigcolored_tracebacklinesidxliner#   r   r%   rj      s   

 

zDebugFormatter.formatExceptionrv   r(   c                 C  sR   t |}|s	|S |d}|d}tj tj | tj dtj | tj S )Nexcr   z: )EXCEPTION_LINE_REmatchgroupr5   SANICBOLDr6   )r    rv   ry   rw   r   r   r   r%   rp      s   


,z$DebugFormatter._color_exception_linec                 C  sj   t |}|s	|S |d}|d}|d}d| dtj tj | tj dtj tj | tj S )Npathline_numlocationz  File "z", line z, in )FILE_LINE_REsearchrz   r5   CYANr|   r6   BLUE)r    rv   ry   r}   r~   r   r   r   r%   rn      s    



 zDebugFormatter._color_file_linec                 C  s   t j | t j S r)   )r5   YELLOWr6   )r    rv   r   r   r%   ro      s   zDebugFormatter._color_code_linerX   )rv   r(   r   r(   )rY   rZ   r[   r\   r;   r=   r   r+   rj   rp   rn   ro   rb   r   r   r#   r%   rc   x   s    

rc   c                   @  s   e Zd ZdZdS )ProdFormatterz
    The ProdFormatter is used for production environments.

    It can be used directly, or it will be automatically selected if the
    environment is set up for production and is using the AutoFormatter.
    N)rY   rZ   r[   r\   r   r   r   r%   r      s    r   c                   @     e Zd ZdZdZdZdS )LegacyFormattera  
    The LegacyFormatter is used if you want to use the old style of logging.

    You can use it as follows, typically in conjunction with the
    LegacyAccessFormatter:

    .. code-block:: python

        from sanic.log import LOGGING_CONFIG_DEFAULTS

        LOGGING_CONFIG_DEFAULTS["formatters"] = {
            "generic": {
                "class": "sanic.logging.formatter.LegacyFormatter"
            },
            "access": {
                "class": "sanic.logging.formatter.LegacyAccessFormatter"
            },
        }
    z*%(asctime)s [%(process)s] [%(levelname)s] z[%Y-%m-%d %H:%M:%S %z]N)rY   rZ   r[   r\   r>   r   r   r   r   r%   r          r   c                	      sX   e Zd Zej dejej  dej dej dej 	Z	d fd	d
Z
dddZ  ZS )AutoAccessFormatter	%(host)s %(request)s %(right)s%(status)s %(byte)s %(duration)sr&   r'   r   r(   c                   sl   t tt|dd}t tt|dd}t tt|dd}| jr-tj|| | d dnd|_t |S )Nstatusr   bytedurationr   )r
   )r   r(   getattrr0   CONTROL_LIMIT_ENDr,   r
   r   )r    r&   r   r   r   r#   r   r%   r,      s   zAutoAccessFormatter.formatr   c                 C  s2   | j r|jtjkrtj dtj |_d S d S d S )NACCESS)r0   r3   loggingINFOr5   r{   r6   r4   rg   r   r   r%   r+      s   z"AutoAccessFormatter._set_levelnamerW   rX   )rY   rZ   r[   r5   PURPLEr   r|   r6   ra   r?   r,   r+   rb   r   r   r#   r%   r      s    
r   c                   @  r   )LegacyAccessFormattera  
    The LegacyFormatter is used if you want to use the old style of logging.

    You can use it as follows, typically in conjunction with the
    LegacyFormatter:

    .. code-block:: python

        from sanic.log import LOGGING_CONFIG_DEFAULTS

        LOGGING_CONFIG_DEFAULTS["formatters"] = {
            "generic": {
                "class": "sanic.logging.formatter.LegacyFormatter"
            },
            "access": {
                "class": "sanic.logging.formatter.LegacyAccessFormatter"
            },
        }
    z3%(asctime)s - (%(name)s)[%(levelname)s][%(host)s]: z+%(request)s %(message)s %(status)s %(byte)sN)rY   rZ   r[   r\   r>   r?   r   r   r   r%   r      r   r   c                   @  s   e Zd ZdZdZdZdZdS )DebugAccessFormatterr   rd   re   FN)rY   rZ   r[   r;   r=   r   r-   r   r   r   r%   r     s
    r   c                	   @  s\   e Zd ZdZdZej dej dZej	 dej
ej  dej dej dej 	Zd	Zd
S )ProdAccessFormatterr   r   z%(ident)s{limit}|%(asctime)sz %(levelname)s: {start}r   r   r   r   FN)rY   rZ   r[   r;   r=   r5   ra   r6   r>   r   r   r|   r?   r-   r   r   r   r%   r     s    r   c                   @  sB   e Zd ZdZdZdZg dZeZdd	d
Z	dddZ
dddZdS )JSONFormattera  
    The JSONFormatter is used to output logs in JSON format.

    This is useful for logging to a file or to a log aggregator that
    understands JSON. It will output all the fields from the LogRecord
    as well as the extra fields that are passed in.

    You can use it as follows:

    .. code-block:: python

        from sanic.log import LOGGING_CONFIG_DEFAULTS

        LOGGING_CONFIG_DEFAULTS["formatters"] = {
            "generic": {
                "class": "sanic.logging.formatter.JSONFormatter"
            },
            "access": {
                "class": "sanic.logging.formatter.JSONFormatter"
            },
        }
    FT)namer3   pathnamemodulefilenamelinenor&   r'   r   r(   c                 C  s   |  | |S r)   )format_dictto_dictrg   r   r   r%   r,   @  s   zJSONFormatter.formatrQ   c                   s    fdd| j D }dd  j D }i } jr!|  j|d<  jr,|  j|d< |  | j j	 
 d|||S )Nc                      i | ]	}|t  |d qS r)   r   .0fieldr&   r   r%   
<dictcomp>D      z)JSONFormatter.to_dict.<locals>.<dictcomp>c                 S  s   i | ]\}}|t vr||qS r   )rI   )r   rM   rN   r   r   r%   r   E  s
    exc_info
stack_info	timestamplevelr   )FIELDSrG   rH   r   rj   r   formatStack
formatTimedatefmtr4   
getMessage)r    r&   baseextrainfor   r   r%   r   C  s&   zJSONFormatter.to_dictc                 C  s
   |  |S r)   )dumpsrg   r   r   r%   r   X  s   
zJSONFormatter.format_dictNrW   r&   r'   r   rQ   )r&   rQ   r   r(   )rY   rZ   r[   r\   r0   r1   r   r   r   r,   r   r   r   r   r   r%   r     s    	

r   c                   @  s"   e Zd ZdZg dZd
ddZd	S )JSONAccessFormattera  
    The JSONAccessFormatter is used to output access logs in JSON format.

    This is useful for logging to a file or to a log aggregator that
    understands JSON. It will output all the fields from the LogRecord
    as well as the extra fields that are passed in.

    You can use it as follows:

    .. code-block:: python

        from sanic.log import LOGGING_CONFIG_DEFAULTS

        LOGGING_CONFIG_DEFAULTS["formatters"] = {
            "generic": {
                "class": "sanic.logging.formatter.JSONFormatter"
            },
            "access": {
                "class": "sanic.logging.formatter.JSONAccessFormatter"
            },
        }
    )hostrequestr   r   r   r&   r'   r   rQ   c                   s4    fdd| j D }|  | j j  d|S )Nc                   r   r)   r   r   r   r   r%   r   }  r   z/JSONAccessFormatter.to_dict.<locals>.<dictcomp>r   )r   r   r   r4   r   )r    r&   r   r   r   r%   r   |  s   zJSONAccessFormatter.to_dictNr   )rY   rZ   r[   r\   r   r   r   r   r   r%   r   \  s    r   )#
__future__r   r   r^   resanic.helpersr   r   sanic.logging.colorr   r   r5   compiler@   r:   r<   r   rx   r   set	LogRecordrG   keysrI   	Formatterr   rc   r   r   r   r   r   r   r   r   r   r   r   r%   <module>   s<    


Z;	A