Python logger is not printing debug messages, although it is set correctly

Arthur picture Arthur · Jun 1, 2017 · Viewed 9.6k times · Source

I have the following code, where I just want to play around with the logging module using contextmanager.

from contextlib import contextmanager
import logging

@contextmanager
def log_level(level, name):
    logger = logging.getLogger(name)
    old_level = logger.getEffectiveLevel()
    print('log_level.old_level: ' + str(old_level))
    logger.setLevel(level)
    print('log_level.new_level: ' + str(logger.getEffectiveLevel()))
    try:
        yield logger
    finally:
        logger.setLevel(old_level)

if __name__ == '__main__':

    with log_level(logging.DEBUG, 'my-log') as logger:
        print('__main__.log_level.logger.level: ' + str(logger.getEffectiveLevel()))
        logger.debug('Debug with logger: will print')
        logger.warning('Warning')
        print('__main__.log_level.logger.level: ' + str(logger.getEffectiveLevel()))
    print('__main__.logger.level: ' + str(logger.getEffectiveLevel()))

As one can see, inside the main.log_level, the logger level should be DEBUG and it should print the message 'Debug with logger: will print'. However, when I run the code, this debug message does not print. Looking the prints of the code, It says that the logger has DEBUG level while inside log_level, and that the level goes back to WARNING when it exits log_level. Here it is my output, when executing with python 3:

log_level.old_level: 30
log_level.new_level: 10
__main__.log_level.logger.level: 10
Warning
__main__.log_level.logger.level: 10
__main__.logger.level: 30

I would like some help to understand why logger.debug('Debug with logger: will print') is not printing.

Answer

Vinay Sajip picture Vinay Sajip · Jun 1, 2017

You haven't attached any handlers to your logger. As a result, an internal "handler of last resort" is used, which only outputs events at levels WARNING and above. See this part of the documentation to see what happens if no handler configuration is provided. If you call logging.basicConfig() before your with statement, the DEBUG messages should appear.

Note that the docs also contain working examples of using context managers with logging.