Skip to main content

Plug & play auto-logging middleware for FastAPI with async I/O, structured JSON logs, request IDs, loguru integration, and a built-in dashboard

Project description

fastapi-api-logger

Plug & play auto-logging middleware for FastAPI with async I/O, structured JSON logs, request tracing, loguru integration, and a built-in dashboard.

Features

  • Zero-config middleware — add one line and all requests are logged
  • Structured JSON logs — timestamp, method, endpoint, status, status_code, response_time_ms
  • Correlation / Request ID — unique ID per request, forwarded from API gateways, injected into response headers
  • Day-wise log fileslogs/2026-03-25.log, logs/2026-03-26.log, ...
  • Async & non-blocking — logging never slows your API (bounded queue + background writer)
  • Status categorization — SUCCESS (2xx), REDIRECT (3xx), WARNING (4xx), ERROR (5xx)
  • Error tracebacks — full traceback captured for 5xx errors
  • Request/response body capture — opt-in, with automatic sensitive field masking
  • Loguru integration — optionally pipe all logs through loguru with configurable levels
  • Built-in dashboard — web UI at /logs to browse, filter, and search logs in real-time
  • Configurable log rotation — auto-deletes log files older than N days (you choose how many)
  • Pure ASGI — works with FastAPI, Starlette, or any ASGI framework

Quick Start

Install

pip install fastapi-api-logger

# With loguru support
pip install fastapi-api-logger[loguru]

# With everything
pip install fastapi-api-logger[all]

Basic Usage (2 lines)

from fastapi import FastAPI
from fastapi_logger import LoggingMiddleware

app = FastAPI()
app.add_middleware(LoggingMiddleware)

That's it! All requests are now logged to logs/YYYY-MM-DD.log with unique request IDs.

Full-Featured Usage

from fastapi import FastAPI
from fastapi_logger import LoggingMiddleware, LogConfig, create_dashboard_router

app = FastAPI()

config = LogConfig(
    log_dir="logs",
    excluded_paths=["/health", "/docs", "/openapi.json"],
    enable_request_body=True,
    enable_response_body=True,
    sensitive_fields={"password", "token", "secret"},

    # Request ID
    enable_request_id=True,
    request_id_header="X-Request-ID",

    # Loguru
    enable_loguru=True,

    # Dashboard
    enable_dashboard=True,
    dashboard_prefix="/logs",

    # Rotation — delete logs older than 7 days
    log_rotation_days=7,
)

app.add_middleware(LoggingMiddleware, config=config)

# Mount the dashboard (visit http://localhost:8000/logs)
app.mount("", create_dashboard_router(config))

Correlation / Request ID

Every request gets a unique ID (UUID4). This is essential for debugging in production.

$ curl -v http://localhost:8000/users/1
< x-request-id: a1b2c3d4e5f6...

How it works:

  • If the client sends X-Request-ID header (e.g., from an API gateway), the middleware uses it
  • Otherwise, a new UUID is generated
  • The ID is added to the response headers AND the log entry
  • Your endpoint can access it via request.scope["state"]["request_id"]
@app.get("/users/{user_id}")
async def get_user(user_id: int, request: Request):
    request_id = request.scope["state"]["request_id"]
    return {"id": user_id, "request_id": request_id}

Loguru Integration

Enable loguru to get beautiful colored terminal output alongside file logging:

config = LogConfig(
    enable_loguru=True,
    loguru_level_success="INFO",     # 2xx
    loguru_level_warning="WARNING",  # 4xx
    loguru_level_error="ERROR",      # 5xx
)

Output:

2026-03-25 14:30:00 | INFO     | [a1b2c3d4] GET /users/1 → 200 SUCCESS (42.1ms)
2026-03-25 14:30:01 | WARNING  | [b2c3d4e5] GET /users/0 → 404 WARNING (3.2ms)
2026-03-25 14:30:02 | ERROR    | [c3d4e5f6] GET /crash → 500 ERROR (1.1ms)

Install loguru: pip install fastapi-api-logger[loguru]

Dashboard

A built-in web UI to browse your logs — no React, no npm, just enable it:

config = LogConfig(enable_dashboard=True, dashboard_prefix="/logs")
app.mount("", create_dashboard_router(config))

