The basics of the logging module mystify me

Thomas Jollans tjol at
Thu Apr 19 05:52:34 EDT 2018

On 2018-04-19 03:00, Skip Montanaro wrote:
> This session is from Python 3.6.5 on Linux:
>>>> import logging
>>>> log = logging.getLogger()
>>>> log.level
> 30
>>>> logging.WARN
> 30
>>>> log.warn("Awk! Goodbye...")
> Awk! Goodbye...
>>>> log.level = logging.INFO
>>>>"Awk! Goodbye...")
>>>> log.level
> 20
>>>> log.level == logging.INFO
> True
>>>> log.setLevel(logging.INFO)
>>>>"Awk! Goodbye...")
>>>> log.isEnabledFor(logging.INFO)
> True
> Why do the two calls not produce output on stderr when
> the level has clearly been set to logging.INFO? There is an active
> stream handler as demonstrated by the successful log.warn(...) call.

Loggers have levels, and log handlers have levels. To get log messages
to display, you have to add a log handler (with the right level) to your

Now, you never added a handler, so why are the warnings printing? Log
messages that have nowhere to go are given to the "last resort" handler,
which has its level set to WARNING.

You *could* change this:

Python 3.6.3 |Anaconda, Inc.| (default, Oct 13 2017, 12:02:49)
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import logging
>>> log = logging.getLogger()
>>> log.setLevel(logging.INFO)
>>> log.warn('warning 1')
warning 1
>>>'info 1')
>>> logging.lastResort
<_StderrHandler <stderr> (WARNING)>
>>> logging.lastResort.setLevel(logging.INFO) # DON'T DO THIS THOUGH
>>>'info 2')
info 2

Of course you should rather be creating your own handler

>>> handler = logging.StreamHandler()
>>> handler.setLevel(logging.DEBUG)
>>> log.addHandler(handler)
>>> log.setLevel(logging.DEBUG)
>>> log.debug('test test test')
test test test

Or, more often than not, it's best to use the logging module's
configuration system that creates the right web of handlers and
formatters for you.

-- Thomas

> I really don't like the logging module, but it looks like I'm stuck
> with it. Why aren't simple/obvious things either simple or obvious?

More information about the Python-list mailing list