How to Log Requests in FastAPI: Simple Guide with Examples
To log requests in
FastAPI, create a custom middleware that intercepts each request and logs details like method and URL. Use BaseHTTPMiddleware from starlette.middleware.base to add this middleware to your app.Syntax
Use BaseHTTPMiddleware to create a middleware class that intercepts requests. Override the dispatch method to access the request object and log its properties before passing control to the next handler.
Then add this middleware to your FastAPI app with add_middleware().
python
from fastapi import FastAPI, Request from starlette.middleware.base import BaseHTTPMiddleware import logging class LogRequestsMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next): logging.info(f"Request: {request.method} {request.url}") response = await call_next(request) return response app = FastAPI() app.add_middleware(LogRequestsMiddleware)
Example
This example shows a FastAPI app with a middleware that logs each incoming request's method and URL to the console.
python
import logging from fastapi import FastAPI, Request from starlette.middleware.base import BaseHTTPMiddleware logging.basicConfig(level=logging.INFO) class LogRequestsMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next): logging.info(f"Request: {request.method} {request.url}") response = await call_next(request) return response app = FastAPI() app.add_middleware(LogRequestsMiddleware) @app.get("/") async def read_root(): return {"message": "Hello World"}
Output
INFO:root:Request: GET http://127.0.0.1:8000/
Common Pitfalls
- Not awaiting
call_next(request)causes the request to hang. - Logging too much data synchronously can slow down requests.
- For production, configure logging properly instead of using
print. - Middleware order matters; place logging middleware early to capture all requests.
python
from fastapi import FastAPI, Request from starlette.middleware.base import BaseHTTPMiddleware import logging # Wrong: forgetting to await call_next class BadMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next): logging.info(f"Request: {request.method} {request.url}") response = call_next(request) # Missing await return response # Correct: class GoodMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next): logging.info(f"Request: {request.method} {request.url}") response = await call_next(request) return response
Quick Reference
- Use
BaseHTTPMiddlewareto create request logging middleware. - Override
dispatchto log request details. - Always
await call_next(request)to continue processing. - Configure Python's
loggingmodule for better control.
Key Takeaways
Create a custom middleware by subclassing BaseHTTPMiddleware to log requests in FastAPI.
Always await call_next(request) inside dispatch to avoid blocking requests.
Use Python's logging module instead of print for better log management.
Place logging middleware early to capture all incoming requests.
Keep logging lightweight to avoid slowing down your API responses.