Debugging Made Easy: Using Logging to Monitor and Troubleshoot Your Python Code
Best Practices for Implementing Logging in Your Python Projects and Writing Cleaner, More Maintainable Code
When building and maintaining software applications, debugging is an inevitable part of the development process. Even the most experienced developers can make mistakes or encounter unexpected issues during runtime. To help with troubleshooting, Python provides a built-in logging module that enables developers to easily record and output information about their code’s execution.
In this blog post, we will explore the basics of logging in Python, including why it’s important, how to set up a logger, and best practices for using it effectively. We will also provide code examples demonstrating how logging can be used to improve the quality and maintainability of your codebase.
Let us go through the necessary steps required to prepare the logging module.
Start by creating a logging_util.py
file.
import logging
def get_logger(name, level):
logger = logging.getLogger(name)
logger.setLevel(logging.DEBUG)
console_handler = logging.StreamHandler()
file_handler = logging.FileHandler("file_log.log") # skip incase file saving not required
c_format = logging.Formatter("%(name)s - %(levelname)s - %(message)s")
f_format = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
console_handler.setFormatter(c_format)
file_handler.setFormatter(f_format)
logger.addHandler(console_handler)
logger.addHandler(file_handler)
return logger
The above code defines a function “get_logger ” that returns a logger object for logging messages.
The function takes two arguments: “name ”(the name of the logger) and “level” (the level of logging messages to be recorded).
The logging module is imported at the top of the code.
The logger is set to debug level and two handlers are created: console_handler and file_handler. Two different formatters are created for each handler to format the log messages in a specific way.
The console_handler will show the name, level name and message, while the file_handler will show the time, name, level name and message. Both handlers are added to the logger and the logger is returned.
The logger can be used to log messages at various levels, such as —
- Debug
- Info
- Warning
- Error
- Critical
When a log message is sent to the logger, it will be passed to both handlers, and they will output the log message in their respective format to the console and a log file. In this case, the log file is named “file_log.log”.
Next, import the module into the application and log the required outputs.
from logging_util import get_logger
logger = get_logger(__name__)
logger.info("This is the log statement")
This code imports the “get_logger” function from the “logging_util” module.
A logger object is then created by calling the “get_logger” function and passing the argument “name”. This argument is a built-in Python variable that holds the name of the current module (in this case, the name of the module that this code is part of).
The “info” method of the logger object is then called to log a message with the log level “info”. This log statement will be handled by the handlers defined in the “get_logger” function of the “logging_util” module, which will output the log message to the console and/or a log file in a specific format.
That’s all folks!
Happy Coding 💛