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.

Observability for DjangoLogsJSON, request IDsMetricsRED, queues, DBTracesspans across servicesAlertsSLOs, runbooksCorrelated logs, metrics, and traces turn symptoms into causes quickly.
  1. Emit structured JSON logs with request ID, user or tenant ID, release, and view name.
  2. Collect RED metrics (rate, errors, duration) per endpoint, plus Celery queue length, task failures, and database health.
  3. Add distributed tracing with OpenTelemetry or an APM, covering web, Celery, database, cache, and outbound HTTP.
  4. Track errors with release tags, and annotate dashboards with deploys.
  5. 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.
signal and question it answersAnswersToolingStructured logswhat happened to this requestLoki, ELK, DatadogRED metricsis the system healthyPrometheus, APMTraceswhere did the time goOpenTelemetry, APMError trackingwhich code failedSentry, GlitchTipDeploy markersdid a release cause itannotations, tagsEach signal answers a different question; correlation IDs connect themdjango-deployment.com
The request ID in logs, traces, and errors is what lets you move between them.

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.
from alert to cause1Symptom alert firesSLO burn, runbook2Dashboard narrows itroute, service, release3Trace shows the slow spanDB, API, task4Logs by request IDexact context5Fix, then add a signalclose the gapEach layer narrows the search until the cause is obviousdjango-deployment.com
After each incident, ask which missing signal would have saved time.

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

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.

Learning path · step 12 of 13

Keeping it running

Keep going