September 11, 2024

Logging in Python

Logging is an essential feature in Python that helps track events that happen during the execution of a program. The logging module in Python provides a flexible framework for emitting log messages from Python programs. It is used to report status, error messages, and for debugging purposes. Below is an overview of how to implement logging in Python.

1. Basic Logging

The simplest way to log messages is to use the logging module’s basic configuration.

Example:

import logging

# Basic configuration for logging
logging.basicConfig(level=logging.DEBUG)

# Example 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:

DEBUG:root:This is a debug message
INFO:root:This is an info message
WARNING:root:This is a warning message
ERROR:root:This is an error message
CRITICAL:root:This is a critical message

2. Configuring Logging

The basicConfig() function of the logging module allows you to configure the logging system. You can specify the log level, log file, format, and other options.

Example: Logging to a File

import logging

# Configuring logging to a file
logging.basicConfig(filename='app.log', filemode='w', level=logging.DEBUG,
                    format='%(asctime)s - %(levelname)s - %(message)s')

# Example 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")

In this example, log messages are written to the app.log file. The filemode='w' argument specifies that the file should be overwritten each time the program runs. The format argument customizes the format of the log messages.

3. Log Levels

Logging levels indicate the severity of events. Python’s logging module has the following levels (in increasing order of severity):

  • DEBUG: Detailed information, typically of interest only when diagnosing problems.
  • INFO: Confirmation that things are working as expected.
  • WARNING: An indication that something unexpected happened, or indicative of some problem in the near future (e.g., ‘disk space low’). The software is still working as expected.
  • ERROR: Due to a more serious problem, the software has not been able to perform some function.
  • CRITICAL: A serious error, indicating that the program itself may be unable to continue running.

4. Customizing Log Formats

You can customize the log format to include more details like the time of the log entry, the severity level, the module name, and more.

Example: Custom Log Format

import logging

# Customizing the log format
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

logger = logging.getLogger('MyLogger')

logger.debug("This is a debug message")
logger.info("This is an info message")
logger.warning("This is a warning message")
logger.error("This is an error message")
logger.critical("This is a critical message")

Output:

2024-08-26 12:00:00,000 - MyLogger - DEBUG - This is a debug message
2024-08-26 12:00:00,001 - MyLogger - INFO - This is an info message
2024-08-26 12:00:00,002 - MyLogger - WARNING - This is a warning message
2024-08-26 12:00:00,003 - MyLogger - ERROR - This is an error message
2024-08-26 12:00:00,004 - MyLogger - CRITICAL - This is a critical message

5. Logging Exceptions

You can also log exceptions using the exception() method. This is useful for logging errors and tracebacks when an exception occurs.

Example: Logging an Exception

import logging

# Configuring logging
logging.basicConfig(level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s')

try:
    1 / 0
except ZeroDivisionError:
    logging.exception("Exception occurred")

Output:

2024-08-26 12:00:00,000 - ERROR - Exception occurred
Traceback (most recent call last):
  File "script.py", line 6, in <module>
    1 / 0
ZeroDivisionError: division by zero

6. Rotating Log Files

For long-running applications, you might want to rotate log files to avoid having a single large log file. This can be done using the RotatingFileHandler from the logging.handlers module.

Example: Rotating Log Files

import logging
from logging.handlers import RotatingFileHandler

# Configuring rotating log files
handler = RotatingFileHandler('app.log', maxBytes=2000, backupCount=5)
logger = logging.getLogger('MyLogger')
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)

for i in range(1000):
    logger.debug(f"This is log message number {i}")

In this example, the log file app.log will rotate when it reaches 2000 bytes, keeping up to 5 backup files.