如何在Ruby on Rails中通过Remote Write向Prometheus发送指标
在Ruby on Rails中通过Remote Write向Prometheus推送指标的实现问题
近期尝试通过Remote Write向Prometheus发送指标,但在prometheus-client的文档里找不到相关示例,只看到Prometheus::Client::Push方法,不过这个是配合Pushgateway用的。想知道有没有人在Ruby on Rails里实现过Remote Write方式推送指标。
当前配置与操作步骤
Docker Compose配置
version: '3' services: prometheus: image: prom/prometheus volumes: - /Users/jerryfang/pratice_rails/prometheus.yml:/etc/prometheus/prometheus.yml ports: - 9090:9090 web: build: . ports: - 3000:3000 volumes: - .:/app depends_on: - prometheus networks: default: name: prom
Prometheus配置文件
global: scrape_interval: 15s scrape_timeout: 10s evaluation_interval: 15s alerting: alertmanagers: - follow_redirects: true enable_http2: true scheme: http timeout: 10s api_version: v2 static_configs: - targets: [] scrape_configs: - job_name: prom_test honor_timestamps: true scrape_interval: 15s scrape_timeout: 10s metrics_path: /metrics scheme: http static_configs: - targets: - web:3000 remote_write: - url: http://prometheus:9090/api/v1/write
使用的Gem
gem "prometheus-client"
执行的测试代码(Rails控制台)
require 'prometheus/client/push' registry = Prometheus::Client.registry counter = Prometheus::Client::Counter.new(:my_counter, docstring: 'A counter of things') registry.register(counter) Prometheus::Client::Push.new( job: 'Jerry_test', gateway: 'https://prometheus:9090/api/v1/write', ).add(registry)
遇到的错误
Prometheus::Client::Push::HttpClientError (status: 404, message: Not Found, body: 404 page not found)
问题原因与解决方法
Prometheus::Client::Push不支持Remote Write
这个类是专门给Pushgateway设计的,它会在你传入的gateway地址后追加Pushgateway的特定路径(比如/metrics/job/...),而Prometheus的Remote Write API不需要这些额外路径,直接请求/api/v1/write即可,这就导致最终请求的URL不存在,触发404。另外你代码里用了https,但Prometheus默认没开启HTTPS,这也是问题之一。实现Remote Write的正确方式
Ruby的prometheus-clientgem没有直接提供Remote Write的客户端,你需要自己构造符合要求的请求:- 先把registry里的指标转换成Prometheus文本格式
- 用HTTP客户端POST到Remote Write的API地址,设置正确的
Content-Type
示例代码:
require 'prometheus/client' require 'net/http' require 'uri' # 初始化并更新指标 registry = Prometheus::Client.registry counter = Prometheus::Client::Counter.new(:my_counter, docstring: 'A counter of things') registry.register(counter) counter.increment # 先给指标加个值,不然推送空指标意义不大 # 把指标转换成Prometheus文本格式 metric_text = registry.to_text # 发送Remote Write请求 uri = URI('http://prometheus:9090/api/v1/write') http = Net::HTTP.new(uri.host, uri.port) request = Net::HTTP::Post.new(uri) request['Content-Type'] = 'text/plain; version=0.0.4' request.body = metric_text response = http.request(request) puts "请求返回码: #{response.code}" # 返回200表示推送成功额外注意事项
- 确保Rails容器和Prometheus在同一网络:你用了自定义网络
prom,所以直接用prometheus:9090是可以正常访问的。 - 如果追求更高性能,可以改用Protobuf格式的Remote Write,但文本格式足够满足大部分场景需求。
- 建议把推送逻辑封装成一个单独的服务类,在Rails应用的合适时机(比如请求结束后、定时任务执行完成后)调用。
- 确保Rails容器和Prometheus在同一网络:你用了自定义网络
内容的提问来源于stack exchange,提问作者Jerry Fang
相关产品推荐
相关产品推荐

