[Python-Dev] Using logging in the stdlib and its unit tests

Robert Kern robert.kern at gmail.com
Wed Dec 8 17:35:59 CET 2010

On 12/8/10 2:51 AM, Vinay Sajip wrote:
> Robert Kern<robert.kern<at>  gmail.com>  writes:
>> I really don't understand how this view can be consistent with the
>> practice of adding NullHandler to loggers. If this message is so important
>> to prevent misconfiguration, then why should a library author decide to
>> silence it for his users?
> Because the application developer knows more about the end-user audience for
> their application, they are better placed to know how logging should work for
> their application. It's not an error for a particular application developer to
> decide that nothing should be produced by logging for a particular application;
> they (particularly when casual users) would be confused by the misconfiguration
> message due to logging by a library they're using.
> The library author's users are the application developers who use the library,
> not the end users who use their applications. Sometimes they're the same people,
> I know, but I just think of them as wearing different hats :-)

I'm sorry, but it's not at all clear that you have understood my point. There is 
no way for me to parse your words as a sensible reply to what I said.

Let's say I write a library called Foo. I want to add logging to my functions. 
You want to write an application called Bar that uses Foo and you want to 
configure logging for your application (at the very least to provide a default 
if not production). The warning is supposed to help you not make mistakes when 
configuring logging in your application. If I, library author, attach 
NullHandlers to all of Foo's loggers, then you will not get that warning if you 
forget to add handlers the Foo loggers. My adding the NullHandler to Foo 
prevented that warning that you consider to be so important.

I don't think the warning helps much, if at all.

>> [...] I strongly suspect that almost all configurations include a
>> catch-all root logger and that most of those *only* consist of that
>> root logger.
> That doesn't seem right: your comment might be conflating loggers with handlers.
> The common pattern would be (or should be) to name loggers according to __name__
> in the modules which use logging, but only configure *handlers* for the root
> logger. That way, logging messages indicate their origin (because of the
> __name__ convention) but you only need to add handlers at the root logger to
> capture all the logging information.

Yes. That's what I meant.

>> I think that boilerplate should be minimized. If using getLogger() should
>> almost always be followed by adding a NullHandler, then it should be the
>> default behavior. The easiest way to achieve this effect is to simply not
>> issue the warning message.
> getLogger() should NOT "almost always be followed by adding a NullHandler". For
> example, in Django, only the logger named "django" would have that handler
> added; no other Django logger (e.g. "django.db.models") would need to have that
> handler added.

In a large package (particularly a namespace package), I can't guarantee that 
any particular module will get imported. I will want to be able to import just 
foo.bar.baz without needing to worry about whether foo.setup_logging got 
imported and ran the logging configuration as a side-effect. I want to be able 
to loosen the coupling between modules across my package, not add more coupling.

But in any case, while adding a NullHandler to just the package's root logger 
helps you to avoid needing a NullHandler on every logger, the effect is the 
same. Almost all loggers effectively terminate in a NullHandler either directly 
or through a chain of parent loggers. So why not just make it the default?

Personally, I would back the proposals being made elsewhere in this thread, that 
in the absence of configuration, warnings and errors should be printed to stderr 
no matter where they come from. This gives useful behavior out-of-the-box 
without configuration but remains completely configurable. Library errors don't 
pass silently, but logging allows people to silence them explicitly. It 
separates the concerns of library authors (who should never touch logging 
configuration and shouldn't be required to think about it) from those of the 
application authors and application users.

Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
  that is made terrible by our own mad attempt to interpret it as though it had
  an underlying truth."
   -- Umberto Eco

More information about the Python-Dev mailing list