prometheus_exporter 0.1.16 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/CHANGELOG +4 -0
- data/README.md +29 -5
- data/lib/prometheus_exporter/instrumentation/delayed_job.rb +43 -0
- data/lib/prometheus_exporter/instrumentation/process.rb +4 -4
- data/lib/prometheus_exporter/instrumentation.rb +1 -0
- data/lib/prometheus_exporter/middleware.rb +38 -0
- data/lib/prometheus_exporter/server/collector.rb +11 -10
- data/lib/prometheus_exporter/server/delayed_job_collector.rb +42 -0
- data/lib/prometheus_exporter/server/process_collector.rb +10 -10
- data/lib/prometheus_exporter/server/sidekiq_collector.rb +10 -10
- data/lib/prometheus_exporter/server/web_collector.rb +16 -8
- data/lib/prometheus_exporter/server/web_server.rb +12 -12
- data/lib/prometheus_exporter/server.rb +1 -0
- data/lib/prometheus_exporter/version.rb +1 -1
- data/prometheus_exporter.gemspec +3 -0
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c30ea9a86408e636402bd2d12167b7a2da30970
|
4
|
+
data.tar.gz: 05657f39e1322fdc4f2c3886f16616dd21d0ce3c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b8c45beaac491fbc6673b3e9897ff0b91490ce34fdb68e4d393068056605696c300d757adc5869bd277e2d1facd0657156460cc09e9bbcbe5f3e8ac6ebdbdf0
|
7
|
+
data.tar.gz: efb69fc5380f233fb3564f782cfc8e2f978b4ca4fc78cba3d66ff96738b9c8804d213e980a8e9db63e833437353debddeab3251ecc515657c403ab013d82b6c9
|
data/.travis.yml
CHANGED
data/CHANGELOG
CHANGED
data/README.md
CHANGED
@@ -20,7 +20,11 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
$ gem install prometheus_exporter
|
22
22
|
|
23
|
-
##
|
23
|
+
## Ruby Version
|
24
|
+
|
25
|
+
Minimum Ruby of version 2.3.0 is required, Ruby 2.2.0 is EOL as of 2018-03-31
|
26
|
+
|
27
|
+
## Can I have some pretty pictures please?
|
24
28
|
|
25
29
|
Sure, check out: [Instrumenting Rails with Prometheus](https://samsaffron.com/archive/2018/02/02/instrumenting-rails-with-prometheus)
|
26
30
|
|
@@ -153,12 +157,32 @@ Sidekiq.configure_server do |config|
|
|
153
157
|
end
|
154
158
|
```
|
155
159
|
|
160
|
+
It also comes with a DelayedJob plugin.
|
161
|
+
|
162
|
+
```
|
163
|
+
# in an initializer
|
164
|
+
unless Rails.env == "test"
|
165
|
+
require 'prometheus_exporter/instrumentation'
|
166
|
+
PrometheusExporter::Instrumentation::DelayedJob.register_plugin
|
167
|
+
end
|
168
|
+
```
|
169
|
+
|
156
170
|
Ensure you run the exporter in a monitored background process via
|
157
171
|
|
158
172
|
```
|
159
173
|
% bundle exec prometheus_exporter
|
160
174
|
```
|
161
175
|
|
176
|
+
#### Instrumenting Request Queueing Time
|
177
|
+
|
178
|
+
Request Queueing is defined as the time it takes for a request to reach your application (instrumented by this `prometheus_exporter`) from farther upstream (as your load balancer). A high queueing time usually means that your backend cannot handle all the incoming requests in time, so they queue up (= you should see if you need to add more capacity)
|
179
|
+
|
180
|
+
As this metric starts before `prometheus_exporter` can handle the request, you must add a specific HTTP header as early in your infrastructure as possible (we recommend your load balancer or reverse proxy).
|
181
|
+
|
182
|
+
Configure your HTTP server / load balancer to add a header `X-Request-Start: t=<MSEC>` when passing the request upstream. For more information, please consult your software manual.
|
183
|
+
|
184
|
+
Hint: we aim to be API-compatible with the big APM solutions, so if you've got requests queueing time configured for them, it should be expected to also work with `prometheus_exporter`.
|
185
|
+
|
162
186
|
### Custom type collectors
|
163
187
|
|
164
188
|
In some cases you may have custom metrics you want to ship the collector in a batch, in this case you may still be interested in the base collector behavior but would like to add your own special messages.
|
@@ -205,7 +229,7 @@ bundle exec prometheus_exporter -a person_collector.rb
|
|
205
229
|
|
206
230
|
#### Global metrics in a custom type collector
|
207
231
|
|
208
|
-
Custom type collectors are the ideal place to collect global metrics, such as user/article counts and connection counts. The custom type collector runs in the collector which usually runs in the prometheus exporter process.
|
232
|
+
Custom type collectors are the ideal place to collect global metrics, such as user/article counts and connection counts. The custom type collector runs in the collector which usually runs in the prometheus exporter process.
|
209
233
|
|
210
234
|
Out-of-the-box we try to keep the prometheus exporter as lean as possible, we do not load all the Rails dependencies so you will not have access to your models. You can always ensure it is loaded in your custom type collector with:
|
211
235
|
|
@@ -218,14 +242,14 @@ end
|
|
218
242
|
Then you can collect the metrics you need on demand:
|
219
243
|
|
220
244
|
```
|
221
|
-
def metrics
|
245
|
+
def metrics
|
222
246
|
user_count_gague = PrometheusExporter::Metric::Gauge.new('user_count', 'number of users in the app')
|
223
247
|
user_count_gague.observe User.count
|
224
248
|
[user_count_gauge]
|
225
249
|
end
|
226
250
|
```
|
227
251
|
|
228
|
-
The metrics endpoint is called whenever prometheus calls the `/metrics` HTTP endpoint, it may make sense to introduce some caching so database calls are only performed once every N seconds. [lru_redux](https://github.com/SamSaffron/lru_redux) is the perfect gem for that kind of job as you can `LruRedux::TTL::Cache` which will automatically expire after N seconds.
|
252
|
+
The metrics endpoint is called whenever prometheus calls the `/metrics` HTTP endpoint, it may make sense to introduce some caching so database calls are only performed once every N seconds. [lru_redux](https://github.com/SamSaffron/lru_redux) is the perfect gem for that kind of job as you can `LruRedux::TTL::Cache` which will automatically expire after N seconds.
|
229
253
|
|
230
254
|
|
231
255
|
### Multi process mode with custom collector
|
@@ -301,7 +325,7 @@ thing2 12
|
|
301
325
|
|
302
326
|
## Transport concerns
|
303
327
|
|
304
|
-
Prometheus Exporter handles transport using a simple HTTP protocol. In multi process mode we avoid needing a large number of HTTP request by using chunked encoding to send metrics. This means that a single HTTP channel can deliver 100s or even 1000s of metrics over a single HTTP session to the `/send-metrics` endpoint. All calls to `send` and `send_json` on the PrometheusExporter::Client class are **non-blocking** and batched.
|
328
|
+
Prometheus Exporter handles transport using a simple HTTP protocol. In multi process mode we avoid needing a large number of HTTP request by using chunked encoding to send metrics. This means that a single HTTP channel can deliver 100s or even 1000s of metrics over a single HTTP session to the `/send-metrics` endpoint. All calls to `send` and `send_json` on the PrometheusExporter::Client class are **non-blocking** and batched.
|
305
329
|
|
306
330
|
The `/bench` directory has simple benchmark it is able to send through 10k messages in 500ms.
|
307
331
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module PrometheusExporter::Instrumentation
|
2
|
+
class DelayedJob
|
3
|
+
JOB_CLASS_REGEXP = %r{job_class: (\w+:{0,2})+}.freeze
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def register_plugin(client: nil)
|
7
|
+
instrumenter = self.new(client: client)
|
8
|
+
return unless defined?(Delayed::Plugin)
|
9
|
+
|
10
|
+
plugin = Class.new(Delayed::Plugin) do
|
11
|
+
callbacks do |lifecycle|
|
12
|
+
lifecycle.around(:invoke_job) do |job, *args, &block|
|
13
|
+
instrumenter.call(job, *args, &block)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Delayed::Worker.plugins << plugin
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(client: nil)
|
23
|
+
@client = client || PrometheusExporter::Client.default
|
24
|
+
end
|
25
|
+
|
26
|
+
def call(job, *args, &block)
|
27
|
+
success = false
|
28
|
+
start = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
|
29
|
+
result = block.call(job, *args)
|
30
|
+
success = true
|
31
|
+
result
|
32
|
+
ensure
|
33
|
+
duration = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) - start
|
34
|
+
|
35
|
+
@client.send_json(
|
36
|
+
type: "delayed_job",
|
37
|
+
name: job.handler.to_s.match(JOB_CLASS_REGEXP).to_a[1].to_s,
|
38
|
+
success: success,
|
39
|
+
duration: duration
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -10,7 +10,7 @@ module PrometheusExporter::Instrumentation
|
|
10
10
|
metric = process_collector.collect
|
11
11
|
client.send_json metric
|
12
12
|
rescue => e
|
13
|
-
STDERR.puts("Prometheus
|
13
|
+
STDERR.puts("Prometheus Exporter Failed To Collect Process Stats #{e}")
|
14
14
|
ensure
|
15
15
|
sleep frequency
|
16
16
|
end
|
@@ -51,9 +51,9 @@ module PrometheusExporter::Instrumentation
|
|
51
51
|
stat = GC.stat
|
52
52
|
metric[:heap_live_slots] = stat[:heap_live_slots]
|
53
53
|
metric[:heap_free_slots] = stat[:heap_free_slots]
|
54
|
-
metric[:
|
55
|
-
metric[:
|
56
|
-
metric[:
|
54
|
+
metric[:major_gc_ops_total] = stat[:major_gc_count]
|
55
|
+
metric[:minor_gc_ops_total] = stat[:minor_gc_count]
|
56
|
+
metric[:allocated_objects_total] = stat[:total_allocated_objects]
|
57
57
|
end
|
58
58
|
|
59
59
|
def collect_v8_stats(metric)
|
@@ -23,9 +23,12 @@ class PrometheusExporter::Middleware
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def call(env)
|
26
|
+
queue_time = measure_queue_time(env)
|
27
|
+
|
26
28
|
MethodProfiler.start
|
27
29
|
result = @app.call(env)
|
28
30
|
info = MethodProfiler.stop
|
31
|
+
|
29
32
|
result
|
30
33
|
ensure
|
31
34
|
status = (result && result[0]) || -1
|
@@ -39,9 +42,44 @@ class PrometheusExporter::Middleware
|
|
39
42
|
@client.send_json(
|
40
43
|
type: "web",
|
41
44
|
timings: info,
|
45
|
+
queue_time: queue_time,
|
42
46
|
action: action,
|
43
47
|
controller: controller,
|
44
48
|
status: status
|
45
49
|
)
|
46
50
|
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# measures the queue time (= time between receiving the request in downstream
|
55
|
+
# load balancer and starting request in ruby process)
|
56
|
+
def measure_queue_time(env)
|
57
|
+
start_time = queue_start(env)
|
58
|
+
|
59
|
+
return unless start_time
|
60
|
+
|
61
|
+
queue_time = request_start.to_f - start_time.to_f
|
62
|
+
queue_time unless queue_time.negative?
|
63
|
+
end
|
64
|
+
|
65
|
+
# need to use CLOCK_REALTIME, as nginx/apache write this also out as the unix timestamp
|
66
|
+
def request_start
|
67
|
+
Process.clock_gettime(Process::CLOCK_REALTIME)
|
68
|
+
end
|
69
|
+
|
70
|
+
# get the content of the x-queue-start or x-request-start header
|
71
|
+
def queue_start(env)
|
72
|
+
value = env['HTTP_X_REQUEST_START'] || env['HTTP_X_QUEUE_START']
|
73
|
+
unless value.nil? || value == ''
|
74
|
+
convert_header_to_ms(value.to_s)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# nginx returns time as milliseconds with 3 decimal places
|
79
|
+
# apache returns time as microseconds without decimal places
|
80
|
+
# this method takes care to convert both into a proper second + fractions timestamp
|
81
|
+
def convert_header_to_ms(str)
|
82
|
+
str = str.gsub(/t=|\./, '')
|
83
|
+
"#{str[0,10]}.#{str[10,13]}".to_f
|
84
|
+
end
|
47
85
|
end
|
@@ -5,19 +5,19 @@ module PrometheusExporter::Server
|
|
5
5
|
class Collector < CollectorBase
|
6
6
|
MAX_PROCESS_METRIC_AGE = 60
|
7
7
|
PROCESS_GAUGES = {
|
8
|
-
heap_free_slots: "Free ruby heap slots",
|
9
|
-
heap_live_slots: "Used ruby heap slots",
|
10
|
-
v8_heap_size: "Total JavaScript V8 heap size (bytes)",
|
11
|
-
v8_used_heap_size: "Total used JavaScript V8 heap size (bytes)",
|
12
|
-
v8_physical_size: "Physical size consumed by V8 heaps",
|
13
|
-
v8_heap_count: "Number of V8 contexts running",
|
14
|
-
rss: "Total RSS used by process",
|
8
|
+
heap_free_slots: "Free ruby heap slots.",
|
9
|
+
heap_live_slots: "Used ruby heap slots.",
|
10
|
+
v8_heap_size: "Total JavaScript V8 heap size (bytes).",
|
11
|
+
v8_used_heap_size: "Total used JavaScript V8 heap size (bytes).",
|
12
|
+
v8_physical_size: "Physical size consumed by V8 heaps.",
|
13
|
+
v8_heap_count: "Number of V8 contexts running.",
|
14
|
+
rss: "Total RSS used by process.",
|
15
15
|
}
|
16
16
|
|
17
17
|
PROCESS_COUNTERS = {
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
major_gc_ops_total: "Major GC operations by process.",
|
19
|
+
minor_gc_ops_total: "Minor GC operations by process.",
|
20
|
+
allocated_objects_total: "Total number of allocated objects by process.",
|
21
21
|
}
|
22
22
|
|
23
23
|
def initialize(json_serializer: nil)
|
@@ -29,6 +29,7 @@ module PrometheusExporter::Server
|
|
29
29
|
register_collector(WebCollector.new)
|
30
30
|
register_collector(ProcessCollector.new)
|
31
31
|
register_collector(SidekiqCollector.new)
|
32
|
+
register_collector(DelayedJobCollector.new)
|
32
33
|
end
|
33
34
|
|
34
35
|
def register_collector(collector)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module PrometheusExporter::Server
|
2
|
+
class DelayedJobCollector < TypeCollector
|
3
|
+
|
4
|
+
def type
|
5
|
+
"delayed_job"
|
6
|
+
end
|
7
|
+
|
8
|
+
def collect(obj)
|
9
|
+
ensure_delayed_job_metrics
|
10
|
+
@delayed_job_duration_seconds.observe(obj["duration"], job_name: obj["name"])
|
11
|
+
@delayed_jobs_total.observe(1, job_name: obj["name"])
|
12
|
+
@delayed_failed_jobs_total.observe(1, job_name: obj["name"]) if !obj["success"]
|
13
|
+
end
|
14
|
+
|
15
|
+
def metrics
|
16
|
+
if @delayed_jobs_total
|
17
|
+
[@delayed_job_duration_seconds, @delayed_jobs_total, @delayed_failed_jobs_total]
|
18
|
+
else
|
19
|
+
[]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
def ensure_delayed_job_metrics
|
26
|
+
if !@delayed_jobs_total
|
27
|
+
|
28
|
+
@delayed_job_duration_seconds =
|
29
|
+
PrometheusExporter::Metric::Counter.new(
|
30
|
+
"delayed_job_duration_seconds", "Total time spent in delayed jobs.")
|
31
|
+
|
32
|
+
@delayed_jobs_total =
|
33
|
+
PrometheusExporter::Metric::Counter.new(
|
34
|
+
"delayed_jobs_total", "Total number of delayed jobs executed.")
|
35
|
+
|
36
|
+
@delayed_failed_jobs_total =
|
37
|
+
PrometheusExporter::Metric::Counter.new(
|
38
|
+
"delayed_failed_jobs_total", "Total number failed delayed jobs executed.")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -5,19 +5,19 @@ module PrometheusExporter::Server
|
|
5
5
|
class ProcessCollector < TypeCollector
|
6
6
|
MAX_PROCESS_METRIC_AGE = 60
|
7
7
|
PROCESS_GAUGES = {
|
8
|
-
heap_free_slots: "Free ruby heap slots",
|
9
|
-
heap_live_slots: "Used ruby heap slots",
|
10
|
-
v8_heap_size: "Total JavaScript V8 heap size (bytes)",
|
11
|
-
v8_used_heap_size: "Total used JavaScript V8 heap size (bytes)",
|
12
|
-
v8_physical_size: "Physical size consumed by V8 heaps",
|
13
|
-
v8_heap_count: "Number of V8 contexts running",
|
14
|
-
rss: "Total RSS used by process",
|
8
|
+
heap_free_slots: "Free ruby heap slots.",
|
9
|
+
heap_live_slots: "Used ruby heap slots.",
|
10
|
+
v8_heap_size: "Total JavaScript V8 heap size (bytes).",
|
11
|
+
v8_used_heap_size: "Total used JavaScript V8 heap size (bytes).",
|
12
|
+
v8_physical_size: "Physical size consumed by V8 heaps.",
|
13
|
+
v8_heap_count: "Number of V8 contexts running.",
|
14
|
+
rss: "Total RSS used by process.",
|
15
15
|
}
|
16
16
|
|
17
17
|
PROCESS_COUNTERS = {
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
major_gc_ops_total: "Major GC operations by process.",
|
19
|
+
minor_gc_ops_total: "Minor GC operations by process.",
|
20
|
+
allocated_objects_total: "Total number of allocated objects by process.",
|
21
21
|
}
|
22
22
|
|
23
23
|
def initialize
|
@@ -8,13 +8,13 @@ module PrometheusExporter::Server
|
|
8
8
|
def collect(obj)
|
9
9
|
ensure_sidekiq_metrics
|
10
10
|
@sidekiq_job_duration_seconds.observe(obj["duration"], job_name: obj["name"])
|
11
|
-
@
|
12
|
-
@
|
11
|
+
@sidekiq_jobs_total.observe(1, job_name: obj["name"])
|
12
|
+
@sidekiq_failed_jobs_total.observe(1, job_name: obj["name"]) if !obj["success"]
|
13
13
|
end
|
14
14
|
|
15
15
|
def metrics
|
16
|
-
if @
|
17
|
-
[@sidekiq_job_duration_seconds, @
|
16
|
+
if @sidekiq_jobs_total
|
17
|
+
[@sidekiq_job_duration_seconds, @sidekiq_jobs_total, @sidekiq_failed_jobs_total]
|
18
18
|
else
|
19
19
|
[]
|
20
20
|
end
|
@@ -23,19 +23,19 @@ module PrometheusExporter::Server
|
|
23
23
|
protected
|
24
24
|
|
25
25
|
def ensure_sidekiq_metrics
|
26
|
-
if !@
|
26
|
+
if !@sidekiq_jobs_total
|
27
27
|
|
28
28
|
@sidekiq_job_duration_seconds =
|
29
29
|
PrometheusExporter::Metric::Counter.new(
|
30
|
-
"sidekiq_job_duration_seconds", "Total time spent in sidekiq jobs")
|
30
|
+
"sidekiq_job_duration_seconds", "Total time spent in sidekiq jobs.")
|
31
31
|
|
32
|
-
@
|
32
|
+
@sidekiq_jobs_total =
|
33
33
|
PrometheusExporter::Metric::Counter.new(
|
34
|
-
"
|
34
|
+
"sidekiq_jobs_total", "Total number of sidekiq jobs executed.")
|
35
35
|
|
36
|
-
@
|
36
|
+
@sidekiq_failed_jobs_total =
|
37
37
|
PrometheusExporter::Metric::Counter.new(
|
38
|
-
"
|
38
|
+
"sidekiq_failed_jobs_total", "Total number failed sidekiq jobs executed.")
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
@@ -22,25 +22,30 @@ module PrometheusExporter::Server
|
|
22
22
|
protected
|
23
23
|
|
24
24
|
def ensure_metrics
|
25
|
-
unless @
|
26
|
-
@metrics["
|
27
|
-
"
|
28
|
-
"Total HTTP requests from web app"
|
25
|
+
unless @http_requests_total
|
26
|
+
@metrics["http_requests_total"] = @http_requests_total = PrometheusExporter::Metric::Counter.new(
|
27
|
+
"http_requests_total",
|
28
|
+
"Total HTTP requests from web app."
|
29
29
|
)
|
30
30
|
|
31
31
|
@metrics["http_duration_seconds"] = @http_duration_seconds = PrometheusExporter::Metric::Summary.new(
|
32
32
|
"http_duration_seconds",
|
33
|
-
"Time spent in HTTP reqs in seconds"
|
33
|
+
"Time spent in HTTP reqs in seconds."
|
34
34
|
)
|
35
35
|
|
36
36
|
@metrics["http_redis_duration_seconds"] = @http_redis_duration_seconds = PrometheusExporter::Metric::Summary.new(
|
37
37
|
"http_redis_duration_seconds",
|
38
|
-
"Time spent in HTTP reqs in
|
38
|
+
"Time spent in HTTP reqs in Redis, in seconds."
|
39
39
|
)
|
40
40
|
|
41
41
|
@metrics["http_sql_duration_seconds"] = @http_sql_duration_seconds = PrometheusExporter::Metric::Summary.new(
|
42
42
|
"http_sql_duration_seconds",
|
43
|
-
"Time spent in HTTP reqs in SQL in seconds"
|
43
|
+
"Time spent in HTTP reqs in SQL in seconds."
|
44
|
+
)
|
45
|
+
|
46
|
+
@metrics["http_queue_duration_seconds"] = @http_queue_duration_seconds = PrometheusExporter::Metric::Summary.new(
|
47
|
+
"http_queue_duration_seconds",
|
48
|
+
"Time spent queueing the request in load balancer in seconds."
|
44
49
|
)
|
45
50
|
end
|
46
51
|
end
|
@@ -52,7 +57,7 @@ module PrometheusExporter::Server
|
|
52
57
|
action: obj["action"] || "other"
|
53
58
|
}
|
54
59
|
|
55
|
-
@
|
60
|
+
@http_requests_total.observe(1, labels.merge(status: obj["status"]))
|
56
61
|
|
57
62
|
if timings = obj["timings"]
|
58
63
|
@http_duration_seconds.observe(timings["total_duration"], labels)
|
@@ -63,6 +68,9 @@ module PrometheusExporter::Server
|
|
63
68
|
@http_sql_duration_seconds.observe(sql["duration"], labels)
|
64
69
|
end
|
65
70
|
end
|
71
|
+
if queue_time = obj["queue_time"]
|
72
|
+
@http_queue_duration_seconds.observe(queue_time, labels)
|
73
|
+
end
|
66
74
|
end
|
67
75
|
end
|
68
76
|
end
|
@@ -13,15 +13,15 @@ module PrometheusExporter::Server
|
|
13
13
|
|
14
14
|
@verbose = verbose
|
15
15
|
|
16
|
-
@
|
16
|
+
@metrics_total = PrometheusExporter::Metric::Counter.new("collector_metrics_total", "Total metrics processed by exporter web.")
|
17
17
|
|
18
|
-
@
|
18
|
+
@sessions_total = PrometheusExporter::Metric::Counter.new("collector_sessions_total", "Total send_metric sessions processed by exporter web.")
|
19
19
|
|
20
|
-
@
|
20
|
+
@bad_metrics_total = PrometheusExporter::Metric::Counter.new("collector_bad_metrics_total", "Total mis-handled metrics by collector.")
|
21
21
|
|
22
|
-
@
|
23
|
-
@
|
24
|
-
@
|
22
|
+
@metrics_total.observe(0)
|
23
|
+
@sessions_total.observe(0)
|
24
|
+
@bad_metrics_total.observe(0)
|
25
25
|
|
26
26
|
access_log, logger = nil
|
27
27
|
|
@@ -73,10 +73,10 @@ module PrometheusExporter::Server
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def handle_metrics(req, res)
|
76
|
-
@
|
76
|
+
@sessions_total.observe
|
77
77
|
req.body do |block|
|
78
78
|
begin
|
79
|
-
@
|
79
|
+
@metrics_total.observe
|
80
80
|
@collector.process(block)
|
81
81
|
rescue => e
|
82
82
|
if @verbose
|
@@ -85,7 +85,7 @@ module PrometheusExporter::Server
|
|
85
85
|
STDERR.puts e.backtrace
|
86
86
|
STDERR.puts
|
87
87
|
end
|
88
|
-
@
|
88
|
+
@bad_metrics_total.observe
|
89
89
|
res.body = "Bad Metrics #{e}"
|
90
90
|
res.status = e.respond_to?(:status_code) ? e.status_code : 500
|
91
91
|
return
|
@@ -135,9 +135,9 @@ module PrometheusExporter::Server
|
|
135
135
|
get_rss
|
136
136
|
)
|
137
137
|
|
138
|
-
metrics << @
|
139
|
-
metrics << @
|
140
|
-
metrics << @
|
138
|
+
metrics << @metrics_total
|
139
|
+
metrics << @sessions_total
|
140
|
+
metrics << @bad_metrics_total
|
141
141
|
|
142
142
|
<<~TEXT
|
143
143
|
#{metrics.map(&:to_prometheus_text).join("\n\n")}
|
@@ -3,6 +3,7 @@ require_relative "server/type_collector"
|
|
3
3
|
require_relative "server/web_collector"
|
4
4
|
require_relative "server/process_collector"
|
5
5
|
require_relative "server/sidekiq_collector"
|
6
|
+
require_relative "server/delayed_job_collector"
|
6
7
|
require_relative "server/collector_base"
|
7
8
|
require_relative "server/collector"
|
8
9
|
require_relative "server/web_server"
|
data/prometheus_exporter.gemspec
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
lib = File.expand_path("../lib", __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
@@ -28,4 +29,6 @@ Gem::Specification.new do |spec|
|
|
28
29
|
spec.add_development_dependency "mini_racer", "~> 0.1"
|
29
30
|
spec.add_development_dependency "guard-minitest", "~> 2.0"
|
30
31
|
spec.add_development_dependency "oj", "~> 3.0"
|
32
|
+
spec.add_development_dependency "rack-test", "~> 0.8.3"
|
33
|
+
spec.required_ruby_version = '>= 2.3.0'
|
31
34
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prometheus_exporter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Saffron
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-04-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '3.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rack-test
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.8.3
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.8.3
|
111
125
|
description: Prometheus metric collector and exporter for Ruby
|
112
126
|
email:
|
113
127
|
- sam.saffron@gmail.com
|
@@ -133,6 +147,7 @@ files:
|
|
133
147
|
- lib/prometheus_exporter.rb
|
134
148
|
- lib/prometheus_exporter/client.rb
|
135
149
|
- lib/prometheus_exporter/instrumentation.rb
|
150
|
+
- lib/prometheus_exporter/instrumentation/delayed_job.rb
|
136
151
|
- lib/prometheus_exporter/instrumentation/global.rb
|
137
152
|
- lib/prometheus_exporter/instrumentation/method_profiler.rb
|
138
153
|
- lib/prometheus_exporter/instrumentation/process.rb
|
@@ -146,6 +161,7 @@ files:
|
|
146
161
|
- lib/prometheus_exporter/server.rb
|
147
162
|
- lib/prometheus_exporter/server/collector.rb
|
148
163
|
- lib/prometheus_exporter/server/collector_base.rb
|
164
|
+
- lib/prometheus_exporter/server/delayed_job_collector.rb
|
149
165
|
- lib/prometheus_exporter/server/process_collector.rb
|
150
166
|
- lib/prometheus_exporter/server/runner.rb
|
151
167
|
- lib/prometheus_exporter/server/sidekiq_collector.rb
|
@@ -166,7 +182,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
166
182
|
requirements:
|
167
183
|
- - ">="
|
168
184
|
- !ruby/object:Gem::Version
|
169
|
-
version:
|
185
|
+
version: 2.3.0
|
170
186
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
171
187
|
requirements:
|
172
188
|
- - ">="
|
@@ -174,7 +190,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
174
190
|
version: '0'
|
175
191
|
requirements: []
|
176
192
|
rubyforge_project:
|
177
|
-
rubygems_version: 2.
|
193
|
+
rubygems_version: 2.6.13
|
178
194
|
signing_key:
|
179
195
|
specification_version: 4
|
180
196
|
summary: Prometheus Exporter
|