3 \Ќ @stdZddlZddlZddlZddlZddlZddlZddlZddlZyddl Z ddl Z Wne k rpdZ YnXddl mZmZdZejZdad+ddZdd Zd d Zd d ZddZddZddZddZejdejZddZGddde Z!Gddde"e!Z#Gddde$e!Z%Gdd d e&e!Z'Gd!d"d"e Z(Gd#d$d$e(Z)e)Z*d%d&Z+edfd'd(Z,d)d*Z-dS),a Configuration functions for the logging package for Python. The core package is based on PEP 282 and comments thereto in comp.lang.python, and influenced by Apache's log4j system. Copyright (C) 2001-2014 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! N)ThreadingTCPServerStreamRequestHandleriF#Tc Csddl}t||jr|}n*|j|}t|dr:|j|n |j|t|}tj z t t ||}t |||Wdtj XdS)aD Read the logging configuration from a ConfigParser-format file. This can be called several times from an application, allowing an end user the ability to select from various pre-canned configurations (if the developer provides a mechanism to present the choices and load the chosen configuration). rNreadline) configparser isinstanceZRawConfigParserZ ConfigParserhasattrZ read_fileread_create_formatterslogging _acquireLock_clearExistingHandlers_install_handlers_install_loggers _releaseLock)ZfnameZdefaultsdisable_existing_loggersrcp formattershandlersr&/usr/lib64/python3.6/logging/config.py fileConfig8s       rc Csp|jd}|jd}t|}xN|D]F}|d|}yt||}Wq"tk rft|t||}Yq"Xq"W|S)z)Resolve a dotted name to a global object..r)splitpop __import__getattrAttributeError)nameusedfoundnrrr_resolveZs    r!cCstdd|S)NcSs|jS)N)strip)xrrrisz_strip_spaces..)map)Zalistrrr _strip_spaceshsr&c Cs|dd}t|siS|jd}t|}i}x~|D]v}d|}|j|dddd}|j|d ddd}|j|d dd d}tj}||jd } | rt| }||||} | ||<q4W|S) zCreate and return formattersrkeys,z formatter_%sformatTN)rawfallbackdatefmtstyle%class)lenrr&getr Formatterr!) rZflistrZformZsectnameZfsZdfsZstlc class_namefrrrr ks$     r c CsD|dd}t|siS|jd}t|}i}g}x|D]}|d|}|d}|jdd}yt|tt}Wn ttfk rt |}YnX|d} t| tt} || } d |kr|d } | j | t|r| j ||t |tj jr|jd d} t| r|j| | f| ||<q8Wx |D]\} } | j|| q$W|S) zInstall and return handlersrr'r(z handler_%sr/ formatterargsleveltarget)r0rr&r1evalvarsr r NameErrorr!setLevel setFormatter issubclassr MemoryHandlerappendZ setTarget)rrhlistrZfixupshandsectionklassfmtr8hr9r:trrrr s>         r cCsHtj}x<|D]4}|jj|}||kr:tj|_g|_d|_q ||_q WdS)a When (re)configuring logging, handle loggers which were in the previous configuration but are not in the new configuration. There's no point deleting them as other threads may continue to hold references to them; and by disabling them, you stop them doing any logging. However, don't disable children of named loggers, as that's probably not what was intended by the user. Also, allow existing loggers to NOT be disabled if disable_existing is false. TN) r rootmanager loggerDictZNOTSETr9r propagatedisabled)existing child_loggersdisable_existingrJlogloggerrrr_handle_existing_loggerss   rTcCs,|dd}|jd}ttdd|}|jd|d}tj}|}d|kr^|d}|j|x |jd d D]}|j|qnW|d } t | r| jd} t | } x| D]} |j || qWt|j j j} | jg} x>|D]4}|d |}|d } |jd dd}tj| }| | kr| j| d}| d}t |}t | }x<||kr| |d ||krt| j| ||d7}qFW| j| d|kr|d}|j|x"|jd d D]}|j|qW||_d|_|d } t | r| jd} t | } x| D]} |j || qWqWt| | |d S)zCreate and install loggersloggersr'r(cSs|jS)N)r")r#rrrr$sz"_install_loggers..rJZ logger_rootr9Nrz logger_%squalnamerM)r+rr)rlistr%remover rJr>r removeHandlerr0r& addHandlerrKrLr'sortZgetint getLoggerindexrBrMrNrT)rrrQZllistrErJrRr9rHrCrDrOrPZqnrMrSiprefixedpflen num_existingrrrrsd                rcCs.tjjtjtjddtjdd=dS)z!Clear and close existing handlersN)r _handlersclearZshutdownZ _handlerListrrrrr s r z^[a-z_][a-z0-9_]*$cCstj|}|std|dS)Nz!Not a valid Python identifier: %rT) IDENTIFIERmatch ValueError)smrrr valid_idents  rjc@s"eZdZdZdddZddZdS) ConvertingMixinz?For ConvertingXXX's, this mixin class provides common functionsTcCsB|jj|}||k r>|r |||<t|tttfkr>||_||_|S)N) configuratorconverttypeConvertingDictConvertingListConvertingTupleparentkey)selfrsvaluereplaceresultrrrconvert_with_key$s  z ConvertingMixin.convert_with_keycCs0|jj|}||k r,t|tttfkr,||_|S)N)rlrmrnrorprqrr)rtrurwrrrrm0s   zConvertingMixin.convertN)T)__name__ __module__ __qualname____doc__rxrmrrrrrk!s rkc@s,eZdZdZddZd ddZd ddZdS) roz A converting dictionary wrapper.cCstj||}|j||S)N)dict __getitem__rx)rtrsrurrrr~Es zConvertingDict.__getitem__NcCstj|||}|j||S)N)r}r1rx)rtrsdefaultrurrrr1IszConvertingDict.getcCstj|||}|j||ddS)NF)rv)r}rrx)rtrsrrurrrrMszConvertingDict.pop)N)N)ryrzr{r|r~r1rrrrrroBs roc@s"eZdZdZddZd ddZdS) rpzA converting list wrapper.cCstj||}|j||S)N)rXr~rx)rtrsrurrrr~Ss zConvertingList.__getitem__rWcCstj||}|j|S)N)rXrrm)rtidxrurrrrWs zConvertingList.popN)r)ryrzr{r|r~rrrrrrpQsrpc@seZdZdZddZdS)rqzA converting tuple wrapper.cCstj||}|j||ddS)NF)rv)tupler~rx)rtrsrurrrr~]s zConvertingTuple.__getitem__N)ryrzr{r|r~rrrrrq[srqc@seZdZdZejdZejdZejdZejdZ ejdZ ddd Z e e Zd d Zd d ZddZddZddZddZddZdS)BaseConfiguratorzI The configurator base class which defines some useful defaults. z%^(?P[a-z]+)://(?P.*)$z ^\s*(\w+)\s*z^\.\s*(\w+)\s*z^\[\s*(\w+)\s*\]\s*z^\d+$ ext_convert cfg_convert)ZextZcfgcCst||_||j_dS)N)roconfigrl)rtrrrr__init__vs zBaseConfigurator.__init__c Cs|jd}|jd}y`|j|}xP|D]H}|d|7}yt||}Wq&tk rl|j|t||}Yq&Xq&W|Stk rtjdd\}}td||f}|||_ |_ |YnXdS)z` Resolve strings to objects using standard import and attribute syntax. rrrWNzCannot resolve %r: %s) rrimporterrr ImportErrorsysexc_inforg __cause__ __traceback__) rtrhrrrZfragetbvrrrresolvezs"      zBaseConfigurator.resolvecCs |j|S)z*Default converter for the ext:// protocol.)r)rtrurrrrszBaseConfigurator.ext_convertc Cs|}|jj|}|dkr&td|n||jd}|j|jd}x|r|jj|}|rp||jd}nd|jj|}|r|jd}|jj|s||}n2yt |}||}Wnt k r||}YnX|r||jd}qJtd||fqJW|S)z*Default converter for the cfg:// protocol.NzUnable to convert %rrzUnable to convert %r at %r) WORD_PATTERNrfrgendrgroups DOT_PATTERN INDEX_PATTERN DIGIT_PATTERNint TypeError)rtrurestridrr rrrrs2       zBaseConfigurator.cfg_convertcCst|t r&t|tr&t|}||_nt|t rLt|trLt|}||_n|t|t rrt|trrt|}||_nVt|tr|j j |}|r|j }|d}|j j |d}|r|d}t||}||}|S)z Convert values to an appropriate type. dicts, lists and tuples are replaced by their converting alternatives. Strings are checked to see if they have a conversion format and are converted if they do. prefixNsuffix)rror}rlrprXrqrstrCONVERT_PATTERNrf groupdictvalue_convertersr1r)rtrurirrZ converterrrrrrms*     zBaseConfigurator.convertcsrjd}t|s|j|}jdd}tfddD}|f|}|rnx |jD]\}}t|||qVW|S)z1Configure an object with a user-supplied factory.z()rNcs g|]}t|r||fqSr)rj).0k)rrr sz5BaseConfigurator.configure_custom..)rcallablerr}itemssetattr)rtrr3propskwargsrwrrur)rrconfigure_customs    z!BaseConfigurator.configure_customcCst|trt|}|S)z0Utility function which converts lists to tuples.)rrXr)rtrurrras_tuples zBaseConfigurator.as_tupleN)ryrzr{r|recompilerrrrrr staticmethodrrrrrrrmrrrrrrrbs      "rc@s^eZdZdZddZddZddZdd Zd d Zd d Z dddZ dddZ dddZ dS)DictConfiguratorz] Configure logging using a dictionary-like object to describe the configuration. cCs|j}d|krtd|ddkr2td|d|jdd}i}tjz|r|jd|}x|D]}|tjkrtd|qfy6tj|}||}|jd d }|r|jtj|Wqft k r} ztd || fWYd d } ~ XqfXqfW|jd |} xZ| D]R}y|j || |d Wn4t k rP} ztd|| fWYd d } ~ XnXqW|jdd } | ry|j | d Wn0t k r} ztd| WYd d } ~ XnXn:|jdd } t |jd|} xZ| D]R}y|j | || |<Wn4t k r"} ztd|| fWYd d } ~ XnXqW|jd|}xZ|D]R}y|j||||<Wn4t k r} ztd|| fWYd d } ~ XnXq _checkLevel Exceptionconfigure_loggerconfigure_rootr configure_formatterconfigure_filtersortedconfigure_handlerrrrBrJrXrKrLr'r\r^r0rYrTr)rtrrZ EMPTY_DICTrrhandlerZhandler_configr9rrUrJrQrrZdeferredrOrPr_r`rarbrrr configures        "  $    $  $   $  $      $ zDictConfigurator.configurec Csd|krr|d}y|j|}Wqtk rn}z4dt|kr>|jd|d<||d<|j|}WYdd}~XqXnP|jdd}|jdd}|jdd}|jd d}|stj} nt|} | |||}|S) z(Configure a formatter from a dictionary.z()z'format'r)rGNr,r-r.r/)rrrrr1r r2r!) rtrfactoryrwterGZdfmtr-cnamer3rrrrs&      z$DictConfigurator.configure_formattercCs.d|kr|j|}n|jdd}tj|}|S)z%Configure a filter from a dictionary.z()rr7)rr1r ZFilter)rtrrwrrrrrs    z!DictConfigurator.configure_filtercCs^xX|D]P}y|j|jd|Wqtk rT}ztd||fWYdd}~XqXqWdS)z/Add filters to a filterer from a list of names.rzUnable to add filter %r: %sN)Z addFilterrrrg)rtZfiltererrr5rrrr add_filterss  zDictConfigurator.add_filtersc/st}jdd}|r^y|jd|}Wn2tk r\}ztd||fWYdd}~XnXjdd}jdd}dkrjd}t|s|j|}|}njd} |j| } t| tj j od krHy>|jd d } t | tj sj |td | d <Wn8tk rD}ztd d |fWYdd}~XnXnZt| tj jrvd krv|jd d <n,t| tj jrdkr|jdd<| }jdd} tfddD} y|f| }WnLtk r"}z.dt|kr| jd| d<|f| }WYdd}~XnX|r4|j||dk rN|jtj||r`|j||| rx"| jD]\}}t|||qpW|S)z&Configure a handler from a dictionary.r6NrzUnable to set formatter %r: %sr9rz()r/r:rztarget not configured yetz#Unable to set target handler %r: %sZmailhostZaddressrcs g|]}t|r||fqSr)rj)rr)rrrrsz6DictConfigurator.configure_handler..z'stream'streamZstrm)r}rrrrgrrr@r rrArZHandlerupdaterZ SMTPHandlerrZ SysLogHandlerrr?r>rrrr)rtrZ config_copyr6rr9rr3rrrFZthrrrwrrrur)rrrsl          $      z"DictConfigurator.configure_handlercCs^xX|D]P}y|j|jd|Wqtk rT}ztd||fWYdd}~XqXqWdS)z.Add handlers to a logger from a list of names.rzUnable to add handler %r: %sN)r[rrrg)rtrSrrHrrrr add_handlerss  zDictConfigurator.add_handlersFcCs|jdd}|dk r$|jtj||sx |jddD]}|j|q8W|jdd}|rf|j|||jdd}|r|j||dS)zU Perform configuration which is common to root and non-root loggers. r9Nrr)r1r>r rrrZrr)rtrSrrr9rHrrrrrcommon_logger_configs    z%DictConfigurator.common_logger_configcCs6tj|}|j||||jdd}|dk r2||_dS)z.Configure a non-root logger from a dictionary.rMN)r r]rr1rM)rtrrrrSrMrrrrs   z!DictConfigurator.configure_loggercCstj}|j|||dS)z*Configure a root logger from a dictionary.N)r r]r)rtrrrJrrrrszDictConfigurator.configure_rootN)F)F)F) ryrzr{r|rrrrrrrrrrrrrrs ?  rcCst|jdS)z%Configure logging using a dictionary.N)dictConfigClassr)rrrr dictConfig srcsPts tdGdddt}Gdddt}Gfdddtj||||S)au Start up a socket server on the specified port, and listen for new configurations. These will be sent as a file suitable for processing by fileConfig(). Returns a Thread object on which you can call start() to start the server, and which you can join() when appropriate. To stop the server, call stopListening(). Use the ``verify`` argument to verify any bytes received across the wire from a client. If specified, it should be a callable which receives a single argument - the bytes of configuration data received across the network - and it should return either ``None``, to indicate that the passed in bytes could not be verified and should be discarded, or a byte string which is then passed to the configuration machinery as normal. Note that you can return transformed bytes, e.g. by decrypting the bytes passed in. z listen() needs threading to workc@seZdZdZddZdS)z#listen..ConfigStreamHandlerz Handler for a logging configuration request. It expects a completely new logging configuration and uses fileConfig to install it. cSsHy|j}|jd}t|dkrtjd|d}|jj|}x&t||krd||j|t|}q@W|jjdk r~|jj|}|dk r|jd}yddl}|j |}t |WnHt k rt j |}y t|Wnt k rtjYnXYnX|jjr|jjjWn2tk rB}z|jtkr2WYdd}~XnXdS)z Handle a request. Each request is expected to be a 4-byte length, packed using struct.pack(">L", n), followed by the config file. Uses fileConfig() to do the grunt work. z>LrNzutf-8)Z connectionZrecvr0structZunpackserververifydecodejsonloadsrrioStringIOr traceback print_excreadysetOSErrorerrno RESET_ERROR)rtZconnchunkZslenrrfilerrrrhandleBs6           z*listen..ConfigStreamHandler.handleN)ryrzr{r|rrrrrConfigStreamHandler;src@s0eZdZdZdZdedddfddZddZdS) z$listen..ConfigSocketReceiverzD A simple TCP socket-based logging config receiver. rWZ localhostNcSs>tj|||f|tjd|_tjd|_||_||_dS)NrrW) rrr r abortrtimeoutrr)rthostportrrrrrrrpsz-listen..ConfigSocketReceiver.__init__cSsfddl}d}xJ|sV|j|jjggg|j\}}}|r>|jtj|j}tjqW|jj dS)Nr) selectZsocketfilenorZhandle_requestr r rrclose)rtrrZrdwrZexrrrserve_until_stoppedzs z8listen..ConfigSocketReceiver.serve_until_stopped)ryrzr{r|Zallow_reuse_addressDEFAULT_LOGGING_CONFIG_PORTrrrrrrConfigSocketReceiveris  rcs&eZdZfddZddZZS)zlisten..Servercs4t|j||_||_||_||_tj|_dS)N) superrrcvrhdlrrr threadingZEventr)rtrrrr)Server __class__rrrs zlisten..Server.__init__cSsZ|j|j|j|j|jd}|jdkr0|jd|_|jjtj|a tj |j dS)N)rrrrrrW) rrrrrZserver_addressrr r _listenerrr)rtrrrrruns     zlisten..Server.run)ryrzr{rr __classcell__r)r)rrrsr)threadNotImplementedErrorrrrZThread)rrrrr)rrlisten%s .rc Cs*tjztrdt_daWdtjXdS)zN Stop the listening server which was created with a call to listen(). rWN)r r rrrrrrr stopListenings r)NT).r|rrr Zlogging.handlersrrrr_threadrrrZ socketserverrrrZ ECONNRESETrrrr!r&r r rTrr rIrerjobjectrkr}rorXrprrqrrrrrrrrrrsP   "#W! 9|