forked from prometheus/client_ruby
-
Notifications
You must be signed in to change notification settings - Fork 0
/
collector.rb
84 lines (72 loc) · 2.47 KB
/
collector.rb
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# encoding: UTF-8
require 'prometheus/client'
module Prometheus
module Client
module Rack
# Collector is a Rack middleware that provides a sample implementation of
# a HTTP tracer. The default label builder can be modified to export a
# different set of labels per recorded metric.
class Collector
attr_reader :app, :registry
def initialize(app, options = {}, &label_builder)
@app = app
@registry = options[:registry] || Client.registry
@label_builder = label_builder || DEFAULT_LABEL_BUILDER
init_request_metrics
init_exception_metrics
end
def call(env) # :nodoc:
trace(env) { @app.call(env) }
end
protected
DEFAULT_LABEL_BUILDER = proc do |env|
{
method: env['REQUEST_METHOD'].downcase,
host: env['HTTP_HOST'].to_s,
path: env['PATH_INFO'].to_s,
}
end
def init_request_metrics
@requests = @registry.counter(
:http_requests_total,
'A counter of the total number of HTTP requests made.')
@requests_duration = @registry.counter(
:http_request_duration_total_microseconds,
'The total amount of time spent answering HTTP requests ' \
'(microseconds).')
@durations = @registry.summary(
:http_request_duration_microseconds,
'A histogram of the response latency (microseconds).')
end
def init_exception_metrics
@exceptions = @registry.counter(
:http_exceptions_total,
'A counter of the total number of exceptions raised.')
end
def trace(env)
start = Time.now
yield.tap do |response|
duration = ((Time.now - start) * 1_000_000).to_i
record(labels(env, response), duration)
end
rescue => exception
@exceptions.increment(exception: exception.class.name)
raise
end
def labels(env, response)
@label_builder.call(env).tap do |labels|
labels[:code] = response.first.to_s
end
end
def record(labels, duration)
@requests.increment(labels)
@requests_duration.increment(labels, duration)
@durations.add(labels, duration)
rescue
# TODO: log unexpected exception during request recording
nil
end
end
end
end
end