1 """Helpers for the logger integration."""
3 from __future__
import annotations
5 from collections
import defaultdict
6 from collections.abc
import Mapping
8 from dataclasses
import asdict, dataclass
9 from enum
import StrEnum
10 from functools
import lru_cache
12 from typing
import Any, cast
39 SAVE_DELAY_LONG = 180.0
44 """Return the domain config."""
45 return cast(LoggerDomainConfig, hass.data[DOMAIN])
50 """Set the default log level for components."""
52 hass.bus.async_fire(EVENT_LOGGING_CHANGED)
56 def set_log_levels(hass: HomeAssistant, logpoints: Mapping[str, int]) ->
None:
57 """Set the specified log levels."""
59 for key, value
in logpoints.items():
61 hass.bus.async_fire(EVENT_LOGGING_CHANGED)
67 Any logger fetched before this integration is loaded will use old class.
69 getattr(logger,
"orig_setLevel", logger.setLevel)(level)
73 """Return the chattiest log level."""
74 if level1 == logging.NOTSET:
76 if level2 == logging.NOTSET:
78 return min(level1, level2)
82 """Get loggers for an integration."""
83 loggers: set[str] = {f
"homeassistant.components.{domain}"}
84 with contextlib.suppress(IntegrationNotFound):
86 loggers.add(integration.pkg_path)
87 if integration.loggers:
88 loggers.update(integration.loggers)
92 @dataclass(slots=True)
94 """Settings for a single module or integration."""
101 @dataclass(slots=True)
103 """Logger domain config."""
105 overrides: dict[str, Any]
106 settings: LoggerSettings
110 """Log persistence."""
114 PERMANENT =
"permanent"
118 """Log settings type."""
120 INTEGRATION =
"integration"
125 """Manage log settings."""
127 _stored_config: dict[str, dict[str, LoggerSetting]]
129 def __init__(self, hass: HomeAssistant, yaml_config: ConfigType) ->
None:
130 """Initialize log settings."""
134 if DOMAIN
in yaml_config
and LOGGER_DEFAULT
in yaml_config[DOMAIN]:
135 self.
_default_level_default_level = yaml_config[DOMAIN][LOGGER_DEFAULT]
136 self._store: Store[dict[str, dict[str, dict[str, Any]]]] =
Store(
137 hass, STORAGE_VERSION, STORAGE_KEY
141 """Load stored settings."""
142 stored_config = await self._store.
async_load()
143 if not stored_config:
147 def reset_persistence(settings: LoggerSetting) -> LoggerSetting:
148 """Reset persistence."""
149 if settings.persistence == LogPersistance.ONCE:
150 settings.persistence = LogPersistance.NONE
153 stored_log_config = stored_config[STORAGE_LOG_KEY]
158 for domain, settings
in stored_log_config.items()
165 """Generate data to be saved."""
166 stored_log_config = self.
_stored_config_stored_config[STORAGE_LOG_KEY]
169 domain: asdict(settings)
170 for domain, settings
in stored_log_config.items()
171 if settings.persistence
172 in (LogPersistance.ONCE, LogPersistance.PERMANENT)
183 """Get the logger logs."""
190 self, hass: HomeAssistant, domain: str, settings: LoggerSetting
192 """Update settings."""
193 stored_log_config = self.
_stored_config_stored_config[STORAGE_LOG_KEY]
194 if settings.level == LOGSEVERITY_NOTSET:
195 stored_log_config.pop(domain,
None)
197 stored_log_config[domain] = settings
201 if settings.type == LogSettingsType.INTEGRATION:
206 combined_logs = {logger: LOGSEVERITY[settings.level]
for logger
in loggers}
213 """Get combination of levels from yaml and storage."""
214 combined_logs = defaultdict(
lambda: logging.CRITICAL)
215 for domain, settings
in self.
_stored_config_stored_config[STORAGE_LOG_KEY].items():
216 if settings.type == LogSettingsType.INTEGRATION:
221 for logger
in loggers:
222 combined_logs[logger] = LOGSEVERITY[settings.level]
225 for domain, level
in yaml_log_settings.items():
227 combined_logs[domain], level
230 return dict(combined_logs)
233 get_logger = lru_cache(maxsize=256)(logging.getLogger)
236 getLogger uses a threading.RLock, so we cache the result to avoid
237 locking the threads every time the integrations page is loaded.
dict[str, int] async_get_levels(self, HomeAssistant hass)
None async_update(self, HomeAssistant hass, str domain, LoggerSetting settings)
dict[str, int] _async_get_logger_logs(self)
dict[str, dict[str, dict[str, str]]] _async_data_to_save(self)
None async_save(self, float delay=SAVE_DELAY)
None __init__(self, HomeAssistant hass, ConfigType yaml_config)
web.Response get(self, web.Request request, str config_key)
None set_log_levels(HomeAssistant hass, Mapping[str, int] logpoints)
LoggerDomainConfig async_get_domain_config(HomeAssistant hass)
int _chattiest_log_level(int level1, int level2)
set[str] get_integration_loggers(HomeAssistant hass, str domain)
None _set_log_level(logging.Logger logger, int level)
None set_default_log_level(HomeAssistant hass, int level)
None async_delay_save(self, Callable[[], _T] data_func, float delay=0)
Integration async_get_integration(HomeAssistant hass, str domain)