66 lines
2.1 KiB
Python
66 lines
2.1 KiB
Python
"""
|
|
Request ID middleware for tracking requests across services
|
|
"""
|
|
import uuid
|
|
from fastapi import Request
|
|
from starlette.middleware.base import BaseHTTPMiddleware
|
|
from starlette.responses import Response
|
|
from ..config.logging_config import get_logger
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
|
|
class RequestIDMiddleware(BaseHTTPMiddleware):
|
|
"""Add unique request ID to each request for tracing"""
|
|
|
|
async def dispatch(self, request: Request, call_next):
|
|
# Generate or get request ID
|
|
request_id = request.headers.get("X-Request-ID") or str(uuid.uuid4())
|
|
|
|
# Add request ID to request state
|
|
request.state.request_id = request_id
|
|
|
|
# Log request
|
|
logger.info(
|
|
f"Request started: {request.method} {request.url.path}",
|
|
extra={
|
|
"request_id": request_id,
|
|
"method": request.method,
|
|
"path": request.url.path,
|
|
"client_ip": request.client.host if request.client else None
|
|
}
|
|
)
|
|
|
|
# Process request
|
|
try:
|
|
response = await call_next(request)
|
|
|
|
# Add request ID to response headers
|
|
response.headers["X-Request-ID"] = request_id
|
|
|
|
# Log response
|
|
logger.info(
|
|
f"Request completed: {request.method} {request.url.path} - {response.status_code}",
|
|
extra={
|
|
"request_id": request_id,
|
|
"method": request.method,
|
|
"path": request.url.path,
|
|
"status_code": response.status_code
|
|
}
|
|
)
|
|
|
|
return response
|
|
except Exception as e:
|
|
logger.error(
|
|
f"Request failed: {request.method} {request.url.path} - {str(e)}",
|
|
extra={
|
|
"request_id": request_id,
|
|
"method": request.method,
|
|
"path": request.url.path,
|
|
"error": str(e)
|
|
},
|
|
exc_info=True
|
|
)
|
|
raise
|
|
|