Ojasa Mirai

Ojasa Mirai

FastAPI

Loading...

Learning Level

🟢 Beginner🔵 Advanced
🚀 Error Basics📚 HTTP Exceptions📚 Custom Exceptions📚 Error Responses📚 Exception Handlers📚 Validation Errors📚 Error Logging📚 Error Best Practices
Fastapi/Error Handling/Error Logging

Error Logging

Learn the fundamentals of error logging in FastAPI.

🎯 Core Concept

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).

📖 What You'll Learn

In this section, you'll understand:

  • Setting up logging in FastAPI
  • How it applies to real-world API development
  • Logging at different severity levels
  • Common patterns and best practices

💡 Basic Logging Setup

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)
        raise

🔍 Logging at Different Levels

import 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")

💼 Production-Grade Error Logging

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)
        raise

How it applies to real-world API development

Error logging is essential for:

  • **Monitoring**: Track error patterns and spikes
  • **Debugging**: Understand what happened when errors occur
  • **Auditing**: Record important events for compliance
  • **Alerting**: Send notifications for critical errors

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
        }
    )

Common patterns and best practices

  • ✅ Log at appropriate levels (DEBUG, INFO, WARNING, ERROR)
  • ✅ Include context information (user ID, request ID)
  • ✅ Use structured logging (JSON format)
  • ✅ Log with `exc_info=True` to capture stack traces
  • ✅ Rotate logs to prevent disk space issues
  • ✅ Avoid logging sensitive information (passwords, tokens)
  • ✅ Monitor logs for error patterns
  • ✅ Set appropriate log levels (DEBUG in dev, WARNING in prod)

🔑 Key Takeaways

  • ✅ Understand the purpose of error logging
  • ✅ Know when to apply this pattern
  • ✅ Recognize its benefits in real-world scenarios
  • ✅ Be prepared to use it in your projects

Ready to explore more? Check out the advanced section for production patterns and edge cases.


Resources

Python Docs

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

Courses

PythonFastapiReactJSCloud

© 2026 Ojasa Mirai. All rights reserved.

TwitterGitHubLinkedIn