Avoid useless stat() syscalls for every logger record (#114987)

* Avoid useless stat() syscalls for every logger record

shouldRollover will always return False since we do
not use maxBytes as we are only using RotatingFileHandler
for the backupCount option. Since every log record will
stat the log file to see if it exists and if its a normal
file, we can override the shouldRollover to reduce the
logging overhead quite a bit

1d3225ae05/Lib/logging/handlers.py (L189)

* assert False is False
This commit is contained in:
J. Nick Koston 2024-04-05 16:00:09 -10:00 committed by GitHub
parent 00db97a765
commit bf5cf382dc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 1 deletions

View File

@ -574,7 +574,7 @@ def async_enable_logging(
err_log_path, when="midnight", backupCount=log_rotate_days
)
else:
err_handler = logging.handlers.RotatingFileHandler(
err_handler = _RotatingFileHandlerWithoutShouldRollOver(
err_log_path, backupCount=1
)
@ -598,6 +598,19 @@ def async_enable_logging(
async_activate_log_queue_handler(hass)
class _RotatingFileHandlerWithoutShouldRollOver(logging.handlers.RotatingFileHandler):
"""RotatingFileHandler that does not check if it should roll over on every log."""
def shouldRollover(self, record: logging.LogRecord) -> bool:
"""Never roll over.
The shouldRollover check is expensive because it has to stat
the log file for every log record. Since we do not set maxBytes
the result of this check is always False.
"""
return False
async def async_mount_local_lib_path(config_dir: str) -> str:
"""Add local library to Python Path.

View File

@ -1398,3 +1398,13 @@ async def test_setup_does_base_platforms_first(hass: HomeAssistant) -> None:
# only that they are setup before other integrations.
assert set(order[1:3]) == {"sensor", "binary_sensor"}
assert order[3:] == ["root", "first_dep", "second_dep"]
def test_should_rollover_is_always_false():
"""Test that shouldRollover always returns False."""
assert (
bootstrap._RotatingFileHandlerWithoutShouldRollOver(
"any.log", delay=True
).shouldRollover(Mock())
is False
)