Python prometheus_client实现exporter多目标采集参数传递问题求助
问题根因
你当前的exporter采用全局固定注册Collector的实现方式,启动时就把REST API地址写死了,完全不会读取每次Prometheus采集请求携带的target参数,所以所有请求都会访问同一个固定地址。
解决方案
1. 修改exporter代码
调整逻辑为每次收到Prometheus的/probe采集请求时,动态解析请求中的target参数,再传入采集逻辑调用REST API:
from prometheus_client import GaugeMetricFamily, generate_latest, CollectorRegistry, CONTENT_TYPE_LATEST import json import requests import sys from http.server import BaseHTTPRequestHandler, HTTPServer import urllib.parse as urlparse class JsonCollector(object): def __init__(self, rest_base_url, target): self._rest_base_url = rest_base_url self._target = target def collect(self): # 可根据实际需求调整target传递给REST API的逻辑 # 示例为将target作为查询参数传给REST服务 query_params = {'target': self._target} response = requests.get(self._rest_base_url, params=query_params) response.raise_for_status() api_data = json.loads(response.content.decode('UTF-8')) metric = GaugeMetricFamily( 'my_metric_devices_status', 'blah blah', labels=["device"]) for p in api_data['devices']: host = p['host'] status= p['status'] metric.add_metric([host], float(status)) yield metric class ProbeHandler(BaseHTTPRequestHandler): rest_base_url = None def do_GET(self): # 可选:暴露exporter自身运行指标 if self.path == '/metrics': self.send_response(200) self.send_header('Content-Type', CONTENT_TYPE_LATEST) self.end_headers() self.wfile.write(generate_latest()) return # 处理多目标采集请求 if self.path.startswith('/probe'): parsed_path = urlparse.urlparse(self.path) query_params = urlparse.parse_qs(parsed_path.query) if 'target' not in query_params: self.send_error(400, 'Missing target parameter') return target = query_params['target'][0] # 每个请求创建独立采集实例,传入动态target registry = CollectorRegistry() registry.register(JsonCollector(self.rest_base_url, target)) self.send_response(200) self.send_header('Content-Type', CONTENT_TYPE_LATEST) self.end_headers() self.wfile.write(generate_latest(registry)) return self.send_error(404) if __name__ == '__main__': # 启动命令保持不变:python json_exporter.py port rest_base_url port = int(sys.argv[1]) ProbeHandler.rest_base_url = sys.argv[2] server = HTTPServer(('', port), ProbeHandler) server.serve_forever()
2. 配置与验证
你现有的Prometheus配置不需要修改,重启exporter后可手动访问http://localhost:1234/probe?target=my_target1验证:检查REST服务是否收到携带对应target参数的请求,返回的指标是否符合预期即可。
内容的提问来源于stack exchange,提问作者user721730
相关产品推荐
相关产品推荐

