What is the point of setLevel in a python logging handler?

logging, python, python-logging

Solution

It allows finer control. By default the root logger has `WARNING` level set; this means that it won't print messages with a lower level (no matter how the handlers' levels are set!). But, if you set the root logger's level to `DEBUG`, indeed the message gets sent to the log file:

import logging
import logging.handlers

a = logging.getLogger('myapp')
a.setLevel(logging.DEBUG)   # set root's level
h = logging.handlers.RotatingFileHandler('foo.log')
h.setLevel(logging.DEBUG)
a.addHandler(h)
print a.getEffectiveLevel() 
a.debug('foo message')
a.warn('warning message')

Now, imagine that you want to add a new handler that doesn't record debug information. You can do this by simply setting the handler logging level:

import logging
import logging.handlers

a = logging.getLogger('myapp')
a.setLevel(logging.DEBUG)   # set root's level

h = logging.handlers.RotatingFileHandler('foo.log')
h.setLevel(logging.DEBUG)
a.addHandler(h)

h2 = logging.handlers.RotatingFileHandler('foo2.log')
h2.setLevel(logging.WARNING)
a.addHandler(h2)

print a.getEffectiveLevel() 
a.debug('foo message')
a.warn('warning message')

Now, the log file `foo.log` will contain both messages, while the file `foo2.log` will only contain the warning message. You could be interested in having a log file of only error-level messages; then, simply add a `Handler` and set its level to `logging.ERROR`, everything using the same `Logger`.

You may think of the `Logger` logging level as a global restriction on which messages are "interesting" for a given logger and its handlers. The messages that are considered by the logger afterwards get sent to the handlers, which perform their own filtering and logging process.

Problem

Let's say I have the following code: ``` import logging import logging.handlers a = logging.getLogger('myapp') h = logging.handlers.RotatingFileHandler('foo.log') h.setLevel(logging.DEBUG) a.addHandler(h) # The effective log level is still logging.WARN print a.getEffectiveLevel() a.debug('foo message') a.warn('warning message') ``` I expect that setting `logging.DEBUG` on the handler would cause debug-level messages to be written to the log file. However, this prints 30 for the effective level (equal to `logging.WARNING`, the default), and only logs the `warn` message to the log file, not the debug message. It appears that the handler's log level is being dropped on the floor, e.g. it's silently ignored. Which makes me wonder, why have `setLevel` on the handler at all?

Original source