Registry / observability / structlog

structlog

JSON →
library26.1.0pypypi✓ verified 26d ago

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 structlog
INSTALL
IMPORT
SIG · STRUCTLOG
S
structlog
observabilitypythonv26.1.0
Install
1.7s avg
Import
247ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v26.1.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.260s · 18.6MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.7s · import 0.234s · 19MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

structlog
import structlog
import logging import structlog
get_logger
from structlog import get_logger
configure
from structlog import configure

structlog — configure, bind, contextvars, and event filtering.

# pip install structlog import logging import structlog # Configure at app startup structlog.configure( processors=[ structlog.contextvars.merge_contextvars, structlog.stdlib.add_log_level, structlog.processors.TimeStamper(fmt='iso'), structlog.processors.JSONRenderer(), ], wrapper_class=structlog.make_filtering_bound_logger(logging.INFO), cache_logger_on_first_use=True, ) log = structlog.get_logger() # Basic structured logging log.info('user_login', user_id='usr-123', method='oauth') log.error('payment_failed', order_id='ord-456', reason='insufficient_funds') # bind() — immutable, returns new logger req_log = log.bind(request_id='req-789', ip='1.2.3.4') req_log.info('request_received', path='/api/checkout') req_log.info('request_completed', status=200, duration_ms=42) # Request-scoped context via contextvars (for async/web frameworks) structlog.contextvars.bind_contextvars(trace_id='abc123') log.info('db_query', table='orders') # trace_id auto-included structlog.contextvars.clear_contextvars() # Drop event from pipeline def filter_health_checks(logger, method, event_dict): if event_dict.get('path') == '/health': raise structlog.DropEvent() return event_dict
Debug
Known issues
breakingNo log level filtering by default — ALL levels (debug, info, warning, error) are emitted. Must use make_filtering_bound_logger(logging.INFO) in wrapper_class to filter.
fix
wrapper_class=structlog.make_filtering_bound_logger(logging.INFO) in structlog.configure()
affects: all
breakingbind() is immutable — returns a new logger, does NOT mutate the original. log.bind(key='val') without reassignment is silently discarded.
fix
Always reassign: log = log.bind(key='val') or request_log = log.bind(request_id='123')
affects: all
breakingstructlog.configure() must be called before first use. With cache_logger_on_first_use=True (default in prod), loggers cached before configure() use default settings permanently.
fix
Call structlog.configure() at app startup, before any module-level get_logger() calls are invoked.
affects: all
gotcha_context attribute on bound loggers is deprecated since v21.1. Raises DeprecationWarning.
fix
Use structlog.get_context(log) instead of log._context
affects: >= 21.1
gotchacontextvars (bind_contextvars) context is NOT automatically cleared between requests. Forgetting clear_contextvars() leaks context from one request to the next.
fix
Call structlog.contextvars.clear_contextvars() at the start or end of each request in middleware.
affects: all
gotchastructlog.stdlib.AsyncBoundLogger deprecated since v23.1. Use native async methods (ainfo, adebug, etc.) on the standard bound logger instead.
fix
await log.ainfo('event') instead of configuring AsyncBoundLogger as wrapper_class.
affects: >= 23.1
Upgrade
Version history
26.1.0latest on PyPI · released Jun 6, 2026
Audit
Dependencies

No dependency data recorded yet.

Agent activity
31 hits · last 30 days
node
24
Amazon
1
OpenAI (training)
1
Resources
structlog — pip install structlog · libregistry