prometheus_exporter 0.7.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +35 -24
  3. data/Appraisals +1 -1
  4. data/CHANGELOG +54 -24
  5. data/README.md +129 -38
  6. data/bin/prometheus_exporter +19 -6
  7. data/lib/prometheus_exporter/client.rb +15 -5
  8. data/lib/prometheus_exporter/instrumentation/active_record.rb +7 -9
  9. data/lib/prometheus_exporter/instrumentation/delayed_job.rb +3 -2
  10. data/lib/prometheus_exporter/instrumentation/method_profiler.rb +2 -1
  11. data/lib/prometheus_exporter/instrumentation/process.rb +1 -1
  12. data/lib/prometheus_exporter/instrumentation/puma.rb +28 -16
  13. data/lib/prometheus_exporter/instrumentation/resque.rb +40 -0
  14. data/lib/prometheus_exporter/instrumentation/sidekiq.rb +1 -1
  15. data/lib/prometheus_exporter/instrumentation/sidekiq_process.rb +58 -0
  16. data/lib/prometheus_exporter/instrumentation/sidekiq_queue.rb +27 -13
  17. data/lib/prometheus_exporter/instrumentation/sidekiq_stats.rb +43 -0
  18. data/lib/prometheus_exporter/instrumentation/unicorn.rb +4 -4
  19. data/lib/prometheus_exporter/instrumentation.rb +3 -0
  20. data/lib/prometheus_exporter/metric/base.rb +9 -0
  21. data/lib/prometheus_exporter/metric/gauge.rb +4 -0
  22. data/lib/prometheus_exporter/middleware.rb +19 -9
  23. data/lib/prometheus_exporter/server/active_record_collector.rb +2 -1
  24. data/lib/prometheus_exporter/server/collector.rb +3 -0
  25. data/lib/prometheus_exporter/server/delayed_job_collector.rb +17 -17
  26. data/lib/prometheus_exporter/server/puma_collector.rb +16 -8
  27. data/lib/prometheus_exporter/server/resque_collector.rb +54 -0
  28. data/lib/prometheus_exporter/server/runner.rb +11 -2
  29. data/lib/prometheus_exporter/server/sidekiq_collector.rb +1 -1
  30. data/lib/prometheus_exporter/server/sidekiq_process_collector.rb +46 -0
  31. data/lib/prometheus_exporter/server/sidekiq_queue_collector.rb +1 -1
  32. data/lib/prometheus_exporter/server/sidekiq_stats_collector.rb +46 -0
  33. data/lib/prometheus_exporter/server/unicorn_collector.rb +3 -3
  34. data/lib/prometheus_exporter/server/web_collector.rb +4 -4
  35. data/lib/prometheus_exporter/server/web_server.rb +6 -8
  36. data/lib/prometheus_exporter/server.rb +3 -0
  37. data/lib/prometheus_exporter/version.rb +1 -1
  38. data/prometheus_exporter.gemspec +3 -3
  39. metadata +16 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f949348bbafc06b8f7a3dd3927693de8fef54090d85a7889afbfbf7dcb167b6
4
- data.tar.gz: adeca8000ebb59c7225c1453135900aeab5c1760902edd5b4fecf9fa4b879a57
3
+ metadata.gz: 9a885aa655d0bd9d939bef77ec5d7c37027d19882a96b184d0351c49593393b9
4
+ data.tar.gz: bca2080108cb8169d5589ee481fc40b0edb39e890a8a0fba6ec301a987c35396
5
5
  SHA512:
6
- metadata.gz: 7d3829ad57f03a19f6081c3444f9b13906aedd4fa1c5b99237d454096e0d993c27c2df0993482c421b6034a58a55c9603620bcdf7698248e4ac23a5063d63718
7
- data.tar.gz: fb915716acbbb4f24a152c8ebf9eb35bdc97185a7144eb986e50aafad07a36d5cc83cbbbf7c16e8b399207e9c66d90973d2e6f9ddcdc8a17cab797840d13ed8b
6
+ metadata.gz: b21fe8ad31aec32b877ab50146759715c41968dd1edc510af7b986436983217fd7eb0c468faf2ceca7897ae855a36a88f3b6aef1e0dcf776846051e4cd35b822
7
+ data.tar.gz: 5a0a61bd914c269385bb6b46df97b2eca5e6fe4573092f10dfed7d92a4f052b62761faa53902bfdf93e2286dc96a13bc804dd56e820dec99c95a00550026b741
@@ -1,7 +1,9 @@
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
9
  - cron: '0 0 * * 0' # weekly
