Structured logging for FastAPI — JSON Lines daily files and a built-in log viewer
Project description
fastapi-logview
Structured logging for FastAPI. Drop-in plugin that adds JSON Lines file logging, automatic request correlation, and a built-in log viewer — zero infrastructure required.
from fastapi import FastAPI
from fastapi_logview import get_log, setup_fastapi_logview
app = FastAPI()
setup_fastapi_logview(app, service_name="my-api", environment="dev")
logger = get_log("my-api")
@app.get("/orders/{order_id}")
def get_order(order_id: str):
logger.info("order fetched", order_id=order_id, user_id=42)
return {"order_id": order_id}
Open http://localhost:8000/logs — your logs are already there.
For AI assistants/agents, see LLMS.txt for project-specific guidance.
Why fastapi-logview
Most logging setups in FastAPI require wiring structlog or loguru by hand, building a custom middleware, and setting up a separate log viewer. fastapi-logview gives you all of that in one setup_fastapi_logview() call.
- No external services. No Elasticsearch, no Grafana, no Loki.
- Every log event is a JSON line in a local file — simple to read, grep, ship, or archive.
- The viewer is part of your app. Useful in staging and dev; disable it in prod with one flag.
Install
pip install fastapi-logview
Requires Python 3.10+ and FastAPI 0.110+.
Features
- Structured JSON Lines — daily log files at
logs/YYYY-MM-DD.log, one event per line - Automatic request correlation — every log emitted during a request is tagged with the same
request_id - Built-in log viewer — filter by level, request, user, trace ID or free-text search at
/logs - Request logging middleware — auto-captures method, path, status code and duration for every request
- Timezone-aware display — store in UTC, display in any IANA timezone
- Viewer auth — protect
/logswith HTTP Basic Auth or an IP allowlist - Lightweight — depends only on FastAPI, Pydantic and structlog
- 100% local — your logs never leave your server. No data is sent to any external service, not even to the author. Everything stays in your
logs/directory.
Quickstart
Minimal
from fastapi import FastAPI
from fastapi_logview import get_log, setup_fastapi_logview
app = FastAPI()
setup_fastapi_logview(app, service_name="payments-api", environment="dev")
logger = get_log("payments")
@app.post("/pay")
def pay(amount: int):
logger.info("payment initiated", amount=amount)
return {"status": "ok"}
With custom timezone
setup_fastapi_logview(
app,
service_name="payments-api",
environment="dev",
display_timezone="America/New_York",
)
Production — disable the viewer
setup_fastapi_logview(
app,
service_name="payments-api",
environment="prod",
enable_ui=False,
)
Log viewer
Mount path: GET /logs (configurable via mount_path).
| Endpoint | Description |
|---|---|
GET /logs |
Viewer UI |
GET /logs/api/files |
List available log files |
GET /logs/api/events |
Query events with filters |
GET /logs/api/events/{event_id} |
Single event detail |
GET /logs/api/requests/{request_id} |
All events for a request |
GET /logs/api/stats |
Aggregated counts by level |
Query filters: level, request_id, trace_id, user_id, search, file, source, limit, offset.
Security
Protect the viewer with a FastAPI dependency passed to viewer_auth_dependency.
HTTP Basic Auth:
from fastapi_logview.security import basic_auth_dependency
setup_fastapi_logview(
app,
service_name="payments-api",
environment="prod",
viewer_auth_dependency=basic_auth_dependency(
username="admin",
password="supersecret",
),
)
IP allowlist:
from fastapi_logview.security import ip_allowlist_dependency
setup_fastapi_logview(
app,
service_name="payments-api",
environment="prod",
viewer_auth_dependency=ip_allowlist_dependency(
allowed_ips=["127.0.0.1"],
allowed_cidrs=["10.0.0.0/24"],
trust_proxy_headers=True,
),
)
You can pass any FastAPI dependency — use your existing auth system if you have one.
Configuration reference
setup_fastapi_logview(app, **options)
| Parameter | Type | Default | Description |
|---|---|---|---|
app |
FastAPI |
— | FastAPI application instance |
service_name |
str |
"fastapi-service" |
Identifier written to every log event |
environment |
str |
"dev" |
Environment label (dev, staging, prod) |
mount_path |
str |
"/logs" |
Path where the viewer is mounted |
log_dir |
str |
"logs" |
Directory for daily .log files |
enable_ui |
bool |
True |
Mount the log viewer UI |
enable_request_logging |
bool |
True |
Log every HTTP request automatically |
return_request_id_header |
bool |
True |
Return X-Request-ID in responses |
display_timezone |
str |
"UTC" |
IANA timezone for the viewer (e.g. "America/New_York") |
viewer_auth_dependency |
Callable | None |
None |
FastAPI dependency to protect the viewer |
log_level |
str |
"INFO" |
Minimum level (DEBUG, INFO, WARNING, ERROR, CRITICAL) |
max_events_per_query |
int |
1000 |
Max events returned per viewer API call |
Log format
Each event is a single JSON line in logs/YYYY-MM-DD.log:
{
"timestamp": "2026-03-08T12:00:00.000000+00:00",
"level": "INFO",
"logger_name": "payments",
"message": "payment initiated",
"request_id": "01HX4K2J...",
"service_name": "payments-api",
"environment": "prod",
"method": "POST",
"path": "/pay",
"status_code": 200,
"duration_ms": 3.2,
"amount": 150,
"extra": {},
"event_id": "01HX4K2J..."
}
All extra keyword arguments passed to logger.info(...) are included at the top level of the event.
Request correlation
fastapi-logview middleware reads the incoming X-Request-ID header or generates a new one (UUID). Every log emitted during that request — regardless of which logger — carries the same request_id.
# client sends: X-Request-ID: my-trace-123
# all logs for that request will have:
{"request_id": "my-trace-123", ...}
License
MIT — Copyright (c) 2026 OmarGC
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fastapi_logview-0.1.0.tar.gz.
File metadata
- Download URL: fastapi_logview-0.1.0.tar.gz
- Upload date:
- Size: 30.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c668c40186d83d7beca916f2c4e10e5c47afa02d6307a15fd9307d7080534555
|
|
| MD5 |
51c9fca2dca17486db52207b4e0cb1f9
|
|
| BLAKE2b-256 |
175e6f3e9bf77a34fde9dc1d3b5d3a92391b4485988ba9f02743e7863d7063d5
|
File details
Details for the file fastapi_logview-0.1.0-py3-none-any.whl.
File metadata
- Download URL: fastapi_logview-0.1.0-py3-none-any.whl
- Upload date:
- Size: 28.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bdf97e5d648588c9d0bc76672f4abf2e9ad80299eb1ce76c5a69306ce485c102
|
|
| MD5 |
397714f745295f56778f844e93f2d5a1
|
|
| BLAKE2b-256 |
c7b92f8517891e490cf96fdfcce0abdb1a51c68608e5ade69bf5c9fb73d3d468
|