Update Stream logging on EVENT_LOGGING_CHANGED (#99256)

This commit is contained in:
uvjustin 2023-09-13 01:38:11 +08:00 committed by GitHub
parent 8af7475f73
commit 5021c69886
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 25 deletions

View File

@ -29,6 +29,7 @@ from typing import TYPE_CHECKING, Any, Final, cast
import voluptuous as vol import voluptuous as vol
from yarl import URL from yarl import URL
from homeassistant.components.logger import EVENT_LOGGING_CHANGED
from homeassistant.const import EVENT_HOMEASSISTANT_STOP from homeassistant.const import EVENT_HOMEASSISTANT_STOP
from homeassistant.core import Event, HomeAssistant, callback from homeassistant.core import Event, HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
@ -188,36 +189,32 @@ CONFIG_SCHEMA = vol.Schema(
) )
def filter_libav_logging() -> None: @callback
"""Filter libav logging to only log when the stream logger is at DEBUG.""" def update_pyav_logging(_event: Event | None = None) -> None:
"""Adjust libav logging to only log when the stream logger is at DEBUG."""
def libav_filter(record: logging.LogRecord) -> bool: def set_pyav_logging(enable: bool) -> None:
return logging.getLogger(__name__).isEnabledFor(logging.DEBUG) """Turn PyAV logging on or off."""
import av # pylint: disable=import-outside-toplevel
for logging_namespace in ( av.logging.set_level(av.logging.VERBOSE if enable else av.logging.FATAL)
"libav.NULL",
"libav.h264",
"libav.hevc",
"libav.hls",
"libav.mp4",
"libav.mpegts",
"libav.rtsp",
"libav.tcp",
"libav.tls",
):
logging.getLogger(logging_namespace).addFilter(libav_filter)
# Set log level to error for libav.mp4 # enable PyAV logging iff Stream logger is set to debug
logging.getLogger("libav.mp4").setLevel(logging.ERROR) set_pyav_logging(logging.getLogger(__name__).isEnabledFor(logging.DEBUG))
# Suppress "deprecated pixel format" WARNING
logging.getLogger("libav.swscaler").setLevel(logging.ERROR)
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up stream.""" """Set up stream."""
# Drop libav log messages if stream logging is above DEBUG # Only pass through PyAV log messages if stream logging is above DEBUG
filter_libav_logging() cancel_logging_listener = hass.bus.async_listen(
EVENT_LOGGING_CHANGED, update_pyav_logging
)
# libav.mp4 and libav.swscaler have a few unimportant messages that are logged
# at logging.WARNING. Set those Logger levels to logging.ERROR
for logging_namespace in ("libav.mp4", "libav.swscaler"):
logging.getLogger(logging_namespace).setLevel(logging.ERROR)
update_pyav_logging()
# Keep import here so that we can import stream integration without installing reqs # Keep import here so that we can import stream integration without installing reqs
# pylint: disable-next=import-outside-toplevel # pylint: disable-next=import-outside-toplevel
@ -258,6 +255,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
]: ]:
await asyncio.wait(awaitables) await asyncio.wait(awaitables)
_LOGGER.debug("Stopped stream workers") _LOGGER.debug("Stopped stream workers")
cancel_logging_listener()
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, shutdown) hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, shutdown)

View File

@ -2,7 +2,7 @@
"domain": "stream", "domain": "stream",
"name": "Stream", "name": "Stream",
"codeowners": ["@hunterjm", "@uvjustin", "@allenporter"], "codeowners": ["@hunterjm", "@uvjustin", "@allenporter"],
"dependencies": ["http"], "dependencies": ["http", "logger"],
"documentation": "https://www.home-assistant.io/integrations/stream", "documentation": "https://www.home-assistant.io/integrations/stream",
"integration_type": "system", "integration_type": "system",
"iot_class": "local_push", "iot_class": "local_push",

View File

@ -109,6 +109,7 @@ load-plugins = [
persistent = false persistent = false
extension-pkg-allow-list = [ extension-pkg-allow-list = [
"av.audio.stream", "av.audio.stream",
"av.logging",
"av.stream", "av.stream",
"ciso8601", "ciso8601",
"orjson", "orjson",

View File

@ -4,6 +4,7 @@ import logging
import av import av
import pytest import pytest
from homeassistant.components.logger import EVENT_LOGGING_CHANGED
from homeassistant.components.stream import __name__ as stream_name from homeassistant.components.stream import __name__ as stream_name
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
@ -14,8 +15,6 @@ async def test_log_levels(
) -> None: ) -> None:
"""Test that the worker logs the url without username and password.""" """Test that the worker logs the url without username and password."""
logging.getLogger(stream_name).setLevel(logging.INFO)
await async_setup_component(hass, "stream", {"stream": {}}) await async_setup_component(hass, "stream", {"stream": {}})
# These namespaces should only pass log messages when the stream logger # These namespaces should only pass log messages when the stream logger
@ -31,11 +30,17 @@ async def test_log_levels(
"NULL", "NULL",
) )
logging.getLogger(stream_name).setLevel(logging.INFO)
hass.bus.async_fire(EVENT_LOGGING_CHANGED)
await hass.async_block_till_done()
# Since logging is at INFO, these should not pass # Since logging is at INFO, these should not pass
for namespace in namespaces_to_toggle: for namespace in namespaces_to_toggle:
av.logging.log(av.logging.ERROR, namespace, "SHOULD NOT PASS") av.logging.log(av.logging.ERROR, namespace, "SHOULD NOT PASS")
logging.getLogger(stream_name).setLevel(logging.DEBUG) logging.getLogger(stream_name).setLevel(logging.DEBUG)
hass.bus.async_fire(EVENT_LOGGING_CHANGED)
await hass.async_block_till_done()
# Since logging is now at DEBUG, these should now pass # Since logging is now at DEBUG, these should now pass
for namespace in namespaces_to_toggle: for namespace in namespaces_to_toggle: