简体   繁体   中英

Python: How to properly configure logging for a library with dictConfig?

I have a project folder with this structure:

.
├── myapp.py
└── mypackage
    ├── __init__.py
    └── mymodule.py

Now I wanted to configure logging for mypackage as described in the documentation ( Configuring Logging for a Library ) so I added a NullHandler to the top-level logger in my __init__.py :

import logging
logging.getLogger(__name__).addHandler(logging.NullHandler())

In mymodule.py I then generate an instance of the logger and use it:

import logging
logger=logging.getLogger(__name__)

def myfunc():
    logger.warning('logging from mymodule.py')

In myapp.py I configure the logger like so:

import logging
import logging.config
import mypackage.mymodule as mm

if __name__ == '__main__':

    LOGGING = {'version': 1}
    console_handler = {'class': 'logging.StreamHandler'}
    LOGGING['handlers'] = {'console_handler': console_handler}
    root_logger = {'handlers': ['console_handler']}
    LOGGING['loggers'] = {'': root_logger}
    
    logging.config.dictConfig(LOGGING)
    
    applogger = logging.getLogger(__name__)
    applogger.warning('logging from myapp.py')
    
    mm.myfunc()

Since I am adding handlers to the root-logger ( '' ) I now expected to see both messages (the one in myapp.py and the one in myfunc ) but I only see:

$ python -m myapp
logging from myapp.py

What am I doing wrong?

You missed that the logging.config.dictConfig() method disables existing loggers , unless you tell it not to. See the Dict Schema Details section :

disable_existing_loggers - whether any existing non-root loggers are to be disabled. This setting mirrors the parameter of the same name in fileConfig() . If absent, this parameter defaults to True . This value is ignored if incremental is True .

(bold emphasis mine).

Your library loggers were disabled:

(Pdb) logging.getLogger("mypackage.mymodule").disabled
False
(Pdb) n
> /.../myapp.py(16)<module>()
-> applogger = logging.getLogger(__name__)
(Pdb) logging.getLogger("mypackage.mymodule").disabled
True

Either explicitly set it to False , or set incremental to True , eg:

    LOGGING = {'version': 1, 'disable_existing_loggers': False}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM