Framework Guide
Django API Monitoring
Set up health check endpoints and uptime monitoring for your Django application. Works with Django REST Framework and standard Django views.
Simple Health View
# health/views.py
from django.http import JsonResponse
from datetime import datetime
def health(request):
return JsonResponse({
'status': 'healthy',
'timestamp': datetime.utcnow().isoformat()
})
# urls.py
from django.urls import path
from health import views
urlpatterns = [
path('health/', views.health, name='health'),
]
Comprehensive Health Check
# health/views.py
from django.http import JsonResponse
from django.db import connection
from django.core.cache import cache
from django.conf import settings
from datetime import datetime
import time
def health(request):
"""Liveness probe - just confirms Django is running"""
return JsonResponse({'status': 'healthy'})
def ready(request):
"""Readiness probe - checks all dependencies"""
checks = {}
healthy = True
# Check database
try:
start = time.time()
with connection.cursor() as cursor:
cursor.execute('SELECT 1')
cursor.fetchone()
checks['database'] = {
'status': 'ok',
'response_time_ms': round((time.time() - start) * 1000, 2)
}
except Exception as e:
healthy = False
checks['database'] = {'status': 'error', 'message': str(e)}
# Check cache (Redis/Memcached)
try:
start = time.time()
cache.set('health_check', 'ok', 10)
cache.get('health_check')
checks['cache'] = {
'status': 'ok',
'response_time_ms': round((time.time() - start) * 1000, 2)
}
except Exception as e:
healthy = False
checks['cache'] = {'status': 'error', 'message': str(e)}
response = {
'status': 'healthy' if healthy else 'unhealthy',
'timestamp': datetime.utcnow().isoformat(),
'checks': checks,
'version': getattr(settings, 'VERSION', 'unknown')
}
status_code = 200 if healthy else 503
return JsonResponse(response, status=status_code)
Using django-health-check
For a more robust solution, use the django-health-check package:
# Install
pip install django-health-check
# settings.py
INSTALLED_APPS = [
# ...
'health_check',
'health_check.db',
'health_check.cache',
'health_check.storage',
'health_check.contrib.migrations',
'health_check.contrib.celery', # if using Celery
'health_check.contrib.redis', # if using Redis
]
# urls.py
urlpatterns = [
path('health/', include('health_check.urls')),
]
Django REST Framework
# health/views.py
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework import status
from django.db import connection
@api_view(['GET'])
@permission_classes([AllowAny])
def health(request):
return Response({'status': 'healthy'})
@api_view(['GET'])
@permission_classes([AllowAny])
def ready(request):
try:
with connection.cursor() as cursor:
cursor.execute('SELECT 1')
return Response({
'status': 'healthy',
'checks': {'database': 'ok'}
})
except Exception as e:
return Response({
'status': 'unhealthy',
'checks': {'database': str(e)}
}, status=status.HTTP_503_SERVICE_UNAVAILABLE)
Exclude from Middleware
Skip authentication and logging for health checks:
# middleware.py
class HealthCheckMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if request.path in ['/health/', '/ready/']:
# Skip other middleware for health checks
from health.views import health
return health(request)
return self.get_response(request)
Best Practices
- Separate liveness and readiness — /health for "is Django running", /ready for "are dependencies working"
- Skip authentication — Monitoring services need unauthenticated access
- Check migrations — Ensure database schema is up to date
- Add timeouts — Don't let slow checks hang forever