o
    f                     @   s   d dl Zd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dlm
Z
 d dlmZ d dlmZ dZdZejd ZG dd	 d	ejZejdfd
dZdd ZdddZdddZG dd dejZdd Zdd ZG dd dejZdd ZdS )    N)defaultdict)suppress)DefaultDictz6%(asctime)s - %(filename)s[%(levelname)s]: %(message)s#      c                   @   s    e Zd ZdZdd Zdd ZdS )CustomLoggerTypezA hack to get mypy to stop complaining about custom logging methods.

    When using deprecated or trace logging, rather than:
        LOG = logging.getLogger(__name__)
    Instead do:
        LOG = cast(CustomLoggerType, logging.getLogger(__name__))
    c                 O      d S N selfargskwargsr
   r
   //usr/lib/python3/dist-packages/cloudinit/log.pytrace&      zCustomLoggerType.tracec                 O   r   r	   r
   r   r
   r
   r   
deprecated)   r   zCustomLoggerType.deprecatedN)__name__
__module____qualname____doc__r   r   r
   r
   r
   r   r      s    r   c                 C   sN   |pt t}t  }t tj}|| ||  |	| ||  d S r	   )
logging	FormatterDEFAULT_LOG_FORMAT	getLoggerStreamHandlersysstderrsetFormattersetLevel
addHandler)level	formatterrootconsoler
   r
   r   setup_basic_logging-   s   


r%   c              	   C   s^   | sd S | j D ] }t|tjr'tt |  W d    n1 s"w   Y  qt| j d S r	   )	handlers
isinstancer   r   r   IOErrorflushflush_loggersparent)r#   hr
   r
   r   r*   7   s   


r*   returnc                  C   sH   dd } t td t td tt jd| t tt jd| t dS )z:Add DEPRECATED and TRACE log levels to the logging module.c                    s    fdd}|S )Nc                    s(   |   r| j ||fi | d S d S r	   )isEnabledFor_log)r   messager   r   r!   r
   r   log_at_levelE   s   
z>define_extra_loggers.<locals>.new_logger.<locals>.log_at_levelr
   )r!   r2   r
   r1   r   
new_loggerD   s   z(define_extra_loggers.<locals>.new_logger
DEPRECATEDTRACEr   r   N)r   addLevelNamer4   r5   setattrLogger)r3   r
   r
   r   define_extra_loggersA   s
   r9   c           	   	   C   st  | si } t  }t }|t j g }| d}|r't|tr'|t| n4d| v r[| d D ]+}t|tr<|| q/t|t	j
jrSdd |D }|d| q/|t| q/d}|D ]8}tt* |d7 }|drutj|szt|}t j| || 	 W d     d S 1 sw   Y  q_|| | d	d
}tjd|  |rtjd t  d S d S )Nlogcfglog_cfgsc                 S   s   g | ]}t |qS r
   )str).0cr
   r
   r   
<listcomp>e   s    z!setup_logging.<locals>.<listcomp>
r      /	log_basicTz0WARN: no logging configured! (tried %s configs)
zSetting up basic logging...
)r   r   LogExporterr   WARNgetr'   r<   appendcollectionsabcIterablejoinr   FileNotFoundError
startswithospathisfileioStringIOconfig
fileConfigr    r   r   writer%   )	cfgroot_loggerexporterr;   log_cfga_cfgcfg_stram_triedbasic_enabledr
   r
   r   setup_loggingQ   sH   




$

r^   c                   @   sN   e Zd ZU eeZeeef ed< de	j
fddZdd Zdd Zd	d
 ZdS )rD   holderrecordc                 C   s   | j |j |  d S r	   )r_   	levelnamerG   
getMessager   r`   r
   r
   r   emit   s   zLogExporter.emitc                 C   s   t | jS r	   )copydeepcopyr_   r   r
   r
   r   export_logs   s   zLogExporter.export_logsc                 C   s   t t| _d S r	   )r   listr_   rg   r
   r
   r   
clean_logs   s   zLogExporter.clean_logsc                 C   r   r	   r
   rg   r
   r
   r   r)      r   zLogExporter.flushN)r   r   r   r   ri   r_   r   r<   __annotations__r   	LogRecordrd   rh   rj   r)   r
   r
   r
   r   rD      s   
 rD   c                  C   sF   t  } t| j}|D ]}|  |  | | q| t j dS )z0Remove all current handlers and unset log level.N)	r   r   ri   r&   r)   closeremoveHandlerr   NOTSET)logr&   r,   r
   r
   r   reset_logging   s   
rq   c                     sJ   t tj t ddd   t d  fdd} tt jd|  dS )zIn the event that internal logging exception occurs and logging is not
    possible for some reason, make a desperate final attempt to log to stderr
    which may ease debugging.
    handleErrorc                 S   r   r	   r
   )r`   r
   r
   r   <lambda>   s    z&setup_backup_logging.<locals>.<lambda>z@FALLBACK: %(asctime)s - %(filename)s[%(levelname)s]: %(message)sc                    s@   t t  |    W d   dS 1 sw   Y  dS )z;A closure that emits logs on stderr when other methods failN)r   r(   handler)   rc   fallback_handlerr
   r   rr      s   


"z)setup_backup_logging.<locals>.handleErrorN)r   r   r   r   r7   r   r   Handler)rr   r
   ru   r   setup_backup_logging   s   rx   c                       s    e Zd ZdZ fddZ  ZS )CloudInitLogRecordzreporting the filename as __init__.py isn't very useful in logs

    if the filename is __init__.py, use the parent directory as the filename
    c                    s<   t  j|i | d| jkrtjtj| j| _d S d S )Nz__init__.py)super__init__filenamerN   rO   basenamedirnamepathnamer   	__class__r
   r   r{      s   
zCloudInitLogRecord.__init__)r   r   r   r   r{   __classcell__r
   r
   r   r   ry      s    ry   c                  C   sJ   t jtj_t  t  t  t } | 	tj
 t |  tt dS )z(Customize the root logger for cloud-initN)timegmtimer   r   	converterr9   rx   rq   rD   r   rE   r   r    setLogRecordFactoryry   )handlerr
   r
   r   configure_root_logger   s   
r   )r-   Nr	   ) collections.abcrH   re   rQ   r   logging.configlogging.handlersrN   r   r   r   
contextlibr   typingr   r   r4   DEBUGr5   r8   r   r%   r*   r9   r^   r   rD   rq   rx   rl   ry   r   r
   r
   r
   r   <module>   s2   





A