Structlog Contextual Bound Logging
Bind request-scoped context with structlog, so every log line carries correlation fields without threading state through call stacks.
Code
import logging
import uuid
import structlog
structlog.configure(
processors=[
structlog.contextvars.merge_contextvars,
structlog.processors.add_log_level,
structlog.processors.TimeStamper(fmt='iso'),
structlog.processors.JSONRenderer(),
],
wrapper_class=structlog.make_filtering_bound_logger(logging.INFO),
logger_factory=structlog.PrintLoggerFactory(),
)
logger = structlog.get_logger()
def charge_order(order_id: str, amount: int) -> None:
logger.info('charge_started', order_id=order_id, amount=amount)
try:
if amount > 100_000:
raise ValueError('amount exceeds single-charge limit')
except ValueError:
logger.exception('charge_rejected', order_id=order_id)
raise
def handle_request(request_id: str, order: dict) -> None:
structlog.contextvars.bind_contextvars(
request_id=request_id,
tenant=order['tenant'],
)
charge_order(order['id'], order['amount'])
handle_request(
request_id=str(uuid.uuid4())[:8],
order={'id': 'ord-91', 'tenant': 'acme', 'amount': 250_000},
)Report a problem with this exampleOpens a pre-filled issue on GitHub.