flask应用暴露prometheus指标端点,必须通过/metrics路由返回符合openmetrics文本协议的响应,推荐使用prometheus_client的make_wsgi_app()注册,而非手动拼接字符串;多进程部署需启用multiprocesscollector并设置prometheus_multiproc_dir环境变量。

Flask 应用如何暴露 Prometheus 指标端点?
Prometheus 不主动拉取 Flask 应用数据,必须由 Flask 主动暴露 /metrics 端点,且返回内容需严格符合 Prometheus 文本格式(以 # HELP 开头、metric_name{label="value"} value timestamp 结构)。直接手写格式极易出错,推荐用 prometheus_client 库。
- 安装:
pip install prometheus-client - 在 Flask 初始化后注册指标收集器:
from prometheus_client import Counter, Gauge, make_wsgi_app,然后用app.add_url_rule('/metrics', 'metrics', make_wsgi_app) - 注意:不要用
@app.route('/metrics')自定义视图返回字符串——make_wsgi_app内部已处理 Content-Type、编码和多进程并发安全问题 - 若用 Gunicorn 部署,必须启用
prometheus_client.multiprocess.MultiProcessCollector并设置PROMETHEUS_MULTIPROC_DIR环境变量,否则指标会丢失或重复
怎么定义并更新自定义业务指标(如请求成功率、处理延迟)?
业务指标不是“埋点”完就结束,关键在何时、在哪、以什么粒度更新。比如统计「订单创建失败率」,不能只在异常分支里 counter.inc(),而要统一在请求生命周期末尾做原子更新。
- 用
Counter记录事件次数(如order_created_total = Counter('order_created_total', 'Total orders created', ['status'])),成功/失败都调用order_created_total.labels(status='success').inc()或.labels(status='failed').inc() - 用
Histogram测延迟:request_latency_seconds = Histogram('request_latency_seconds', 'Request latency in seconds', ['endpoint']),配合with request_latency_seconds.labels(endpoint=request.endpoint).time():包裹核心逻辑 - 避免在循环内高频调用
.inc()或.observe()—— 这会显著拖慢响应;若需每秒数千次计数,改用Gauge+ 后台线程聚合再批量更新 - 标签(
labels)不宜过多(建议 ≤5 个),且值应来自可控枚举(如 status=success/failed),避免用用户 ID、URL 参数等高基数字段,否则导致指标膨胀、Prometheus OOM
为什么本地调试时指标正常,上线后 /metrics 返回空或 404?
常见原因不是代码写错,而是部署环境与开发环境的隐式差异。
- Gunicorn 启动时未传递
--preload参数,导致make_wsgi_app在 worker 进程中初始化失败(指标注册只发生在主进程) - 使用了
flask run命令启动,但make_wsgi_app依赖 WSGI 环境,此时app.add_url_rule注册无效(需改用gunicorn app:app) - Nginx 反向代理拦截了
/metrics路径,或配置了location / { ... }但没显式放行/metrics,返回 404 - 多进程下未设置
PROMETHEUS_MULTIPROC_DIR,且该目录不存在或无写权限,make_wsgi_app静默失败,返回空响应体(HTTP 200 但 body 为空)
如何验证指标是否被 Prometheus 正确采集?
别只看 Grafana 图表,先确认原始数据链路畅通。
- 手动访问
curl @#@#@#@#@#@#@#@#@#@0,检查响应头Content-Type: text/plain; version=0.0.4; charset=utf-8,且 body 中有你定义的指标名(如order_created_total),无 Python traceback - 登录 Prometheus Web UI,进入
@#@#@#@#@#@#@#@#@#@1,确认你的 Flask job 状态为 UP,Last Scrape 时间距现在 ≤30 秒 - 在 Prometheus 表达式浏览器输入
order_created_total,看是否有时间序列返回;若无,检查指标名拼写、标签是否匹配(Prometheus 区分大小写,且 label 值带引号) - 如果用了
MultiProcessCollector,确保所有 worker 进程的PROMETHEUS_MULTIPROC_DIR指向同一目录,且该目录下有多个*.db文件(每个 worker 一个)
Flask 的 Prometheus 集成看似简单,真正卡点往往在部署时的进程模型、路径代理、多进程指标合并这些细节上。指标名拼错能立刻发现,但标签爆炸或采集间隔错配,可能要等几小时后才在 Grafana 上看到异常曲线。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











