django-prometheus可快速暴露指标端点,自动集成django中间件、数据库、缓存等默认指标,但不兼容django 4.2+ asgi模式;需配置installed_apps、middleware及url路由,自定义指标须用prometheus-client单独注册并全局复用,多进程部署需设置prometheus_multiproc_dir。

用 django-prometheus 快速暴露指标端点
直接装 django-prometheus 是最省事的方案,它自动集成 Django 中间件、数据库、缓存等组件的默认指标,不需要手动写 Counter 或 Gauge。但要注意:它不兼容 Django 4.2+ 的新中间件协议(ASGI 模式下部分钩子失效),如果你用的是 runserver 或 WSGI 部署(如 Gunicorn + Nginx),没问题;若跑在 Uvicorn + ASGI 下,得降级到 django-prometheus==2.3.1 或改用 prometheus-client 手动注册。
安装和配置步骤:
- 运行
pip install django-prometheus - 在
INSTALLED_APPS开头加入'django_prometheus' - 把
'django_prometheus.middleware.PrometheusBeforeMiddleware'和'django_prometheus.middleware.PrometheusAfterMiddleware'加入MIDDLEWARE最前和最后 - URL 路由中添加
path('metrics/', include('django_prometheus.urls'))
启动后访问 /metrics/ 就能看到 django_http_requests_total、django_db_queries_total 等原生指标 —— 这些是开箱即用的,不用额外编码。
自定义业务指标必须用 prometheus-client 注册
django-prometheus 不提供自由创建指标的 API,想监控“用户登录失败次数”或“订单创建耗时”,得引入 prometheus-client 单独管理。关键点在于:指标对象必须全局唯一且复用,不能每次请求都新建 Counter,否则会触发 ValueError: Duplicated timeseries in CollectorRegistry。
推荐做法:
- 在 Django app 的
apps.py里定义指标变量,例如:from prometheus_client import Counter<br><br>login_failure_counter = Counter(<br> 'myapp_login_failures_total',<br> 'Total number of failed login attempts',<br> ['reason'] # 带标签维度<br>)
- 在视图或信号中调用
login_failure_counter.labels(reason='wrong_password').inc() - 避免在函数内部初始化指标,尤其别放在视图函数体里
注意:Django 多进程部署(如 Gunicorn 多 worker)下,prometheus-client 默认的内存 registry 无法跨进程聚合。此时必须用 MultiProcessCollector,并在启动 Gunicorn 前设置环境变量 PROMETHEUS_MULTIPROC_DIR 指向可写目录。
让 Prometheus 正确抓取 metrics 端点的路径和权限
默认 /metrics/ 是 Django URL 路由的一部分,Prometheus 抓取时会走完整请求生命周期 —— 包括中间件、CSRF 校验、认证等。如果开了 LOGIN_REQUIRED = True 或用了 django.contrib.auth.middleware.AuthenticationMiddleware,未登录用户(包括 Prometheus)会收到 302 跳转或 403,导致抓取失败。
解决办法只有两个:
- 给 metrics 路由加白名单中间件,跳过认证(推荐):
class MetricsAuthSkipMiddleware:<br> def __init__(self, get_response):<br> self.get_response = get_response<br><br> def __call__(self, request):<br> if request.path == '/metrics/':<br> # 清除用户认证状态,避免后续中间件拦截<br> request.user = None<br> request._cached_user = None<br> return self.get_response(request)
然后把这个中间件放在AuthenticationMiddleware之前 - 或者把 metrics 端点移到 Nginx 层反代,绕过 Django(更安全,但需额外配置)
另外,Prometheus 抓取目标要写对:如果是 Docker 部署,targets 不能填 localhost:8000(容器内 localhost 指自己),得填宿主机 IP 或服务名,比如 my-django-app:8000。
Gunicorn 多 worker 下的计数器不准确?检查 multiproc_dir 权限和生命周期
即使用了 MultiProcessCollector,仍可能发现指标值忽高忽低、甚至归零 —— 常见原因是 PROMETHEUS_MULTIPROC_DIR 目录被清理了,或 Gunicorn worker 重启时没正确清理旧文件。
验证和修复步骤:
- 确认该目录存在且所有 Gunicorn worker 进程都有读写权限(建议设为
/tmp/prometheus-metrics,并chmod 755) - 启动 Gunicorn 前执行
rm -f /tmp/prometheus-metrics/*.db,避免残留文件干扰 - 在 settings.py 中显式初始化 collector:
import os<br>from prometheus_client import multiprocess<br><br>if 'PROMETHEUS_MULTIPROC_DIR' in os.environ:<br> multiprocess.MultiProcessCollector(<br> registry, # 你的 custom registry<br> path=os.environ['PROMETHEUS_MULTIPROC_DIR']<br> )
- 抓取
/metrics时,响应头部应含X-Prometheus-Scrape-Timeout-Seconds,否则 collector 未生效
真正容易被忽略的是:Django 的 manage.py runserver 是单线程开发服务器,MultiProcessCollector 完全无效,调试时看到的指标只是当前线程的,上线前务必切到 Gunicorn 并验证多 worker 行为。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











