Python Logging Module Summary

sjchin
2 min readApr 20, 2024

--

A good reference from the official document

I will recommend starting with understanding the logging flow diagram here.

The Basics that you need to know

To use a logger in your module, you need a logger object, a handler(optional), and a formatter.

Logger Object

  • A logger object is specified by name.
  • Doing everything with the logging class directly (like logging.info(“message”) will use the root logger
  • If you don’t specify the name when trying to get the logger, you will also use the root logger
  • The logger names are period-separated hierarchical structures. For example, foo.bar and foo.barz both belong to the same parent logger foo. The implication is that if the setting is not specified in foo.bar level, then the module will look for the setting of its parent (which is at foo level)
  • There are five severity levels from low to high: DEBUG, INFO, WARNING, ERROR, CRITICAL. You can set the severity level of the message that you want the logger to store. The default severity level is WARNING, meaning only messages with a severity level equal to or higher than WARNING will be stored.
  • You only need to set the setting for the logger (like severity level) once. If you change the setting in one place, it will affect all subsequent code that uses the logger. The setting will only be in affect when related code is called.

Handler

  • The handler specifies how the log message is being handled. A common handling mechanism is to just output the log message to the console.
  • Like a logger, a handler also has a severity level setting that determines what level of message will be handled. The default severity level is also WARNING.
  • A logger without specifying the handler will output only the stderr stream to the console.

Formatter

  • Specified how logging messages look when displayed/stored.

Example code

check here

Do & Donts (Best Practise)

Do

  • Create a specific logger for your module
  • The logger names should have period-separated hierarchical structures. Mimicking the actual module structure of your project
  • For example, if you have a module name myproj/module1/submodule.py. Then you will can use a logger with name as below
logger = logging.getLogger("myproj.module1.submodule")
  • Set the handler and formatter to customize what level of message to be handled, and the formatting output of the message.

Best to Avoid

  • Avoid calling the logging.basicConfig() function any place in your module. This will implicitly add the StreamHandler to the root logger
  • Avoid calling the logging.info, logging.error etc. directly. Even without configuring the root logger, the basicConfig() function will be called internally, which implicitly added to the root logger.
  • Effect of adding the StreamHandler to the root logger : All logger will inherit this StreamHandler. This mean if you add another StreamHandler to the child logger, the logging message will be export twice (by two different StreamHandler)

--

--

sjchin
sjchin

Written by sjchin

NEU MSCS student interned with Intel. Ex Oil & Gas Profession

No responses yet