
FastAPI
Learn the fundamentals of error logging in FastAPI.
Logging errors helps you monitor API health, debug issues, and audit important events. Python's `logging` module integrates seamlessly with FastAPI to record errors at different levels (DEBUG, INFO, WARNING, ERROR, CRITICAL).
In this section, you'll understand:
import logging
from fastapi import FastAPI
from fastapi.responses import JSONResponse
# Configure logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)
app = FastAPI()
@app.get("/items/{item_id}")
async def get_item(item_id: int):
try:
logger.info(f"Fetching item {item_id}")
item = db.get_item(item_id)
if not item:
logger.warning(f"Item {item_id} not found")
raise HTTPException(status_code=404, detail="Not found")
return item
except Exception as e:
logger.error(f"Error fetching item {item_id}: {str(e)}", exc_info=True)
raiseimport logging
logger = logging.getLogger(__name__)
# DEBUG - Detailed diagnostic info
logger.debug("Database connection established")
# INFO - General informational messages
logger.info("User 123 logged in")
# WARNING - Something unexpected but not an error
logger.warning("Disk space low, only 10GB remaining")
# ERROR - A serious problem occurred
logger.error("Failed to process payment", exc_info=True)
# CRITICAL - A very serious error
logger.critical("Database connection lost, shutting down")import json
from datetime import datetime
from typing import Optional
class APILogger:
def __init__(self, logger_name: str):
self.logger = logging.getLogger(logger_name)
def log_request(self, method: str, path: str, user_id: Optional[int] = None):
self.logger.info(json.dumps({
"event": "api_request",
"method": method,
"path": path,
"user_id": user_id,
"timestamp": datetime.utcnow().isoformat()
}))
def log_error(self, error_code: str, message: str, exception: Exception = None):
self.logger.error(json.dumps({
"event": "api_error",
"error_code": error_code,
"message": message,
"timestamp": datetime.utcnow().isoformat(),
"exception_type": type(exception).__name__ if exception else None
}))
api_logger = APILogger(__name__)
@app.post("/orders/")
async def create_order(order: Order, request: Request):
api_logger.log_request("POST", "/orders", user_id=current_user.id)
try:
# Process order
result = process_payment(order)
logger.info(f"Order created: {result.id}")
return result
except PaymentError as e:
api_logger.log_error("PAYMENT_FAILED", str(e), e)
raise HTTPException(status_code=402, detail="Payment failed")
except Exception as e:
api_logger.log_error("INTERNAL_ERROR", "Unexpected error", e)
raiseError logging is essential for:
Example - Complete logging strategy:
import logging
import sys
from loguru import logger
# Configure loguru for structured logging
logger.remove()
logger.add(
sys.stderr,
format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | {message}",
level="DEBUG"
)
logger.add("logs/api.log", rotation="500 MB")
@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
request_id = request.headers.get("X-Request-ID", "unknown")
logger.bind(request_id=request_id).error(
f"Unhandled exception: {type(exc).__name__}",
extra={
"path": str(request.url.path),
"method": request.method,
"exception_detail": str(exc)
}
)
return JSONResponse(
status_code=500,
content={
"error": "InternalError",
"request_id": request_id
}
)Ready to explore more? Check out the advanced section for production patterns and edge cases.
Resources
Ojasa Mirai
Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.
Learn Deep • Build Real • Verify Skills • Launch Forward