Customizing Logging in Python with Practical Examples

The logging module in Python's standard library offers comprehensive logging capabilities, enabling developers to manage log generation and output through loggers, handlers, and formatters. Key components include:

  • Logger: The primary entry point for logging operations, typically created per module or subsystem using logging.getLogger(name).
  • Handler: Directs log records to destinations like consoles or files, implemented via classses such as logging.StreamHandler.
  • Formatter: Defines the appearance of log messages, customizable with format strings or the logging.Formatter class.
  • Log Level: Indicates message severity, ordered from low to high: DEBUG, INFO, WARNING, ERROR, CRITICAL. Loggers and handlers filter messages based on set levels.
import logging

# Initialize a logger
logger = logging.getLogger('app_logger')
logger.setLevel(logging.DEBUG)

# Configure a console handler
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)

# Define a formatter
log_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
formatter = logging.Formatter(log_format)
console_handler.setFormatter(formatter)

# Attach handler to logger
logger.addHandler(console_handler)

# Log messages
logger.debug('Debug message')
logger.info('Informational message')
logger.warning('Warning message')
logger.error('Error message')
logger.critical('Critical message')

If the logger's level is set to WARNING, only messages of WARNING or higher severity are processed.

Custom loggers extend functionality to meet specific project needs, such as tailored formats, multiple output targets, adjustable levels, and enhanced features like log rotation. Below is an example using the loguru libray for a custom logger with file output and rotation.

from datetime import datetime
from os import path
from sys import stdout
from loguru import logger

class CustomLogger:
    def __init__(self, log_name, level='INFO'):
        logger.remove()
        fmt = '<level>{time:YYYY-MM-DD HH:mm:ss} | {module}: {level} >> {message}</level>'
        logger.add(stdout, format=fmt)
        self.logger = logger
        today = datetime.today().strftime('%Y_%m_%d')
        log_path = f'{log_name}{today}.log'
        self.name = path.basename(log_path)
        self.logger.add(
            log_path,
            encoding='utf-8',
            retention='7 days',
            rotation='50 MB',
            compression='zip',
            format=fmt,
            enqueue=True,
            level=level
        )

    def info(self, content):
        self.logger.opt(depth=1).info(content)

    def debug(self, content):
        self.logger.opt(depth=1).debug(content)

    def error(self, content, *args, **kwargs):
        self.logger.opt(depth=1).error(content)
        if args or kwargs:
            self.exception('Error details:', *args, **kwargs)

    def exception(self, content, *args, **kwargs):
        self.logger.opt(depth=1).exception(content, *args, **kwargs)

    def warning(self, content):
        self.logger.opt(depth=1).warning(content)

# Usage example
app_logger = CustomLogger('app_log')
app_logger.info('Informational message')
app_logger.debug('Debug message')
app_logger.error('Error message')
app_logger.warning('Warning message')
app_logger.error('Error occurred.', 'Additional info', param='value')
try:
    result = 1 / 0
except Exception as e:
    app_logger.exception('Calculation error occurred.')

Tags: python logging custom-logger Loguru software-development

Posted on Mon, 12 Oct 2026 16:00:09 +0000 by ReVeR