The shortest path from nothing to one event you can read.
Install
uv add widelog-pypip install widelog-pyThe distribution is widelog-py. The import is widelog. Nothing else is pulled in:
widelog uses only the standard library.
Log one operation
Save this as hello.py. No framework, no server.
from widelog import init, use_logger, wide_event
init(service="checkout")
with wide_event(job="hello") as log:
log.set(user={"id": "u_123", "plan": "premium"})
log.set(cart={"items": 3, "total": 9999})
log.warn("coupon expired")Run it
python hello.pyOne line of NDJSON on stdout, with everything the block collected:
{
"timestamp": "2026-07-30T10:23:45.612Z",
"level": "warn",
"service": "checkout",
"environment": "development",
"duration_ms": 0.14,
"job": "hello",
"user": { "id": "u_123", "plan": "premium" },
"cart": { "items": 3, "total": 9999 },
"messages": [{ "level": "warn", "message": "coupon expired" }]
}The level is warn because that was the most severe thing recorded. Nothing called
emit(): the event was written when the block exited.
What just happened
wide_event() opened one event and put it in a contextvars slot. log.set() merged fields
into it. When the block exited, widelog stamped the duration, redacted anything that looked like
a secret, and wrote a single JSON line.
An exception would not have changed that. The event is still emitted, with the error attached
and the level raised to error, and the exception continues to propagate.
Next
Log HTTP requests
Add the ASGI middleware and get one event per request, with method, path, and status. Requests
Declare your errors
Give every error a stable code, a why, and a fix, in one place.
Errors
Wire up FastAPI
Middleware order, the exception handler you need, background tasks, and streaming. FastAPI
Run on Lambda
One event per invocation, including the ones that time out. AWS Lambda
Look something up
Every function, the redaction rules, and the limits. Reference