Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The difference between 'setLevel' of a logger and 'setLevel' of a handler connected to the logger

Tags:

python

logging

I am trying to grasp the difference between the impact of logger.setLevel and the impact of handler.setLevel, where the logger and the handler are created as follows:

import logging

def getLogger(name, loggerLevel, handlerLevel):
    formatter = logging.Formatter('%(message)s')

    handler = logging.StreamHandler()
    handler.setLevel(handlerLevel)
    handler.setFormatter(formatter)

    logger = logging.getLogger(name)
    logger.setLevel(loggerLevel)
    logger.addHandler(handler)

    return logger

Note that the handler is connected to the logger.

Here is what the official doc says about setLevel:

Sets the threshold for this logger to level. Logging messages which are less severe than level will be ignored; logging messages which have severity level or higher will be emitted by whichever handler or handlers service this logger, unless a handler’s level has been set to a higher severity level than level.

I didn't quite fully understand this, so I implemented the following script to test all possible combinations:

for loggerLevel in ['DEBUG', 'INFO', 'WARNING', 'ERROR']:
    for handlerLevel in ['DEBUG', 'INFO', 'WARNING', 'ERROR']:
        name = loggerLevel + '_' + handlerLevel
        print('{}:'.format(name))
        logger = getLogger(name,eval('logging.'+loggerLevel),eval('logging.'+handlerLevel))
        logger.debug  ('    debug  ')
        logger.info   ('    info   ')
        logger.warning('    warning')
        logger.error  ('    error  ')

And the output (see below) proves one thing - the higher level out of the two is the one to determine the course of action, regardless of which entity was set to that level.

So my question is - why do we need more than one level to begin with?

DEBUG_DEBUG:
    debug
    info
    warning
    error
DEBUG_INFO:
    info
    warning
    error
DEBUG_WARNING:
    warning
    error
DEBUG_ERROR:
    error
INFO_DEBUG:
    info
    warning
    error
INFO_INFO:
    info
    warning
    error
INFO_WARNING:
    warning
    error
INFO_ERROR:
    error
WARNING_DEBUG:
    warning
    error
WARNING_INFO:
    warning
    error
WARNING_WARNING:
    warning
    error
WARNING_ERROR:
    error
ERROR_DEBUG:
    error
ERROR_INFO:
    error
ERROR_WARNING:
    error
ERROR_ERROR:
    error
like image 942
goodvibration Avatar asked Oct 29 '25 13:10

goodvibration


1 Answers

You can attach more than one handler to a logger, and logger levels matter when propagating messages in a hierarchy.

Using multiple handlers lets you direct different severity levels to different outputs. You can put WARNING messages to the console, INFO and better go to the system log, and DEBUG messages go to an application-specific log file. This is what setting the log level on a handler is for, to configure what messages each handler will process, independently.

Logger levels matter in a hierarchy; all loggers are children of the root logger, and you can create further levels by using . dots in the name. You can then pick and choose what loggers produce what levels of output; setting a more strict log level means the logger will not process a message (including not handing it to the parent logger).

For example, many third-party libraries will produce log output at various levels. So, for a specific application, it could be quite helpful to see the ERROR level messages produced by the urllib3 library, but for SQLAlchemy you only want to see WARNING messages. You just configure the levels for these library loggers with a getLogger(name_of_library) call to stop them propagating lower level messages to the root logger, where the handlers typically live.

like image 102
Martijn Pieters Avatar answered Oct 31 '25 03:10

Martijn Pieters



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!