Table of Contents

    Logging Module

    CHAPTER 30.1 · LOGGING AND CONFIGURATION

    Logging Module in Python

    Learn how to record application events, errors, warnings, and diagnostic information using Python's built-in logging module.

    During application development, programmers need to understand what the application is doing, where an error occurred, and which operations completed successfully.

    Python provides the built-in logging module for recording application events. It supports severity levels, formatted messages, console output, file output, named loggers, handlers, and exception information.

    Learning objective: Learn how to create log messages, configure log levels, include variables, format output, record exceptions, and create module-specific loggers.

    Prerequisites

    What You Should Know

    • Python variables and data types
    • Functions and modules
    • Import statements
    • Exception handling with try and except
    • Basic file and application concepts
    • String formatting

    What is Logging?

    Logging is the process of recording information about events that occur while an application is running.

    A log record may contain a message, severity level, timestamp, logger name, module name, function name, or exception details.

    Think of logging as an application diary

    The application records important events as they happen. Developers can later review those records to understand application behavior and investigate failures.

    Import the Logging Module

    The logging module is part of Python's standard library.

    import logging
    No additional package installation is required for Python's standard logging module.

    Create Your First Log Message

    import logging
    
    
    logging.warning(
        "The application is using a default configuration."
    )

    Possible output:

    WARNING:root:The application is using a default configuration.

    The output identifies the severity level, logger name, and log message.

    Logging Levels

    Logging levels classify records according to their importance or severity.

    Level Typical Purpose
    DEBUG Detailed diagnostic information used during development or investigation.
    INFO Confirmation that an expected operation occurred.
    WARNING An unexpected situation occurred, but processing may continue.
    ERROR An operation failed or could not be completed.
    CRITICAL A severe failure may prevent continued operation.

    Record Different Log Levels

    import logging
    
    
    logging.debug(
        "Preparing diagnostic data."
    )
    
    logging.info(
        "Application started successfully."
    )
    
    logging.warning(
        "The configuration file was not found."
    )
    
    logging.error(
        "The customer record could not be saved."
    )
    
    logging.critical(
        "The application cannot continue."
    )
    Without additional configuration, lower-severity messages such as DEBUG and INFO may not be displayed.

    Configure Logging with basicConfig()

    Use logging.basicConfig() to define introductory logging settings.

    import logging
    
    
    logging.basicConfig(
        level=logging.INFO
    )
    
    logging.debug(
        "Debug message"
    )
    
    logging.info(
        "Application started"
    )
    
    logging.warning(
        "Configuration is incomplete"
    )

    Possible output:

    INFO:root:Application started
    WARNING:root:Configuration is incomplete

    The configured level allows INFO and higher-severity records to be processed.

    Format Log Messages

    import logging
    
    
    logging.basicConfig(
        level=logging.INFO,
        format=(
            "%(asctime)s | "
            "%(levelname)s | "
            "%(name)s | "
            "%(message)s"
        )
    )
    
    logging.info(
        "Application started."
    )

    Possible output:

    2026-08-08 10:30:15,125 | INFO | root | Application started.

    Common Formatting Fields

    Field Information
    %(asctime)s Time when the log record was created.
    %(levelname)s Severity level of the record.
    %(name)s Name of the logger.
    %(module)s Module that created the record.
    %(funcName)s Function that created the record.
    %(lineno)d Source-code line number.
    %(message)s Final formatted log message.

    Include Variables in Log Messages

    import logging
    
    
    logging.basicConfig(
        level=logging.INFO,
        format=(
            "%(levelname)s | "
            "%(message)s"
        )
    )
    
    customer_id = "CUST-101"
    order_total = 2500
    
    logging.info(
        "Order processed for customer %s with total %s",
        customer_id,
        order_total
    )

    Possible output:

    INFO | Order processed for customer CUST-101 with total 2500
    Passing message arguments separately allows the logging system to perform message interpolation when the record is processed.

    Create a Named Logger

    Application modules commonly create a logger using the module name.

    import logging
    
    
    logger = logging.getLogger(
        __name__
    )
    
    logger.warning(
        "A named logger created this message."
    )

    The __name__ value identifies the module that created the logger.

    Use Logging Inside a Function

    import logging
    
    
    logging.basicConfig(
        level=logging.INFO,
        format=(
            "%(levelname)s | "
            "%(name)s | "
            "%(message)s"
        )
    )
    
    logger = logging.getLogger(
        __name__
    )
    
    
    def process_order(order_number):
        logger.info(
            "Processing order %s",
            order_number
        )
    
        logger.info(
            "Order %s processed successfully",
            order_number
        )
    
    
    process_order(
        "ORD-101"
    )

    Record Exception Information

    Use logger.exception() inside an exception handler when traceback information should be included.

    import logging
    
    
    logging.basicConfig(
        level=logging.ERROR
    )
    
    logger = logging.getLogger(
        __name__
    )
    
    try:
        result = 100 / 0
    
    except ZeroDivisionError:
        logger.exception(
            "The calculation failed."
        )

    The generated record includes the message and exception traceback.

    Avoid Do not record passwords, authentication tokens, private keys, complete payment details, or other confidential values in logs.

    Create a Console Handler

    A handler determines where matching log records are sent.

    import logging
    
    
    logger = logging.getLogger(
        "application"
    )
    
    logger.setLevel(
        logging.DEBUG
    )
    
    console_handler = logging.StreamHandler()
    
    console_handler.setLevel(
        logging.INFO
    )
    
    formatter = logging.Formatter(
        "%(levelname)s | %(name)s | %(message)s"
    )
    
    console_handler.setFormatter(
        formatter
    )
    
    logger.addHandler(
        console_handler
    )
    
    logger.debug(
        "Diagnostic message"
    )
    
    logger.info(
        "Application is ready"
    )

    Possible output:

    INFO | application | Application is ready

    Core Logging Components

    Component Responsibility
    Logger Creates log records for an application or module.
    Handler Sends records to a destination.
    Formatter Defines the displayed structure of a log record.
    Filter Applies additional rules to record processing.
    Log Record Contains the information associated with one event.

    print() vs Logging

    print()

    • Useful for simple visible output
    • Does not provide severity levels
    • Requires manual formatting
    • Difficult to control across large applications

    Logging

    • Provides severity levels
    • Supports structured formatting
    • Supports multiple output destinations
    • Can be configured for application modules

    Practical Example: Order Processing

    import logging
    
    
    logging.basicConfig(
        level=logging.INFO,
        format=(
            "%(asctime)s | "
            "%(levelname)s | "
            "%(message)s"
        )
    )
    
    logger = logging.getLogger(
        __name__
    )
    
    
    def process_order(order):
        order_number = order.get(
            "order_number"
        )
    
        amount = order.get(
            "amount",
            0
        )
    
        logger.info(
            "Processing order %s",
            order_number
        )
    
        if amount <= 0:
            logger.error(
                "Order %s has an invalid amount",
                order_number
            )
    
            return False
    
        logger.info(
            "Order %s processed successfully",
            order_number
        )
    
        return True
    
    
    order = {
        "order_number": "ORD-101",
        "amount": 2500
    }
    
    process_order(order)

    Common Mistakes

    1

    Using the Wrong Log Level

    Recording ordinary events as errors makes important failures harder to identify.

    Solution Select the level according to the meaning and severity of the event.
    2

    Configuring Logging Repeatedly

    Repeated configuration can produce confusing or duplicate behavior.

    Solution Configure application logging in one clear initialization location.
    3

    Adding the Same Handler More Than Once

    Multiple identical handlers can cause duplicate output.

    Solution Ensure application initialization does not repeatedly attach the same handler.
    4

    Logging Sensitive Information

    Logs may be stored, monitored, shared, or retained.

    Solution Record only the information required for diagnostics, operations, or approved audit requirements.

    Logging Best Practices

    Recommended Practices

    • Use a named logger for application modules.
    • Select a log level that matches the event.
    • Include enough context to identify the affected operation.
    • Use consistent formatting throughout the application.
    • Record exceptions with traceback information when useful.
    • Avoid recording passwords, tokens, secrets, or confidential business data.
    • Do not use logging as the only mechanism for user-visible error communication.
    • Follow organizational logging, retention, privacy, and security requirements.

    Knowledge Check

    1

    Is logging part of the standard library?

    Yes. It can be imported using import logging.

    2

    Which level contains detailed diagnostics?

    The DEBUG level is used for detailed diagnostic information.

    3

    How do you create a module logger?

    logger = logging.getLogger(
        __name__
    )
    4

    How do you record an exception traceback?

    try:
        perform_operation()
    
    except Exception:
        logger.exception(
            "The operation failed."
        )

    Logging Quick Reference

    import logging
    
    
    # Configure basic logging
    logging.basicConfig(
        level=logging.INFO,
        format=(
            "%(asctime)s | "
            "%(levelname)s | "
            "%(name)s | "
            "%(message)s"
        )
    )
    
    # Create a module logger
    logger = logging.getLogger(
        __name__
    )
    
    # Record messages
    logger.debug(
        "Diagnostic details"
    )
    
    logger.info(
        "Operation completed"
    )
    
    logger.warning(
        "Unexpected condition"
    )
    
    logger.error(
        "Operation failed"
    )
    
    logger.critical(
        "Application cannot continue"
    )

    Summary

    What You Learned

    • Python provides logging through its standard library.
    • Log levels classify records according to severity.
    • basicConfig() provides introductory configuration.
    • Formatters control the structure of displayed records.
    • Named loggers identify application modules.
    • Handlers determine where log records are sent.
    • logger.exception() records exception information.
    • Sensitive information should not be written to logs.

    Key Takeaway

    Use Python's logging module to record application events with appropriate severity levels, consistent context, and controlled formatting. Create named loggers for modules and never place secrets or unnecessary sensitive information in log messages.