Context Propagation
April 20, 2026 ยท View on GitHub
mollog supports context-local structured fields using Python contextvars.
This is useful for:
- request IDs in async services
- trace IDs in worker pools
- tenant or batch IDs in data pipelines
- any field that should follow the current execution flow without being passed manually every time
All context operations live under the Context namespace class.
Bind fields globally for the current context
from mollog import Context, get_logger
logger = get_logger("api")
token = Context.bind(request_id="req-7", trace_id="trace-9")
try:
logger.info("accepted")
finally:
Context.reset(token)
Use a scoped context
from mollog import Context, get_logger
logger = get_logger("worker")
with Context.scope(batch="nightly", request_id="req-42"):
logger.info("started")
Named scopes and logfire spans
When you pass a name to Context.scope(...), it records a scope field
in the context and opens a matching logfire span if
logfire is configured:
from mollog import Context, get_logger
logger = get_logger("api")
with Context.scope("request", user_id=42):
logger.info("handling") # mollog record carries scope="request"
logger.fire("handled") # logfire event attached to the span
If logfire isn't configured, the span is a no-op and the scope still works as a plain bind/reset block.
Merge behavior
Field precedence is:
- context-local fields (
Context.bind/Context.scope) - logger-bound fields (
Logger.bind) - per-call
extra
Later sources overwrite earlier ones. That means explicit per-call values always win.