prometheus_exporter 0.8.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +36 -25
  3. data/CHANGELOG +51 -26
  4. data/README.md +151 -52
  5. data/bin/prometheus_exporter +19 -6
  6. data/lib/prometheus_exporter/client.rb +13 -6
  7. data/lib/prometheus_exporter/instrumentation/active_record.rb +5 -5
  8. data/lib/prometheus_exporter/instrumentation/process.rb +1 -1
  9. data/lib/prometheus_exporter/instrumentation/puma.rb +12 -12
  10. data/lib/prometheus_exporter/instrumentation/resque.rb +7 -7
  11. data/lib/prometheus_exporter/instrumentation/sidekiq.rb +27 -7
  12. data/lib/prometheus_exporter/instrumentation/sidekiq_process.rb +58 -0
  13. data/lib/prometheus_exporter/instrumentation/sidekiq_queue.rb +27 -13
  14. data/lib/prometheus_exporter/instrumentation/sidekiq_stats.rb +43 -0
  15. data/lib/prometheus_exporter/instrumentation/unicorn.rb +4 -4
  16. data/lib/prometheus_exporter/instrumentation.rb +2 -0
  17. data/lib/prometheus_exporter/metric/base.rb +11 -9
  18. data/lib/prometheus_exporter/metric/gauge.rb +4 -0
  19. data/lib/prometheus_exporter/metric/histogram.rb +13 -1
  20. data/lib/prometheus_exporter/middleware.rb +8 -4
  21. data/lib/prometheus_exporter/server/collector.rb +2 -0
  22. data/lib/prometheus_exporter/server/delayed_job_collector.rb +17 -18
  23. data/lib/prometheus_exporter/server/puma_collector.rb +7 -7
  24. data/lib/prometheus_exporter/server/resque_collector.rb +6 -6
  25. data/lib/prometheus_exporter/server/runner.rb +11 -2
  26. data/lib/prometheus_exporter/server/sidekiq_collector.rb +1 -1
  27. data/lib/prometheus_exporter/server/sidekiq_process_collector.rb +46 -0
  28. data/lib/prometheus_exporter/server/sidekiq_queue_collector.rb +1 -1
  29. data/lib/prometheus_exporter/server/sidekiq_stats_collector.rb +46 -0
  30. data/lib/prometheus_exporter/server/unicorn_collector.rb +3 -3
  31. data/lib/prometheus_exporter/server/web_collector.rb +17 -17
  32. data/lib/prometheus_exporter/server/web_server.rb +6 -8
  33. data/lib/prometheus_exporter/server.rb +2 -0
  34. data/lib/prometheus_exporter/version.rb +1 -1
  35. data/prometheus_exporter.gemspec +1 -1
  36. metadata +10 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 562647915cd81e672056a83fc79a031d2a0ebb2b4a7a5e32f5786ae5c7d480a7
4
- data.tar.gz: 525e28d0cbe4e853c91bb463970fd231b134dba6b5a190c61a2ff7710074fb7b
3
+ metadata.gz: f5e708b8c63be6ecff9750deebf18cad149d9b4fa7350a4523af2f145caffec5
4
+ data.tar.gz: 1204a53af367dc60e24ded2e1630e2b447ef79d3caff32165ac5c40b62955ded
5
5
  SHA512:
6
- metadata.gz: 324b3b0acd1c97e8b5535dff8f57500b4dc3f2433456372c609accbc78d1baf839d82a1e38eabb543f043bbc9fefb401ab1460ba252ee8b9330fe0a91acffc1d
7
- data.tar.gz: b2a0082d4e2431cc1f24f11a6af86d6965e2db7c93df1021ed58b38ff8651c84d1e8939b42a13b1b7cac60c9237435ff838a24918ed0ee18d13c3df2aece76d4
6
+ metadata.gz: 5dee50712e73be92702e2948a0a69aa8b8007df59de35f10c5980d9d5a2653092a4247e7ad207713460df80f59bb0691835a3aa2b04fa751d28cc5b9c3f66f48
7
+ data.tar.gz: 0af7415fd207b1eb5f7f62639f8d48bc7735df9397537524c536631d24150b9b7daa87d17652f070a79f8134d50e780c9143ddeedcfc2d44eaa27586ffe64b19
@@ -1,42 +1,53 @@
1
- name: Test Exporter
1
+ name: CI
2
2
 
3
3
  on:
4
4
  push:
5
+ branches:
6
+ - main
5
7
  pull_request:
6
8
  schedule:
7
- - cron: '0 0 * * 0' # weekly
9
+ - cron: "0 0 * * 0" # weekly
8
10
 
9
11
  jobs:
10
12
  build:
