A comprehensive logging solution for FastAPI applications that provides enhanced debugging capabilities, performance monitoring, and cleaner log output.
- IDE Integration: Log messages include clickable file paths that work in both PyCharm and VS Code
- Precise Location: Shows exact line numbers where log messages originate
- Relative Paths: Uses relative paths for cleaner output
clickable-logs.mp4
- Reduced Boilerplate: Filters out verbose FastAPI and uvicorn logs
- HTTPX Filtering: Suppresses noisy HTTP client library logs
- Error Focus: Shows only your application's errors, not framework noise
- Stack Trace Cleanup: Removes irrelevant framework stack
reduced-logs.mp4
- Handler Timing: Automatically measures and logs execution time for each endpoint handler

- Validation Error Logging: Automatically logs Pydantic validation errors with detailed context
- HTTP Exception Tracking: Captures and logs HTTP exceptions with proper error details
- Human Readable Error Messages: Returns clean error messages while maintaining comprehensive logging

Copy the logging_.py
module into your project and use it as follows:
import logging_ # noqa
from logging_ import logger
from fastapi import FastAPI, HTTPException
from fastapi.exception_handlers import http_exception_handler
from fastapi.exceptions import RequestValidationError
from fastapi.requests import Request
from fastapi.responses import PlainTextResponse
from pydantic import ValidationError
from starlette.exceptions import HTTPException as StarletteHTTPException
app = FastAPI()
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
as_validation_error = ValidationError.from_exception_data(
str(request.url.path),
line_errors=exc.errors(),
)
error_str = str(as_validation_error)
logger.warning(error_str, exc_info=False)
return PlainTextResponse(error_str, status_code=422)
@app.exception_handler(StarletteHTTPException)
async def custom_http_exception_handler(request: Request, exc: StarletteHTTPException):
logger.warning(exc, exc_info=exc)
return await http_exception_handler(request, exc)
@app.get("/")
async def root():
logger.info("This will show with source code location and timing")
return {"message": "Hello World"}
@app.get("/error")
async def error():
raise Exception("This is a test error")
[2025-07-27 20:24:48,880] [INFO] [File "app.py", line 19] This will show with source code location and timing
[2025-07-27 20:24:48,880] [INFO] [File "app.py", line 20] Handler `root` took 1 ms
[2025-07-27 21:59:30,463] [INFO] [uvicorn.access] 127.0.0.1:59962 - "GET /error HTTP/1.1" 500
[2025-07-27 21:59:30,464] [ERROR] [uvicorn.error] Exception in ASGI application
Traceback (most recent call last):
File "/home/dante/fastapi-how-to-log/app.py", line 54, in error
raise Exception("This is a test error")
Exception: This is a test error
The file path in the log message will be clickable ([File "app.py", line 19]) in your IDE, taking you directly to the source code.
You can modify the dictConfig
in logging_.py
to adjust:
- Log levels for different components
- Output formatting
- Color schemes
- Filtered paths and libraries
The RelativePathFilter
adds relative file paths to log records, making them clickable in IDEs.
The run_endpoint_function
is monkey-patched into FastAPI to automatically measure handler execution time.
The CleanErrorFilter
removes framework noise from stack traces and suppresses unwanted log sources.
The custom exception handlers provide structured logging for validation errors and HTTP exceptions:
- Validation Errors: Converts FastAPI's
RequestValidationError
to Pydantic'sValidationError
format for human readable messages - HTTP Exceptions: Logs HTTP exceptions with full context while maintaining FastAPI's default error response behavior
This solution uses some "cursed" techniques:
- Monkey Patching: Directly modifies FastAPI's internal
run_endpoint_function
- Internal API Usage: Relies on FastAPI's internal dependency injection system
- Framework Coupling: Tightly coupled to specific FastAPI and Starlette versions
While effective, these techniques may break with framework updates. Use at your own risk in production environments.
- Python 3.11+
- FastAPI
- colorlog
- uvicorn (for ASGI server)
MIT License - feel free to use and modify as needed.