0
# Metrics Export
1
2
Export Prometheus metrics through Django views or standalone HTTP servers, with support for multiprocess environments and flexible deployment configurations.
3
4
## Capabilities
5
6
### Django View Export
7
8
Export Prometheus metrics as a standard Django HTTP response, integrating with Django's URL routing and middleware stack.
9
10
```python { .api }
11
def ExportToDjangoView(request):
12
"""
13
Exports /metrics as a Django view.
14
15
You can use django_prometheus.urls to map /metrics to this view.
16
Handles multiprocess environments automatically.
17
18
Parameters:
19
- request: Django HttpRequest object
20
21
Returns:
22
HttpResponse with Prometheus metrics data and appropriate content type
23
"""
24
```
25
26
### Standalone HTTP Server Export
27
28
Run dedicated HTTP servers for metrics export, independent of Django's application server.
29
30
```python { .api }
31
def SetupPrometheusEndpointOnPort(port: int, addr: str = ""):
32
"""
33
Exports Prometheus metrics on HTTPServer running in its own thread.
34
35
The server runs on the given port and listens on all interfaces by default.
36
This HTTPServer is fully independent of Django and its stack, providing
37
metrics even if Django becomes unresponsive.
38
39
Cannot be used when Django's autoreloader is active (development mode).
40
41
Parameters:
42
- port: int, port number to serve metrics on
43
- addr: str, address to bind to (default: "" for all interfaces)
44
45
Raises:
46
AssertionError: When called with Django autoreloader active
47
"""
48
49
def SetupPrometheusEndpointOnPortRange(port_range, addr: str = ""):
50
"""
51
Like SetupPrometheusEndpointOnPort, but tries several ports.
52
53
Useful for WSGI applications with multiple processes where each
54
worker needs its own metrics port for Prometheus scraping.
55
56
Parameters:
57
- port_range: iterable, ports to try (e.g., range(8001, 8010))
58
- addr: str, address to bind to (default: "" for all interfaces)
59
60
Returns:
61
int or None: Port number chosen, or None if no port available
62
63
Raises:
64
AssertionError: When called with Django autoreloader active
65
"""
66
67
def SetupPrometheusExportsFromConfig():
68
"""
69
Exports metrics based on Django settings configuration.
70
71
Automatically called by DjangoPrometheusConfig.ready().
72
Reads PROMETHEUS_METRICS_EXPORT_* settings and configures appropriate export method.
73
"""
74
```
75
76
### HTTP Server Thread Management
77
78
```python { .api }
79
class PrometheusEndpointServer(threading.Thread):
80
"""
81
A thread class that holds an HTTP server and makes it serve_forever().
82
Used internally by port-based export functions.
83
"""
84
85
def __init__(self, httpd, *args, **kwargs):
86
"""
87
Initialize server thread.
88
89
Parameters:
90
- httpd: HTTPServer instance to run
91
- *args, **kwargs: Arguments passed to Thread.__init__
92
"""
93
94
def run(self):
95
"""Run the HTTP server forever in this thread."""
96
```
97
98
## Configuration
99
100
### Django Settings
101
102
Configure metrics export through Django settings:
103
104
```python { .api }
105
# settings.py
106
107
# Export metrics on a dedicated port (standalone HTTP server)
108
PROMETHEUS_METRICS_EXPORT_PORT = 8001
109
110
# Or export on a range of ports (for multiprocess deployments)
111
PROMETHEUS_METRICS_EXPORT_PORT_RANGE = range(8001, 8010)
112
113
# Bind to specific address (default: all interfaces)
114
PROMETHEUS_METRICS_EXPORT_ADDRESS = "127.0.0.1"
115
116
# Custom metric namespace
117
PROMETHEUS_METRIC_NAMESPACE = "myapp"
118
119
# Custom latency buckets
120
PROMETHEUS_LATENCY_BUCKETS = (0.1, 0.5, 1.0, 2.5, 5.0, 10.0, float('inf'))
121
```
122
123
### URL Configuration
124
125
Include metrics endpoint in Django URL configuration:
126
127
```python
128
# urls.py
129
from django.urls import path, include
130
131
urlpatterns = [
132
# Include django-prometheus URLs (provides /metrics endpoint)
133
path('', include('django_prometheus.urls')),
134
135
# Or manually configure the endpoint
136
path('metrics', ExportToDjangoView, name='prometheus-metrics'),
137
138
# Your application URLs
139
path('admin/', admin.site.urls),
140
path('api/', include('myapp.urls')),
141
]
142
```
143
144
## Usage Examples
145
146
### Django View Export
147
148
```python
149
# urls.py
150
from django.urls import path, include
151
152
urlpatterns = [
153
path('', include('django_prometheus.urls')), # Adds /metrics endpoint
154
# ... other URLs
155
]
156
157
# The /metrics endpoint will be available at http://your-site.com/metrics
158
# and will return Prometheus-formatted metrics
159
```
160
161
### Standalone Port Export
162
163
```python
164
# settings.py
165
PROMETHEUS_METRICS_EXPORT_PORT = 8001
166
167
# apps.py or any Django app configuration
168
from django_prometheus.exports import SetupPrometheusEndpointOnPort
169
170
class MyAppConfig(AppConfig):
171
def ready(self):
172
# Metrics will be available on http://localhost:8001/metrics
173
# This happens automatically via DjangoPrometheusConfig.ready()
174
pass
175
```
176
177
### Multi-Process Export
178
179
```python
180
# settings.py for WSGI deployment with multiple workers
181
PROMETHEUS_METRICS_EXPORT_PORT_RANGE = range(8001, 8010)
182
183
# Each worker process will grab an available port in the range
184
# Prometheus can scrape all ports:
185
# - job_name: 'django-app'
186
# static_configs:
187
# - targets: ['localhost:8001', 'localhost:8002', 'localhost:8003']
188
```
189
190
### Manual Export Setup
191
192
```python
193
from django_prometheus.exports import SetupPrometheusEndpointOnPort, SetupPrometheusEndpointOnPortRange
194
195
# Manual port setup
196
def setup_metrics():
197
try:
198
SetupPrometheusEndpointOnPort(9090)
199
print("Metrics available on http://localhost:9090/metrics")
200
except AssertionError as e:
201
print(f"Cannot setup metrics server: {e}")
202
203
# Multi-port setup
204
def setup_metrics_multiprocess():
205
port = SetupPrometheusEndpointOnPortRange(range(9090, 9100))
206
if port:
207
print(f"Metrics available on http://localhost:{port}/metrics")
208
else:
209
print("No available ports for metrics server")
210
```
211
212
### Custom View Export
213
214
```python
215
from django.http import HttpResponse
216
from django_prometheus.exports import ExportToDjangoView
217
from django.views.decorators.csrf import csrf_exempt
218
219
@csrf_exempt
220
def custom_metrics_view(request):
221
"""Custom metrics endpoint with additional logic."""
222
if not request.user.is_authenticated:
223
return HttpResponse("Unauthorized", status=401)
224
225
# Add custom logic before metrics export
226
# ... logging, authentication, etc.
227
228
return ExportToDjangoView(request)
229
230
# urls.py
231
urlpatterns = [
232
path('admin/metrics', custom_metrics_view, name='admin-metrics'),
233
]
234
```
235
236
## Multiprocess Support
237
238
### Environment Variables
239
240
Django-prometheus automatically detects multiprocess environments:
241
242
```python
243
import os
244
245
# Set by gunicorn, uWSGI, or other WSGI servers
246
os.environ['PROMETHEUS_MULTIPROC_DIR'] = '/tmp/prometheus_metrics'
247
248
# Alternative environment variable
249
os.environ['prometheus_multiproc_dir'] = '/tmp/prometheus_metrics'
250
```
251
252
### Multiprocess Configuration
253
254
```python
255
# When multiprocess directory is set, metrics are aggregated across processes
256
from prometheus_client import multiprocess, CollectorRegistry
257
258
# This happens automatically in ExportToDjangoView
259
if "PROMETHEUS_MULTIPROC_DIR" in os.environ:
260
registry = CollectorRegistry()
261
multiprocess.MultiProcessCollector(registry)
262
else:
263
registry = prometheus_client.REGISTRY
264
```
265
266
## Deployment Patterns
267
268
### Single Process (Development)
269
270
```python
271
# settings.py
272
PROMETHEUS_METRICS_EXPORT_PORT = 8001
273
274
# Metrics available at http://localhost:8001/metrics
275
# Also available through Django at http://localhost:8000/metrics
276
```
277
278
### Gunicorn Deployment
279
280
```bash
281
# Start gunicorn with multiple workers
282
gunicorn --workers 4 --bind 0.0.0.0:8000 myproject.wsgi
283
284
# With multiprocess metrics
285
export PROMETHEUS_MULTIPROC_DIR=/tmp/prometheus_metrics
286
mkdir -p $PROMETHEUS_MULTIPROC_DIR
287
gunicorn --workers 4 --bind 0.0.0.0:8000 myproject.wsgi
288
```
289
290
### Docker Deployment
291
292
```dockerfile
293
# Dockerfile
294
EXPOSE 8000 8001
295
ENV PROMETHEUS_METRICS_EXPORT_PORT=8001
296
297
# Metrics will be available on port 8001
298
# Application on port 8000
299
```
300
301
### Kubernetes Deployment
302
303
```yaml
304
# deployment.yaml
305
spec:
306
template:
307
metadata:
308
annotations:
309
prometheus.io/scrape: "true"
310
prometheus.io/port: "8001"
311
prometheus.io/path: "/metrics"
312
spec:
313
containers:
314
- name: django-app
315
ports:
316
- containerPort: 8000 # Django app
317
- containerPort: 8001 # Metrics
318
env:
319
- name: PROMETHEUS_METRICS_EXPORT_PORT
320
value: "8001"
321
```
322
323
## Security Considerations
324
325
- Metrics may contain sensitive information (response times, error rates, etc.)
326
- Consider authentication for metrics endpoints in production
327
- Separate metrics ports can be firewalled differently than application ports
328
- Monitor access to metrics endpoints in security logs
329
330
## Troubleshooting
331
332
### Common Issues
333
334
```python
335
# Django autoreloader conflict
336
AssertionError: The thread-based exporter can't be safely used when django's autoreloader is active
337
338
# Solution: Use --noreload in development or use URL exporter
339
python manage.py runserver --noreload
340
341
# Or use URL-based export instead of port-based export
342
```
343
344
### Port Conflicts
345
346
```python
347
# When port is already in use
348
OSError: [Errno 48] Address already in use
349
350
# Solution: Use port range instead of fixed port
351
PROMETHEUS_METRICS_EXPORT_PORT_RANGE = range(8001, 8010)
352
```