如何让Python Prometheus自定义Exporter按设定频率运行?
解决Python Prometheus自定义Exporter定时更新指标的问题
问题根源
Prometheus采用拉取式工作模式,只有当Prometheus服务器主动向Exporter发起请求时,你的collect()方法才会执行,用来返回当前指标值。你之前的循环调用collect()只是生成了临时指标对象,并不会更新注册中心里的Collector实例所关联的指标数据。
修正方案
把指标值的更新逻辑与collect()方法分离:在定时循环里更新存储指标的变量,collect()仅负责读取当前变量值并返回给Prometheus。
修正后的代码:
import time import random from prometheus_client.core import GaugeMetricFamily, REGISTRY, CounterMetricFamily from prometheus_client import start_http_server # 存储指标的全局变量,定时更新这些值 current_random_num = 0 total_random_num = 0 class RandomNumberCollector(object): def collect(self): # 返回当前的Gauge指标值 gauge = GaugeMetricFamily( "random_number", "实时随机数", labels=["randomNum"] ) gauge.add_metric(['random_num'], current_random_num) yield gauge # 返回当前的Counter指标值 count = CounterMetricFamily( "random_number_total", "累加随机数总和", labels=['randomNum'] ) count.add_metric(['random_num'], total_random_num) yield count if __name__ == "__main__": start_http_server(9000) # 仅需注册一次Collector实例 REGISTRY.register(RandomNumberCollector()) # 定时更新指标变量 while True: current_random_num = random.randint(1, 20) total_random_num += random.randint(1, 30) time.sleep(1)
关键改动说明
- 将随机数生成逻辑从
collect()移到主循环,定时更新全局变量 collect()仅读取当前变量值,生成指标返回给Prometheus拉取- 只注册一次Collector实例,无需每次循环创建新实例
参考博客核心内容翻译
构建Python自定义Prometheus Exporter
Prometheus Exporter是用于暴露监控指标的服务,供Prometheus服务器拉取数据。自定义Exporter的核心是实现Collector接口,重写collect()方法定义指标规则。
基础结构:
- 用
prometheus_client库的start_http_server启动HTTP服务,指定指标暴露端口 - 自定义Collector类,实现
collect()方法,返回GaugeMetricFamily或CounterMetricFamily类型的指标 - 将Collector实例注册到
REGISTRY,Prometheus拉取时会自动调用该实例的collect()方法
- 用
常见指标类型:
- Gauge:可增可减的指标,适合记录当前状态(如内存使用率、实时随机数)
- Counter:只增不减的指标,适合记录累计值(如请求总数、累加随机数总和)
注意事项:
collect()方法会在每次Prometheus拉取时执行,避免在其中处理耗时操作- 指标命名需符合Prometheus规范(小写字母、下划线分隔)
- 若需定时更新指标值,应在独立循环中更新存储指标的变量,而非在
collect()中动态生成值(除非每次拉取都需要实时计算)
内容的提问来源于stack exchange,提问作者Bharath
相关产品推荐
相关产品推荐

