log_level=INFO filters DEBUG from captured Jubilant logs - #58
Open
github-actions[bot] wants to merge 1 commit into
Open
log_level=INFO filters DEBUG from captured Jubilant logs#58github-actions[bot] wants to merge 1 commit into
github-actions[bot] wants to merge 1 commit into
Conversation
github-actions
Bot
force-pushed
the
probe/issue-57
branch
2 times, most recently
from
August 25, 2026 13:26
beea977 to
1975cde
Compare
log_level = "INFO" make a difference with latest Jubilant?
log_level = "INFO" make a difference with latest Jubilant?
github-actions
Bot
force-pushed
the
probe/issue-57
branch
from
August 25, 2026 22:32
1975cde to
c4e3fa9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Claims
The ops docs' "Log to a file" section shows a sample
pyproject.tomlwith this comment abovelog_level = "INFO":I read two claims in there:
log_level = "INFO"retains INFO logs in the "Captured log call" section (i.e. it filters out DEBUG).log_level = "INFO"(but withlog_file_level = "DEBUG"), the captured section fills up with DEBUG logs that "come from"log_file_level.Issue #57 asks whether this really makes a difference with the latest Jubilant.
What I believe and why
I believe both claims are true, and the mechanism is in pytest's logging plugin rather than Jubilant itself — but the latest Jubilant is what supplies the INFO and DEBUG logs that make the setting meaningful.
From reading
_pytest/logging.py: the file handler is wrapped around the whole test run (pytest_runtestloop) viacatching_logs(self.log_file_handler, level=self.log_file_level). That context manager lowers the root logger tolog_file_level(DEBUG), so DEBUG records start propagating. The per-test capture handler (caplog) is wrapped separately withcatching_logs(self.caplog_handler, level=self.log_level):log_level = "INFO": the capture handler is set to INFO, so it stores INFO+ and drops DEBUG — even though the root logger is at DEBUG. That is claim A.log_level(it resolves toNone): the capture handler is left at NOTSET (captures everything), and since the root logger was already lowered to DEBUG by the file handler, DEBUG records get captured. That is claim B — the DEBUG logs "come from"log_file_levelbecauselog_file_levelis what lowered the root logger.The Jubilant side: Jubilant 1.12.0 (the latest, "Improved Jubilant logging", PR #351) changed
juju.wait()so that app/unit status changes are logged at INFO (_log_short_status_if_needed) and the verbose gron diff is logged at DEBUG (logger_wait.debug('wait: status changed: ...')). So on the first poll ofjuju.wait()there is always at least one INFO record and one DEBUG record on thejubilant.waitlogger. That is exactly the INFO/DEBUG split thatlog_level = "INFO"acts on. I pinnedjubilant==1.12.0in both charms.What the PR tests
I used differential testing across the two k- charms (kepler + kosmos), which are structurally identical. Both have
log_file_level = "DEBUG"andjubilant==1.12.0. They differ only inlog_level:log_level = "INFO"(matches the doc sample).log_level(so the capture handler stays at NOTSET and DEBUG leaks in).Both get the identical integration test
test_log_level_filters_debug_from_captured_logs, which runsjuju.wait(jubilant.all_active), filterscaplog.recordsto thejubilant.waitlogger, and asserts:The kosmos copy is marked
@pytest.mark.xfail(strict=True). The test bodies are identical modulo that marker.What the CI result means
log_level = "INFO"does make a difference with the latest Jubilant — it keeps Jubilant's INFO status-change logs in the captured section and filters out the DEBUG gron-diff logs, and without it the DEBUG logs leak in vialog_file_level.log_level = "INFO", or no INFO is captured): the doc is refuted.