Rails集成prometheus的几个经验

安装prometheus和设置指标

单纯地将prometheus集成进rails,整体上比较方便:

安装rometheus-client

  1. 在Gemfile中添加prometheus-client:
    1
    bundle add prometheus-client

引入prometheus 中间件

  1. 在config/application.rb中引入:
    1
    2
    require 'prometheus/middleware/exporter'
    config.middleware.use Prometheus::Middleware::Exporter

创建指标

新建文件 config/initializers/promethues.rb文件,在这里创建一些需要的指标。

1
2
3
4
require 'prometheus/client'
$prometheus = Prometheus::Client.registry
$metrics = {}
$metrics[:msgs_handled] = $prometheus.counter(:msgs_handled, docstring: 'A counter of messages handled')

在必要时,更新指标

比如,在某个controller方法中:

1
2
3
4
5
6
7
8
class SomeController << ApplicationController

def handle
#...
$metrics[:msgs_handled].increment
#...
end

检查指标是否输出

访问localhost:3000/metrics ,看是否输出了所有指标。

解决认证问题

默认情况下,用中间件方式引入prometheus,是开放访问的,我们可以给他加一个basic auth认证。

提示:请记得修改成自己的密码。

创建认证中间件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#lib/middleware/promethues_middleware.rb
# frozen_string_literal: true

# lib/middleware/prometheus_middleware.rb
require 'rack/auth/basic'

class PrometheusMiddleware
USERS = {"some-username" => "some-password"}
def initialize(app)
@app = app
end

def call(env)
auth = Rack::Auth::Basic::Request.new(env)

uri = env['REQUEST_URI'] || env['PATH_INFO']


if auth.provided? && auth.basic? && auth.credentials && USERS[auth.credentials.first] == auth.credentials.last
@app.call(env)
else
if uri == "/metrics"
unauthorized_response
else
@app.call(env)
end
end
end

def unauthorized_response
[401, {"Content-Type" => "text/plain","WWW-Authenticate"=>"Basic realm='metrics'"}, ["Unauthorized\n"]]
end
end

引入中间件

在config/application.rb中做一下修改:

1
2
3
4
5
6
7
8
9
10
11
class Application < Rails::Application
#.... some more


require 'prometheus/middleware/exporter'
require "#{Rails.root}/lib/middleware/prometheus_middleware"

config.middleware.use Prometheus::Middleware::Exporter
config.middleware.insert_before 0,PrometheusMiddleware

end

其他经验

通过rails c 进入控制台时,或者在crono任务中,是另外开启了新的进程,是无法更新到rails进程中的$metrics变量的,切记。
如果要用到定时任务,可以用rufus这个定时器。


Rails集成prometheus的几个经验
https://404.ms/2024/02/21/how-to-integrate-prometheus-with-rails/
作者
rocky.xander
发布于
2024年2月21日
许可协议