Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

logging.basicConfig in Python won't work if calling logging.info() before declaring

Based on this answer, Easier way to enable verbose logging

Let's take this Python script.

import argparse
import logging


def main():
    import argparse
    import logging

    parser = argparse.ArgumentParser(
        description='A test script for http://stackoverflow.com/q/14097061/78845'
    )
    parser.add_argument("-v", "--verbose", help="increase output verbosity",
                        action="store_true")

    args = parser.parse_args()
    if args.verbose:
        logging.basicConfig(level=logging.DEBUG)

    logging.info('Shown in debug and info mode')
    logging.debug('Only shown in debug mode')


if __name__ == "__main__":
    logging.info('Starting script!')
    main()

Running this script from terminal as python -m verbose -v won't print anything.

If you comment the line logging.info('Starting script!') from the file as in

if __name__ == "__main__":
    #logging.info('Starting script!')
    main()

then logging works as expected.

It looks like an attempt to call a logging.info() before basicConfig is defined will fully disable any logging.

Is it a bug in logging or a common gotcha and why does this happen?

I am on Python 3.6.7.

like image 861
Alex Tereshenkov Avatar asked Aug 25 '26 15:08

Alex Tereshenkov


2 Answers

From the logging documentation: (Emphasis mine)

 logging.basicConfig(**kwargs)

Does basic configuration for the logging system by creating a StreamHandler with a default Formatter and adding it to the root logger.

The functions debug(), info(), warning(), error() and critical() will call basicConfig() automatically if no handlers are defined for the root logger.

This function does nothing if the root logger already has handlers configured for it.

So basically your first call to logging.info made some automatic configuration. Your later configuration attempt silently failed because of the automatic configuration that already happend.

like image 192
dgw Avatar answered Aug 27 '26 05:08

dgw


Don't use basicConfig to change the level. Use logging.getLogger().setLevel(logging.DEBUG) to change the level on the root logger. One can do this on any logger or handler as well.

like image 21
Dan D. Avatar answered Aug 27 '26 04:08

Dan D.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!