Search_Engine / src /api /middleware /logging_middleware.py
IndraneelKumar
Initial search engine commit
266d7bc
import time
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware
from src.utils.logger_util import setup_logging
logger = setup_logging()
class LoggingMiddleware(BaseHTTPMiddleware):
"""Middleware for logging incoming HTTP requests and their responses.
Logs the request method, URL, client IP, and headers.
Excludes sensitive headers like Authorization and Cookie.
as well as the response status code and request duration in milliseconds.
Exceptions raised during request processing are logged with the full traceback.
Usage:
Add this middleware to your FastAPI app:
app.add_middleware(LoggingMiddleware)
Attributes:
logger: Configured logger from `setup_logging`.
"""
async def dispatch(self, request: Request, call_next):
"""Process the incoming request, log its details, and measure execution time.
Args:
request (Request): The incoming FastAPI request.
call_next: Callable to invoke the next middleware or route handler.
Returns:
Response: The HTTP response returned by the next middleware or route handler.
Raises:
Exception: Propagates any exceptions raised by downstream handlers after logging them.
"""
start_time = time.time()
client_host = request.client.host if request.client else "unknown"
# logger.debug(f"Request headers: {request.headers}")
# logger.debug(f"Request cookies: {request.cookies}")
# Exclude sensitive headers from logging
safe_headers = {
k: v for k, v in request.headers.items() if k.lower() not in {"authorization", "cookie"}
}
logger.info(
f"Incoming request: {request.method} {request.url} from {client_host} "
f"headers={safe_headers}"
)
try:
response = await call_next(request)
except Exception:
duration = (time.time() - start_time) * 1000
logger.exception(
f"Request failed: {request.method} {request.url} from {client_host} "
f"duration={duration:.2f}ms"
)
raise
duration = (time.time() - start_time) * 1000
logger.info(
f"Completed request: {request.method} {request.url} from {client_host} "
f"status_code={response.status_code} duration={duration:.2f}ms"
)
return response