Logging Capture and Formatting
Purpose
This subtopic addresses the need to **capture, control, and format logging output** generated during test execution. While the broader parent topic covers capturing all output streams (stdout, stderr, and logs), this subtopic specifically focuses on managing log messages emitted by Python’s `logging` module. It provides features to:
Intercept log records during tests.
Control log levels dynamically.
Format logs with timestamps, colors, and indentation.
Enable live log streaming to the terminal.
Write logs to files with configurable formats and levels.
Facilitate detailed log inspection in test reports.
This allows tests to assert on log content, helps developers debug by viewing logs live or in reports, and integrates logging output seamlessly with pytest’s test lifecycle.
Functionality
Core Components
LogCaptureHandler: A specialized logging handler that stores all emitted log records and their formatted output in memory, enabling later access and assertions.
LogCaptureFixture (
caplog): A pytest fixture interface providing convenient methods to access captured logs:caplog.records: Raw LogRecord objects.caplog.text: Formatted log output as a string.caplog.messages: Interpolated log messages without formatting.caplog.record_tuples: Simplified tuples for easy assertions.Methods to clear captured logs and set logger levels during tests.
LoggingPlugin: The central pytest plugin managing log capturing lifecycle. It:
Configures formatters and handlers based on CLI options and ini settings.
Registers handlers for capturing logs during test phases (
setup,call,teardown).Supports writing logs to files with configurable format and encoding.
Enables live logging to terminal with colored and indented output.
Hooks into pytest’s test lifecycle events to start and stop capturing.
Log Formatting
DatetimeFormatter: Extends standard logging formatter to support microsecond-precise timestamps using
datetime.strftime.ColoredLevelFormatter: Wraps log level names (e.g., ERROR, INFO) in ANSI color codes to enhance terminal readability when colors are enabled.
PercentStyleMultiline: Custom formatting style that handles multi-line log messages by optionally auto-indenting subsequent lines for cleaner output.
Dynamic Log Level Control
Through the `caplog` fixture, tests can dynamically adjust logger levels to capture or suppress messages:
caplog.set_level("INFO", logger="my.module")
with caplog.at_level("DEBUG"):
# code producing debug logs here
This facility restores original logger levels after test completion, ensuring no side effects leak between tests.
Live Logging to Terminal
The plugin supports "live logging," streaming logs to the terminal in real-time during test execution. This is handled by `_LiveLoggingStreamHandler`, which writes log messages with appropriate section headers and spacing, while temporarily disabling stdout/stderr capturing to avoid interference.
Log File Output
When configured, logs can be written to a file with separate format and level settings, enabling persistent log storage for test runs.
Relationship
This subtopic tightly integrates with its parent topic, **Output and Log Capture**, by specializing in the logging portion of output capturing. It complements the stdout/stderr capture subtopic by focusing on the structured log records and their formatting rather than raw byte streams.
Works alongside the CaptureManager from the parent topic to coordinate when logging output is intercepted or passed through.
Supports pytest’s test execution and reporting by adding captured logs as sections in test reports, enabling post-mortem log inspection.
Interacts with pytest’s configuration system to provide CLI options and ini settings controlling logging behavior.
Enhances the plugin system by registering itself as a plugin and providing hooks for extending or customizing log capture.
The logging capture and formatting subtopic introduces advanced formatting features (color, timestamp precision, multi-line indentation) and dynamic logger level control, which are not covered by the more general output capturing mechanisms.
Code Snippets Illustrating Key Interactions
Accessing Captured Logs in Tests
def test_logging_example(caplog):
logger = logging.getLogger("myapp")
logger.info("Starting")
logger.error("An error occurred")
assert ("myapp", logging.INFO, "Starting") in caplog.record_tuples
assert "An error occurred" in caplog.text
Setting Logger Level Temporarily
with caplog.at_level("DEBUG"):
logging.getLogger("myapp").debug("Debug message")
assert "Debug message" in caplog.text
LoggingPlugin Setup of Handlers and Formatters
self.caplog_handler = LogCaptureHandler()
self.caplog_handler.setFormatter(self.formatter)
self.log_file_handler = _FileHandler(log_file, mode=self.log_file_mode, encoding="UTF-8")
self.log_file_handler.setFormatter(file_formatter)
if self._log_cli_enabled():
self.log_cli_handler = _LiveLoggingStreamHandler(terminal_reporter, capture_manager)
else:
self.log_cli_handler = _LiveLoggingNullHandler()
Diagram: Log Capturing and Reporting Flow
sequenceDiagram
participant Test as Test Code
participant Logger as Python Logger
participant LogHandler as LogCaptureHandler
participant Caplog as caplog Fixture
participant Plugin as LoggingPlugin
participant Report as Test Report
Test->>Logger: Emit log record
Logger->>LogHandler: Handle log record (store & format)
LogHandler->>Caplog: Store record & formatted text
Note right of Caplog: Provides access via attributes and methods
Plugin->>LogHandler: Add/Remove handler during test phases
Test->>Plugin: pytest hooks trigger capturing setup/teardown
Plugin->>Report: Add log sections (setup, call, teardown)
Report->>User: Display logs in test report
This flowchart visualizes how log messages emitted during tests are intercepted by handlers registered by the plugin, stored and formatted, accessed via the `caplog` fixture, and attached to test reports for user inspection.
This logging capture and formatting feature ensures pytest users can flexibly control and inspect logging output in their tests with rich formatting and integration into the test lifecycle, enhancing test diagnostics and developer productivity.