Speed up logger setup (#114610)

* Speed up logger setup

Preload core.logger and avoid saving it
until after startup

* add comment about 180s

* Adjust grammar

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
J. Nick Koston 2024-04-03 20:35:44 -10:00 committed by GitHub
parent 7a2e529bb7
commit 0c3ccabfb1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 28 additions and 4 deletions

View file

@ -223,6 +223,7 @@ SETUP_ORDER = (
# If they do not exist they will not be loaded # If they do not exist they will not be loaded
# #
PRELOAD_STORAGE = [ PRELOAD_STORAGE = [
"core.logger",
"core.network", "core.network",
"http.auth", "http.auth",
"image", "image",

View file

@ -28,6 +28,16 @@ from .const import (
STORAGE_VERSION, STORAGE_VERSION,
) )
SAVE_DELAY = 15.0
# At startup, we want to save after a long delay to avoid
# saving while the system is still starting up. If the system
# for some reason restarts quickly, it will still be written
# at the final write event. In most cases we expect startup
# to happen in less than 180 seconds, but if it takes longer
# it's likely delayed because of remote I/O and not local
# I/O so it's fine to save at that point.
SAVE_DELAY_LONG = 180.0
@callback @callback
def async_get_domain_config(hass: HomeAssistant) -> LoggerDomainConfig: def async_get_domain_config(hass: HomeAssistant) -> LoggerDomainConfig:
@ -148,7 +158,7 @@ class LoggerSettings:
for domain, settings in stored_log_config.items() for domain, settings in stored_log_config.items()
} }
} }
await self._store.async_save(self._async_data_to_save()) self.async_save(SAVE_DELAY_LONG)
@callback @callback
def _async_data_to_save(self) -> dict[str, dict[str, dict[str, str]]]: def _async_data_to_save(self) -> dict[str, dict[str, dict[str, str]]]:
@ -164,9 +174,9 @@ class LoggerSettings:
} }
@callback @callback
def async_save(self) -> None: def async_save(self, delay: float = SAVE_DELAY) -> None:
"""Save settings.""" """Save settings."""
self._store.async_delay_save(self._async_data_to_save, 15) self._store.async_delay_save(self._async_data_to_save, delay)
@callback @callback
def _async_get_logger_logs(self) -> dict[str, int]: def _async_get_logger_logs(self) -> dict[str, int]:

View file

@ -1,6 +1,7 @@
"""The tests for the Logger component.""" """The tests for the Logger component."""
from collections import defaultdict from collections import defaultdict
import datetime
import logging import logging
from typing import Any from typing import Any
from unittest.mock import Mock, patch from unittest.mock import Mock, patch
@ -9,8 +10,12 @@ import pytest
from homeassistant.components import logger from homeassistant.components import logger
from homeassistant.components.logger import LOGSEVERITY from homeassistant.components.logger import LOGSEVERITY
from homeassistant.components.logger.helpers import SAVE_DELAY_LONG
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from homeassistant.util import dt as dt_util
from tests.common import async_fire_time_changed
HASS_NS = "unused.homeassistant" HASS_NS = "unused.homeassistant"
COMPONENTS_NS = f"{HASS_NS}.components" COMPONENTS_NS = f"{HASS_NS}.components"
@ -403,7 +408,7 @@ async def test_log_once_removed_from_store(
hass: HomeAssistant, hass_storage: dict[str, Any] hass: HomeAssistant, hass_storage: dict[str, Any]
) -> None: ) -> None:
"""Test logs with persistence "once" are removed from the store at startup.""" """Test logs with persistence "once" are removed from the store at startup."""
hass_storage["core.logger"] = { store_contents = {
"data": { "data": {
"logs": { "logs": {
ZONE_NS: {"type": "module", "level": "DEBUG", "persistence": "once"} ZONE_NS: {"type": "module", "level": "DEBUG", "persistence": "once"}
@ -412,7 +417,15 @@ async def test_log_once_removed_from_store(
"key": "core.logger", "key": "core.logger",
"version": 1, "version": 1,
} }
hass_storage["core.logger"] = store_contents
assert await async_setup_component(hass, "logger", {}) assert await async_setup_component(hass, "logger", {})
assert hass_storage["core.logger"]["data"] == store_contents["data"]
async_fire_time_changed(
hass, dt_util.utcnow() + datetime.timedelta(seconds=SAVE_DELAY_LONG)
)
await hass.async_block_till_done()
assert hass_storage["core.logger"]["data"] == {"logs": {}} assert hass_storage["core.logger"]["data"] == {"logs": {}}