diff --git a/src/livepeer_gateway/__init__.py b/src/livepeer_gateway/__init__.py index 3a82a4d..269479e 100644 --- a/src/livepeer_gateway/__init__.py +++ b/src/livepeer_gateway/__init__.py @@ -17,6 +17,8 @@ ) from .errors import LivepeerGatewayError, NoOrchestratorAvailableError, PaymentError from .events import Events +from .logging_config import configure_logging + from .media_publish import ( AudioOutputConfig, MediaPublish, @@ -80,6 +82,7 @@ "ChannelReader", "JSONLReader", "JSONLWriter", + "configure_logging", "Events", "PaymentSession", "parse_token", @@ -99,3 +102,7 @@ "TrickleSubscriberStats", "VideoDecodedMediaFrame", ] + +# Honor LOG_LEVEL; add a root handler only if the app has not configured logging. +configure_logging() + diff --git a/src/livepeer_gateway/logging_config.py b/src/livepeer_gateway/logging_config.py new file mode 100644 index 0000000..3ddc459 --- /dev/null +++ b/src/livepeer_gateway/logging_config.py @@ -0,0 +1,33 @@ +from __future__ import annotations + +import logging +import os + + +_PACKAGE_LOGGER = "livepeer_gateway" +_DEFAULT_LEVEL = logging.INFO +_LOG_FORMAT = "%(levelname)s %(name)s: %(message)s" + + +def _resolve_level(level: str | int | None = None) -> int: + if level is None: + level = os.environ.get("LOG_LEVEL", "INFO") + if isinstance(level, int): + return level + return getattr(logging, str(level).upper(), _DEFAULT_LEVEL) + + +def apply_package_log_level(level: str | int | None = None) -> None: + """Set the livepeer_gateway logger level from arg or LOG_LEVEL env (default INFO).""" + logging.getLogger(_PACKAGE_LOGGER).setLevel(_resolve_level(level)) + + +def configure_logging(level: str | int | None = None) -> None: + """Configure livepeer_gateway log level from arg or LOG_LEVEL env (default INFO). + + Ensures a basic root handler exists so package logs are visible. + """ + resolved = _resolve_level(level) + apply_package_log_level(resolved) + if not logging.getLogger().handlers: + logging.basicConfig(level=resolved, format=_LOG_FORMAT)