Skip to content

Commit

Permalink
Update Stream logging on EVENT_LOGGING_CHANGED (#99256)
Browse files Browse the repository at this point in the history
  • Loading branch information
uvjustin authored Sep 12, 2023
1 parent 8af7475 commit 5021c69
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 25 deletions.
42 changes: 20 additions & 22 deletions homeassistant/components/stream/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
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
Expand Down Expand Up @@ -188,36 +189,32 @@ def convert_stream_options(
)


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
Expand Down Expand Up @@ -258,6 +255,7 @@ async def shutdown(event: Event) -> None:
]:
await asyncio.wait(awaitables)
_LOGGER.debug("Stopped stream workers")
cancel_logging_listener()

hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, shutdown)

Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/stream/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ load-plugins = [
persistent = false
extension-pkg-allow-list = [
"av.audio.stream",
"av.logging",
"av.stream",
"ciso8601",
"orjson",
Expand Down
9 changes: 7 additions & 2 deletions tests/components/stream/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
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
Expand All @@ -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
Expand All @@ -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:
Expand Down

0 comments on commit 5021c69

Please sign in to comment.