Source code for fluxlit.logging.context
"""Request correlation ID storage for the gateway and optional FastAPI logging middleware.
The gateway sets a context variable from the ``X-Request-ID`` header (or generates a UUID)
for each HTTP/WebSocket request. Optional FastAPI middleware can use the same header so
access logs share the same identifier.
Constants:
- :data:`REQUEST_ID_HEADER` — lowercase header name clients may send.
- :data:`request_id_ctx` — :class:`contextvars.ContextVar` holding the current ID.
- :data:`log` — ``logging.getLogger("fluxlit")`` for package diagnostics.
"""
from __future__ import annotations
import contextvars
import logging
import uuid
from typing import Final
REQUEST_ID_HEADER: Final = "x-request-id"
request_id_ctx: contextvars.ContextVar[str | None] = contextvars.ContextVar(
"fluxlit_request_id", default=None
)
log = logging.getLogger("fluxlit")
[docs]
def get_request_id() -> str | None:
"""Return the active request ID from :data:`request_id_ctx`, if any."""
return request_id_ctx.get()
[docs]
def new_request_id() -> str:
"""Generate a new opaque request ID (UUID4 string)."""
return str(uuid.uuid4())
[docs]
def set_request_id(value: str | None) -> contextvars.Token[str | None]:
"""Bind ``value`` into :data:`request_id_ctx`; returns a token for :func:`reset_request_id`."""
return request_id_ctx.set(value)
[docs]
def reset_request_id(token: contextvars.Token[str | None]) -> None:
"""Restore the previous context after :func:`set_request_id` (typically in ``finally``)."""
request_id_ctx.reset(token)