Python如何在单端口下挂载多个Prometheus CollectorRegistry导出指标
问题根因
你之前的实现错误核心有两点:
- prometheus_client自带的
start_http_server是单实例阻塞服务,同一端口无法重复启动,且默认仅会将单个Registry的指标暴露在/metrics路径下 - 你给Collector的
collect()方法加路由、启动前判断PATH_INFO的逻辑完全不生效:collect()是Registry调用采集器的内部方法,不是HTTP handler;PATH_INFO是HTTP请求携带的参数,进程启动时还未收到任何请求,此时的判断没有任何意义
可行方案
方案1:两个采集器合并到同一Registry(无需分路径,最简实现)
如果你不需要把两类指标拆分到不同路径返回,直接把两个采集器注册到同一个Registry即可,只启动一次HTTP服务,所有指标都在默认的/metrics路径返回:
from prometheus_client import CollectorRegistry, start_http_server # 初始化唯一Registry,注册两个采集器 registry = CollectorRegistry() registry.register(JenkinsCollector(jenkinsInstances=jenkinsInstances)) registry.register(pollScm(jenkinsInstances=jenkinsInstances)) # 只启动一次HTTP服务 start_http_server(port=9759, registry=registry)
方案2:自定义HTTP服务实现多路径对应多Registry(需要分路径的场景)
如果确实需要按路径区分返回不同指标,不要用自带的start_http_server,自己实现轻量HTTP服务,用prometheus_client提供的generate_latest()方法序列化对应Registry的指标即可,这里给Flask实现的示例:
from flask import Flask, Response from prometheus_client import CollectorRegistry, generate_latest app = Flask(__name__) # 预先初始化两个Registry,分别注册对应采集器 registry_node = CollectorRegistry() registry_node.register(JenkinsCollector(jenkinsInstances=jenkinsInstances)) registry_scm = CollectorRegistry() registry_scm.register(pollScm(jenkinsInstances=jenkinsInstances)) # 定义不同路由返回对应Registry的指标 @app.route("/collectormetrics") def get_jenkins_metrics(): return Response(generate_latest(registry_node), mimetype="text/plain; version=0.0.4; charset=utf-8") @app.route("/pollmetrics") def get_scm_metrics(): return Response(generate_latest(registry_scm), mimetype="text/plain; version=0.0.4; charset=utf-8") if __name__ == "__main__": # 启动Flask服务,监听9759端口即可 app.run(host="0.0.0.0", port=9759)
如果不想引入Flask依赖,用Python标准库的http.server实现对应路由逻辑也可以,核心就是收到对应路径的请求时,调用generate_latest(对应Registry)返回序列化后的指标数据即可。
内容的提问来源于stack exchange,提问作者ben amara marwa
相关产品推荐
相关产品推荐

