From 9f04c234146b076e9e89c36f1eaab849c05c9adb Mon Sep 17 00:00:00 2001 From: Jonas Bergler Date: Tue, 28 Mar 2023 08:40:58 +1300 Subject: [PATCH] Support toggling debug logging for custom components (#90340) Co-authored-by: J. Nick Koston --- homeassistant/components/logger/helpers.py | 11 ++-- tests/components/logger/test_websocket_api.py | 51 +++++++++++++++++++ 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/logger/helpers.py b/homeassistant/components/logger/helpers.py index d85486a41e0..df275eaae93 100644 --- a/homeassistant/components/logger/helpers.py +++ b/homeassistant/components/logger/helpers.py @@ -66,13 +66,14 @@ def _chattiest_log_level(level1: int, level2: int) -> int: return min(level1, level2) -async def get_integration_loggers(hass: HomeAssistant, domain: str) -> list[str]: +async def get_integration_loggers(hass: HomeAssistant, domain: str) -> set[str]: """Get loggers for an integration.""" - loggers = [f"homeassistant.components.{domain}"] + loggers: set[str] = {f"homeassistant.components.{domain}"} with contextlib.suppress(IntegrationNotFound): integration = await async_get_integration(hass, domain) + loggers.add(integration.pkg_path) if integration.loggers: - loggers.extend(integration.loggers) + loggers.update(integration.loggers) return loggers @@ -188,7 +189,7 @@ class LoggerSettings: if settings.type == LogSettingsType.INTEGRATION: loggers = await get_integration_loggers(hass, domain) else: - loggers = [domain] + loggers = {domain} combined_logs = {logger: LOGSEVERITY[settings.level] for logger in loggers} # Don't override the log levels with the ones from YAML @@ -203,7 +204,7 @@ class LoggerSettings: if settings.type == LogSettingsType.INTEGRATION: loggers = await get_integration_loggers(hass, domain) else: - loggers = [domain] + loggers = {domain} for logger in loggers: combined_logs[logger] = LOGSEVERITY[settings.level] diff --git a/tests/components/logger/test_websocket_api.py b/tests/components/logger/test_websocket_api.py index 1252734df90..10c1ceb2f20 100644 --- a/tests/components/logger/test_websocket_api.py +++ b/tests/components/logger/test_websocket_api.py @@ -1,6 +1,8 @@ """Tests for Logger Websocket API commands.""" import logging +from unittest.mock import patch +from homeassistant import loader from homeassistant.components.logger.helpers import async_get_domain_config from homeassistant.components.websocket_api import const from homeassistant.core import HomeAssistant @@ -79,6 +81,55 @@ async def test_integration_log_level( } +async def test_custom_integration_log_level( + hass: HomeAssistant, hass_ws_client: WebSocketGenerator, hass_admin_user: MockUser +) -> None: + """Test setting integration log level.""" + websocket_client = await hass_ws_client() + assert await async_setup_component(hass, "logger", {}) + + integration = loader.Integration( + hass, + "custom_components.hue", + None, + { + "name": "Hue", + "dependencies": [], + "requirements": [], + "domain": "hue", + "loggers": ["some_other_logger"], + }, + ) + + with patch( + "homeassistant.components.logger.helpers.async_get_integration", + return_value=integration, + ), patch( + "homeassistant.components.logger.websocket_api.async_get_integration", + return_value=integration, + ): + await websocket_client.send_json( + { + "id": 7, + "type": "logger/integration_log_level", + "integration": "hue", + "level": "DEBUG", + "persistence": "none", + } + ) + + msg = await websocket_client.receive_json() + assert msg["id"] == 7 + assert msg["type"] == const.TYPE_RESULT + assert msg["success"] + + assert async_get_domain_config(hass).overrides == { + "homeassistant.components.hue": logging.DEBUG, + "custom_components.hue": logging.DEBUG, + "some_other_logger": logging.DEBUG, + } + + async def test_integration_log_level_unknown_integration( hass: HomeAssistant, hass_ws_client: WebSocketGenerator, hass_admin_user: MockUser ) -> None: