File size: 1,315 Bytes
fa85955
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
"""
Custom middlewares for request ID and timing/logging.
"""
import time
import uuid
from typing import Callable

from fastapi import Request, Response

from app.core.logging import get_logger, RequestLogger


logger = get_logger(__name__)
request_logger = RequestLogger(logger)


async def request_context_middleware(request: Request, call_next: Callable) -> Response:
    """Attach a request id and perform basic request/response logging."""
    request_id = request.headers.get("X-Request-ID") or str(uuid.uuid4())
    request.state.request_id = request_id

    start = time.time()
    request_logger.log_request(request.method, request.url.path, request_id)
    try:
        response = await call_next(request)
    except Exception as exc:  # Let exception handlers format the response
        request_logger.log_error(request_id, str(exc))
        raise
    finally:
        duration_ms = (time.time() - start) * 1000
        # Note: response may not exist if exception raised; guarded above
        try:
            status = getattr(locals().get("response", None), "status_code", 500)
            request_logger.log_response(request_id, status, duration_ms)
        except Exception:
            pass

    # propagate request id header
    response.headers["X-Request-ID"] = request_id
    return response