or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cache-monitoring.mddatabase-monitoring.mdhttp-monitoring.mdindex.mdmetrics-export.mdmigration-monitoring.mdmodel-monitoring.mdtesting-utilities.md

metrics-export.mddocs/

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

```