2.5 KiB
Endpoint Monitor API
A typed FastAPI service for process-local endpoint monitors and secure, on-demand HTTP checks.
Features
- CRUD monitor resources and current-status retrieval
- bounded HTTP/HTTPS checks with latency measurement
- SSRF protection on every DNS lookup and redirect hop
- JSON logs with URL credentials, query strings, and fragments redacted
- health/readiness endpoints and validated
MONITOR_environment settings - concurrency-safe in-memory state
Layout
docs/service-contract.md— API and architecture contractapp/— settings, models, store, checker, logging, and FastAPI routestests/— API and checker/security tests using mocked outbound HTTPdocs/verification.md— validation commands and expected evidence
Run locally
python -m venv .venv && . .venv/bin/activate
pip install -e '.[dev]'
uvicorn app.main:app --reload
Open http://127.0.0.1:8000/docs.
Examples
curl -sS -X POST http://127.0.0.1:8000/monitors \
-H 'content-type: application/json' \
-d '{"name":"example","url":"https://example.com/"}'
curl -sS http://127.0.0.1:8000/monitors
curl -sS -X POST http://127.0.0.1:8000/monitors/MONITOR_ID/check
curl -sS http://127.0.0.1:8000/monitors/MONITOR_ID/status
curl -sS http://127.0.0.1:8000/healthz
curl -sS http://127.0.0.1:8000/readyz
PUT accepts the same body as POST and replaces the mutable fields. DELETE returns 204. Unknown IDs return the JSON error envelope documented in the service contract.
Configuration
All settings are validated at startup.
| Variable | Default | Meaning |
|---|---|---|
MONITOR_REQUEST_TIMEOUT_SECONDS |
5.0 |
Total check timeout, range 0.1–30 |
MONITOR_MAX_REDIRECTS |
5 |
Manual redirect limit, range 0–10 |
MONITOR_MAX_MONITORS |
1000 |
Process-local monitor capacity |
MONITOR_LOG_LEVEL |
INFO |
Python log level |
Private, loopback, link-local, multicast, reserved, and otherwise non-global resolved addresses are rejected. URL userinfo is rejected. Only HTTP and HTTPS are accepted.
Quality checks
ruff format --check .
ruff check .
mypy app
pytest -q
Container
docker build -t endpoint-monitor .
docker run --rm -p 8000:8000 endpoint-monitor
# or
docker compose up --build
The container has a non-root user and one worker intentionally. State is process-local and is lost on restart; multiple workers/replicas do not share monitors. Use a durable shared database before horizontal scaling or production persistence is required.