
Photo by Vladyslava Andriyenko on Unsplash
Debugging is an essential part of software development, and efficient tracking of code execution can save developers hours of frustration. Python’s built-in logging module provides a robust way to handle these tasks, offering functionality that ranges from basic logging to advanced tracking systems.
In this comprehensive guide, we will explore Python’s logging module in depth, understand its features, and learn how to implement it effectively to track and debug your code.
What is Logging in Python?
Logging is a way of capturing information about the flow and behavior of your program as it runs. Instead of relying solely on print statements, the logging module allows you to:
Track events in your application.
Record errors and warnings.
Create detailed reports for debugging.
Control the level and format of information output.
The flexibility and customization of the logging module make it an indispensable tool for Python developers.
Why Use Python Logging Instead of Print Statements?
While print statements can be helpful for simple debugging, they lack the sophistication needed for larger projects. Here’s why you should prefer logging:
Levels of Severity: The
loggingmodule categorizes logs into levels like DEBUG, INFO, WARNING, ERROR, and CRITICAL.Configurable Output: You can control the output format and destination, such as the console, files, or external systems.
Performance: Logging can be enabled or disabled at runtime, reducing overhead in production.
Thread Safety: The
loggingmodule is designed to handle multithreaded applications efficiently.
Getting Started with Python Logging
Basic Logging Example
Here’s a quick example to get you started:
import logging
# Configure logging
logging.basicConfig(level=logging.INFO)
# Log messages
logging.debug("This is a debug message")
logging.info("This is an info message")
logging.warning("This is a warning message")
logging.error("This is an error message")
logging.critical("This is a critical message")Output:
This is an info message
This is a warning message
This is an error message
This is a critical messageNotice that the DEBUG message is not displayed because the default logging level is set to INFO. To see all messages, you can change the level to DEBUG.
Understanding Logging Levels
The logging module provides five standard levels of severity:
DEBUG : Detailed information, for diagnosing issues.
INFO : Confirmation that things are working as expected.
WARNING : An indication that something unexpected happened.
ERROR : A more serious problem preventing functionality.
CRITICAL : A critical error causing program termination.
Setting the Logging Level
You can set the logging level during configuration:
logging.basicConfig(level=logging.DEBUG)This ensures that all messages of the specified level and higher are logged.
Customizing Log Messages
The logging module allows you to format log messages for better readability.
Formatting Logs
Use the format parameter in basicConfig to customize log messages:
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s"
)
logging.info("This is an info message")Output:
2025-01-13 14:30:25,123 - INFO - This is an info messageCommon Format Specifiers
%(asctime)s: Timestamp of the log entry.%(levelname)s: Logging level (e.g., INFO, WARNING).%(message)s: The log message.%(name)s: The name of the logger.%(filename)s: The name of the file where the log was called.
Logging to a File
To store logs for future reference, you can log messages to a file instead of the console.
Example: Writing Logs to a File
logging.basicConfig(
filename="app.log",
level=logging.DEBUG,
format="%(asctime)s - %(levelname)s - %(message)s"
)
logging.info("This message will be written to a file")Output (in app.log):
2025-01-13 14:35:50,456 - INFO - This message will be written to a fileThis is useful for applications running in production, as you can review the logs later to debug issues.
Using Loggers, Handlers, and Formatters
For advanced logging requirements, you can use the logging module’s hierarchical system involving loggers, handlers, and formatters.
1. Loggers
A Logger is the entry point for logging. It creates log messages and passes them to handlers.
2. Handlers
Handlers define where the log messages go (e.g., console, file, or external system).
3. Formatters
Formatters specify the layout of log messages.
Example: Advanced Configuration
import logging
# Create logger
logger = logging.getLogger("my_logger")
logger.setLevel(logging.DEBUG)
# Create file handler
file_handler = logging.FileHandler("app.log")
file_handler.setLevel(logging.ERROR)
# Create console handler
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
# Create formatter
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
# Add formatter to handlers
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)
# Add handlers to logger
logger.addHandler(file_handler)
logger.addHandler(console_handler)
# Log messages
logger.debug("Debug message")
logger.error("Error message")Output (Console):
2025-01-13 14:45:00,789 - my_logger - DEBUG - Debug message
2025-01-13 14:45:00,790 - my_logger - ERROR - Error messageOutput (File):
2025-01-13 14:45:00,790 - my_logger - ERROR - Error messageLogging Exceptions
The logging module allows you to log exceptions using the exc_info parameter.
Example: Logging Exceptions
try:
1 / 0
except ZeroDivisionError:
logging.error("An error occurred", exc_info=True)Output:
ERROR:root:An error occurred
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zeroRotating Log Files
For long-running applications, you might want to limit the size of log files. The RotatingFileHandler helps manage log files by rotating them when they reach a certain size.
Example: Rotating Log Files
from logging.handlers import RotatingFileHandler
handler = RotatingFileHandler("app.log", maxBytes=2000, backupCount=5)
logging.basicConfig(handlers=[handler], level=logging.INFO)
for i in range(100):
logging.info(f"Log message {i}")This will create up to 5 backup log files (app.log.1, app.log.2, etc.), each with a maximum size of 2KB.
Best Practices for Python Logging
Set Appropriate Log Levels: Use DEBUG for development and INFO or WARNING for production.
Avoid Hardcoding Configurations: Use configuration files for log settings.
Log Only What’s Necessary: Avoid logging sensitive data.
Use Rotating Logs: Prevent disk space issues by using rotating log handlers.
Document Logs: Ensure logs are readable and provide context for debugging.
Conclusion
The logging module in Python is a powerful tool that enables developers to track, debug, and manage their applications effectively. By using its advanced features like log levels, handlers, and formatters, you can create a robust logging system tailored to your application’s needs.
Whether you’re building a small script or a large-scale application, mastering Python’s logging capabilities will make your development process smoother and more efficient.
Happy coding! 🚀


