import time import uuid from fastapi import Request from starlette.middleware.base import BaseHTTPMiddleware from app.utils.logger import logger class RequestLoggingMiddleware(BaseHTTPMiddleware): """ Middleware để log mọi request và response """ async def dispatch(self, request: Request, call_next): # Generate request ID request_id = str(uuid.uuid4()) 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": request.client.host if request.client else None } ) # Measure time start_time = time.time() # Process request try: response = await call_next(request) process_time = time.time() - start_time # Log response logger.info( f"Request completed: {request.method} {request.url.path} - Status: {response.status_code}", extra={ "request_id": request_id, "method": request.method, "path": request.url.path, "status_code": response.status_code, "process_time": f"{process_time:.3f}s" } ) # Add request ID to response headers response.headers["X-Request-ID"] = request_id response.headers["X-Process-Time"] = f"{process_time:.3f}s" return response except Exception as e: process_time = time.time() - start_time # Log error logger.error( f"Request failed: {request.method} {request.url.path}", extra={ "request_id": request_id, "method": request.method, "path": request.url.path, "error": str(e), "process_time": f"{process_time:.3f}s" }, exc_info=True ) raise