1

Consider this snippet of code, which I'm running under Python 2.7.6:

import logging, sys

assert (__name__ not in logging.Logger.manager.loggerDict)
logger = logging.getLogger(__name__)
stdout_handler = logging.StreamHandler(sys.stdout)
logger.addHandler(stdout_handler)

logger.error("You'll see this once")
logging.debug("Imagine logging now happens in some other module, maybe via an import")
logger.error("You'll see this twice")
logger.propagate = False
logger.error("BUT this you'll only see once")

It gives this output:

You'll see this once
You'll see this twice
ERROR:__main__:You'll see this twice
BUT this you'll only see once

The problem seems to be that logging.debug calls logging.basicConfig:

The above module-level convenience functions, which delegate to the root logger, call basicConfig() to ensure that at least one handler is available (source).

I'd like to simply take away from this the rule "Do not use the module-level convenience functions" but the scary thing is that any module that uses these functions (or calls logging.basicConfig) will break the rest of my logging. So instead the lesson could be "always use propagate=False for loggers whose parent is the root logger," but that doesn't feel right--propagate must default to True for a reason. Is there a better way?

1 Answer 1

2

the scary thing is that any module that uses these functions (or calls logging.basicConfig) will break the rest of my logging

Yes, it might, but those modules wouldn't be following good practice (which is documented). In fact, in your snippet above, you're doing it wrong - you're not supposed to attach handlers to loggers (other than NullHandler) except from code called from if __name__ == '__main__ in the main script. Importing the code shouldn't have side-effects.

The module-level convenience functions are for short scripts, simple usage and people just getting started with logging. They are not intended for use when logging requirements go beyond this.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the explanation. I went back and read through some of the docs again. For posterity, here is an excerpt from the documentation explaining this: "Note: It is strongly advised that you do not add any handlers other than NullHandler to your library’s loggers. This is because the configuration of handlers is the prerogative of the application developer who uses your library."
How does adding null handler to child logger (name) prevent root loggers handler (lastResort) from displaying log messages? The log will still propagate to the root logger isnt it?
@variable It doesn't. Where did that idea come from?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.