Skip to content

Commit

Permalink
Fix catch_logs behaviour for 3rd-party modules
Browse files Browse the repository at this point in the history
catch_logs was supposed to ignore warnings not coming from brian2, but
it included messages from loggers whose names *start* with "brian2",
including "brian2cuda"…
  • Loading branch information
mstimberg committed Mar 20, 2024
1 parent 03225b2 commit 0583e5e
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 2 deletions.
65 changes: 64 additions & 1 deletion brian2/tests/test_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pytest

from brian2.core.preferences import prefs
from brian2.utils.logger import BrianLogger, get_logger
from brian2.utils.logger import BrianLogger, catch_logs, get_logger

logger = get_logger("brian2.tests.test_logger")

Expand Down Expand Up @@ -95,6 +95,69 @@ def test_file_logging_multiprocessing_with_loggers():
prefs.logging.delete_log_on_exit = True


@pytest.mark.codegen_independent
def test_submodule_logging():
submodule_logger = get_logger("submodule.dummy")
BrianLogger.initialize()
submodule_logger.error("error message xxx")
submodule_logger.warn("warning message xxx")
submodule_logger.info("info message xxx")
submodule_logger.debug("debug message xxx")
submodule_logger.diagnostic("diagnostic message xxx")
BrianLogger.file_handler.flush()
# By default, only >= debug messages should show up
assert os.path.isfile(BrianLogger.tmp_log)
with open(BrianLogger.tmp_log, encoding="utf-8") as f:
log_content = f.readlines()
for level, line in zip(["error", "warning", "info", "debug"], log_content[-4:]):
assert "submodule.dummy" in line
# The logger name has brian2 internally prefixed, but this shouldn't show up in logs
assert not "brian2.submodule.dummy" in line
assert f"{level} message xxx" in line
assert level.upper() in line

with catch_logs() as l:
logger.warn("warning message from Brian")
submodule_logger.warn("warning message from submodule")
# only the warning from Brian should be logged
assert len(l) == 1
assert "warning message from Brian" in l[0]

with catch_logs(only_from=("submodule",)) as l:
logger.warn("warning message from Brian")
submodule_logger.warn("warning message from submodule")
# only the warning from submodule should be logged
assert len(l) == 1
assert "warning message from submodule" in l[0]

# Make sure that a submodule with a name starting with "brian2" gets handled correctly
submodule_logger = get_logger("brian2submodule.dummy")
BrianLogger.initialize()
submodule_logger.error("error message xxx")
submodule_logger.warn("warning message xxx")
submodule_logger.info("info message xxx")
submodule_logger.debug("debug message xxx")
submodule_logger.diagnostic("diagnostic message xxx")
BrianLogger.file_handler.flush()
# By default, only >= debug messages should show up
assert os.path.isfile(BrianLogger.tmp_log)
with open(BrianLogger.tmp_log, encoding="utf-8") as f:
log_content = f.readlines()
for level, line in zip(["error", "warning", "info", "debug"], log_content[-4:]):
assert "submodule.dummy" in line
# The logger name has brian2 internally prefixed, but this shouldn't show up in logs
assert not "brian2.submodule.dummy" in line
assert f"{level} message xxx" in line
assert level.upper() in line

with catch_logs() as l:
logger.warn("warning message from Brian")
submodule_logger.warn("warning message from submodule")
# only the warning from Brian should be logged
assert len(l) == 1
assert "warning message from Brian" in l[0]


if __name__ == "__main__":
test_file_logging()
test_file_logging_special_characters()
Expand Down
5 changes: 4 additions & 1 deletion brian2/utils/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,10 @@ def __init__(self, log_list, log_level=logging.WARN, only_from=("brian2",)):
def emit(self, record):
# Append a tuple consisting of (level, name, msg) to the list of
# warnings
if any(record.name.startswith(name) for name in self.only_from):
if any(
record.name == self.only_from or record.name.startswith(name + ".")
for name in self.only_from
):
self.log_list.append((record.levelname, record.name, record.msg))

def install(self):
Expand Down

0 comments on commit 0583e5e

Please sign in to comment.