You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
FastStream keeps its own stderr handler next to lite-bootstrap's, so every FastStream log line is written twice #336
FastStream installs a StreamHandler(sys.stderr) with its colourized text format on the faststream logger at import time (faststream/_internal/logger/logging.py:94-99 in faststream 0.7.4). FastStreamLoggingInstrument.bootstrap (lite_bootstrap/bootstrappers/faststream_bootstrapper.py:155-163) hands brokers structlog.get_logger("faststream"), and MemoryLoggerFactory adds its MemoryHandler to the same stdlib logger on first use (lite_bootstrap/instruments/logging_factory.py:120-133) without removing FastStream's. Every FastStream record is then written as lite-bootstrap JSON on stdout and again, in FastStream's text format, on stderr.
At the default faststream_log_level=logging.WARNING the happy path logs nothing, so this shows up on errors and for services that lower the level. Measured on 2026-10-24 at 705d8a3 on Linux with 2 CPUs (CPython 3.14.9, a real RedisBroker, the subscriber's process_message on a prebuilt message), with faststream_log_level=logging.INFO: removing FastStream's handler as a prototype takes the cost from +35.2 to +25.1 µs per message, 10 µs per message or 5 µs per record ("Received" and "Processed"). The tables and scripts are to be published with #335.
Test first: after bootstrapping a FastStreamBootstrapper with a broker, logging.getLogger("faststream").handlers holds no StreamHandler writing to sys.stderr, and one FastStream INFO record at faststream_log_level=logging.INFO produces one line. It fails today.
In FastStreamLoggingInstrument.bootstrap, remove the handlers already on the faststream stdlib logger before lite-bootstrap's is added, and put them back in teardown() so a torn-down process logs as it did before bootstrap.
Alternative to weigh: clear existing handlers in MemoryLoggerFactory.__call__ for every logger it creates. That covers other libraries with the same pattern, but it touches loggers lite-bootstrap does not own, so the FastStream-only fix is the safer default.
Docs: none; docs/integrations/faststream.md does not describe FastStream's own output.
Verify: the new test passes, and the existing FastStream logging tests in tests/test_faststream_bootstrap.py still pass.
Not breaking: the duplicate stderr line goes away.
Activity
fix: remove FastStream's stderr handler while lite-bootstrap logs Fas…