diff --git a/lite_bootstrap/bootstrappers/faststream_bootstrapper.py b/lite_bootstrap/bootstrappers/faststream_bootstrapper.py index a6281e0..776c363 100644 --- a/lite_bootstrap/bootstrappers/faststream_bootstrapper.py +++ b/lite_bootstrap/bootstrappers/faststream_bootstrapper.py @@ -151,11 +151,17 @@ class FastStreamLoggingInstrument(LoggingInstrument[FastStreamConfig]): _prior_broker_params_storages: list[tuple[typing.Any, typing.Any]] = dataclasses.field( default_factory=list, init=False, repr=False, compare=False ) + _prior_faststream_handlers: list[logging.Handler] | None = dataclasses.field( + default=None, init=False, repr=False, compare=False + ) def bootstrap(self) -> None: super().bootstrap() brokers = self.bootstrap_config.application.brokers if brokers and import_checker.is_structlog_installed and import_checker.is_faststream_installed: + faststream_stdlib_logger = logging.getLogger("faststream") + self._prior_faststream_handlers = faststream_stdlib_logger.handlers + faststream_stdlib_logger.handlers = [] logger = structlog.get_logger("faststream") logger.setLevel(self.bootstrap_config.faststream_log_level) for broker in brokers: @@ -168,7 +174,12 @@ def teardown(self) -> None: broker, prior_storage = self._prior_broker_params_storages.pop() broker.config.logger.params_storage = prior_storage finally: - super().teardown() + try: + super().teardown() + finally: + if self._prior_faststream_handlers is not None: + logging.getLogger("faststream").handlers = self._prior_faststream_handlers + self._prior_faststream_handlers = None @dataclasses.dataclass(kw_only=True) diff --git a/tests/test_faststream_bootstrap.py b/tests/test_faststream_bootstrap.py index 0bedf06..f4e103f 100644 --- a/tests/test_faststream_bootstrap.py +++ b/tests/test_faststream_bootstrap.py @@ -1,5 +1,7 @@ import dataclasses import logging +import logging.handlers +import sys import typing import uuid import warnings @@ -152,6 +154,26 @@ def test_faststream_logging_instrument_injects_structlog_logger(broker: RedisBro bootstrapper.teardown() +def test_faststream_logging_replaces_faststream_stderr_handler(broker: RedisBroker) -> None: + faststream_logger = logging.getLogger("faststream") + original_handlers = faststream_logger.handlers[:] + bootstrapper = FastStreamBootstrapper( + bootstrap_config=FastStreamConfig( + logging_buffer_capacity=0, + faststream_log_level=logging.INFO, + application=faststream.asgi.AsgiFastStream(broker), + ) + ) + bootstrapper.bootstrap() + try: + assert not [one for one in faststream_logger.handlers if getattr(one, "stream", None) is sys.stderr] + assert [type(one) for one in faststream_logger.handlers].count(logging.handlers.MemoryHandler) == 1 + finally: + bootstrapper.teardown() + + assert faststream_logger.handlers == original_handlers + + def test_faststream_config_default_application() -> None: config = FastStreamConfig() assert isinstance(config.application, faststream.asgi.AsgiFastStream)