You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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)

问题原因与解决方法

  1. Prometheus::Client::Push不支持Remote Write
    这个类是专门给Pushgateway设计的,它会在你传入的gateway地址后追加Pushgateway的特定路径(比如/metrics/job/...),而Prometheus的Remote Write API不需要这些额外路径,直接请求/api/v1/write即可,这就导致最终请求的URL不存在,触发404。另外你代码里用了https,但Prometheus默认没开启HTTPS,这也是问题之一。

  2. 实现Remote Write的正确方式
    Ruby的prometheus-client gem没有直接提供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表示推送成功
    
  3. 额外注意事项

    • 确保Rails容器和Prometheus在同一网络:你用了自定义网络prom,所以直接用prometheus:9090是可以正常访问的。
    • 如果追求更高性能,可以改用Protobuf格式的Remote Write,但文本格式足够满足大部分场景需求。
    • 建议把推送逻辑封装成一个单独的服务类,在Rails应用的合适时机(比如请求结束后、定时任务执行完成后)调用。

内容的提问来源于stack exchange,提问作者Jerry Fang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 19:17:52