Logging like a Lumberjack

This article was first published on Python - datawookie , and kindly contributed to python-bloggers. (You can report issue about the content on this page here)
Want to share your content on python-bloggers? click here.

Sprinkling status messages across you code using print() statements can be a good temporary fix for tracking down issues in your code.

But it can get messy and there’s no way for you to selectively disable them. Sure you can redirect output to a file or /dev/null but this is an all-or-nothing solution. How about disabling some messages and retaining others?

This is where the logging module comes into its own.

Local Logging

For each project I like to create a logger.py file that looks like this:

import logging
from logging import debug, info, warning, error
from datetime import datetime

FMT_MESSAGE = "%(asctime)s [%(levelname)7s] %(message)s"
FMT_DATETIME = "%Y-%m-%d %H:%M:%S"

# Get default logger.
#
logger = logging.getLogger()

# Set logging level.
#
logger.setLevel(logging.DEBUG)

formatter = logging.Formatter(FMT_MESSAGE, datefmt=FMT_DATETIME)

# Logging to console.
#
console = logging.StreamHandler()
console.setFormatter(formatter)
logger.addHandler(console)

# Logging to file.
#
file = logging.FileHandler(datetime.utcnow().strftime("%Y-%m-%d-%H%M%S.log"))
file.setFormatter(formatter)
logger.addHandler(file)

# Suppress logging from other packages.
#
logging.getLogger("asyncio").setLevel(logging.WARNING)
logging.getLogger("botocore").setLevel(logging.WARNING)

This does a number of things:

  • creates a formatter that specifies the layout of the log messages;
  • set the logging level;
  • add handler for logging to console and set format;
  • add handler for logging to file and set format (file name embeds date and time); and
  • restrict logging from a few other packages (add more as required).

Test it.

import logger

logger.info("An INFO message.")
logger.debug("A DEBUG message.")
2024-04-18 12:28:02 [   INFO] An INFO message.
2024-04-18 12:28:02 [  DEBUG] A DEBUG message.

That’s the output on the terminal. But there’s also a 2024-04-18-112802.log file that contains the same content. There will be a new log file each time you run the command. If you don’t want to create all of those log files then you can specify a fixed filename for the FileHandler object.

Integration

Provided that your main script imports the logger.py module, all other parts of your project can simply import logging. Since we have set up the default logger all subsequent logs will go to the same destination and have the same format.

To leave a comment for the author, please follow the link and comment on their blog: Python - datawookie .

Want to share your content on python-bloggers? click here.