Monitoring & Logging¶
Health Checks¶
All backend services expose GET /health. Docker Compose healthchecks poll this endpoint and automatically restart a service if it fails to respond.
curl http://localhost:8000/health # gateway
curl http://localhost:8001/health # auth
curl http://localhost:8002/health # catalog
curl http://localhost:8003/health # ai (optional service)
Expected response: {"status": "ok"}
What to Look For at Startup¶
After a deploy, check the logs for these lines confirming a healthy startup:
# auth-service, catalog-service, ai-service (each migrates its own schema in
# the shared "jinbocho" database):
INFO [alembic] Running upgrade -> <revision>, <description>
INFO [alembic] Done.
INFO: Application startup complete.
# api-gateway (no database):
INFO: Application startup complete.
# Any service — bad sign:
ERROR - Connection refused
sqlalchemy.exc.OperationalError: (asyncpg.exceptions.InvalidPasswordError)
If Alembic lines are missing or show errors, the DATABASE_URL is misconfigured — see Troubleshooting.
Application Logging¶
Logs are written to stdout, visible via:
docker compose -f docker/docker-compose.all.yml --env-file .env logs -f # all services
docker compose -f docker/docker-compose.all.yml --env-file .env logs -f auth-service # one service
| Level | When |
|---|---|
INFO |
Service start, migration completions, request summaries |
WARNING |
Non-fatal issues (e.g. ISBN not found in any source) |
ERROR |
Exceptions, failed requests, database errors |
Monitoring the Server (Netdata)¶
Host + per-container metrics (CPU/RAM/disk/network) are available via a single Netdata container — no external account, no secrets to configure.
Off by default. Enable it at install time (--netdata-enabled true on
setup-vps-community.sh) or later with:
docker compose -f docker/docker-compose.all.yml --profile observability up -d
The dashboard binds to 127.0.0.1:19999 only — never exposed publicly.
Reach it over SSH:
ssh -L 19999:localhost:19999 <user>@<host>
Then open http://localhost:19999 locally.