Structured logging for Python. Current version: 25.5.0 (Mar 2026). No level filtering by default — ALL log levels emitted until configured. structlog.configure() must be called before first use; loggers obtained before configure() use default settings. bind() is immutable — returns a new logger, does not mutate in place. structlog.contextvars.merge_contextvars needed for request-scoped context. stdlib interop requires ProcessorFormatter. _context attribute deprecated — use structlog.get_context().
pip install structlogVerified import paths — ran on the pinned version, not inferred.
structlog — configure, bind, contextvars, and event filtering.
wrapper_class=structlog.make_filtering_bound_logger(logging.INFO) in structlog.configure()
Always reassign: log = log.bind(key='val') or request_log = log.bind(request_id='123')
Call structlog.configure() at app startup, before any module-level get_logger() calls are invoked.
Use structlog.get_context(log) instead of log._context
Call structlog.contextvars.clear_contextvars() at the start or end of each request in middleware.
await log.ainfo('event') instead of configuring AsyncBoundLogger as wrapper_class.No dependency data recorded yet.