Skip to content

verify: log_level=INFO does make a difference — it filters DEBUG logs from - #54

Closed
github-actions[bot] wants to merge 1 commit into
mainfrom
probe/issue-49
Closed

github-actions[bot] wants to merge 1 commit into
mainfrom
probe/issue-49

Conversation

@github-actions

Copy link
Copy Markdown

log_level=INFO does make a difference — it filters DEBUG logs from pytest's captured logs, while without it log_file_level=DEBUG lets DEBUG through

The doc's "Log to a file" section makes two claims. Claim A: setting log_level = "INFO" retains INFO logs in the "Captured log call" section (i.e., DEBUG is filtered out). Claim B: without log_level, that section will have DEBUG logs "coming from log_file_level." The issue also hints at a version angle (claim C): maybe the latest Jubilant behaves differently.

I read pytest's _pytest/logging.py source to understand the mechanism rather than trusting the doc. Here's what actually happens. pytest's LoggingPlugin reads log_level (None if unset) and log_file_level (which falls back to log_level). During the test loop, catching_logs wraps the file handler with level=log_file_level, which calls root_logger.setLevel(min(orig, level)). So log_file_level=DEBUG lowers the root logger to DEBUG regardless of whether log_level is set. Then during each test, catching_logs wraps the caplog handler with level=log_level. If log_level=INFO, the handler is set to INFO and filters out DEBUG records even though the root logger is at DEBUG. If log_level is unset (None), catching_logs skips setting the handler level, so it stays at NOTSET (0) and captures everything the root logger lets through — including DEBUG. Jubilant's jubilant.wait logger just calls logging.getLogger('jubilant.wait') with no level or handler config, so it propagates to root and inherits root's level. The behavior is entirely pytest's, not Jubilant's — the latest Jubilant (1.12.0, which I pinned) doesn't change it.

I believe the doc is correct on both claims. I wrote a differential test to prove it. The identical test runs in kepler and kosmos: it emits a DEBUG log via the jubilant.wait logger and asserts the message appears in caplog.records. kepler's pyproject.toml has log_level = "INFO" alongside log_file_level = "DEBUG" (matching the doc's config); kosmos has only log_file_level = "DEBUG" (no log_level). In kepler, the caplog handler is at INFO so the DEBUG record is filtered out — the assertion fails, and I marked it xfail(strict=True). In kosmos, the handler stays at NOTSET and the root logger is at DEBUG, so the DEBUG record is captured — the assertion passes. The test files are identical except for the xfail decorator.

If CI passes (kepler xfails as expected, kosmos passes), the doc is correct: log_level = "INFO" genuinely makes a difference by filtering DEBUG from captured logs, and without it DEBUG logs do appear because log_file_level lowers the root logger. If kepler's xfail unexpectedly passes (DEBUG captured despite log_level=INFO), the doc is wrong about claim A. If kosmos fails (DEBUG not captured without log_level), the doc is wrong about claim B. Either failure would surface clearly due to strict=True on the xfail.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant