sidekiq_prometheus 1.8.2 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -2
- data/CHANGELOG.md +20 -0
- data/Gemfile +1 -1
- data/README.md +7 -2
- data/Rakefile +4 -11
- data/lib/sidekiq_prometheus/job_metrics.rb +5 -5
- data/lib/sidekiq_prometheus/metrics.rb +110 -95
- data/lib/sidekiq_prometheus/periodic_metrics.rb +55 -23
- data/lib/sidekiq_prometheus/version.rb +1 -1
- data/lib/sidekiq_prometheus.rb +31 -23
- data/sidekiq_prometheus.gemspec +21 -21
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 654002b3b3138eef5307c4e4c3cab5a6d8ca45cc283c49341d3c1760f4d3ef67
|
4
|
+
data.tar.gz: 5abf477f0a4a8baa64e82d22527477614d57f48c8bf26c4d637a7c24bbb5cc70
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0544dc888a169886f532b2aa08ef8ab3c8c34ec1dea5a72bb9a75618aecfaaf4d1de81f6ae44cd61cc2621189ad69489a082f4af877cf63e7139ca3eb124a8dc
|
7
|
+
data.tar.gz: 7eb8689d5514e3585a6ee722a5f21d6f964a56146750d922fa578164a72ffbb36415c47befb10f7f7c61cc82ada60c7a4200b55370cf74ceae72270f4b423d98
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
CHANGELOG
|
2
2
|
|
3
|
+
<a name="v1.8.3"></a>
|
4
|
+
## [v1.8.3](https://github.com/fastly/sidekiq-prometheus/compare/v1.8.2...v1.8.3) (2023-01-30)
|
5
|
+
|
6
|
+
## What's Changed
|
7
|
+
* Track leader state so that can unregister when demoted by @leklund in https://github.com/fastly/sidekiq-prometheus/pull/36
|
8
|
+
|
9
|
+
**Full Changelog**: https://github.com/fastly/sidekiq-prometheus/compare/v1.8.2...v1.8.3
|
10
|
+
|
11
|
+
<a name="v1.8.2"></a>
|
12
|
+
## [v1.8.2](https://github.com/fastly/sidekiq-prometheus/compare/v1.8.1...v1.8.2) (2022-11-29)
|
13
|
+
|
14
|
+
## What's Changed
|
15
|
+
* Allow sidekiq-prometheus to work with prometheus-client version > 2 by @hieuk09 in https://github.com/fastly/sidekiq-prometheus/pull/29
|
16
|
+
* Fixes Newer Sidekiq-Enterprise versions that have a Senate.leader? issue with Sidekiq Prometheus 1.8.1 by @imightbeinatree in https://github.com/fastly/sidekiq-prometheus/pull/32
|
17
|
+
|
18
|
+
## New Contributors
|
19
|
+
* @hieuk09 made their first contribution in https://github.com/fastly/sidekiq-prometheus/pull/29
|
20
|
+
|
21
|
+
**Full Changelog**: https://github.com/fastly/sidekiq-prometheus/compare/v1.8.1...v1.8.2
|
22
|
+
|
3
23
|
<a name="v1.8.1"></a>
|
4
24
|
## [v1.8.1](https://github.com/fastly/sidekiq-prometheus/compare/v1.8.0...v1.8.1) (2022-10-18)
|
5
25
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -79,6 +79,7 @@ end
|
|
79
79
|
* `custom_labels`: Hash of metrics and labels that can be applied to specific metrics. The metric name must be a registered metric. `Hash{Symbol (metric name) => Array<Symbol> (label names)}`
|
80
80
|
* `gc_metrics_enabled`: Boolean that determines whether to record object allocation metrics per job. The default is `true`. Setting this to `false` if you don't need this metric.
|
81
81
|
* `global_metrics_enabled`: Boolean that determines whether to report global metrics from the PeriodicMetrics reporter. When `true` this will report on a number of stats from the Sidekiq API for the cluster. This requires Sidekiq::Enterprise as the reporter uses the leader election functionality to ensure that only one worker per cluster is reporting metrics.
|
82
|
+
* `init_label_sets`: Hash of metrics and label sets that are initialized by calling `metric.init_label_set` after the metric is registered. See[ prometheus-client docs](https://github.com/prometheus/client_ruby/tree/e144d6225d3c346e9a4dd0a11f41f8acde386dd8#init_label_set) for details. `Hash{Symbol (metric name) => Array<Hash> (label sets)}`.
|
82
83
|
* `periodic_metrics_enabled`: Boolean that determines whether to run the periodic metrics reporter. `PeriodicMetrics` runs a separate thread that reports on global metrics (if enabled) as well worker GC stats (if enabled). It reports metrics on the interval defined by `periodic_reporting_interval`. Defaults to `true`.
|
83
84
|
* `periodic_reporting_interval`: interval in seconds for reporting periodic metrics. Default: `30`
|
84
85
|
* `metrics_server_enabled`: Boolean that determines whether to run the rack server. Defaults to `true`
|
@@ -94,6 +95,7 @@ SidekiqPrometheus.configure do |config|
|
|
94
95
|
config.custom_labels = { sidekiq_job_count: [:worker_class, :job_type, :any_other_label] }
|
95
96
|
config.gc_metrics_enabled = false
|
96
97
|
config.global_metrics_enabled = true
|
98
|
+
config.init_label_sets = { sidekiq_job_count: [{worker_class: "class", job_type: "single", any_other_label: "value"}, {worker_class: "class", job_type: "batch", any_other_label: "other-value"}] }
|
97
99
|
config.periodic_metrics_enabled = true
|
98
100
|
config.periodic_reporting_interval = 20
|
99
101
|
config.metrics_server_enabled = true
|
@@ -101,7 +103,7 @@ SidekiqPrometheus.configure do |config|
|
|
101
103
|
end
|
102
104
|
```
|
103
105
|
|
104
|
-
Custom labels may be added by defining the `prometheus_labels` method in the worker class,
|
106
|
+
Custom labels may be added by defining the `prometheus_labels` method in the worker class,
|
105
107
|
prior you need to register the custom labels as of the above example:
|
106
108
|
|
107
109
|
```ruby
|
@@ -130,10 +132,13 @@ All Sidekiq job metrics are reported with these labels:
|
|
130
132
|
| sidekiq_job_success | counter | Count of successful Sidekiq jobs |
|
131
133
|
| sidekiq_job_allocated_objects | histogram | Count of ruby objects allocated by a Sidekiq job |
|
132
134
|
| sidekiq_job_failed | counter | Count of failed Sidekiq jobs |
|
135
|
+
| sidekiq_job_over_limit | counter | Count of over limit Sidekiq jobs |
|
136
|
+
|
133
137
|
|
134
138
|
Notes:
|
135
139
|
|
136
140
|
* when a job fails only `sidekiq_job_count` and `sidekiq_job_failed` will be reported.
|
141
|
+
* when a job fails due to Sidekiq::Limiter::OverLimit error, only `sidekiq_job_count` and `sidekiq_job_over_limit` will be reported.
|
137
142
|
* `sidekiq_job_allocated_objects` will only be reported if `SidekiqPrometheus.gc_metrics_enabled? == true`
|
138
143
|
|
139
144
|
### Periodic GC Metrics
|
@@ -217,7 +222,7 @@ There is also a method to register more than one metric at a time:
|
|
217
222
|
customer_worker_metrics = [
|
218
223
|
{
|
219
224
|
name: :file_count, type: :counter, docstring: 'Number of active files',
|
220
|
-
name: :file_size, type: :gauge, docstring: 'Size of files in bytes',
|
225
|
+
name: :file_size, type: :gauge, docstring: 'Size of files in bytes',
|
221
226
|
}
|
222
227
|
]
|
223
228
|
|
data/Rakefile
CHANGED
@@ -1,19 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rspec/core/rake_task"
|
5
|
+
require "standard/rake"
|
5
6
|
|
6
7
|
RSpec::Core::RakeTask.new(:spec)
|
7
8
|
|
8
|
-
begin
|
9
|
-
require 'rubocop/rake_task'
|
10
|
-
RuboCop::RakeTask.new(:rubocop) do |task|
|
11
|
-
task.options = ['-c.rubocop.yml']
|
12
|
-
end
|
13
|
-
rescue LoadError
|
14
|
-
end
|
15
|
-
|
16
9
|
task default: %w[
|
17
|
-
|
10
|
+
standard
|
18
11
|
spec
|
19
12
|
]
|
@@ -7,8 +7,8 @@ class SidekiqPrometheus::JobMetrics
|
|
7
7
|
# If we're using a wrapper class, like ActiveJob, use the "wrapped"
|
8
8
|
# attribute to expose the underlying thing.
|
9
9
|
labels = {
|
10
|
-
class: job[
|
11
|
-
queue: queue
|
10
|
+
class: job["wrapped"] || worker.class.to_s,
|
11
|
+
queue: queue
|
12
12
|
}
|
13
13
|
|
14
14
|
begin
|
@@ -29,11 +29,11 @@ class SidekiqPrometheus::JobMetrics
|
|
29
29
|
end
|
30
30
|
|
31
31
|
result
|
32
|
-
rescue
|
33
|
-
if e.
|
32
|
+
rescue => e
|
33
|
+
if e.instance_of?(::Sidekiq::Limiter::OverLimit)
|
34
34
|
registry[:sidekiq_job_over_limit].increment(labels: labels)
|
35
35
|
else
|
36
|
-
err_label = {
|
36
|
+
err_label = {error_class: e.class.to_s}
|
37
37
|
registry[:sidekiq_job_failed].increment(labels: err_label.merge(labels))
|
38
38
|
end
|
39
39
|
|
@@ -3,106 +3,106 @@
|
|
3
3
|
module SidekiqPrometheus::Metrics
|
4
4
|
module_function
|
5
5
|
|
6
|
-
UNKNOWN =
|
6
|
+
UNKNOWN = "unknown"
|
7
7
|
|
8
8
|
VALID_TYPES = %i[counter gauge histogram summary].freeze
|
9
9
|
JOB_LABELS = %i[class queue].freeze
|
10
10
|
SIDEKIQ_GLOBAL_METRICS = [
|
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
|
-
|
11
|
+
{name: :sidekiq_workers_size,
|
12
|
+
type: :gauge,
|
13
|
+
docstring: "Total number of workers processing jobs"},
|
14
|
+
{name: :sidekiq_processes_size,
|
15
|
+
type: :gauge,
|
16
|
+
docstring: "Total number of running sidekiq processes"},
|
17
|
+
{name: :sidekiq_dead_size,
|
18
|
+
type: :gauge,
|
19
|
+
docstring: "Total Dead Size"},
|
20
|
+
{name: :sidekiq_enqueued,
|
21
|
+
type: :gauge,
|
22
|
+
docstring: "Total Size of all known queues",
|
23
|
+
labels: %i[queue]},
|
24
|
+
{name: :sidekiq_queue_latency,
|
25
|
+
type: :summary,
|
26
|
+
docstring: "Latency (in seconds) of all queues",
|
27
|
+
labels: %i[queue]},
|
28
|
+
{name: :sidekiq_failed,
|
29
|
+
type: :gauge,
|
30
|
+
docstring: "Number of job executions which raised an error"},
|
31
|
+
{name: :sidekiq_processed,
|
32
|
+
type: :gauge,
|
33
|
+
docstring: "Number of job executions completed (success or failure)"},
|
34
|
+
{name: :sidekiq_retry_size,
|
35
|
+
type: :gauge,
|
36
|
+
docstring: "Total Retries Size"},
|
37
|
+
{name: :sidekiq_scheduled_size,
|
38
|
+
type: :gauge,
|
39
|
+
docstring: "Total Scheduled Size"},
|
40
|
+
{name: :sidekiq_redis_connected_clients,
|
41
|
+
type: :gauge,
|
42
|
+
docstring: "Number of clients connected to Redis instance for Sidekiq"},
|
43
|
+
{name: :sidekiq_redis_used_memory,
|
44
|
+
type: :gauge,
|
45
|
+
docstring: "Used memory from Redis.info"},
|
46
|
+
{name: :sidekiq_redis_used_memory_peak,
|
47
|
+
type: :gauge,
|
48
|
+
docstring: "Used memory peak from Redis.info"},
|
49
|
+
{name: :sidekiq_redis_keys,
|
50
|
+
type: :gauge,
|
51
|
+
docstring: "Number of redis keys",
|
52
|
+
labels: %i[database]},
|
53
|
+
{name: :sidekiq_redis_expires,
|
54
|
+
type: :gauge,
|
55
|
+
docstring: "Number of redis keys with expiry set",
|
56
|
+
labels: %i[database]}
|
57
57
|
].freeze
|
58
58
|
SIDEKIQ_JOB_METRICS = [
|
59
|
-
{
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
{
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
{
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
{
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
{
|
76
|
-
|
77
|
-
|
78
|
-
|
59
|
+
{name: :sidekiq_job_count,
|
60
|
+
type: :counter,
|
61
|
+
docstring: "Count of Sidekiq jobs",
|
62
|
+
labels: JOB_LABELS},
|
63
|
+
{name: :sidekiq_job_duration,
|
64
|
+
type: :histogram,
|
65
|
+
docstring: "Sidekiq job processing duration",
|
66
|
+
labels: JOB_LABELS},
|
67
|
+
{name: :sidekiq_job_failed,
|
68
|
+
type: :counter,
|
69
|
+
docstring: "Count of failed Sidekiq jobs",
|
70
|
+
labels: JOB_LABELS + [:error_class]},
|
71
|
+
{name: :sidekiq_job_success,
|
72
|
+
type: :counter,
|
73
|
+
docstring: "Count of successful Sidekiq jobs",
|
74
|
+
labels: JOB_LABELS},
|
75
|
+
{name: :sidekiq_job_over_limit,
|
76
|
+
type: :counter,
|
77
|
+
docstring: "Count of over limit Sidekiq jobs",
|
78
|
+
labels: JOB_LABELS}
|
79
79
|
].freeze
|
80
80
|
SIDEKIQ_GC_METRIC = {
|
81
|
-
name:
|
82
|
-
type:
|
83
|
-
docstring:
|
84
|
-
buckets:
|
85
|
-
labels:
|
81
|
+
name: :sidekiq_job_allocated_objects,
|
82
|
+
type: :histogram,
|
83
|
+
docstring: "Count of ruby objects allocated by a Sidekiq job",
|
84
|
+
buckets: [10, 50, 100, 500, 1_000, 2_500, 5_000, 10_000, 50_000, 100_000, 500_000, 1_000_000, 5_000_000, 10_000_000, 25_000_000],
|
85
|
+
labels: JOB_LABELS
|
86
86
|
}.freeze
|
87
87
|
SIDEKIQ_WORKER_GC_METRICS = [
|
88
|
-
{
|
89
|
-
|
90
|
-
|
91
|
-
{
|
92
|
-
|
93
|
-
|
94
|
-
{
|
95
|
-
|
96
|
-
|
97
|
-
{
|
98
|
-
|
99
|
-
|
100
|
-
{
|
101
|
-
|
102
|
-
|
103
|
-
{
|
104
|
-
|
105
|
-
|
88
|
+
{name: :sidekiq_allocated_objects,
|
89
|
+
type: :counter,
|
90
|
+
docstring: "Count of ruby objects allocated by a Sidekiq worker"},
|
91
|
+
{name: :sidekiq_heap_free_slots,
|
92
|
+
type: :gauge,
|
93
|
+
docstring: "Sidekiq worker GC.stat[:heap_free_slots]"},
|
94
|
+
{name: :sidekiq_heap_live_slots,
|
95
|
+
type: :gauge,
|
96
|
+
docstring: "Sidekiq worker GC.stat[:heap_live_slots]"},
|
97
|
+
{name: :sidekiq_major_gc_count,
|
98
|
+
type: :counter,
|
99
|
+
docstring: "Sidekiq worker GC.stat[:major_gc_count]"},
|
100
|
+
{name: :sidekiq_minor_gc_count,
|
101
|
+
type: :counter,
|
102
|
+
docstring: "Sidekiq worker GC.stat[:minor_gc_count]"},
|
103
|
+
{name: :sidekiq_rss,
|
104
|
+
type: :gauge,
|
105
|
+
docstring: "Sidekiq process RSS"}
|
106
106
|
].freeze
|
107
107
|
|
108
108
|
def registry
|
@@ -131,6 +131,16 @@ module SidekiqPrometheus::Metrics
|
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
|
+
def unregister_sidekiq_global_metrics
|
135
|
+
unregister_metrics SIDEKIQ_GLOBAL_METRICS
|
136
|
+
end
|
137
|
+
|
138
|
+
def unregister_metrics(metrics)
|
139
|
+
metrics.each do |metric|
|
140
|
+
unregister(name: metric[:name])
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
134
144
|
##
|
135
145
|
# Fetch a metric from the registry
|
136
146
|
# @param name [Symbol] name of metric to fetch
|
@@ -139,7 +149,7 @@ module SidekiqPrometheus::Metrics
|
|
139
149
|
end
|
140
150
|
|
141
151
|
class << self
|
142
|
-
|
152
|
+
alias_method :get, :[]
|
143
153
|
end
|
144
154
|
|
145
155
|
##
|
@@ -160,13 +170,18 @@ module SidekiqPrometheus::Metrics
|
|
160
170
|
# Aggregate all labels
|
161
171
|
all_labels = labels | SidekiqPrometheus.custom_labels.fetch(name, []) | all_preset_labels.keys
|
162
172
|
|
163
|
-
options = {
|
164
|
-
|
165
|
-
|
173
|
+
options = {docstring: docstring,
|
174
|
+
labels: all_labels,
|
175
|
+
preset_labels: all_preset_labels}
|
166
176
|
|
167
177
|
options[:buckets] = buckets if buckets
|
168
178
|
|
169
|
-
registry.send(type, name.to_sym, **options)
|
179
|
+
metric = registry.send(type, name.to_sym, **options)
|
180
|
+
|
181
|
+
init_label_sets = SidekiqPrometheus.init_label_sets.fetch(name, [])
|
182
|
+
init_label_sets.each { |label_set| metric.init_label_set(label_set) }
|
183
|
+
|
184
|
+
metric
|
170
185
|
end
|
171
186
|
|
172
187
|
def unregister(name:)
|
@@ -11,7 +11,7 @@
|
|
11
11
|
# @see https://github.com/mperham/sidekiq/blob/main/lib/sidekiq/api.rb
|
12
12
|
|
13
13
|
begin
|
14
|
-
require
|
14
|
+
require "sidekiq/component"
|
15
15
|
rescue LoadError
|
16
16
|
end
|
17
17
|
|
@@ -21,6 +21,9 @@ class SidekiqPrometheus::PeriodicMetrics
|
|
21
21
|
# @return [Boolean] When +true+ will stop the reporting loop.
|
22
22
|
attr_accessor :done
|
23
23
|
|
24
|
+
# @return [Boolean] Indicates if this instance is currently the leader.
|
25
|
+
attr_accessor :leader
|
26
|
+
|
24
27
|
# @return [Integer] Interval in seconds to record metrics. Default: [SidekiqPrometheus.periodic_reporting_interval]
|
25
28
|
attr_reader :interval
|
26
29
|
attr_reader :senate, :sidekiq_stats, :sidekiq_queue
|
@@ -28,7 +31,7 @@ class SidekiqPrometheus::PeriodicMetrics
|
|
28
31
|
GLOBAL_STATS = %i[failed processed retry_size dead_size scheduled_size workers_size processes_size].freeze
|
29
32
|
GC_STATS = {
|
30
33
|
counters: %i[major_gc_count minor_gc_count total_allocated_objects],
|
31
|
-
gauges: %i[heap_live_slots heap_free_slots]
|
34
|
+
gauges: %i[heap_live_slots heap_free_slots]
|
32
35
|
}.freeze
|
33
36
|
REDIS_STATS = %w[connected_clients used_memory used_memory_peak].freeze
|
34
37
|
|
@@ -50,24 +53,25 @@ class SidekiqPrometheus::PeriodicMetrics
|
|
50
53
|
@sidekiq_stats = sidekiq_stats
|
51
54
|
@sidekiq_queue = sidekiq_queue
|
52
55
|
@senate = if senate.nil?
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
56
|
+
if Object.const_defined?("Sidekiq::Senate")
|
57
|
+
if respond_to?(:leader?)
|
58
|
+
self
|
59
|
+
else
|
60
|
+
Sidekiq::Senate
|
61
|
+
end
|
62
|
+
else
|
63
|
+
Senate
|
64
|
+
end
|
65
|
+
else
|
66
|
+
senate
|
67
|
+
end
|
68
|
+
@leader = false
|
65
69
|
end
|
66
70
|
|
67
71
|
##
|
68
72
|
# Start the period mettric reporter
|
69
73
|
def start
|
70
|
-
Sidekiq.logger.info(
|
74
|
+
Sidekiq.logger.info("SidekiqPrometheus: Starting periodic metrics reporting")
|
71
75
|
@thread = Thread.new(&method(:run))
|
72
76
|
end
|
73
77
|
|
@@ -100,8 +104,8 @@ class SidekiqPrometheus::PeriodicMetrics
|
|
100
104
|
end
|
101
105
|
|
102
106
|
sidekiq_queue.all.each do |queue|
|
103
|
-
SidekiqPrometheus[:sidekiq_enqueued]&.set(queue.size, labels: {
|
104
|
-
SidekiqPrometheus[:sidekiq_queue_latency]&.observe(queue.latency, labels: {
|
107
|
+
SidekiqPrometheus[:sidekiq_enqueued]&.set(queue.size, labels: {queue: queue.name})
|
108
|
+
SidekiqPrometheus[:sidekiq_queue_latency]&.observe(queue.latency, labels: {queue: queue.name})
|
105
109
|
end
|
106
110
|
end
|
107
111
|
|
@@ -122,7 +126,7 @@ class SidekiqPrometheus::PeriodicMetrics
|
|
122
126
|
|
123
127
|
db_stats = redis_info.select { |k, _v| k.match(/^db/) }
|
124
128
|
db_stats.each do |db, stat|
|
125
|
-
label = {
|
129
|
+
label = {database: db}
|
126
130
|
values = stat.scan(/\d+/)
|
127
131
|
SidekiqPrometheus[:sidekiq_redis_keys]&.set(values[0].to_i, labels: label)
|
128
132
|
SidekiqPrometheus[:sidekiq_redis_expires]&.set(values[1].to_i, labels: label)
|
@@ -134,8 +138,16 @@ class SidekiqPrometheus::PeriodicMetrics
|
|
134
138
|
# @see https://github.com/discourse/prometheus_exporter/blob/v0.3.3/lib/prometheus_exporter/instrumentation/process.rb#L39-L42
|
135
139
|
def rss
|
136
140
|
pid = Process.pid
|
137
|
-
@pagesize ||=
|
138
|
-
|
141
|
+
@pagesize ||= begin
|
142
|
+
`getconf PAGESIZE`.to_i
|
143
|
+
rescue
|
144
|
+
4096
|
145
|
+
end
|
146
|
+
begin
|
147
|
+
File.read("/proc/#{pid}/statm").split(" ")[1].to_i * @pagesize
|
148
|
+
rescue
|
149
|
+
0
|
150
|
+
end
|
139
151
|
end
|
140
152
|
|
141
153
|
##
|
@@ -144,10 +156,14 @@ class SidekiqPrometheus::PeriodicMetrics
|
|
144
156
|
def run
|
145
157
|
until done
|
146
158
|
begin
|
147
|
-
|
148
|
-
|
159
|
+
if SidekiqPrometheus.global_metrics_enabled?
|
160
|
+
handle_leader_state(senate.leader?)
|
161
|
+
report_global_metrics if leader
|
162
|
+
report_redis_metrics if leader
|
163
|
+
end
|
164
|
+
|
149
165
|
report_gc_metrics if SidekiqPrometheus.gc_metrics_enabled?
|
150
|
-
rescue
|
166
|
+
rescue => e
|
151
167
|
Sidekiq.logger.error e
|
152
168
|
ensure
|
153
169
|
sleep interval
|
@@ -155,6 +171,22 @@ class SidekiqPrometheus::PeriodicMetrics
|
|
155
171
|
end
|
156
172
|
end
|
157
173
|
|
174
|
+
##
|
175
|
+
# If this instance was promoted to the leader set the local state and register the metrics.
|
176
|
+
def handle_leader_state(senate_leader)
|
177
|
+
return if senate_leader == leader
|
178
|
+
|
179
|
+
if senate_leader && !leader
|
180
|
+
# This instance is now the leader
|
181
|
+
self.leader = true
|
182
|
+
SidekiqPrometheus::Metrics.register_sidekiq_global_metrics
|
183
|
+
else
|
184
|
+
# we've been demoted!
|
185
|
+
SidekiqPrometheus::Metrics.unregister_sidekiq_global_metrics
|
186
|
+
self.leader = false
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
158
190
|
##
|
159
191
|
# Fake Senate class to guard against undefined constant errors.
|
160
192
|
# @private
|
data/lib/sidekiq_prometheus.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
3
|
+
require "benchmark"
|
4
|
+
require "rack"
|
5
|
+
require "prometheus/client"
|
6
|
+
require "prometheus/middleware/exporter"
|
7
|
+
require "sidekiq"
|
8
|
+
require "sidekiq/api"
|
9
|
+
require "webrick"
|
10
10
|
|
11
11
|
begin
|
12
|
-
require
|
12
|
+
require "sidekiq/ent"
|
13
13
|
rescue LoadError
|
14
14
|
end
|
15
15
|
|
@@ -42,6 +42,14 @@ module SidekiqPrometheus
|
|
42
42
|
# @return [Boolean] Setting to control enabling/disabling global metrics. Default: true
|
43
43
|
attr_accessor :global_metrics_enabled
|
44
44
|
|
45
|
+
# @return [Hash{Symbol => Array(Hash)}] Label sets that will be initiliazed when a metric is registered.
|
46
|
+
# @example
|
47
|
+
# {
|
48
|
+
# metric_name: [{label: 'value1', other_label: 'value1'}, {label: 'value1', other_label: 'value2'}],
|
49
|
+
# another_metric_name: [{label: 'value1', other_label: 'value1'}]
|
50
|
+
# }
|
51
|
+
attr_accessor :init_label_sets
|
52
|
+
|
45
53
|
# @return [Boolean] Setting to control enabling/disabling periodic metrics. Default: true
|
46
54
|
attr_accessor :periodic_metrics_enabled
|
47
55
|
|
@@ -77,11 +85,12 @@ module SidekiqPrometheus
|
|
77
85
|
self.global_metrics_enabled = true
|
78
86
|
self.periodic_reporting_interval = 30
|
79
87
|
self.metrics_server_enabled = true
|
80
|
-
self.metrics_host =
|
88
|
+
self.metrics_host = "localhost"
|
81
89
|
self.metrics_port = 9359
|
82
90
|
self.metrics_server_logger_enabled = true
|
83
91
|
self.custom_labels = {}
|
84
92
|
self.custom_metrics = []
|
93
|
+
self.init_label_sets = {}
|
85
94
|
|
86
95
|
module_function
|
87
96
|
|
@@ -115,7 +124,7 @@ module SidekiqPrometheus
|
|
115
124
|
# Requires +Sidekiq::Enterprise+ as it uses the leader election functionality
|
116
125
|
# @return [Boolean] defaults to true if +Sidekiq::Enterprise+ is available
|
117
126
|
def global_metrics_enabled?
|
118
|
-
Object.const_defined?(
|
127
|
+
Object.const_defined?("Sidekiq::Enterprise") && global_metrics_enabled
|
119
128
|
end
|
120
129
|
|
121
130
|
##
|
@@ -149,8 +158,8 @@ module SidekiqPrometheus
|
|
149
158
|
end
|
150
159
|
|
151
160
|
class << self
|
152
|
-
|
153
|
-
|
161
|
+
alias_method :configure!, :configure
|
162
|
+
alias_method :get, :[]
|
154
163
|
end
|
155
164
|
|
156
165
|
##
|
@@ -166,7 +175,7 @@ module SidekiqPrometheus
|
|
166
175
|
def register_custom_metrics
|
167
176
|
return if custom_metrics.empty?
|
168
177
|
|
169
|
-
raise SidekiqPrometheus::Error,
|
178
|
+
raise SidekiqPrometheus::Error, "custom_metrics is not an array." unless custom_metrics.is_a?(Array)
|
170
179
|
|
171
180
|
SidekiqPrometheus::Metrics.register_metrics(custom_metrics)
|
172
181
|
end
|
@@ -178,7 +187,6 @@ module SidekiqPrometheus
|
|
178
187
|
SidekiqPrometheus::Metrics.register_sidekiq_job_metrics
|
179
188
|
SidekiqPrometheus::Metrics.register_sidekiq_gc_metric if gc_metrics_enabled?
|
180
189
|
SidekiqPrometheus::Metrics.register_sidekiq_worker_gc_metrics if gc_metrics_enabled? && periodic_metrics_enabled?
|
181
|
-
SidekiqPrometheus::Metrics.register_sidekiq_global_metrics if global_metrics_enabled? && periodic_metrics_enabled?
|
182
190
|
register_custom_metrics
|
183
191
|
|
184
192
|
sidekiq_setup
|
@@ -195,12 +203,12 @@ module SidekiqPrometheus
|
|
195
203
|
end
|
196
204
|
|
197
205
|
if periodic_metrics_enabled?
|
198
|
-
config.on(:startup)
|
206
|
+
config.on(:startup) { SidekiqPrometheus::PeriodicMetrics.reporter(config).start }
|
199
207
|
config.on(:shutdown) { SidekiqPrometheus::PeriodicMetrics.reporter(config).stop }
|
200
208
|
end
|
201
209
|
|
202
210
|
if metrics_server_enabled?
|
203
|
-
config.on(:startup)
|
211
|
+
config.on(:startup) { SidekiqPrometheus.metrics_server }
|
204
212
|
config.on(:shutdown) { SidekiqPrometheus.metrics_server.kill }
|
205
213
|
end
|
206
214
|
end
|
@@ -213,11 +221,11 @@ module SidekiqPrometheus
|
|
213
221
|
def metrics_server
|
214
222
|
opts = {
|
215
223
|
Port: SidekiqPrometheus.metrics_port,
|
216
|
-
Host: SidekiqPrometheus.metrics_host
|
224
|
+
Host: SidekiqPrometheus.metrics_host
|
217
225
|
}
|
218
226
|
|
219
227
|
unless metrics_server_logger_enabled?
|
220
|
-
opts[:Logger] = WEBrick::Log.new(
|
228
|
+
opts[:Logger] = WEBrick::Log.new("/dev/null")
|
221
229
|
opts[:AccessLog] = []
|
222
230
|
end
|
223
231
|
|
@@ -225,7 +233,7 @@ module SidekiqPrometheus
|
|
225
233
|
Rack::Handler::WEBrick.run(
|
226
234
|
Rack::Builder.new {
|
227
235
|
use Prometheus::Middleware::Exporter, registry: SidekiqPrometheus.registry
|
228
|
-
run ->(_) { [301, {
|
236
|
+
run ->(_) { [301, {"Location" => "/metrics"}, []] }
|
229
237
|
},
|
230
238
|
**opts
|
231
239
|
)
|
@@ -235,7 +243,7 @@ end
|
|
235
243
|
|
236
244
|
class SidekiqPrometheus::Error < StandardError; end
|
237
245
|
|
238
|
-
require
|
239
|
-
require
|
240
|
-
require
|
241
|
-
require
|
246
|
+
require "sidekiq_prometheus/job_metrics"
|
247
|
+
require "sidekiq_prometheus/metrics"
|
248
|
+
require "sidekiq_prometheus/periodic_metrics"
|
249
|
+
require "sidekiq_prometheus/version"
|
data/sidekiq_prometheus.gemspec
CHANGED
@@ -1,34 +1,34 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
lib = File.expand_path(
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
-
require
|
5
|
+
require "sidekiq_prometheus/version"
|
6
6
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
|
-
spec.name
|
9
|
-
spec.version
|
10
|
-
spec.authors
|
11
|
-
spec.email
|
8
|
+
spec.name = "sidekiq_prometheus"
|
9
|
+
spec.version = SidekiqPrometheus::VERSION
|
10
|
+
spec.authors = ["Lukas Eklund", "NHM Tanveer Hossain Khan"]
|
11
|
+
spec.email = ["leklund@fastly.com"]
|
12
12
|
|
13
|
-
spec.summary
|
14
|
-
spec.homepage
|
15
|
-
spec.license
|
13
|
+
spec.summary = "Prometheus Instrumentation for Sidekiq"
|
14
|
+
spec.homepage = "https://github.com/fastly/sidekiq-prometheus"
|
15
|
+
spec.license = "MIT"
|
16
16
|
|
17
17
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
18
|
f.match(%r{^(test|spec|features)/})
|
19
19
|
end
|
20
|
-
spec.bindir
|
21
|
-
spec.executables
|
22
|
-
spec.require_paths = [
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
23
|
|
24
|
-
spec.add_development_dependency
|
25
|
-
spec.add_development_dependency
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
24
|
+
spec.add_development_dependency "bundler"
|
25
|
+
spec.add_development_dependency "pry"
|
26
|
+
spec.add_development_dependency "rake", "~> 12.3.3"
|
27
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
28
|
+
spec.add_development_dependency "standard"
|
29
29
|
|
30
|
-
spec.add_runtime_dependency
|
31
|
-
spec.add_runtime_dependency
|
32
|
-
spec.add_runtime_dependency
|
33
|
-
spec.add_runtime_dependency
|
30
|
+
spec.add_runtime_dependency "prometheus-client", ">= 2.0"
|
31
|
+
spec.add_runtime_dependency "rack"
|
32
|
+
spec.add_runtime_dependency "sidekiq", "> 5.1", "< 7.0"
|
33
|
+
spec.add_runtime_dependency "webrick"
|
34
34
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq_prometheus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lukas Eklund
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2023-08-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -68,19 +68,19 @@ dependencies:
|
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '3.0'
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
|
-
name:
|
71
|
+
name: standard
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
|
-
- - "
|
74
|
+
- - ">="
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version: 0
|
76
|
+
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
|
-
- - "
|
81
|
+
- - ">="
|
82
82
|
- !ruby/object:Gem::Version
|
83
|
-
version: 0
|
83
|
+
version: '0'
|
84
84
|
- !ruby/object:Gem::Dependency
|
85
85
|
name: prometheus-client
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -188,7 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
188
188
|
- !ruby/object:Gem::Version
|
189
189
|
version: '0'
|
190
190
|
requirements: []
|
191
|
-
rubygems_version: 3.
|
191
|
+
rubygems_version: 3.3.7
|
192
192
|
signing_key:
|
193
193
|
specification_version: 4
|
194
194
|
summary: Prometheus Instrumentation for Sidekiq
|