mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Allow excluding modules from noisy logs check (#142020)
* Allow excluding modules from noisy logs check * Cache non-excluded modules; hardcode self module name; optimize call * Address review comments
This commit is contained in:
parent
2396fd1090
commit
b38c647830
@ -29,16 +29,22 @@ class HomeAssistantQueueListener(logging.handlers.QueueListener):
|
||||
LOG_COUNTS_RESET_INTERVAL = 300
|
||||
MAX_LOGS_COUNT = 200
|
||||
|
||||
EXCLUDED_LOG_COUNT_MODULES = [
|
||||
"homeassistant.components.automation",
|
||||
"homeassistant.components.script",
|
||||
"homeassistant.setup",
|
||||
"homeassistant.util.logging",
|
||||
]
|
||||
|
||||
_last_reset: float
|
||||
_log_counts: dict[str, int]
|
||||
_warned_modules: set[str]
|
||||
|
||||
def __init__(
|
||||
self, queue: SimpleQueue[logging.Handler], *handlers: logging.Handler
|
||||
) -> None:
|
||||
"""Initialize the handler."""
|
||||
super().__init__(queue, *handlers)
|
||||
self._warned_modules = set()
|
||||
self._module_log_count_skip_flags: dict[str, bool] = {}
|
||||
self._reset_counters(time.time())
|
||||
|
||||
@override
|
||||
@ -53,7 +59,11 @@ class HomeAssistantQueueListener(logging.handlers.QueueListener):
|
||||
self._reset_counters(record.created)
|
||||
|
||||
module_name = record.name
|
||||
if module_name == __name__ or module_name in self._warned_modules:
|
||||
|
||||
if skip_flag := self._module_log_count_skip_flags.get(module_name):
|
||||
return
|
||||
|
||||
if skip_flag is None and self._update_skip_flags(module_name):
|
||||
return
|
||||
|
||||
self._log_counts[module_name] += 1
|
||||
@ -66,13 +76,20 @@ class HomeAssistantQueueListener(logging.handlers.QueueListener):
|
||||
module_name,
|
||||
module_count,
|
||||
)
|
||||
self._warned_modules.add(module_name)
|
||||
self._module_log_count_skip_flags[module_name] = True
|
||||
|
||||
def _reset_counters(self, time_sec: float) -> None:
|
||||
_LOGGER.debug("Resetting log counters")
|
||||
self._last_reset = time_sec
|
||||
self._log_counts = defaultdict(int)
|
||||
|
||||
def _update_skip_flags(self, module_name: str) -> bool:
|
||||
excluded = any(
|
||||
module_name.startswith(prefix) for prefix in self.EXCLUDED_LOG_COUNT_MODULES
|
||||
)
|
||||
self._module_log_count_skip_flags[module_name] = excluded
|
||||
return excluded
|
||||
|
||||
|
||||
class HomeAssistantQueueHandler(logging.handlers.QueueHandler):
|
||||
"""Process the log in another thread."""
|
||||
|
@ -160,6 +160,10 @@ async def test_catch_log_exception_catches_and_logs() -> None:
|
||||
|
||||
|
||||
@patch("homeassistant.util.logging.HomeAssistantQueueListener.MAX_LOGS_COUNT", 5)
|
||||
@patch(
|
||||
"homeassistant.util.logging.HomeAssistantQueueListener.EXCLUDED_LOG_COUNT_MODULES",
|
||||
["excluded"],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
(
|
||||
"logger1_count",
|
||||
@ -182,6 +186,7 @@ async def test_noisy_loggers(
|
||||
logging_util.async_activate_log_queue_handler(hass)
|
||||
logger1 = logging.getLogger("noisy1")
|
||||
logger2 = logging.getLogger("noisy2.module")
|
||||
logger_excluded = logging.getLogger("excluded.module")
|
||||
|
||||
for _ in range(logger1_count):
|
||||
logger1.info("This is a log")
|
||||
@ -189,6 +194,9 @@ async def test_noisy_loggers(
|
||||
for _ in range(logger2_count):
|
||||
logger2.info("This is another log")
|
||||
|
||||
for _ in range(logging_util.HomeAssistantQueueListener.MAX_LOGS_COUNT + 1):
|
||||
logger_excluded.info("This log should not trigger a warning")
|
||||
|
||||
await empty_log_queue()
|
||||
|
||||
assert (
|
||||
@ -203,6 +211,33 @@ async def test_noisy_loggers(
|
||||
)
|
||||
== logger2_expected_notices
|
||||
)
|
||||
# Ensure that the excluded module did not trigger a warning
|
||||
assert (
|
||||
caplog.text.count("is logging too frequently")
|
||||
== logger1_expected_notices + logger2_expected_notices
|
||||
)
|
||||
|
||||
# close the handler so the queue thread stops
|
||||
logging.root.handlers[0].close()
|
||||
|
||||
|
||||
@patch("homeassistant.util.logging.HomeAssistantQueueListener.MAX_LOGS_COUNT", 1)
|
||||
async def test_noisy_loggers_ignores_self(
|
||||
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""Test that the noisy loggers warning does not trigger a warning for its own module."""
|
||||
|
||||
logging_util.async_activate_log_queue_handler(hass)
|
||||
logger1 = logging.getLogger("noisy_module1")
|
||||
logger2 = logging.getLogger("noisy_module2")
|
||||
logger3 = logging.getLogger("noisy_module3")
|
||||
|
||||
logger1.info("This is a log")
|
||||
logger2.info("This is a log")
|
||||
logger3.info("This is a log")
|
||||
|
||||
await empty_log_queue()
|
||||
assert caplog.text.count("logging too frequently") == 3
|
||||
|
||||
# close the handler so the queue thread stops
|
||||
logging.root.handlers[0].close()
|
||||
|
Loading…
x
Reference in New Issue
Block a user