o x[h@sddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddlm Z ddl m Z ddl mZdZdZejdZGdd d ejZejdfd d Zd d ZdddZdddZGdddejZddZddZGdddejZddZdS)N) defaultdict)suppress) DefaultDictz6%(asctime)s - %(filename)s[%(levelname)s]: %(message)s#c@s eZdZdZddZddZdS)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__)) cOdSNselfargskwargsr r 7/usr/lib/python3/dist-packages/cloudinit/log/loggers.pytrace&zCustomLoggerType.tracecOrr r r r r r deprecated)rzCustomLoggerType.deprecatedN)__name__ __module__ __qualname____doc__rrr r r rrs rcCsN|ptt}t}ttj}||||| |||dSr ) logging FormatterDEFAULT_LOG_FORMAT getLogger StreamHandlersysstderr setFormattersetLevel addHandler)level formatterrootconsoler r rsetup_basic_logging-s    r%c Cs^|sdS|jD] }t|tjr'tt |Wdn1s"wYqt|jdSr ) handlers isinstancerrrIOErrorflush flush_loggersparent)r#hr r rr*7s    r*returncCsHdd}ttdttdttjd|tttjd|tdS)z:Add DEPRECATED and TRACE log levels to the logging module.csfdd}|S)Ncs(|r|j||fi|dSdSr ) isEnabledFor_log)r messager rr!r r log_at_levelEs z>define_extra_loggers..new_logger..log_at_levelr )r!r2r r1r new_loggerDs z(define_extra_loggers..new_logger DEPRECATEDTRACErrN)r addLevelNamer4r5setattrLogger)r3r r rdefine_extra_loggersAs   r9c Cst|si}t}t}|tjg}|d}|r't|tr'|t|n4d|vr[|dD]+}t|tr<||q/t|t j j rSdd|D}|d |q/|t|q/d}|D]8}t t*|d7}|drutj|szt|}tj||| WddS1swYq_|||d d }tjd ||rtjd tdSdS) Nlogcfglog_cfgscSsg|]}t|qSr )str).0cr r r esz!setup_logging.. r/ log_basicTz0WARN: no logging configured! (tried %s configs) zSetting up basic logging... )rr LogExporterrWARNgetr'r<append collectionsabcIterablejoinrFileNotFoundError startswithospathisfileioStringIOconfig fileConfigr rrwriter%) cfg root_loggerexporterr;log_cfga_cfgcfg_stram_tried basic_enabledr r r setup_loggingQsH         $    r^c@sNeZdZUeeZeeefed<de j fddZ ddZ ddZ d d Zd S) rDholderrecordcCs|j|j|dSr )r_ levelnamerG getMessager r`r r remitszLogExporter.emitcCs t|jSr )copydeepcopyr_r r r r export_logss zLogExporter.export_logscCstt|_dSr )rlistr_rgr r r clean_logsszLogExporter.clean_logscCrr r rgr r rr)rzLogExporter.flushN)rrrrrir_rr<__annotations__r LogRecordrdrhrjr)r r r rrDs  rDcCsFt}t|j}|D]}||||q |tjdS)z0Remove all current handlers and unset log level.N) rrrir&r)close removeHandlerrNOTSET)logr&r,r r r reset_loggings  rqcsJttjtdddtdfdd}ttjd|dS)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. handleErrorcSrr r )r`r r rsz&setup_backup_logging..z@FALLBACK: %(asctime)s - %(filename)s[%(levelname)s]: %(message)scs@tt|WddS1swYdS)z;A closure that emits logs on stderr when other methods failN)rr(handler)rcfallback_handlerr rrrs   "z)setup_backup_logging..handleErrorN)rrrrr7rrHandler)rrr rursetup_backup_loggings  rxcs eZdZdZfddZZS)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 cs<tj|i|d|jkrtjtj|j|_dSdS)Nz __init__.py)super__init__filenamerNrObasenamedirnamepathnamer  __class__r rr{s zCloudInitLogRecord.__init__)rrrrr{ __classcell__r r rrrysrycCsJtjtj_tttt}| tj t |t tdS)z(Customize the root logger for cloud-initN)timegmtimerr converterr9rxrqrDrrErr setLogRecordFactoryry)handlerr r rconfigure_root_loggers  r)r-Nr ) collections.abcrHrerQrlogging.configlogging.handlersrNrrr contextlibrtypingrrr4DEBUGr5r8rr%r*r9r^rrDrqrxrlryrr r r rs2      A