11
13
  runs-on: ubuntu-latest
12
- name: Ruby ${{ matrix.ruby }}
14
+ name: Ruby ${{ matrix.ruby }} AR ${{ matrix.activerecord }}
15
+ timeout-minutes: 10
16
+
17
+ env:
18
+ BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/ar_${{ matrix.activerecord }}.gemfile
19
+
13
20
  strategy:
21
+ fail-fast: false
14
22
  matrix:
15
- ruby: ["2.7", "2.6", "2.5"]
23
+ ruby: ['2.6', '2.7', '3.0', '3.1']
24
+ activerecord: [60, 61]
25
+
16
26
  steps:
17
- - uses: actions/checkout@master
18
- with:
19
- fetch-depth: 1
20
- - uses: actions/setup-ruby@v1
27
+ - uses: actions/checkout@v2
28
+
29
+ - uses: ruby/setup-ruby@v1
21
30
  with:
22
31
  ruby-version: ${{ matrix.ruby }}
23
- - uses: actions/cache@v2
24
- with:
25
- path: vendor/bundle
26
- key: ${{ runner.os }}-${{ matrix.ruby }}-gems-v2-${{ hashFiles('**/Gemfile.lock') }}
27
- restore-keys: |
28
- ${{ runner.os }}-${{ matrix.ruby }}-gems-v2-
29
- - name: Setup gems
30
- run: |
31
- gem install bundler
32
- # for Ruby <= 2.6 , details https://github.com/rubygems/rubygems/issues/3284
33
- gem update --system 3.0.8 && gem update --system
34
- bundle config path vendor/bundle
35
- bundle install --jobs 4
36
- bundle exec appraisal install
32
+ bundler-cache: true
33
+
37
34
  - name: Rubocop
38
35
  run: bundle exec rubocop
39
- - name: install gems
40
- run: bundle exec appraisal bundle
36
+
41
37
  - name: Run tests
