Amelio Vazquez-Reina
Amelio Vazquez-Reina

Reputation: 96398

Logging in Python. Handlers and console duplicates

I have a simple logging setup:

def main()

  # ....
  # Create logger
  logging.basicConfig(filemode='w', level=logging.DEBUG)
  logger = logging.getLogger(__name__)
  logger.setLevel(logging.DEBUG)

  # Create file handler for DEBUG and above
  fh1 = logging.FileHandler(__name__ + '.debug.log')
  fh1.setLevel(logging.DEBUG)

  # Create file handler for INFO and above
  fh2 = logging.FileHandler(__name__ + '.info.log')
  fh2.setLevel(logging.INFO)

  # Create console handler with INFO and above
  ch = logging.StreamHandler()
  ch.setLevel(logging.INFO)

  # Add all the handlers to the logger
  logger.addHandler(fh1)
  logger.addHandler(fh2)
  logger.addHandler(ch)
  # ....

Then when I call

logger.info("this is an INFO message")
logger.debug("this is a DEBUG message")

I get the following on the console:

this is an INFO message
INFO:__main__:this is an INFO message
this is a DEBUG message
DEBUG:__main__:this is a DEBUG message

Even though I expected to only see INFO messages in the console (since I specified logging.info above for the StreamHandler). Why do I get these duplicates?

My .debug.log and info.log files contain only the messages at the right level, but their formatting does not include the prefices INFO:__main__ nor DEBUG:__main__. Why is their formatting different?

Upvotes: 1

Views: 317

Answers (1)

unutbu
unutbu

Reputation: 880537

logging.basicConfig(filemode='w', level=logging.DEBUG)

creates a StreamHandler. So your code is creating two StreamHandlers, one with logging level DEBUG and another with level INFO.

basicConfig is a convenience function. If you want to create your own handlers, it is not necessary to call basicConfig. (Or you can call basicConfig and add additional handlers...)


If you don't supply a filename in the call to basicConfig, then a StreamHandler is added to the root logger. This is the code inside the basicConfig function:

if handlers is None:
    filename = kwargs.get("filename")
    if filename:
        mode = kwargs.get("filemode", 'a')
        h = FileHandler(filename, mode)
    else:
        stream = kwargs.get("stream")
        h = StreamHandler(stream)

Upvotes: 2

Related Questions