Python Standard Library logging module
The `logging` module is a robust and flexible event logging system for Python applications and libraries, integrated into the Python Standard Library since version 2.3. It enables all Python modules to participate in logging, facilitating the integration of messages from applications and third-party modules into a unified log. The module provides extensive functionality to produce structured log messages and direct them to various destinations such as the console, files, or network sockets.
Warnings
- breaking Installing `pip install logging` (PyPI package version 0.4.9.6) can conflict with the standard library `logging` module in modern Python environments (Python 2.3+). This legacy PyPI package was intended for very old Python versions (< 2.3) and can break tools like Pipenv if incorrectly installed.
- gotcha If `logging.basicConfig()` is not called, the default log level for the root logger is `WARNING`. This means `DEBUG` and `INFO` messages will be silently ignored and not appear in output unless the logger's level is explicitly set lower.
- gotcha Using global functions like `logging.debug()` directly operates on the *root logger*. For structured applications, it's recommended to create and configure named loggers using `logging.getLogger(__name__)` for better modularity and control. Libraries should never configure the root logger directly.
- gotcha Libraries should generally avoid adding handlers to their loggers other than `logging.NullHandler`. This allows the application using the library to fully control where and how the library's logs are processed, preventing unexpected output or conflicts with the application's logging configuration.
- gotcha Logging from asynchronous code using blocking network or file handlers can stall the event loop, impacting performance. Standard `StreamHandler` or `FileHandler` can be blocking operations.
- gotcha Log formatters can be vulnerable to log injection if raw newlines or other control characters within log messages are not properly handled (e.g., quoted or sanitized). This can lead to misinterpretation of logs by parsers or security tools.
Imports
- logging
import logging
- getLogger
from logging import getLogger
- basicConfig
from logging import basicConfig
Quickstart
import logging
import os
# Basic configuration for quick scripts (logs to console, INFO level and above)
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
# Recommended for applications: get a named logger
logger = logging.getLogger(__name__)
# Configure a file handler for a more complex setup
log_file_path = os.environ.get('LOG_FILE', 'application.log')
file_handler = logging.FileHandler(log_file_path)
file_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
# Prevent messages from propagating to the root logger handlers (often console) if file is primary
logger.propagate = False
# Example log messages
logger.debug('This is a debug message - will only go to file handler.')
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!', exc_info=True)
print(f"\nCheck '{log_file_path}' for detailed logs.")