Visit http://localhost:8000/logs to see:

  • Real-time log entries (auto-refreshes every 5s)
  • Stats cards: total, success, warning, error counts + avg response time
  • Filters: by status, method, endpoint search, date picker
  • Sorting: newest, oldest, or slowest first
  • Color-coded response times: green (<100ms), yellow (<500ms), red (>500ms)
  • Expandable tracebacks and request bodies

Configuration Reference

All Options

Field Type Default Description
log_dir str "logs" Directory for log files
log_format "json" / "text" "json" Log output format
excluded_paths list[str] ["/health", ...] Glob patterns to skip
enable_request_body bool False Capture request body
enable_response_body bool False Capture response body
sensitive_fields set[str] {"password", ...} Fields to mask as ***
max_body_size int 10000 Max body bytes to capture
log_rotation_days int 30 Auto-delete logs older than N days (0 = keep forever)
include_traceback bool True Include traceback for 5xx errors
enable_request_id bool True Generate unique request ID per request
request_id_header str "X-Request-ID" Header name for request ID
inject_response_header bool True Add request ID to response headers
enable_loguru bool False Also emit logs through loguru
loguru_level_success str "INFO" Loguru level for 2xx
loguru_level_warning str "WARNING" Loguru level for 4xx
loguru_level_error str "ERROR" Loguru level for 5xx
enable_dashboard bool False Enable the /logs web UI
dashboard_prefix str "/logs" URL prefix for dashboard routes
dashboard_page_size int 100 Entries per page in dashboard

Log Format

{
    "timestamp": "2026-03-25T14:30:00.123456+00:00",
    "method": "POST",
    "endpoint": "/orders",
    "status": "SUCCESS",
    "status_code": 201,
    "response_time_ms": 85.23,
    "request_id": "a1b2c3d4e5f67890abcdef1234567890",
    "client_ip": "127.0.0.1",
    "request_body": "{\"item\": \"widget\", \"password\": \"***\"}",
    "response_body": "{\"id\": 42}"
}

Architecture

Request → LoggingMiddleware (pure ASGI)
           ├─ Generates/extracts Request ID
           ├─ Injects X-Request-ID response header
           ├─ Measures response time (perf_counter)
           ├─ Captures status code, method, path
           ├─ Optionally captures request/response body
           ├─ Masks sensitive fields
           └─ Enqueues log entry (non-blocking, O(1))
                    ↓
              asyncio.Queue (bounded, 10k max)
                    ↓
              AsyncLogWriter (background task)
              ├─ Day-wise file: logs/YYYY-MM-DD.log
              ├─ Auto-rotation: deletes old files
              └─ Optional: loguru sink

Development

git clone https://github.com/paresh/fastapi-api-logger.git
cd fastapi-api-logger
pip install -e ".[dev]"

# Run tests (51 tests)
pytest tests/ -v

# Run the demo app
uvicorn examples.demo_app:app --reload
# Visit http://localhost:8000/logs for the dashboard

Publishing to PyPI

# Install build tools
pip install build twine

# Build
python -m build

# Verify
twine check dist/*

# Upload to TestPyPI (testing)
twine upload --repository testpypi dist/*

# Upload to PyPI (production)
twine upload dist/*

Versioning

Update version in two places:

  • pyproject.tomlversion = "X.Y.Z"
  • src/fastapi_logger/__init__.py__version__ = "X.Y.Z"

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastapi_api_logger-0.2.1.tar.gz (20.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastapi_api_logger-0.2.1-py3-none-any.whl (18.3 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_api_logger-0.2.1.tar.gz.

File metadata

  • Download URL: fastapi_api_logger-0.2.1.tar.gz
  • Upload date:
  • Size: 20.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for fastapi_api_logger-0.2.1.tar.gz
Algorithm Hash digest
SHA256 d0df85cd3647fcac721947a363dc9bda32af4c1fdc95621230e101f801fed658
MD5 2f8639a7ac02166be552e1fbc1d62a9e
BLAKE2b-256 dc698bc79c6500c8c6d5561a507e68b7b57d49ad17a9a9f30ba51a490fb2e162

See more details on using hashes here.

File details

Details for the file fastapi_api_logger-0.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for fastapi_api_logger-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 13ea0a37a4b79f894d4994391fd01fa90274e0d27d317a358e53fdc8da97185e
MD5 6e3dd2e00b864235392e640582e4276d
BLAKE2b-256 6a96b8b0b0532fe1556041c9185fe0b5a04b05dd045f66d6db2bfec238304191

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page