Skip to main content

Observability

Structured logging

app/core/logging.py configures structlog and writes JSONL to LOG_DIR (<environment>-<date>.jsonl) plus stdout.
  • Event names are lowercase_with_underscores; variables are passed as kwargs.
  • request_id comes from CorrelationIdMiddleware.
  • user_id is bound once a Supabase token has been verified.

Prometheus

/metrics is exposed by app/core/metrics.py and gated by METRICS_TOKEN: when a token is set, the scraper must send Authorization: Bearer <token>; in a deployed environment (staging/production) without a token the endpoint is disabled (404), while development and test leave it open when no token is set.
  • http_requests_total{method,endpoint,status}
  • http_request_duration_seconds{method,endpoint}
Endpoints are labelled with the matched route template, never the raw path, so ids cannot create unbounded series.

Profiling

When DEBUG=true, ProfilingMiddleware measures every request. Requests slower than PROFILING_THRESHOLD_SECONDS write a pyinstrument JSON report ({request_id}.json) to PROFILING_DIR, including wall time, CPU time, I/O wait, peak/allocated memory, and top memory allocators.