Django Integration¶
This guide shows how to integrate the Gunicorn Prometheus Exporter with Django applications.
Quick Start¶
1. Install Dependencies¶
2. Create Django Project (if needed)¶
3. Create Gunicorn Configuration¶
Create gunicorn.conf.py
in your Django project root:
# gunicorn.conf.py
import os
import sys
# Add the project directory to Python path
sys.path.insert(0, os.path.dirname(__file__))
# Server settings
bind = "0.0.0.0:8000"
workers = 4
worker_class = "gunicorn_prometheus_exporter.PrometheusWorker" # Sync worker
# Alternative worker types:
# worker_class = "gunicorn_prometheus_exporter.PrometheusThreadWorker" # Thread worker
# worker_class = "gunicorn_prometheus_exporter.PrometheusEventletWorker" # Eventlet worker
# worker_class = "gunicorn_prometheus_exporter.PrometheusGeventWorker" # Gevent worker
master_class = "gunicorn_prometheus_exporter.PrometheusMaster"
# Environment variables
raw_env = [
"PROMETHEUS_METRICS_PORT=9091",
"PROMETHEUS_MULTIPROC_DIR=/tmp/prometheus_multiproc",
"GUNICORN_WORKERS=4",
"DJANGO_SETTINGS_MODULE=myproject.settings"
]
# Prometheus hooks
when_ready = "gunicorn_prometheus_exporter.default_when_ready"
on_starting = "gunicorn_prometheus_exporter.default_on_starting"
worker_int = "gunicorn_prometheus_exporter.default_worker_int"
on_exit = "gunicorn_prometheus_exporter.default_on_exit"
# Django-specific settings
preload_app = True
4. Start Django with Gunicorn¶
Advanced Configuration¶
Production Django Setup¶
# gunicorn.conf.py
import os
import sys
sys.path.insert(0, os.path.dirname(__file__))
# Server settings
bind = "0.0.0.0:8000"
workers = 8
worker_class = "gunicorn_prometheus_exporter.PrometheusWorker"
master_class = "gunicorn_prometheus_exporter.PrometheusMaster"
# Environment variables
raw_env = [
"PROMETHEUS_METRICS_PORT=9091",
"PROMETHEUS_MULTIPROC_DIR=/var/lib/prometheus/multiproc",
"GUNICORN_WORKERS=8",
"DJANGO_SETTINGS_MODULE=myproject.settings",
"GUNICORN_TIMEOUT=30"
]
# Prometheus hooks
when_ready = "gunicorn_prometheus_exporter.default_when_ready"
on_starting = "gunicorn_prometheus_exporter.default_on_starting"
worker_int = "gunicorn_prometheus_exporter.default_worker_int"
on_exit = "gunicorn_prometheus_exporter.default_on_exit"
# Django optimizations
preload_app = True
max_requests = 1000
max_requests_jitter = 50
worker_connections = 1000
# Logging
loglevel = "info"
accesslog = "-"
errorlog = "-"
Django Settings Configuration¶
Add to your settings.py
:
# settings.py
# Static files (if serving with Django)
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
# Security settings for production
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = 'DENY'
# Logging configuration
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'root': {
'handlers': ['console'],
'level': 'INFO',
},
}
🐳 Docker Setup¶
Dockerfile¶
FROM python:3.9-slim
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y \
gcc \
&& rm -rf /var/lib/apt/lists/*
# Install Python dependencies
COPY requirements.txt .
RUN pip install -r requirements.txt
RUN pip install gunicorn gunicorn-prometheus-exporter
# Copy Django project
COPY . .
# Create necessary directories
RUN mkdir -p /tmp/prometheus_multiproc
RUN mkdir -p staticfiles
# Collect static files
RUN python manage.py collectstatic --noinput
# Expose ports
EXPOSE 8000 9091
# Set environment variables
ENV PROMETHEUS_METRICS_PORT=9091
ENV PROMETHEUS_MULTIPROC_DIR=/tmp/prometheus_multiproc
ENV GUNICORN_WORKERS=4
ENV DJANGO_SETTINGS_MODULE=myproject.settings
# Start with gunicorn
CMD ["gunicorn", "-c", "gunicorn.conf.py", "myproject.wsgi:application"]
Docker Compose¶
# docker-compose.yml
version: "3.8"
services:
web:
build: .
ports:
- "8000:8000"
- "9091:9091"
environment:
- PROMETHEUS_METRICS_PORT=9091
- PROMETHEUS_MULTIPROC_DIR=/tmp/prometheus_multiproc
- GUNICORN_WORKERS=4
- DJANGO_SETTINGS_MODULE=myproject.settings
volumes:
- prometheus_data:/tmp/prometheus_multiproc
- static_files:/app/staticfiles
prometheus:
image: prom/prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
volumes:
prometheus_data:
static_files:
Prometheus Configuration¶
prometheus.yml¶
global:
scrape_interval: 15s
scrape_configs:
- job_name: "django-gunicorn"
static_configs:
- targets: ["your-app-host:9091"] # Replace with your application hostname
metrics_path: /metrics
scrape_interval: 5s
Monitoring Django-Specific Metrics¶
Custom Django Metrics (Optional)¶
You can extend the monitoring with Django-specific metrics:
# myproject/metrics.py
from prometheus_client import Counter, Histogram
from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin
# Django-specific metrics
django_requests_total = Counter(
'django_requests_total',
'Total Django requests',
['method', 'endpoint', 'status']
)
django_request_duration = Histogram(
'django_request_duration_seconds',
'Django request duration',
['method', 'endpoint']
)
class PrometheusMiddleware(MiddlewareMixin):
def process_request(self, request):
request.start_time = time.time()
def process_response(self, request, response):
if hasattr(request, 'start_time'):
duration = time.time() - request.start_time
django_request_duration.labels(
method=request.method,
endpoint=request.path
).observe(duration)
django_requests_total.labels(
method=request.method,
endpoint=request.path,
status=response.status_code
).inc()
return response
Add to settings.py
:
Troubleshooting¶
Common Django Issues¶
- Static Files Not Found
- Database Connection Issues
- Settings Module Not Found
Debug Mode¶
For development, you can enable Django debug mode:
📈 Performance Tips¶
- Use Database Connection Pooling
# settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydb',
'CONN_MAX_AGE': 600, # 10 minutes
}
}
- Enable Caching
# settings.py
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
}
}
- Optimize Static Files