42
- run: bundle exec appraisal rake
38
+ run: bundle exec rake
39
+
40
+ publish:
41
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
42
+ needs: build
43
+ runs-on: ubuntu-latest
44
+
45
+ steps:
46
+ - uses: actions/checkout@v2
47
+
48
+ - name: Release gem
49
+ uses: discourse/publish-rubygems-action@v2
50
+ env:
51
+ RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
52
+ GIT_EMAIL: team@discourse.org
53
+ GIT_NAME: discoursebot
data/CHANGELOG CHANGED
@@ -1,16 +1,41 @@
1
- 0.8.0 - 05-07-2021
1
+ 2.0.0 - 2022-02-18
2
+
3
+ - FEATURE: Add per worker custom labels
4
+ - FEATURE: support custom histogram buckets
5
+ - FIX: all metrics are exposing status label, and not only `http_requests_total`
6
+ - BREAKING: rename all `http_duration` metrics to `http_request_duration` to match prometheus official naming conventions (See https://prometheus.io/docs/practices/naming/#metric-names).
7
+
8
+ 1.0.1 - 2021-12-22
9
+
10
+ - FEATURE: add labels to preflight requests
11
+ - FEATURE: SidekiqStats metrics
12
+ - FIX: mintor refactors to Sidekiq metrics
13
+
14
+ 1.0.0 - 2021-11-23
15
+
16
+ - BREAKING: rename metrics to match prometheus official naming conventions (See https://prometheus.io/docs/practices/naming/#metric-names)
17
+ - FEATURE: Sidekiq process metrics
18
+ - FEATURE: Allow collecting web metrics as histograms
19
+ - FIX: logger improved for web server
20
+ - FIX: Remove job labels from DelayedJob queues
21
+
22
+ 0.8.1 - 2021-08-04
23
+
24
+ - FEATURE: swap from hardcoded STDERR to logger pattern (see README for details)
25
+
26
+ 0.8.0 - 2021-07-05
2
27
 
3
28
  - FIX: handle ThreadError more gracefully in cases where process shuts down
4
29
  - FEATURE: add job_name and queue_name labels to delayed job metrics
5
30
  - FEATURE: always scope puma metrics on hostname in collector
6
31
  - FEATURE: add customizable labels option to puma collector
7
- - FEATURE: support for Rescue
32
+ - FEATURE: support for Resque
8
33
  - DEV: Remove support for EOL ruby 2.5
9
34
  - FIX: Add source location to MethodProfiler patches
10
35
  - FEATURE: Improve Active Record instrumentation
11
36
  - FEATURE: Support HTTP_X_AMZN_TRACE_ID when supplied
12
37
 
13
- 0.7.0 - 29-12-2020
38
+ 0.7.0 - 2020-12-29
14
39
 
15
40
  - Dev: Removed support from EOL rubies, only 2.5, 2.6, 2.7 and 3.0 are supported now.
16
41
  - Dev: Better support for Ruby 3.0, explicitly depending on webrick
@@ -18,111 +43,111 @@
18
43
  - FEATURE: clean pattern for overriding middleware labels was introduced (in README)
19
44
  - Fix: Better support for forking
20
45
 
21
- 0.6.0 - 17-11-2020
46
+ 0.6.0 - 2020-11-17
22
47
 
23
48
  - FEATURE: add support for basic-auth in the prometheus_exporter web server
24
49
 
25
- 0.5.3 - 29-07-2020
50
+ 0.5.3 - 2020-07-29
26
51
 
27
52
  - FEATURE: added #remove to all metric types so users can remove specific labels if needed
28
53
 
29
- 0.5.2 - 01-07-2020
54
+ 0.5.2 - 2020-07-01
30
55
 
31
56
  - FEATURE: expanded instrumentation for sidekiq
32
57
  - FEATURE: configurable default labels
33
58
 
34
- 0.5.1 - 25-02-2020
59
+ 0.5.1 - 2020-02-25
35
60
 
36
61
  - FEATURE: Allow configuring the default client's host and port via environment variables
37
62
 
38
- 0.5.0 - 14-02-2020
63
+ 0.5.0 - 2020-02-14
39
64
 
40
65
  - Breaking change: listen only to localhost by default to prevent unintended insecure configuration
41
66
  - FIX: Avoid calling `hostname` aggressively, instead cache it on the exporter instance
42
67
 
43
- 0.4.17 - 13-01-2020
68
+ 0.4.17 - 2020-01-13
44
69
 
45
70
  - FEATURE: add support for `to_h` on all metrics which can be used to query existing key/values
46
71
 
47
- 0.4.16 - 04-11-2019
72
+ 0.4.16 - 2019-11-04
48
73
 
49
74
  - FEATURE: Support #reset! on all metric types to reset a metric to default
50
75
 
51
- 0.4.15 - 04-11-2019
76
+ 0.4.15 - 2019-11-04
52
77
 
53
78
  - FEATURE: Improve delayed job collector, add pending counts
54
79
  - FEATURE: New ActiveRecord collector (documented in readme)
55
80
  - FEATURE: Allow passing in histogram and summary options
56
81
  - FEATURE: Allow custom labels for unicorn collector
57
82
 
58
- 0.4.14 - 10-09-2019
83
+ 0.4.14 - 2019-09-10
59
84
 
60
85
  - FEATURE: allow finding metrics by name RemoteMetric #find_registered_metric
61
86
  - FIX: guard socket closing
62
87
 
63
- 0.4.13 - 09-07-2019
88
+ 0.4.13 - 2019-07-09
64
89
 
65
90
  - Fix: Memory leak in unicorn and puma collectors
66
91
 
67
- 0.4.12 - 30-05-2019
92
+ 0.4.12 - 2019-05-30
68
93
 
69
94
  - Fix: unicorn collector reporting incorrect number of unicorn workers
70
95
 
71
- 0.4.11 - 15-05-2019
96
+ 0.4.11 - 2019-05-15
72
97
 
73
98
  - Fix: Handle stopping nil worker_threads in Client
74
99
  - Dev: add frozen string literals
75
100
 
76
- 0.4.10 - 29-04-2019
101
+ 0.4.10 - 2019-04-29
77
102
 
78
103
  - Fix: Custom label support for puma collector
79
104
  - Fix: Raindrops socket collector not working correctly
80
105
 
81
- 0.4.9 - 11-04-2019
106
+ 0.4.9 - 2019-04-11
82
107
 
83
108
  - Fix: Gem was not working correctly in Ruby 2.4 and below due to a syntax error
84
109
 
85
- 0.4.8 - 10-04-2019
110
+ 0.4.8 - 2019-04-10
86
111
 
87
112
  - Feature: added helpers for instrumenting unicorn using raindrops
88
113
 
89
- 0.4.7 - 08-04-2019
114
+ 0.4.7 - 2019-04-08
90
115
 
91
116
  - Fix: collector was not escaping " \ and \n correctly. This could lead
92
117
  to a corrupt payload in some cases.
93
118
 
94
- 0.4.6 - 02-04-2019
119
+ 0.4.6 - 2019-04-02
95
120
 
96
121
  - Feature: Allow resetting a counter
97
122
  - Feature: Add sidekiq metrics: restarted, dead jobs counters
98
123
  - Fix: Client shutting down before sending metrics to collector
99
124
 
100
- 0.4.5 - 14-02-2019
125
+ 0.4.5 - 2019-02-14
101
126
 
102
127
  - Feature: Allow process collector to ship custom labels for all process metrics
103
128
  - Fix: Always scope process metrics on hostname in collector
104
129
 
105
- 0.4.4 - 13-02-2019
130
+ 0.4.4 - 2019-02-13
106
131
 
107
132
  - Feature: add support for local metric collection without using HTTP
108
133
 
109
- 0.4.3 - 11-02-2019
134
+ 0.4.3 - 2019-02-11
110
135
 
111
136
  - Feature: Add alias for Gauge #observe called #set, this makes it a bit easier to migrate from prom
112
137
  - Feature: Add increment and decrement to Counter
113
138
 
114
- 0.4.2 - 30-11-2018
139
+ 0.4.2 - 2018-11-30
115
140
 
116
141
  - Fix/Feature: setting a Gauge to nil will remove Gauge (setting to non numeric will raise)
117
142
 
118
- 0.4.0 - 23-10-2018
143
+ 0.4.0 - 2018-10-23
119
144
 
120
145
  - Feature: histogram support
121
146
  - Feature: custom quantile support for summary
122
147
  - Feature: Puma metrics
123
148
  - Fix: delayed job metrics
124
149
 
125
- 0.3.4 - 02-10-2018
150
+ 0.3.4 - 2018-10-02
126
151
 
127
152
  - Fix: custom collector via CLI was not working correctly
128
153
 
data/README.md CHANGED
@@ -5,6 +5,7 @@ Prometheus Exporter allows you to aggregate custom metrics from multiple process
5
5
  To learn more see [Instrumenting Rails with Prometheus](https://samsaffron.com/archive/2018/02/02/instrumenting-rails-with-prometheus) (it has pretty pictures!)
6
6
 
7
7
  * [Requirements](#requirements)
8
+ * [Migrating from v0.x](#migrating-from-v0.x)
8
9
  * [Installation](#installation)
9
10
  * [Usage](#usage)
10
11
  * [Single process mode](#single-process-mode)
@@ -26,15 +27,24 @@ To learn more see [Instrumenting Rails with Prometheus](https://samsaffron.com/a
26
27
  * [Metrics default prefix / labels](#metrics-default-prefix--labels)
27
28
  * [Client default labels](#client-default-labels)
28
29
  * [Client default host](#client-default-host)
30
+ * [Histogram mode](#histogram-mode)
31
+ * [Histogram - custom buckets](#histogram-custom-buckets)
29
32
  * [Transport concerns](#transport-concerns)
30
33
  * [JSON generation and parsing](#json-generation-and-parsing)
34
+ * [Logging](#logging)
31
35
  * [Contributing](#contributing)
32
36
  * [License](#license)
33
37
  * [Code of Conduct](#code-of-conduct)
34
38
 
35
39
  ## Requirements
36
40
 
37
- Minimum Ruby of version 2.5.0 is required, Ruby 2.4.0 is EOL as of 2020-04-05
41
+ Minimum Ruby of version 2.6.0 is required, Ruby 2.5.0 is EOL as of March 31st 2021.
42
+
43
+ ## Migrating from v0.x
44
+
45
+ There are some major changes in v1.x from v0.x.
46
+
47
+ - Some of metrics are renamed to match [prometheus official guide for metric names](https://prometheus.io/docs/practices/naming/#metric-names). (#184)
38
48
 
39
49
  ## Installation
40
50
 
@@ -193,13 +203,13 @@ $ bundle exec prometheus_exporter
193
203
 
194
204
  #### Metrics collected by Rails integration middleware
195
205
 
196
- | Type | Name | Description |
197
- | --- | --- | --- |
198
- | Counter | `http_requests_total` | Total HTTP requests from web app |
199
- | Summary | `http_duration_seconds` | Time spent in HTTP reqs in seconds |
200
- | Summary | `http_redis_duration_seconds | Time spent in HTTP reqs in Redis, in seconds |
201
- | Summary | `http_sql_duration_seconds | Time spent in HTTP reqs in SQL in seconds |
202
- | Summary | `http_queue_duration_seconds | Time spent queueing the request in load balancer in seconds |
206
+ | Type | Name | Description |
207
+ | --- | --- | --- |
208
+ | Counter | `http_requests_total` | Total HTTP requests from web app |
209
+ | Summary | `http_request_duration_seconds` | Time spent in HTTP reqs in seconds |
210
+ | Summary | `http_request_redis_duration_seconds | Time spent in HTTP reqs in Redis, in seconds |
211
+ | Summary | `http_request_sql_duration_seconds | Time spent in HTTP reqs in SQL in seconds |
212
+ | Summary | `http_request_queue_duration_seconds | Time spent queueing the request in load balancer in seconds |
203
213
 
204
214
  All metrics have a `controller` and an `action` label.
205
215
  `http_requests_total` additionally has a (HTTP response) `status` label.
@@ -242,7 +252,7 @@ end
242
252
  ```
243
253
  That way you won't have all metrics labeled with `controller=other` and `action=other`, but have labels such as
244
254
  ```
245
- ruby_http_duration_seconds{path="/api/v1/teams/:id",method="GET",status="200",quantile="0.99"} 0.009880661998977303
255
+ ruby_http_request_duration_seconds{path="/api/v1/teams/:id",method="GET",status="200",quantile="0.99"} 0.009880661998977303
246
256
  ```
247
257
 
248
258
  ¹) Only available when Redis is used.
@@ -358,40 +368,49 @@ Metrics collected by Process instrumentation include labels `type` (as given wit
358
368
 
359
369
  #### Sidekiq metrics
360
370
 
361
- Including Sidekiq metrics (how many jobs ran? how many failed? how long did they take? how many are dead? how many were restarted?)
362
-
363
- ```ruby
364
- Sidekiq.configure_server do |config|
365
- config.server_middleware do |chain|
366
- require 'prometheus_exporter/instrumentation'
367
- chain.add PrometheusExporter::Instrumentation::Sidekiq
368
- end
369
- config.death_handlers << PrometheusExporter::Instrumentation::Sidekiq.death_handler
370
- end
371
- ```
372
-
373
- To monitor Queue size and latency:
371
+ There are different kinds of Sidekiq metrics that can be collected. A recommended setup looks like this:
374
372
 
375
373
  ```ruby
376
374
  Sidekiq.configure_server do |config|
375
+ require 'prometheus_exporter/instrumentation'
376
+ config.server_middleware do |chain|
377
+ chain.add PrometheusExporter::Instrumentation::Sidekiq
378
+ end
379
+ config.death_handlers << PrometheusExporter::Instrumentation::Sidekiq.death_handler
377
380
  config.on :startup do
378
- require 'prometheus_exporter/instrumentation'
381
+ PrometheusExporter::Instrumentation::Process.start type: 'sidekiq'
382
+ PrometheusExporter::Instrumentation::SidekiqProcess.start
379
383
  PrometheusExporter::Instrumentation::SidekiqQueue.start
384
+ PrometheusExporter::Instrumentation::SidekiqStats.start
380
385
  end
381
386
  end
382
387
  ```
383
388
 
384
- To monitor Sidekiq process info:
389
+ * The middleware and death handler will generate job specific metrics (how many jobs ran? how many failed? how long did they take? how many are dead? how many were restarted?).
390
+ * The [`Process`](#per-process-stats) metrics provide basic ruby metrics.
391
+ * The `SidekiqProcess` metrics provide the concurrency and busy metrics for this process.
392
+ * The `SidekiqQueue` metrics provides size and latency for the queues run by this process.
393
+ * The `SidekiqStats` metrics provide general, global Sidekiq stats (size of Scheduled, Retries, Dead queues, total number of jobs, etc).
394
+
395
+ For `SidekiqQueue`, if you run more than one process for the same queues, note that the same metrics will be exposed by all the processes, just like the `SidekiqStats` will if you run more than one process of any kind. You might want use `avg` or `max` when consuming their metrics.
396
+
397
+ An alternative would be to expose these metrics in lone, long-lived process. Using a rake task, for example:
385
398
 
386
399
  ```ruby
387
- Sidekiq.configure_server do |config|
388
- config.on :startup do
389
- require 'prometheus_exporter/instrumentation'
390
- PrometheusExporter::Instrumentation::Process.start type: 'sidekiq'
391
- end
400
+ task :sidekiq_metrics do
401
+ server = PrometheusExporter::Server::WebServer.new
402
+ server.start
403
+
404
+ PrometheusExporter::Client.default = PrometheusExporter::LocalClient.new(collector: server.collector)
405
+
406
+ PrometheusExporter::Instrumentation::SidekiqQueue.start(all_queues: true)
407
+ PrometheusExporter::Instrumentation::SidekiqStats.start
408
+ sleep
392
409
  end
393
410
  ```
394
411
 
412
+ The `all_queues` parameter for `SidekiqQueue` will expose metrics for all queues.
413
+
395
414
  Sometimes the Sidekiq server shuts down before it can send metrics, that were generated right before the shutdown, to the collector. Especially if you care about the `sidekiq_restarted_jobs_total` metric, it is a good idea to explicitly stop the client:
396
415
 
397
416
  ```ruby
@@ -402,6 +421,18 @@ Sometimes the Sidekiq server shuts down before it can send metrics, that were ge
402
421
  end
403
422
  ```
404
423
 
424
+ Custom labels can be added for individual jobs by defining a class method on the job class. These labels will be added to all Sidekiq metrics written by the job:
425
+
426
+ ```ruby
427
+ class WorkerWithCustomLabels
428
+ def self.custom_labels
429
+ { my_label: 'value-here', other_label: 'second-val' }
430
+ end
431
+
432
+ def perform; end
433
+ end
434
+ ```
435
+
405
436
  ##### Metrics collected by Sidekiq Instrumentation
406
437
 
407
438
  **PrometheusExporter::Instrumentation::Sidekiq**
@@ -424,11 +455,33 @@ This metric has a `job_name` label and a `queue` label.
424
455
  **PrometheusExporter::Instrumentation::SidekiqQueue**
425
456
  | Type | Name | Description |
426
457
  | --- | --- | --- |
427
- | Gauge | `sidekiq_queue_backlog_total` | Size of the sidekiq queue |
458
+ | Gauge | `sidekiq_queue_backlog` | Size of the sidekiq queue |
428
459
  | Gauge | `sidekiq_queue_latency_seconds` | Latency of the sidekiq queue |
429
460
 
430
461
  Both metrics will have a `queue` label with the name of the queue.
431
462
 
463
+ **PrometheusExporter::Instrumentation::SidekiqProcess**
464
+ | Type | Name | Description |
465
+ | --- | --- | --- |
466
+ | Gauge | `sidekiq_process_busy` | Number of busy workers for this process |
467
+ | Gauge | `sidekiq_process_concurrency` | Concurrency for this process |
468
+
469
+ Both metrics will include the labels `labels`, `queues`, `quiet`, `tag`, `hostname` and `identity`, as returned by the [Sidekiq Processes API](https://github.com/mperham/sidekiq/wiki/API#processes).
470
+
471
+ **PrometheusExporter::Instrumentation::SidekiqStats**
472
+ | Type | Name | Description |
473
+ | --- | --- | --- |
474
+ | Gauge | `sidekiq_stats_dead_size` | Size of the dead queue |
475
+ | Gauge | `sidekiq_stats_enqueued` | Number of enqueued jobs |
476
+ | Gauge | `sidekiq_stats_failed` | Number of failed jobs |
477
+ | Gauge | `sidekiq_stats_processed` | Total number of processed jobs |
478
+ | Gauge | `sidekiq_stats_processes_size` | Number of processes |
479
+ | Gauge | `sidekiq_stats_retry_size` | Size of the retries queue |
480
+ | Gauge | `sidekiq_stats_scheduled_size` | Size of the scheduled queue |
481
+ | Gauge | `sidekiq_stats_workers_size` | Number of jobs actively being processed |
482
+
483
+ Based on the [Sidekiq Stats API](https://github.com/mperham/sidekiq/wiki/API#stats).
484
+
432
485
  _See [Metrics collected by Process Instrumentation](#metrics-collected-by-process-instrumentation) for a list of metrics the Process instrumentation will produce._
433
486
 
434
487
  #### Shoryuken metrics
@@ -528,15 +581,15 @@ end
528
581
 
529
582
  #### Metrics collected by Puma Instrumentation
530
583
 
531
- | Type | Name | Description |
532
- | --- | --- | --- |
533
- | Gauge | `puma_workers_total` | Number of puma workers |
534
- | Gauge | `puma_booted_workers_total` | Number of puma workers booted |
535
- | Gauge | `puma_old_workers_total` | Number of old puma workers |
536
- | Gauge | `puma_running_threads_total` | Number of puma threads currently running |
537
- | Gauge | `puma_request_backlog_total` | Number of requests waiting to be processed by a puma thread |
538
- | Gauge | `puma_thread_pool_capacity_total` | Number of puma threads available at current scale |
539
- | Gauge | `puma_max_threads_total` | Number of puma threads at available at max scale |
584
+ | Type | Name | Description |
585
+ | --- | --- | --- |
586
+ | Gauge | `puma_workers` | Number of puma workers |
587
+ | Gauge | `puma_booted_workers` | Number of puma workers booted |
588
+ | Gauge | `puma_old_workers` | Number of old puma workers |
589
+ | Gauge | `puma_running_threads` | Number of puma threads currently running |
590
+ | Gauge | `puma_request_backlog` | Number of requests waiting to be processed by a puma thread |
591
+ | Gauge | `puma_thread_pool_capacity` | Number of puma threads available at current scale |
592
+ | Gauge | `puma_max_threads` | Number of puma threads at available at max scale |
540
593
 
541
594
  All metrics may have a `phase` label and all custom labels provided with the `labels` option.
542
595
 
@@ -553,14 +606,14 @@ PrometheusExporter::Instrumentation::Resque.start
553
606
 
554
607
  #### Metrics collected by Resque Instrumentation
555
608
 
556
- | Type | Name | Description |
557
- | --- | --- | --- |
558
- | Gauge | `processed_jobs_total` | Total number of processed Resque jobs |
559
- | Gauge | `failed_jobs_total` | Total number of failed Resque jobs |
560
- | Gauge | `pending_jobs_total` | Total number of pending Resque jobs |
561
- | Gauge | `queues_total` | Total number of Resque queues |
562
- | Gauge | `workers_total` | Total number of Resque workers running |
563
- | Gauge | `working_total` | Total number of Resque workers working |
609
+ | Type | Name | Description |
610
+ | --- | --- | --- |
611
+ | Gauge | `resque_processed_jobs` | Total number of processed Resque jobs |
612
+ | Gauge | `resque_failed_jobs` | Total number of failed Resque jobs |
613
+ | Gauge | `resque_pending_jobs` | Total number of pending Resque jobs |
614
+ | Gauge | `resque_queues` | Total number of Resque queues |
615
+ | Gauge | `resque_workers` | Total number of Resque workers running |
616
+ | Gauge | `resque_working` | Total number of Resque workers working |
564
617
 
565
618
  ### Unicorn process metrics
566
619
 
@@ -579,11 +632,11 @@ Note: You must install the `raindrops` gem in your `Gemfile` or locally.
579
632
 
580
633
  #### Metrics collected by Unicorn Instrumentation
581
634
 
582
- | Type | Name | Description |
583
- | --- | --- | --- |
584
- | Gauge | `unicorn_workers_total` | Number of unicorn workers |
585
- | Gauge | `unicorn_active_workers_total` | Number of active unicorn workers |
586
- | Gauge | `unicorn_request_backlog_total` | Number of requests waiting to be processed by a unicorn worker |
635
+ | Type | Name | Description |
636
+ | --- | --- | --- |
637
+ | Gauge | `unicorn_workers` | Number of unicorn workers |
638
+ | Gauge | `unicorn_active_workers` | Number of active unicorn workers |
639
+ | Gauge | `unicorn_request_backlog` | Number of requests waiting to be processed by a unicorn worker |
587
640
 
588
641
  ### Custom type collectors
589
642
 
@@ -768,6 +821,7 @@ Usage: prometheus_exporter [options]
768
821
  -c, --collector FILE (optional) Custom collector to run
769
822
  -a, --type-collector FILE (optional) Custom type collectors to run in main collector
770
823
  -v, --verbose
824
+ -g, --histogram Use histogram instead of summary for aggregations
771
825
  --auth FILE (optional) enable basic authentication using a htpasswd FILE
772
826
  --realm REALM (optional) Use REALM for basic authentication (default: "Prometheus Exporter")
773
827
  --unicorn-listen-address ADDRESS
@@ -838,6 +892,38 @@ http_requests_total{service="app-server-01",app_name="app-01"} 1
838
892
 
839
893
  By default, `PrometheusExporter::Client.default` connects to `localhost:9394`. If your setup requires this (e.g. when using `docker-compose`), you can change the default host and port by setting the environment variables `PROMETHEUS_EXPORTER_HOST` and `PROMETHEUS_EXPORTER_PORT`.
840
894
 
895
+ ### Histogram mode
896
+
897
+ By default, the built-in collectors will report aggregations as summaries. If you need to aggregate metrics across labels, you can switch from summaries to histograms:
898
+
899
+ ```
900
+ $ prometheus_exporter --histogram
901
+ ```
902
+
903
+ In histogram mode, the same metrics will be collected but will be reported as histograms rather than summaries. This sacrifices some precision but allows aggregating metrics across actions and nodes using [`histogram_quantile`].
904
+
905
+ [`histogram_quantile`]: https://prometheus.io/docs/prometheus/latest/querying/functions/#histogram_quantile
906
+
907
+ ### Histogram - custom buckets
908
+
909
+ By default these buckets will be used:
910
+ ```
911
+ [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5.0, 10.0].freeze
912
+ ```
913
+ if this is not enough you can specify `default_buckets` like this:
914
+ ```
915
+ Histogram.default_buckets = [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2, 2.5, 3, 4, 5.0, 10.0, 12, 14, 15, 20, 25].freeze
916
+ ```
917
+
918
+ Specfied buckets on the instance takes precedence over default:
919
+
920
+ ```
921
+ Histogram.default_buckets = [0.005, 0.01, 0,5].freeze
922
+ buckets = [0.1, 0.2, 0.3]
923
+ histogram = Histogram.new('test_bucktets', 'I have specified buckets', buckets: buckets)
924
+ histogram.buckets => [0.1, 0.2, 0.3]
925
+ ```
926
+
841
927
  ## Transport concerns
842
928
 
843
929
  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.
@@ -850,6 +936,19 @@ The `PrometheusExporter::Client` class has the method `#send-json`. This method,
850
936
 
851
937
  When `PrometheusExporter::Server::Collector` parses your JSON, by default it will use the faster Oj deserializer if available. This happens cause it only expects a simple Hash out of the box. You can opt in for the default JSON deserializer with `json_serializer: :json`.
852
938
 
939
+ ## Logging
940
+
941
+ `PrometheusExporter::Client.default` will export to `STDERR`. To change this, you can pass your own logger:
942
+ ```ruby
943
+ PrometheusExporter::Client.new(logger: Rails.logger)
944
+ PrometheusExporter::Client.new(logger: Logger.new(STDOUT))
945
+ ```
946
+
947
+ You can also pass a log level (default is [`Logger::WARN`](https://ruby-doc.org/stdlib-3.0.1/libdoc/logger/rdoc/Logger.html)):
948
+ ```ruby
949
+ PrometheusExporter::Client.new(log_level: Logger::DEBUG)
950
+ ```
951
+
853
952
  ## Contributing
854
953
 
855
954
  Bug reports and pull requests are welcome on GitHub at https://github.com/discourse/prometheus_exporter. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
@@ -3,12 +3,15 @@
3
3
 
4
4
  require 'optparse'
5
5
  require 'json'
6
+ require 'logger'
6
7
 
7
8
  require_relative "./../lib/prometheus_exporter"
8
9
  require_relative "./../lib/prometheus_exporter/server"
9
10
 
10
11
  def run
11
- options = {}
12
+ options = {
13
+ logger_path: STDERR
14
+ }
12
15
  custom_collector_filename = nil
13
16
  custom_type_collectors_filenames = []
14
17
 
@@ -47,6 +50,9 @@ def run
47
50
  opt.on('-v', '--verbose') do |o|
48
51
  options[:verbose] = true
49
52
  end
53
+ opt.on('-g', '--histogram', "Use histogram instead of summary for aggregations") do |o|
54
+ options[:histogram] = true
55
+ end
50
56
  opt.on('--auth FILE', String, "(optional) enable basic authentication using a htpasswd FILE") do |o|
51
57
  options[:auth] = o
52
58
  end
@@ -61,21 +67,28 @@ def run
61
67
  opt.on('--unicorn-master PID_FILE', String, '(optional) PID file of unicorn master process to monitor unicorn') do |o|
62
68
  options[:unicorn_pid_file] = o
63
69
  end
70
+
71
+ opt.on('--logger-path PATH', String, '(optional) Path to file for logger output. Defaults to STDERR') do |o|
72
+ options[:logger_path] = o
73
+ end
64
74
  end.parse!
65
75
 
76
+ logger = Logger.new(options[:logger_path])
77
+ logger.level = Logger::WARN
78
+
66
79
  if options.has_key?(:realm) && !options.has_key?(:auth)
67
- STDERR.puts "[Warn] Providing REALM without AUTH has no effect"
80
+ logger.warn "Providing REALM without AUTH has no effect"
68
81
  end
69
82
 
70
83
  if options.has_key?(:auth)
71
84
  unless File.exist?(options[:auth]) && File.readable?(options[:auth])
72
- STDERR.puts "[Error] The AUTH file either doesn't exist or we don't have access to it"
85
+ logger.fatal "The AUTH file either doesn't exist or we don't have access to it"
73
86
  exit 1
74
87
  end
75
88
  end
76
89
 
77
90
  if custom_collector_filename
78
- eval File.read(custom_collector_filename), nil, File.expand_path(custom_collector_filename)
91
+ require File.expand_path(custom_collector_filename)
79
92
  found = false
80
93
 
81
94
  base_klass = PrometheusExporter::Server::CollectorBase
@@ -88,14 +101,14 @@ def run
88
101
  end
89
102
 
90
103
  if !found
91
- STDERR.puts "[Error] Can not find a class inheriting off PrometheusExporter::Server::CollectorBase"
104
+ logger.fatal "Can not find a class inheriting off PrometheusExporter::Server::CollectorBase"
92
105
  exit 1
93
106
  end
94
107
  end
95
108
 
96
109
  if custom_type_collectors_filenames.length > 0
97
110
  custom_type_collectors_filenames.each do |t|
98
- eval File.read(t), nil, File.expand_path(t)
111
+ require File.expand_path(t)
99
112
  end
100
113
 
101
114
  ObjectSpace.each_object(Class) do |klass|