Skip to content

Commit 8acdefe

Browse files
committed
šŸ› Disable propagation for aiida logger (#7319)
Set `propagate` to `False` for the top-level `aiida` logger. This prevents AiiDA log records from bubbling up to the root logger and being emitted twice when third-party code, such as circus, installs its own root handler. Add an autouse test fixture that forwards `aiida` and `verdi` log records to pytest's `caplog` handler even when the production logging configuration disables propagation. This keeps the existing logging assertions working after setting the top-level `aiida` logger to `propagate = False`. The issue #7339 to solve hotfix properly has been created. Reviewed-by: Julian Geiger <julian.geiger@psi.ch>
1 parent fbb209a commit 8acdefe

2 files changed

Lines changed: 47 additions & 1 deletion

File tree

ā€Žsrc/aiida/common/log.pyā€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def get_logging_config() -> dict[str, t.Any]:
9696
'aiida': {
9797
'handlers': ['console'],
9898
'level': lambda: get_config_option('logging.aiida_loglevel'),
99-
'propagate': True,
99+
'propagate': False,
100100
},
101101
'verdi': {
102102
'handlers': ['cli'],

ā€Žtests/conftest.pyā€Ž

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import copy
1818
import dataclasses
19+
import logging
1920
import os
2021
import pathlib
2122
import subprocess
@@ -118,6 +119,51 @@ def pytest_addoption(parser):
118119
)
119120

120121

122+
@pytest.fixture(autouse=True)
123+
def capture_aiida_and_verdi_logs(request, monkeypatch):
124+
"""Forward AiiDA and verdi log records to ``caplog`` despite ``propagate=False``.
125+
126+
The production logging configuration disables propagation for the top-level ``aiida`` and ``verdi`` loggers.
127+
For tests that use ``caplog``, attach the pytest log capture handler directly to those loggers and re-attach it
128+
after any logging reconfiguration so existing ``caplog``-based assertions keep observing their records.
129+
"""
130+
if 'caplog' not in request.fixturenames:
131+
yield
132+
return
133+
134+
from aiida.common import log as common_log
135+
136+
caplog = request.getfixturevalue('caplog')
137+
138+
def attach_handler() -> None:
139+
for logger_name in ('aiida', 'verdi'):
140+
logger = logging.getLogger(logger_name)
141+
if caplog.handler not in logger.handlers:
142+
logger.addHandler(caplog.handler)
143+
144+
original_configure_logging = common_log.configure_logging
145+
146+
def configure_logging(*args, **kwargs):
147+
result = original_configure_logging(*args, **kwargs)
148+
attach_handler()
149+
return result
150+
151+
monkeypatch.setattr(common_log, 'configure_logging', configure_logging)
152+
monkeypatch.setattr('aiida.configure_logging', configure_logging, raising=False)
153+
monkeypatch.setattr('aiida.engine.daemon.worker.configure_logging', configure_logging, raising=False)
154+
monkeypatch.setattr('aiida.cmdline.params.options.main.configure_logging', configure_logging, raising=False)
155+
156+
attach_handler()
157+
158+
try:
159+
yield
160+
finally:
161+
for logger_name in ('aiida', 'verdi'):
162+
logger = logging.getLogger(logger_name)
163+
if caplog.handler in logger.handlers:
164+
logger.removeHandler(caplog.handler)
165+
166+
121167
@pytest.fixture(scope='session')
122168
def aiida_profile(pytestconfig, aiida_config, aiida_profile_factory, config_psql_dos, config_sqlite_dos):
123169
"""Create and load a profile with ``core.psql_dos`` as a storage backend and RabbitMQ as the broker.

0 commit comments

Comments
Ā (0)
⚔