Skip to content

Write structlog lines through a plain StreamHandler and remove logging_buffer_capacity and logging_flush_level - #378

Merged
lesnik512 merged 1 commit into
mainfrom
plain-stream-handler
Oct 29, 2026
Merged

lesnik512 merged 1 commit into
mainfrom
plain-stream-handler

Conversation

@lesnik512

Copy link
Copy Markdown
Member

Closes #377.

MemoryLoggerFactory now attaches its StreamHandler to each structlog stdlib logger directly, with no MemoryHandler in front of it. logging_buffer_capacity and logging_flush_level are removed from LoggingConfig and from _MemoryLoggerFactoryConfig.

The issue and its comment have the reasoning and the sources. In short, MemoryHandler.flush() hands buffered records to the target one at a time, so every line still got its own write and flush. On Linux the buffer made each line 0.2 to 0.3 µs slower, and it wrote structlog lines out of order with stdlib lines, held them back until ten built up or an ERROR arrived, and lost them on a hard exit.

  • close_handlers removes and closes the StreamHandler. StreamHandler.close() leaves the stream open, as before.
  • I kept the names MemoryLoggerFactory, _MemoryLoggerFactoryConfig and memory_logger_factory, although nothing is buffered in memory now. MemoryLoggerFactory is a public export, and a rename belongs in its own change, through deprecated_module_getattr.

Tests

Written first. test_structlog_lines_are_written_at_once_and_in_order_with_stdlib_lines bootstraps LoggingInstrument with the default config and logs structlog "1", stdlib "2", structlog "3". Before teardown, main had written only ['2']. It now reads ['1', '2', '3'].

  • test_memory_logger_factory_writes_each_line_at_once replaces test_memory_logger_factory_info and test_memory_logger_factory_error, which asserted the buffering this removes. It checks that each INFO line is on the stream as soon as it is logged, and that the logger's only handler is a StreamHandler.
  • The handler-type assertions in test_litestar_bootstrap.py and test_faststream_bootstrap.py expect StreamHandler now.
  • logging_buffer_capacity=0 is gone from the tests and from scripts/floor_smoke.py and scripts/ft_smoke.py. Those tests set it only to switch the buffer off.

The full suite passes, 591 tests at 100% coverage (just test-ci). just lint (including ty), just adr-check and just docs-build pass too. scripts/floor_smoke.py passes locally for all five targets. I couldn't run scripts/ft_smoke.py here, because it needs a free-threaded interpreter. No floor changes.

Docs

  • configuration.md no longer lists the two fields. The FastStream and FastMCP examples no longer pass logging_buffer_capacity=0.
  • benchmarks/frameworks/logging_suite.py loses the info_capacity1 scenario. In benchmarks/README.md §8f the logging_buffer_capacity=1 row is gone. The chain description still names MemoryHandler(capacity=10), because that is what the rows measured, and a new note says it has since been removed and the rows have not been rerun.

Breaking changes

  • Passing logging_buffer_capacity or logging_flush_level to a config raises TypeError. from_dict and from_object ignore keys they don't know, so settings loaded through them keep working.
  • Structlog lines are written as they are logged, in order with stdlib lines. Before, they could wait in the buffer until ten built up or an ERROR arrived.
  • The handler on each structlog stdlib logger is now a StreamHandler, not a MemoryHandler.

@lesnik512 lesnik512 added this to the 2.0.0 milestone Oct 29, 2026
@lesnik512
lesnik512 merged commit f9ee273 into main Oct 29, 2026
37 checks passed
@lesnik512
lesnik512 deleted the plain-stream-handler branch October 29, 2026 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Write structlog lines through a plain StreamHandler and remove logging_buffer_capacity and logging_flush_level

1 participant