Implementing Source File Name and Line Number Logging in Python

Dec 06, 2025 · Programming · 12 views · 7.8

Keywords: Python | Logging System | Formatter | Source File Tracking | Line Number Recording

Abstract: This paper provides an in-depth exploration of how to log source file names and line numbers in Python's standard logging system. By analyzing the Formatter object and its formatting variables in the logging module, it详细介绍 the usage of key variables such as %(pathname)s, %(filename)s, and %(lineno)d. The article includes complete code examples demonstrating how to configure log formatters to include file path, file name, and line number information, and discusses the practical effects of different configuration approaches. Additionally, it compares basic configuration with advanced custom configuration, helping developers choose the most appropriate logging solution based on their specific needs.

Architecture of Python's Logging System

Python's standard logging module provides a flexible logging mechanism that allows developers to customize log output formats through the configuration of Formatter objects. The Formatter is one of the core components of the logging module, responsible for converting log records into readable string formats. Each Formatter object can define specific format strings containing various placeholder variables that are replaced with actual values during log recording.

Detailed Explanation of Format Variables

In the logging module, Formatter supports multiple format variables for extracting context information about log calls. Variables related to source file location include:

These variables can be referenced in format strings using the %() syntax, and the Formatter automatically populates the corresponding values when generating log messages.

Basic Configuration Method

The logging.basicConfig() function can be used to quickly configure basic settings of the logging system. The following example shows how to configure a log format that includes file name and line number:

import logging

logging.basicConfig(
    format='%(asctime)s,%(msecs)03d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s',
    datefmt='%Y-%m-%d:%H:%M:%S',
    level=logging.DEBUG
)

logger = logging.getLogger(__name__)
logger.debug("This is a debug log")
logger.info("This is an info log")

This configuration will produce output similar to:

2023-10-15:14:30:45,123 DEBUG    [example.py:10] This is a debug log
2023-10-15:14:30:45,123 INFO     [example.py:11] This is an info log

The [example.py:10] portion displays the source file name and line number, which is valuable for debugging and issue tracking.

Advanced Custom Configuration

For more complex application scenarios, custom Formatter objects can be created to achieve finer control. The following example demonstrates how to create a formatter that includes full path and line number:

import logging

# Create Formatter object
formatter = logging.Formatter(
    '[%(asctime)s] p%(process)s {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s',
    '%m-%d %H:%M:%S'
)

# Create handler and set formatter
handler = logging.StreamHandler()
handler.setFormatter(formatter)

# Get logger and add handler
logger = logging.getLogger(__name__)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)

# Log message
logger.debug("Custom formatted debug log")

This configuration approach provides greater flexibility, allowing developers to adjust log formats according to specific requirements. Using the %(pathname)s variable enables retrieval of complete file paths, which is particularly useful in complex project structures for accurately identifying log call locations.

Performance Considerations and Best Practices

While logging file names and line numbers provides valuable debugging information, performance implications should be considered. Each log call requires Python to obtain current stack frame information to extract this data, which may impact performance-sensitive applications. It is recommended to enable detailed logging in development environments and adjust log levels and formats in production environments based on actual needs.

Another best practice is to organize log formats reasonably to avoid information overload. Typically, it is advisable to place file names and line numbers at the beginning or end of log messages, using consistent formats such as [filename:lineno] or {filepath:lineno} to improve log readability.

Integration with Other Log Attributes

File name and line number information can be combined with other log attributes to create richer log contexts. For example, combining with %(funcName)s allows simultaneous recording of function names and line numbers:

formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(funcName)s:%(lineno)d - %(levelname)s - %(message)s'
)

This format is particularly useful in complex codebases for quickly locating the exact position where issues occur.

Conclusion

Python's logging module provides powerful log formatting capabilities through Formatter objects, making it straightforward to log source file names and line numbers. Developers can choose to use variables such as %(filename)s, %(pathname)s, and %(lineno)d according to specific needs to enhance log traceability. Proper log configuration not only aids debugging and problem resolution but also improves code maintainability. It is recommended that developers plan logging strategies early in projects to ensure the logging system provides sufficient information to support development and operations.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.