Files
compass_backoffice/src/api/middleware/logging.py
2026-06-13 08:23:21 -03:00

57 lines
1.7 KiB
Python

"""
Logging middleware for FastAPI.
Wraps each request in a ``log_operation("http_request")`` so the
started/success/failed pattern from the OCI Logging policy is enforced
uniformly, and clears all contextvars on the way out to avoid leaking
correlation IDs between requests.
"""
import uuid
from typing import Callable
from fastapi import Request, Response
from starlette.middleware.base import BaseHTTPMiddleware
from src.core.logging import (
clear_context,
get_logger,
log_operation,
set_request_id,
)
logger = get_logger(__name__)
class LoggingMiddleware(BaseHTTPMiddleware):
"""
Generates a request_id, populates the logging contextvar, and emits
start/success/failed logs via ``log_operation``. Context is cleared on
exit so subsequent requests start from a clean slate.
"""
async def dispatch(self, request: Request, call_next: Callable) -> Response:
request_id = str(uuid.uuid4())
request.state.request_id = request_id
set_request_id(request_id)
method = request.method
path = request.url.path
client_host = request.client.host if request.client else None
try:
async with log_operation(
"http_request",
component="api",
logger=logger,
method=method,
path=path,
client_host=client_host,
user_agent=request.headers.get("user-agent"),
) as op:
response = await call_next(request)
op.add_field("status_code", response.status_code)
response.headers["X-Request-ID"] = request_id
return response
finally:
clear_context()