Django Observability Checklist: Logs, Metrics, Traces, and Alerts
A checklist for observability of a production Django system: structured logs with request IDs, RED metrics for web and Celery, distributed tracing, error tracking, database and queue visibility, SLO-based alerts, dashboards per service, and runbooks linked from alerts.
Problem statement
Your Django system has uptime checks and Sentry, but when something goes wrong, finding out why still takes too long: you cannot tell which endpoint slowed down, whether Celery queues are growing, which release introduced the problem, or how a slow request spent its time. Observability means being able to answer new questions about production behavior from the data you already collect. This checklist covers the signals and practices that make a Django system debuggable.
- Emit structured JSON logs with request ID, user or tenant ID, release, and view name.
- Collect RED metrics (rate, errors, duration) per endpoint, plus Celery queue length, task failures, and database health.
- Add distributed tracing with OpenTelemetry or an APM, covering web, Celery, database, cache, and outbound HTTP.
- Track errors with release tags, and annotate dashboards with deploys.
- Alert on symptoms tied to SLOs (error rate, latency, queue age), with a runbook link in every alert.
Checklist
Logs
- JSON logs to stdout, collected centrally with retention suited to incident review.
- Request ID generated or accepted at the edge, passed to Django, Celery tasks, and outbound requests, and included in every log line.
- Release (commit SHA), environment, service (web, worker, beat), and tenant included as fields.
- No secrets or personal data in logs; noisy loggers turned down.
Metrics
- Web: request rate, error rate (5xx), and latency percentiles per route.
- Workers: Celery queue length and oldest message age, task failure rate, task runtime percentiles.
- Data stores: PostgreSQL connections, replication lag, slow queries; Redis memory, evictions, hit rate.
- Infrastructure: CPU, memory, disk, container restarts, OOM kills.
Traces
- Tracing on web and Celery, with context propagated through task headers.
- Database, cache, and HTTP client spans enabled; sampling tuned to keep important routes.
- Trace IDs linked from logs and errors.
Errors and releases
- Error tracking with release and environment tags; alerts on new issues and regressions.
- Deploy markers on dashboards and in APM; quick view of error rates before and after each release.
- Source code context and suspect commits configured where the tool supports them.
Alerts and dashboards
- SLOs defined for key user journeys (availability, latency), with alerts on burn rate rather than single spikes.
- Alerts on symptoms users feel: 5xx rate, p95 latency, queue age, failed payments; fewer cause-based alerts.
- Every alert has an owner, a severity, and a runbook link.
- Dashboards per service: one overview, plus drill-downs for web, workers, database, and cache.
- Heartbeat monitoring for scheduled jobs and beat.
Explanation
Monitoring tells you that something is wrong; observability helps you understand why, including for failures you did not predict. For Django, that means consistent identifiers across logs, traces, and errors; metrics that describe user-facing health per route and per queue; and alerts based on symptoms with clear ownership. The tools vary (Prometheus and Grafana, Datadog, New Relic, SigNoz, Sentry), but the practices are the same, and OpenTelemetry keeps instrumentation portable between them.
Edge cases / notes
- Cost. Telemetry volume grows with traffic; sample traces, drop noisy logs, and keep metric labels low-cardinality.
- Privacy. Traces and logs can capture personal data in URLs and SQL; scrub at the source.
- Small teams. Start with error tracking, uptime, a few RED metrics, and request IDs; add tracing as the system grows.
Next steps
- Cover the basics with the Django Monitoring Checklist.
- Add traces with Django OpenTelemetry Tracing.
- Watch workers with Monitor Celery With Prometheus Metrics and Grafana.
FAQ
What is the difference between monitoring and observability?
Monitoring checks known failure conditions; observability lets you investigate new, unexpected problems using logs, metrics, and traces.
Which metrics matter most for Django?
Request rate, error rate, and latency per route, plus Celery queue age and failures, and database connections and slow queries.
Do I need distributed tracing?
It becomes valuable once requests span Celery, external APIs, or several services, and when latency problems are hard to localize.
How do I avoid alert fatigue?
Alert on user-facing symptoms tied to SLOs, give each alert an owner and runbook, and remove alerts nobody acts on.