@@ -9,34 +11,43 @@ on:
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]
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/Appraisals CHANGED
@@ -6,5 +6,5 @@ appraise "ar-60" do
6
6
  end
7
7
 
8
8
  appraise "ar-61" do
9
- gem "activerecord", "~> 6.1.0.rc2"
9
+ gem "activerecord", "~> 6.1.1"
10
10
  end
data/CHANGELOG CHANGED
@@ -1,4 +1,34 @@
1
- 0.7.0 - 29-12-2020
1
+ 1.0.1 - 2021-12-22
2
+
3
+ - FEATURE: add labels to preflight requests
4
+ - FEATURE: SidekiqStats metrics
5
+ - FIX: mintor refactors to Sidekiq metrics
6
+
7
+ 1.0.0 - 2021-11-23
8
+
9
+ - BREAKING: rename metrics to match prometheus official naming conventions (See https://prometheus.io/docs/practices/naming/#metric-names)
10
+ - FEATURE: Sidekiq process metrics
11
+ - FEATURE: Allow collecting web metrics as histograms
12
+ - FIX: logger improved for web server
13
+ - FIX: Remove job labels from DelayedJob queues
14
+
15
+ 0.8.1 - 2021-08-04
16
+
17
+ - FEATURE: swap from hardcoded STDERR to logger pattern (see README for details)
18
+
19
+ 0.8.0 - 2021-07-05
20
+
21
+ - FIX: handle ThreadError more gracefully in cases where process shuts down
22
+ - FEATURE: add job_name and queue_name labels to delayed job metrics
23
+ - FEATURE: always scope puma metrics on hostname in collector
24
+ - FEATURE: add customizable labels option to puma collector
25
+ - FEATURE: support for Resque
26
+ - DEV: Remove support for EOL ruby 2.5
27
+ - FIX: Add source location to MethodProfiler patches
28
+ - FEATURE: Improve Active Record instrumentation
29
+ - FEATURE: Support HTTP_X_AMZN_TRACE_ID when supplied
30
+
31
+ 0.7.0 - 2020-12-29
2
32
 
3
33
  - Dev: Removed support from EOL rubies, only 2.5, 2.6, 2.7 and 3.0 are supported now.
4
34
  - Dev: Better support for Ruby 3.0, explicitly depending on webrick
@@ -6,111 +36,111 @@
6
36
  - FEATURE: clean pattern for overriding middleware labels was introduced (in README)
7
37
  - Fix: Better support for forking
8
38
 
9
- 0.6.0 - 17-11-2020
39
+ 0.6.0 - 2020-11-17
10
40
 
11
41
  - FEATURE: add support for basic-auth in the prometheus_exporter web server
12
42
 
13
- 0.5.3 - 29-07-2020
43
+ 0.5.3 - 2020-07-29
14
44
 
15
45
  - FEATURE: added #remove to all metric types so users can remove specific labels if needed
16
46
 
17
- 0.5.2 - 01-07-2020
47
+ 0.5.2 - 2020-07-01
18
48
 
19
49
  - FEATURE: expanded instrumentation for sidekiq
20
50
  - FEATURE: configurable default labels
21
51
 
22
- 0.5.1 - 25-02-2020
52
+ 0.5.1 - 2020-02-25
23
53
 
24
54
  - FEATURE: Allow configuring the default client's host and port via environment variables
25
55
 
26
- 0.5.0 - 14-02-2020
56
+ 0.5.0 - 2020-02-14
27
57
 
28
58
  - Breaking change: listen only to localhost by default to prevent unintended insecure configuration
29
59
  - FIX: Avoid calling `hostname` aggressively, instead cache it on the exporter instance
30
60
 
31
- 0.4.17 - 13-01-2020
61
+ 0.4.17 - 2020-01-13
32
62
 
33
63
  - FEATURE: add support for `to_h` on all metrics which can be used to query existing key/values
34
64
 
35
- 0.4.16 - 04-11-2019
65
+ 0.4.16 - 2019-11-04
36
66
 
37
67
  - FEATURE: Support #reset! on all metric types to reset a metric to default
38
68
 
39
- 0.4.15 - 04-11-2019
69
+ 0.4.15 - 2019-11-04
40
70
 
41
71
  - FEATURE: Improve delayed job collector, add pending counts
42
72
  - FEATURE: New ActiveRecord collector (documented in readme)
43
73
  - FEATURE: Allow passing in histogram and summary options
44
74
  - FEATURE: Allow custom labels for unicorn collector
45
75
 
46
- 0.4.14 - 10-09-2019
76
+ 0.4.14 - 2019-09-10
47
77
 
48
78
  - FEATURE: allow finding metrics by name RemoteMetric #find_registered_metric
49
79
  - FIX: guard socket closing
50
80
 
51
- 0.4.13 - 09-07-2019
81
+ 0.4.13 - 2019-07-09
52
82
 
53
83
  - Fix: Memory leak in unicorn and puma collectors
54
84
 
55
- 0.4.12 - 30-05-2019
85
+ 0.4.12 - 2019-05-30
56
86
 
57
87
  - Fix: unicorn collector reporting incorrect number of unicorn workers
58
88
 
59
- 0.4.11 - 15-05-2019
89
+ 0.4.11 - 2019-05-15
60
90
 
61
91
  - Fix: Handle stopping nil worker_threads in Client
62
92
  - Dev: add frozen string literals
63
93
 
64
- 0.4.10 - 29-04-2019
94
+ 0.4.10 - 2019-04-29
65
95
 
66
96
  - Fix: Custom label support for puma collector
67
97
  - Fix: Raindrops socket collector not working correctly
68
98
 
69
- 0.4.9 - 11-04-2019
99
+ 0.4.9 - 2019-04-11
70
100
 
71
101
  - Fix: Gem was not working correctly in Ruby 2.4 and below due to a syntax error
72
102
 
73
- 0.4.8 - 10-04-2019
103
+ 0.4.8 - 2019-04-10
74
104
 
75
105
  - Feature: added helpers for instrumenting unicorn using raindrops
76
106
 
77
- 0.4.7 - 08-04-2019
107
+ 0.4.7 - 2019-04-08
78
108
 
79
109
  - Fix: collector was not escaping " \ and \n correctly. This could lead
80
110
  to a corrupt payload in some cases.
81
111
 
82
- 0.4.6 - 02-04-2019
112
+ 0.4.6 - 2019-04-02
83
113
 
84
114
  - Feature: Allow resetting a counter
85
115
  - Feature: Add sidekiq metrics: restarted, dead jobs counters
86
116
  - Fix: Client shutting down before sending metrics to collector
87
117
 
88
- 0.4.5 - 14-02-2019
118
+ 0.4.5 - 2019-02-14
89
119
 
90
120
  - Feature: Allow process collector to ship custom labels for all process metrics
91
121
  - Fix: Always scope process metrics on hostname in collector
92
122
 
93
- 0.4.4 - 13-02-2019
123
+ 0.4.4 - 2019-02-13
94
124
 
95
125
  - Feature: add support for local metric collection without using HTTP
96
126
 
97
- 0.4.3 - 11-02-2019
127
+ 0.4.3 - 2019-02-11
98
128
 
99
129
  - Feature: Add alias for Gauge #observe called #set, this makes it a bit easier to migrate from prom
100
130
  - Feature: Add increment and decrement to Counter
101
131
 
102
- 0.4.2 - 30-11-2018
132
+ 0.4.2 - 2018-11-30
103
133
 
104
134
  - Fix/Feature: setting a Gauge to nil will remove Gauge (setting to non numeric will raise)
105
135
 
106
- 0.4.0 - 23-10-2018
136
+ 0.4.0 - 2018-10-23
107
137
 
108
138
  - Feature: histogram support
109
139
  - Feature: custom quantile support for summary
110
140
  - Feature: Puma metrics
111
141
  - Fix: delayed job metrics
112
142
 
113
- 0.3.4 - 02-10-2018
143
+ 0.3.4 - 2018-10-02
114
144
 
115
145
  - Fix: custom collector via CLI was not working correctly
116
146
 
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)
@@ -19,21 +20,30 @@ To learn more see [Instrumenting Rails with Prometheus](https://samsaffron.com/a
19
20
  * [Hutch metrics](#hutch-message-processing-tracer)
20
21
  * [Puma metrics](#puma-metrics)
21
22
  * [Unicorn metrics](#unicorn-process-metrics)
23
+ * [Resque metrics](#resque-metrics)
22
24
  * [Custom type collectors](#custom-type-collectors)
23
25
  * [Multi process mode with custom collector](#multi-process-mode-with-custom-collector)
24
26
  * [GraphQL support](#graphql-support)
25
27
  * [Metrics default prefix / labels](#metrics-default-prefix--labels)
26
28
  * [Client default labels](#client-default-labels)
27
29
  * [Client default host](#client-default-host)
30
+ * [Histogram mode](#histogram-mode)
28
31
  * [Transport concerns](#transport-concerns)
29
32
  * [JSON generation and parsing](#json-generation-and-parsing)
33
+ * [Logging](#logging)
30
34
  * [Contributing](#contributing)
31
35
  * [License](#license)
32
36
  * [Code of Conduct](#code-of-conduct)
33
37
 
34
38
  ## Requirements
35
39
 
36
- Minimum Ruby of version 2.5.0 is required, Ruby 2.4.0 is EOL as of 2020-04-05
40
+ Minimum Ruby of version 2.6.0 is required, Ruby 2.5.0 is EOL as of March 31st 2021.
41
+
42
+ ## Migrating from v0.x
43
+
44
+ There are some major changes in v1.x from v0.x.
45
+
46
+ - Some of metrics are renamed to match [prometheus official guide for metric names](https://prometheus.io/docs/practices/naming/#metric-names). (#184)
37
47
 
38
48
  ## Installation
39
49
 
@@ -357,40 +367,49 @@ Metrics collected by Process instrumentation include labels `type` (as given wit
357
367
 
358
368
  #### Sidekiq metrics
359
369
 
360
- Including Sidekiq metrics (how many jobs ran? how many failed? how long did they take? how many are dead? how many were restarted?)
361
-
362
- ```ruby
363
- Sidekiq.configure_server do |config|
364
- config.server_middleware do |chain|
365
- require 'prometheus_exporter/instrumentation'
366
- chain.add PrometheusExporter::Instrumentation::Sidekiq
367
- end
368
- config.death_handlers << PrometheusExporter::Instrumentation::Sidekiq.death_handler
369
- end
370
- ```
371
-
372
- To monitor Queue size and latency:
370
+ There are different kinds of Sidekiq metrics that can be collected. A recommended setup looks like this:
373
371
 
374
372
  ```ruby
375
373
  Sidekiq.configure_server do |config|
374
+ require 'prometheus_exporter/instrumentation'
375
+ config.server_middleware do |chain|
376
+ chain.add PrometheusExporter::Instrumentation::Sidekiq
377
+ end
378
+ config.death_handlers << PrometheusExporter::Instrumentation::Sidekiq.death_handler
376
379
  config.on :startup do
377
- require 'prometheus_exporter/instrumentation'
380
+ PrometheusExporter::Instrumentation::Process.start type: 'sidekiq'
381
+ PrometheusExporter::Instrumentation::SidekiqProcess.start
378
382
  PrometheusExporter::Instrumentation::SidekiqQueue.start
383
+ PrometheusExporter::Instrumentation::SidekiqStats.start
379
384
  end
380
385
  end
381
386
  ```
382
387
 
383
- To monitor Sidekiq process info:
388
+ * 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?).
389
+ * The [`Process`](#per-process-stats) metrics provide basic ruby metrics.
390
+ * The `SidekiqProcess` metrics provide the concurrency and busy metrics for this process.
391
+ * The `SidekiqQueue` metrics provides size and latency for the queues run by this process.
392
+ * The `SidekiqStats` metrics provide general, global Sidekiq stats (size of Scheduled, Retries, Dead queues, total number of jobs, etc).
393
+
394
+ 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.
395
+
396
+ An alternative would be to expose these metrics in lone, long-lived process. Using a rake task, for example:
384
397
 
385
398
  ```ruby
386
- Sidekiq.configure_server do |config|
387
- config.on :startup do
388
- require 'prometheus_exporter/instrumentation'
389
- PrometheusExporter::Instrumentation::Process.start type: 'sidekiq'
390
- end
399
+ task :sidekiq_metrics do
400
+ server = PrometheusExporter::Server::WebServer.new
401
+ server.start
402
+
403
+ PrometheusExporter::Client.default = PrometheusExporter::LocalClient.new(collector: server.collector)
404
+
405
+ PrometheusExporter::Instrumentation::SidekiqQueue.start(all_queues: true)
406
+ PrometheusExporter::Instrumentation::SidekiqStats.start
407
+ sleep
391
408
  end
392
409
  ```
393
410
 
411
+ The `all_queues` parameter for `SidekiqQueue` will expose metrics for all queues.
412
+
394
413
  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:
395
414
 
396
415
  ```ruby
@@ -423,11 +442,33 @@ This metric has a `job_name` label and a `queue` label.
423
442
  **PrometheusExporter::Instrumentation::SidekiqQueue**
424
443
  | Type | Name | Description |
425
444
  | --- | --- | --- |
426
- | Gauge | `sidekiq_queue_backlog_total` | Size of the sidekiq queue |
445
+ | Gauge | `sidekiq_queue_backlog` | Size of the sidekiq queue |
427
446
  | Gauge | `sidekiq_queue_latency_seconds` | Latency of the sidekiq queue |
428
447
 
429
448
  Both metrics will have a `queue` label with the name of the queue.
430
449
 
450
+ **PrometheusExporter::Instrumentation::SidekiqProcess**
451
+ | Type | Name | Description |
452
+ | --- | --- | --- |
453
+ | Gauge | `sidekiq_process_busy` | Number of busy workers for this process |
454
+ | Gauge | `sidekiq_process_concurrency` | Concurrency for this process |
455
+
456
+ 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).
457
+
458
+ **PrometheusExporter::Instrumentation::SidekiqStats**
459
+ | Type | Name | Description |
460
+ | --- | --- | --- |
461
+ | Gauge | `sidekiq_stats_dead_size` | Size of the dead queue |
462
+ | Gauge | `sidekiq_stats_enqueued` | Number of enqueued jobs |
463
+ | Gauge | `sidekiq_stats_failed` | Number of failed jobs |
464
+ | Gauge | `sidekiq_stats_processed` | Total number of processed jobs |
465
+ | Gauge | `sidekiq_stats_processes_size` | Number of processes |
466
+ | Gauge | `sidekiq_stats_retry_size` | Size of the retries queue |
467
+ | Gauge | `sidekiq_stats_scheduled_size` | Size of the scheduled queue |
468
+ | Gauge | `sidekiq_stats_workers_size` | Number of jobs actively being processed |
469
+
470
+ Based on the [Sidekiq Stats API](https://github.com/mperham/sidekiq/wiki/API#stats).
471
+
431
472
  _See [Metrics collected by Process Instrumentation](#metrics-collected-by-process-instrumentation) for a list of metrics the Process instrumentation will produce._
432
473
 
433
474
  #### Shoryuken metrics
@@ -478,6 +519,8 @@ end
478
519
  | Summary | `delayed_job_duration_seconds_summary` | Summary of the time it takes jobs to execute | `status` |
479
520
  | Summary | `delayed_job_attempts_summary` | Summary of the amount of attempts it takes delayed jobs to succeed | - |
480
521
 
522
+ All metrics have labels for `job_name` and `queue_name`.
523
+
481
524
  #### Hutch Message Processing Tracer
482
525
 
483
526
  Capture [Hutch](https://github.com/gocardless/hutch) metrics (how many jobs ran? how many failed? how long did they take?)
@@ -505,7 +548,7 @@ Request Queueing is defined as the time it takes for a request to reach your app
505
548
 
506
549
  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).
507
550
 
508
- 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.
551
+ The Amazon Application Load Balancer [request tracing header](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-request-tracing.html) is natively supported. If you are using another upstream entrypoint, you may 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.
509
552
 
510
553
  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`.
511
554
 
@@ -525,17 +568,39 @@ end
525
568
 
526
569
  #### Metrics collected by Puma Instrumentation
527
570
 
528
- | Type | Name | Description |
529
- | --- | --- | --- |
530
- | Gauge | `puma_workers_total` | Number of puma workers |
531
- | Gauge | `puma_booted_workers_total` | Number of puma workers booted |
532
- | Gauge | `puma_old_workers_total` | Number of old puma workers |
533
- | Gauge | `puma_running_threads_total` | Number of puma threads currently running |
534
- | Gauge | `puma_request_backlog_total` | Number of requests waiting to be processed by a puma thread |
535
- | Gauge | `puma_thread_pool_capacity_total` | Number of puma threads available at current scale |
536
- | Gauge | `puma_max_threads_total` | Number of puma threads at available at max scale |
571
+ | Type | Name | Description |
572
+ | --- | --- | --- |
573
+ | Gauge | `puma_workers` | Number of puma workers |
574
+ | Gauge | `puma_booted_workers` | Number of puma workers booted |
575
+ | Gauge | `puma_old_workers` | Number of old puma workers |
576
+ | Gauge | `puma_running_threads` | Number of puma threads currently running |
577
+ | Gauge | `puma_request_backlog` | Number of requests waiting to be processed by a puma thread |
578
+ | Gauge | `puma_thread_pool_capacity` | Number of puma threads available at current scale |
579
+ | Gauge | `puma_max_threads` | Number of puma threads at available at max scale |
537
580
 
538
- All metrics may have a `phase` label.
581
+ All metrics may have a `phase` label and all custom labels provided with the `labels` option.
582
+
583
+ ### Resque metrics
584
+
585
+ The resque metrics are using the `Resque.info` method, which queries Redis internally. To start monitoring your resque
586
+ installation, you'll need to start the instrumentation:
587
+
588
+ ```ruby
589
+ # e.g. config/initializers/resque.rb
590
+ require 'prometheus_exporter/instrumentation'
591
+ PrometheusExporter::Instrumentation::Resque.start
592
+ ```
593
+
594
+ #### Metrics collected by Resque Instrumentation
595
+
596
+ | Type | Name | Description |
597
+ | --- | --- | --- |
598
+ | Gauge | `resque_processed_jobs` | Total number of processed Resque jobs |
599
+ | Gauge | `resque_failed_jobs` | Total number of failed Resque jobs |
600
+ | Gauge | `resque_pending_jobs` | Total number of pending Resque jobs |
601
+ | Gauge | `resque_queues` | Total number of Resque queues |
602
+ | Gauge | `resque_workers` | Total number of Resque workers running |
603
+ | Gauge | `resque_working` | Total number of Resque workers working |
539
604
 
540
605
  ### Unicorn process metrics
541
606
 
@@ -554,11 +619,11 @@ Note: You must install the `raindrops` gem in your `Gemfile` or locally.
554
619
 
555
620
  #### Metrics collected by Unicorn Instrumentation
556
621
 
557
- | Type | Name | Description |
558
- | --- | --- | --- |
559
- | Gauge | `unicorn_workers_total` | Number of unicorn workers |
560
- | Gauge | `unicorn_active_workers_total` | Number of active unicorn workers |
561
- | Gauge | `unicorn_request_backlog_total` | Number of requests waiting to be processed by a unicorn worker |
622
+ | Type | Name | Description |
623
+ | --- | --- | --- |
624
+ | Gauge | `unicorn_workers` | Number of unicorn workers |
625
+ | Gauge | `unicorn_active_workers` | Number of active unicorn workers |
626
+ | Gauge | `unicorn_request_backlog` | Number of requests waiting to be processed by a unicorn worker |
562
627
 
563
628
  ### Custom type collectors
564
629
 
@@ -743,6 +808,7 @@ Usage: prometheus_exporter [options]
743
808
  -c, --collector FILE (optional) Custom collector to run
744
809
  -a, --type-collector FILE (optional) Custom type collectors to run in main collector
745
810
  -v, --verbose
811
+ -g, --histogram Use histogram instead of summary for aggregations
746
812
  --auth FILE (optional) enable basic authentication using a htpasswd FILE
747
813
  --realm REALM (optional) Use REALM for basic authentication (default: "Prometheus Exporter")
748
814
  --unicorn-listen-address ADDRESS
@@ -813,6 +879,18 @@ http_requests_total{service="app-server-01",app_name="app-01"} 1
813
879
 
814
880
  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`.
815
881
 
882
+ ### Histogram mode
883
+
884
+ 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:
885
+
886
+ ```
887
+ $ prometheus_exporter --histogram
888
+ ```
889
+
890
+ 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`].
891
+
892
+ [`histogram_quantile`]: https://prometheus.io/docs/prometheus/latest/querying/functions/#histogram_quantile
893
+
816
894
  ## Transport concerns
817
895
 
818
896
  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.
@@ -825,6 +903,19 @@ The `PrometheusExporter::Client` class has the method `#send-json`. This method,
825
903
 
826
904
  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`.
827
905
 
906
+ ## Logging
907
+
908
+ `PrometheusExporter::Client.default` will export to `STDERR`. To change this, you can pass your own logger:
909
+ ```ruby
910
+ PrometheusExporter::Client.new(logger: Rails.logger)
911
+ PrometheusExporter::Client.new(logger: Logger.new(STDOUT))
912
+ ```
913
+
914
+ You can also pass a log level (default is [`Logger::WARN`](https://ruby-doc.org/stdlib-3.0.1/libdoc/logger/rdoc/Logger.html)):
915
+ ```ruby
916
+ PrometheusExporter::Client.new(log_level: Logger::DEBUG)
917
+ ```
918
+
828
919
  ## Contributing
829
920
 
830
921
  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|