Update Stream logging on EVENT_LOGGING_CHANGED (#99256)

pull/100228/head
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
from yarl import URL
from homeassistant.components.logger import EVENT_LOGGING_CHANGED
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
from homeassistant.core import Event, HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
@ -188,36 +189,32 @@ CONFIG_SCHEMA = vol.Schema(
)
def filter_libav_logging() -> None:
"""Filter libav logging to only log when the stream logger is at DEBUG."""
@callback
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:
return logging.getLogger(__name__).isEnabledFor(logging.DEBUG)
def set_pyav_logging(enable: bool) -> None:
"""Turn PyAV logging on or off."""
import av # pylint: disable=import-outside-toplevel
for logging_namespace in (
"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)
av.logging.set_level(av.logging.VERBOSE if enable else av.logging.FATAL)
# Set log level to error for libav.mp4
logging.getLogger("libav.mp4").setLevel(logging.ERROR)
# Suppress "deprecated pixel format" WARNING
logging.getLogger("libav.swscaler").setLevel(logging.ERROR)
# enable PyAV logging iff Stream logger is set to debug
set_pyav_logging(logging.getLogger(__name__).isEnabledFor(logging.DEBUG))
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up stream."""
# Drop libav log messages if stream logging is above DEBUG
filter_libav_logging()
# Only pass through PyAV log messages if stream logging is above DEBUG
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
# pylint: disable-next=import-outside-toplevel
@ -258,6 +255,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
]:
await asyncio.wait(awaitables)
_LOGGER.debug("Stopped stream workers")
cancel_logging_listener()
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, shutdown)

View File

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

View File

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

View File

@ -4,6 +4,7 @@ import logging
import av
import pytest
from homeassistant.components.logger import EVENT_LOGGING_CHANGED
from homeassistant.components.stream import __name__ as stream_name
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
@ -14,8 +15,6 @@ async def test_log_levels(
) -> None:
"""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": {}})
# These namespaces should only pass log messages when the stream logger
@ -31,11 +30,17 @@ async def test_log_levels(
"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
for namespace in namespaces_to_toggle:
av.logging.log(av.logging.ERROR, namespace, "SHOULD NOT PASS")
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
for namespace in namespaces_to_toggle: