# Context Binding Add request_id, user_id, or any context once—it automatically appears in every log from that request. No need to pass context through your entire call stack. ## How it works When you call `logger.bind(request_id="123", user_id="abc")`, that context automatically appears in every subsequent log from that request: - **Bind once at the request boundary** - typically in middleware or at the start of a handler - **Every log includes it** - no need to pass request_id as a parameter through 10 function calls - **Each request gets its own context** - one user's logs won't leak into another's - **Clear when done** - `logger.clear_context()` removes bound values (optional, automatic with `runtime()`) ## Sync example ```python from fapilog import runtime with runtime() as logger: logger.bind(request_id="req-123", user_id="u-1") logger.info("Request started") logger.clear_context() ``` ## Async example ```python import asyncio from fapilog import runtime_async async def worker(name, logger): await logger.info(f"{name} started") async def main(): async with runtime_async() as logger: logger.bind(request_id="req-123") await asyncio.gather(worker("t1", logger), worker("t2", logger)) logger.clear_context() asyncio.run(main()) ``` ## Tips - **Bind at the start of each request** - In FastAPI, this happens automatically with `FastAPIBuilder`. In other frameworks, bind in your middleware. - **Use `runtime()` or `runtime_async()`** - These context managers automatically clear context when the request ends, preventing leakage. - **Common fields to bind**: `request_id`, `user_id`, `tenant_id`, `trace_id`, `correlation_id`