import logging import time from starlette.middleware.base import BaseHTTPMiddleware from starlette.requests import Request from starlette.responses import Response from fastapi import FastAPI # --- 1. SETUP LOGGER (Do this ONCE, globally) --- logger = logging.getLogger("my_app_logger") logger.setLevel(logging.INFO) # Create file handler once file_handler = logging.FileHandler('logging.txt') formatter = logging.Formatter('%(asctime)s - %(message)s') file_handler.setFormatter(formatter) logger.addHandler(file_handler) class RequestLoggingMiddleware(BaseHTTPMiddleware): """ Logs every request that comes in Middleware class needs - dispatch method that handles the request """ async def dispatch(self, request: Request, call_next) -> Response: # --- 2. BEFORE REQUEST --- start_time = time.time() # Log that we started (Optional) logger.info(f"Incoming: {request.method} {request.url.path}") # --- 3. PASS TO ENDPOINT --- # This jumps to your actual API function and waits for it to return response = await call_next(request) # --- 4. AFTER REQUEST --- process_time = (time.time() - start_time) * 1000 # Calculate duration # Log the result logger.info( f"Completed: {request.method} {request.url.path} " f"- Status: {response.status_code} " f"- Duration: {process_time:.2f}ms" ) return response # # from fastapi import FastAPI # # from fastapi.middleware.cors import CORSMiddleware # from src.api.middleware.logging import RequestLoggingMiddleware # app = FastAPI() # # Add middlewares # # ORDER MATTERS! Last added = First to run # # 1. CORS (Cross-Origin Resource Sharing) # app.add_middleware( # CORSMiddleware, # allow_origins=["http://localhost:3000"], # Frontend URL # allow_credentials=True, # allow_methods=["*"], # allow_headers=["*"], # ) # # 2. Our custom logging middleware # app.add_middleware(RequestLoggingMiddleware)