sidekiq-prometheus-exporter 0.2.0 → 0.3.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -3
  3. data/Appraisals +6 -4
  4. data/Gemfile +13 -0
  5. data/README.md +11 -3
  6. data/Rakefile +20 -4
  7. data/lib/sidekiq/prometheus/exporter/standard.rb +73 -21
  8. data/lib/sidekiq/prometheus/exporter/templates/standard.erb +37 -8
  9. data/lib/sidekiq/prometheus/exporter/version.rb +1 -1
  10. data/lib/sidekiq/prometheus/exporter.rb +5 -4
  11. data/sidekiq-prometheus-exporter.gemspec +2 -15
  12. metadata +4 -211
  13. data/.github/FUNDING.yml +0 -12
  14. data/.github/workflows/ci.yaml +0 -70
  15. data/docker/Dockerfile +0 -24
  16. data/docker/README.md +0 -61
  17. data/docker/config.ru +0 -41
  18. data/examples/docker-compose.yml +0 -49
  19. data/examples/metrics/Dockerfile +0 -7
  20. data/examples/metrics/config.ru +0 -10
  21. data/examples/prometheus/prometheus.yml +0 -8
  22. data/examples/screenshot.png +0 -0
  23. data/examples/sidekiq/Dockerfile +0 -5
  24. data/examples/sidekiq/sidekiq.rb +0 -41
  25. data/examples/sidekiq/sidekiq.yml +0 -5
  26. data/examples/sidekiq-dashboard.grafana-6.json +0 -837
  27. data/examples/sidekiq-dashboard.grafana-7.json +0 -845
  28. data/gemfiles/sidekiq_4.1.0.Gemfile +0 -9
  29. data/gemfiles/sidekiq_4.1.0.Gemfile.lock +0 -117
  30. data/gemfiles/sidekiq_4.x.Gemfile +0 -8
  31. data/gemfiles/sidekiq_4.x.Gemfile.lock +0 -105
  32. data/gemfiles/sidekiq_5.x.Gemfile +0 -8
  33. data/gemfiles/sidekiq_5.x.Gemfile.lock +0 -104
  34. data/gemfiles/sidekiq_6.x.Gemfile +0 -8
  35. data/gemfiles/sidekiq_6.x.Gemfile.lock +0 -101
  36. data/gemfiles/sidekiq_7.x.Gemfile +0 -8
  37. data/gemfiles/sidekiq_7.x.Gemfile.lock +0 -109
  38. data/gemfiles/sidekiq_latest.Gemfile +0 -9
  39. data/gemfiles/sidekiq_latest.Gemfile.lock +0 -121
  40. data/helm/sidekiq-prometheus-exporter/.helmignore +0 -22
  41. data/helm/sidekiq-prometheus-exporter/Chart.yaml +0 -6
  42. data/helm/sidekiq-prometheus-exporter/README.md +0 -89
  43. data/helm/sidekiq-prometheus-exporter/templates/NOTES.txt +0 -15
  44. data/helm/sidekiq-prometheus-exporter/templates/_helpers.tpl +0 -109
  45. data/helm/sidekiq-prometheus-exporter/templates/clusterrole.yaml +0 -20
  46. data/helm/sidekiq-prometheus-exporter/templates/clusterrolebinding.yaml +0 -17
  47. data/helm/sidekiq-prometheus-exporter/templates/deployment.yaml +0 -65
  48. data/helm/sidekiq-prometheus-exporter/templates/service.yaml +0 -17
  49. data/helm/sidekiq-prometheus-exporter/templates/serviceaccount.yaml +0 -9
  50. data/helm/sidekiq-prometheus-exporter/templates/servicemonitor.yaml +0 -26
  51. data/helm/sidekiq-prometheus-exporter/values.yaml +0 -139
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 420aff1e44de33405644188fadfe166fe8b8b1f24994ad0035bc2f350e968718
4
- data.tar.gz: ec7e9d8fba8d9f56151a7c759ccc55202f8a5ef7a776cf5ce273aea834cea60e
3
+ metadata.gz: 992a82a14617db8daeecd9c7b100f0a96f1503ada37ad80a509121ce940a6e38
4
+ data.tar.gz: 06c79dfc4a3652acccd1bffdecff30d46987dfc0a728058b6a8d692e70b59904
5
5
  SHA512:
6
- metadata.gz: 6fba09943f7bbb9c886ee10ad36ea9647e26411bbf378676ae99cdfc26b3adb9e41c9bf346dd496c3b087f119851267fa2a25d997b79117fcd9b88b9524ec8f4
7
- data.tar.gz: 8a2dbb2c61076fc58913f6c83eb27be187279d113fc1c1112eb0fbb051dbf1a56b5ce521e267afccda87aa7a9bfbde86d32ab3cd877f4e9bcbdadf761556d7d7
6
+ metadata.gz: 9bf9f6c91f5f5596d27bce500312545ae92366b71b0efff62b57883fabf12aa3b02557357b7cff2faa9fec890756722df842471d425b0219df1920cf3ea37490
7
+ data.tar.gz: e464afd62399b31b5a3970881a8e6ea73a5f0cca4544429689ba699a275b3b5a18e95fdd7093053a85a946c8e555e06603d7ab71f999d72771a93754451ad0d3
data/.rubocop.yml CHANGED
@@ -105,9 +105,6 @@ RSpec/DescribeMethod:
105
105
  RSpec/ExampleWithoutDescription:
106
106
  EnforcedStyle: single_line_only
107
107
 
108
- RSpec/FilePath:
109
- Enabled: false
110
-
111
108
  RSpec/ImplicitExpect:
112
109
  Enabled: false
113
110
 
@@ -131,5 +128,11 @@ RSpec/NestedGroups:
131
128
  RSpec/ScatteredSetup:
132
129
  Enabled: true
133
130
 
131
+ RSpec/SpecFilePathSuffix:
132
+ Enabled: false
133
+
134
+ RSpec/SpecFilePathFormat:
135
+ Enabled: false
136
+
134
137
  Rake/Desc:
135
138
  Enabled: false
data/Appraisals CHANGED
@@ -15,17 +15,19 @@ appraise 'sidekiq-5.x' do
15
15
  end
16
16
 
17
17
  appraise 'sidekiq-6.x' do
18
+ gem 'base64'
18
19
  gem 'redis', '~> 4.1'
19
20
  gem 'sidekiq', '~> 6.0'
20
21
  end
21
22
 
22
23
  appraise 'sidekiq-7.x' do
23
- gem 'redis', '~> 5.0'
24
24
  gem 'sidekiq', '~> 7.0'
25
25
  end
26
26
 
27
+ appraise 'sidekiq-8.x' do
28
+ gem 'sidekiq', '~> 8.0'
29
+ end
30
+
27
31
  appraise 'sidekiq-latest' do
28
- gem 'rack', '>= 2', github: 'rack/rack'
29
- gem 'redis', '>= 4', github: 'redis/redis-rb'
30
- gem 'sidekiq', '>= 6', github: 'mperham/sidekiq'
32
+ gem 'sidekiq', '>= 8', github: 'mperham/sidekiq'
31
33
  end
data/Gemfile CHANGED
@@ -4,3 +4,16 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in sidekiq-prometheus-exporter.gemspec
6
6
  gemspec
7
+
8
+ gem 'appraisal', '~> 2.2'
9
+ gem 'bundler', '~> 2.1'
10
+ gem 'pry', '~> 0.14'
11
+ gem 'pry-byebug', '~> 3.6'
12
+ gem 'rack-test', '>= 1.1'
13
+ gem 'rake', '~> 13.0'
14
+ gem 'rspec', '~> 3.0'
15
+ gem 'rubocop', '~> 1.22'
16
+ gem 'rubocop-performance', '~> 1.12'
17
+ gem 'rubocop-rake', '~> 0.6'
18
+ gem 'rubocop-rspec', '~> 2.6'
19
+ gem 'timecop', '~> 0.9'
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  ![CI status](https://github.com/Strech/sidekiq-prometheus-exporter/workflows/CI/badge.svg)
2
2
  [![Maintainability](https://api.codeclimate.com/v1/badges/bb1b30cd7aca8ecc9413/maintainability)](https://codeclimate.com/github/Strech/sidekiq-prometheus-exporter/maintainability)
3
3
 
4
+ [Sidekiq Enterprise]: https://sidekiq.org/products/enterprise.html
5
+
4
6
  # Sidekiq Prometheus Exporter
5
7
 
6
8
  > — Hey! Sidekiq dashboard stats looks like a Prometheus metrics!?
@@ -31,6 +33,7 @@ _(starting Sidekiq `v4.1.0`)_
31
33
  | sidekiq_workers | gauge | The number of workers across all the processes |
32
34
  | sidekiq_processes | gauge | The number of processes |
33
35
  | sidekiq_host_processes | gauge | The number of processes running on the host (labels: `host`, `quiet`) |
36
+ | sidekiq_host_processes_memory_usage_bytes | gauge | The amount of real memory (resident set) used by the processes running on the host (labels: `host`) |
34
37
  | sidekiq_busy_workers | gauge | The number of workers performing the job |
35
38
  | sidekiq_enqueued_jobs | gauge | The number of enqueued jobs |
36
39
  | sidekiq_scheduled_jobs | gauge | The number of jobs scheduled for a future execution |
@@ -42,6 +45,7 @@ _(starting Sidekiq `v4.1.0`)_
42
45
  | sidekiq_queue_workers | gauge | The number of workers serving the queue (labels: `name`) |
43
46
  | sidekiq_queue_processes | gauge | The number of processes serving the queue (labels: `name`) |
44
47
  | sidekiq_queue_busy_workers | gauge | The number of workers performing the job for the queue (labels: `name`) |
48
+ | sidekiq_leader_lifetime_seconds | gauge | The number of seconds since cluster leader has been created (available only on [Sidekiq Enterprise]) |
45
49
 
46
50
  <details>
47
51
  <summary>Click to expand for all available contribs</summary>
@@ -67,7 +71,7 @@ _(starting Sidekiq `v4.1.0`)_
67
71
  Add this line to your application's Gemfile:
68
72
 
69
73
  ```ruby
70
- gem 'sidekiq-prometheus-exporter', '~> 0.1'
74
+ gem 'sidekiq-prometheus-exporter', '~> 0.3'
71
75
  ```
72
76
 
73
77
  And then execute:
@@ -79,7 +83,7 @@ $ bundle
79
83
  Or install it yourself as:
80
84
 
81
85
  ```console
82
- $ gem install sidekiq-prometheus-exporter -v '~> 0.1'
86
+ $ gem install sidekiq-prometheus-exporter -v '~> 0.3'
83
87
  ```
84
88
 
85
89
  ## Rack application
@@ -100,8 +104,12 @@ run Sidekiq::Prometheus::Exporter.to_app
100
104
 
101
105
  Use your favorite server to start it up, like this
102
106
 
107
+ > [!IMPORTANT]
108
+ > `rackup` in non-production mode contains few unnecessary middlewares we want to
109
+ > disable, like `Rack::Lint`.
110
+
103
111
  ```console
104
- $ bundle exec rackup -p9292 -o0.0.0.0
112
+ $ bundle exec rackup -Eproduction -p9292 -o0.0.0.0
105
113
  ```
106
114
 
107
115
  and then `curl https://0.0.0.0:9292/metrics`
data/Rakefile CHANGED
@@ -1,7 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rspec/core/rake_task'
3
5
 
4
- RSpec::Core::RakeTask.new(:spec)
6
+ RSpec::Core::RakeTask.new(:spec) do |t, args|
7
+ require 'sidekiq/version'
8
+ directory =
9
+ case Gem::Version.new(Sidekiq::VERSION).segments[0]
10
+ when 7 then 'sidekiq-7.x'
11
+ when 8 then 'sidekiq-8.x'
12
+ else 'sidekiq'
13
+ end
14
+
15
+ t.pattern = "spec/#{directory}/**/*_spec.rb"
16
+ t.rspec_opts = args.to_a.join(' ')
17
+ end
5
18
 
6
19
  task default: :spec
7
20
 
@@ -44,7 +57,7 @@ namespace :docker do
44
57
  image = 'strech/sidekiq-prometheus-exporter'
45
58
 
46
59
  Dir.chdir(File.expand_path('./docker')) do
47
- execute("docker build -t #{image}:#{args.version} -t #{image}:latest .")
60
+ execute("docker buildx build --platform linux/amd64,linux/arm64 -t #{image}:#{args.version} -t #{image}:latest .")
48
61
  end
49
62
 
50
63
  puts "Successfully built strech/sidekiq-prometheus-exporter and tagged #{args.version} (latest)"
@@ -54,8 +67,11 @@ namespace :docker do
54
67
  args.with_defaults(version: docker_version)
55
68
  image = 'strech/sidekiq-prometheus-exporter'
56
69
 
57
- execute("docker push #{image}:#{args.version}")
58
- execute("docker push #{image}:latest")
70
+ # rubocop:disable Layout/LineLength
71
+ Dir.chdir(File.expand_path('./docker')) do
72
+ execute("docker buildx build --push --platform linux/amd64,linux/arm64 -t #{image}:#{args.version} -t #{image}:latest .")
73
+ end
74
+ # rubocop:enable Layout/LineLength
59
75
 
60
76
  puts "Successfully pushed strech/sidekiq-prometheus-exporter:#{args.version} (latest)"
61
77
  end
@@ -7,17 +7,31 @@ module Sidekiq
7
7
  module Prometheus
8
8
  module Exporter
9
9
  class Standard
10
- TEMPLATE = ERB.new(File.read(File.expand_path('templates/standard.erb', __dir__)))
10
+ UNKNOWN_IDENTITY = 'unknown-identity'.freeze
11
+ BYTES_IN_KILOBYTE = 1024
12
+ OMIT_NEWLINES_MODE = '<>'.freeze
13
+ TEMPLATE = ERB.new(
14
+ File.read(File.expand_path('templates/standard.erb', __dir__)),
15
+ trim_mode: OMIT_NEWLINES_MODE
16
+ )
11
17
 
12
- QueueStats = Struct.new(:name, :size, :latency)
13
- QueueWorkersStats = Struct.new(:total_workers, :busy_workers, :processes)
14
- WorkersStats = Struct.new(:total_workers, :by_queue, :by_host)
18
+ HostStats = Struct.new(:memory_usage, :by_quiet, keyword_init: true)
19
+ QueueStats = Struct.new(:name, :size, :latency, keyword_init: true)
20
+ QueueWorkersStats = Struct.new(
21
+ :total_workers, :busy_workers, :processes, keyword_init: true
22
+ )
23
+ WorkersStats = Struct.new(
24
+ :total_workers, :by_queue, :by_host, :leader_lifetime, keyword_init: true
25
+ )
15
26
 
16
27
  def self.available?
17
28
  true
18
29
  end
19
30
 
20
31
  def initialize
32
+ # Version dependent metrics
33
+ @show_memory_usage = false
34
+
21
35
  @overview_stats = Sidekiq::Stats.new
22
36
  @queues_stats = queues_stats
23
37
  @workers_stats = workers_stats
@@ -25,46 +39,84 @@ module Sidekiq
25
39
  end
26
40
 
27
41
  def to_s
28
- TEMPLATE.result(binding).chomp!
42
+ TEMPLATE.result(binding)
29
43
  end
30
44
 
31
45
  private
32
46
 
33
47
  def queues_stats
34
48
  Sidekiq::Queue.all.map do |queue|
35
- QueueStats.new(queue.name, queue.size, queue.latency)
49
+ QueueStats.new(name: queue.name, size: queue.size, latency: queue.latency)
36
50
  end
37
51
  end
38
52
 
39
53
  def workers_stats
40
- workers_stats = WorkersStats.new(0, {}, {})
54
+ processes = Sidekiq::ProcessSet.new
55
+ workers_stats = WorkersStats.new(total_workers: 0, by_queue: {}, by_host: {})
41
56
 
42
- Sidekiq::ProcessSet.new.each_with_object(workers_stats) do |process, stats|
43
- stats.total_workers += process['concurrency'].to_i
57
+ # NOTE: available only on enterprise starting v5.0.1
58
+ leader_identity =
59
+ processes.respond_to?(:leader) ? processes.leader : UNKNOWN_IDENTITY
44
60
 
45
- stats.by_host[process['hostname']] ||= Hash.new(0)
46
- stats.by_host[process['hostname']][process['quiet']] += 1
61
+ processes.each_with_object(workers_stats) do |process, stats|
62
+ stats.total_workers += process['concurrency'].to_i
47
63
 
48
- process['queues'].each do |queue|
49
- stats.by_queue[queue] ||= QueueWorkersStats.new(0, 0, 0)
50
- stats.by_queue[queue].processes += 1
51
- stats.by_queue[queue].busy_workers += process['busy'].to_i
52
- stats.by_queue[queue].total_workers += process['concurrency'].to_i
64
+ if process['identity'] == leader_identity
65
+ stats.leader_lifetime = Time.now.utc.to_i - process['started_at']
53
66
  end
67
+
68
+ collect_process_stats_by_host(process, stats.by_host)
69
+ collect_process_stats_by_queue(process, stats.by_queue)
54
70
  end
55
71
  end
56
72
 
73
+ def collect_process_stats_by_host(process, stats)
74
+ stats[process['hostname']] ||= HostStats.new(memory_usage: 0, by_quiet: Hash.new(0))
75
+ stats[process['hostname']].by_quiet[process['quiet']] += 1
76
+ # NOTE: available only starting v6.2.0
77
+ @show_memory_usage ||= true if process['rss']
78
+ stats[process['hostname']].memory_usage += kilobytes_to_bytes(process['rss'].to_i)
79
+ end
80
+
81
+ def collect_process_stats_by_queue(process, stats)
82
+ process['queues'].each do |queue|
83
+ stats[queue] ||= QueueWorkersStats.new(
84
+ total_workers: 0, busy_workers: 0, processes: 0
85
+ )
86
+
87
+ stats[queue].processes += 1
88
+ stats[queue].busy_workers += process['busy'].to_i
89
+ stats[queue].total_workers += process['concurrency'].to_i
90
+ end
91
+ end
92
+
93
+ def kilobytes_to_bytes(kilobytes)
94
+ kilobytes * BYTES_IN_KILOBYTE
95
+ end
96
+
57
97
  def max_processing_times
98
+ return new_max_processing_times if Sidekiq.const_defined?(:Work)
99
+
58
100
  now = Time.now.to_i
59
101
 
60
102
  Sidekiq::Workers.new
61
- .map { |_, _, execution| execution }
62
- .group_by { |execution| execution['queue'] }
63
- .each_with_object({}) do |(queue, executions), memo|
64
- oldest_execution = executions.min_by { |execution| execution['run_at'] }
65
- memo[queue] = now - oldest_execution['run_at']
103
+ .each_with_object({}) { |(_, _, work), memo| (memo[work['queue']] ||= []).push(work) }
104
+ .transform_values! do |works|
105
+ oldest_work = works.min_by { |work| work['run_at'] }
106
+ now - oldest_work['run_at']
66
107
  end
67
108
  end
109
+
110
+ # TODO: Internally Sidekiq::Work stores `run_at` as a timestamp.
111
+ # It would be great to use it instead of invoking `Time.at` call.
112
+ # See: https://github.com/sidekiq/sidekiq/blob/v8.0.0/lib/sidekiq/api.rb#L1253-L1255
113
+ def new_max_processing_times
114
+ now = Time.now
115
+
116
+ Sidekiq::Workers.new
117
+ .each_with_object({}) { |(_, _, work), memo| (memo[work.queue] ||= []).push(work) }
118
+ .transform_values! { |works| now - works.min_by(&:run_at).run_at }
119
+ end
68
120
  end
69
121
  end
70
122
  end
@@ -16,8 +16,20 @@ sidekiq_processes <%= format('%d', @overview_stats.processes_size) %>
16
16
 
17
17
  # HELP sidekiq_host_processes The number of processes running on the host.
18
18
  # TYPE sidekiq_host_processes gauge
19
- <% @workers_stats.by_host.each do |host, stats| %><% stats.each do |quiet, count| %>sidekiq_host_processes{host="<%= host %>",quiet="<%= quiet %>"} <%= format('%i', count) %>
20
- <% end %><% end %>
19
+ <% @workers_stats.by_host.each do |host, stats| %>
20
+ <% stats.by_quiet.each do |quiet, count| %>
21
+ sidekiq_host_processes{host="<%= host %>",quiet="<%= quiet %>"} <%= format('%i', count) %>
22
+ <% end %>
23
+ <% end %>
24
+
25
+ <% if @show_memory_usage %>
26
+ # HELP sidekiq_host_processes_memory_usage_bytes The real memory (resident set) size of the processes running on the host.
27
+ # TYPE sidekiq_host_processes_memory_usage_bytes gauge
28
+ <% @workers_stats.by_host.each do |host, stats| %>
29
+ sidekiq_host_processes_memory_usage_bytes{host="<%= host %>"} <%= format('%i', stats.memory_usage) %>
30
+ <% end %>
31
+
32
+ <% end %>
21
33
  # HELP sidekiq_busy_workers The number of workers performing the job.
22
34
  # TYPE sidekiq_busy_workers gauge
23
35
  sidekiq_busy_workers <%= format('%d', @overview_stats.workers_size) %>
@@ -40,25 +52,42 @@ sidekiq_dead_jobs <%= format('%d', @overview_stats.dead_size) %>
40
52
 
41
53
  # HELP sidekiq_queue_latency_seconds The number of seconds between oldest job being pushed to the queue and current time.
42
54
  # TYPE sidekiq_queue_latency_seconds gauge
43
- <% @queues_stats.each do |queue| %>sidekiq_queue_latency_seconds{name="<%= queue.name %>"} <%= format('%.3f', queue.latency) %>
55
+ <% @queues_stats.each do |queue| %>
56
+ sidekiq_queue_latency_seconds{name="<%= queue.name %>"} <%= format('%.3f', queue.latency) %>
44
57
  <% end %>
58
+
45
59
  # HELP sidekiq_queue_enqueued_jobs The number of enqueued jobs in the queue.
46
60
  # TYPE sidekiq_queue_enqueued_jobs gauge
47
- <% @queues_stats.each do |queue| %>sidekiq_queue_enqueued_jobs{name="<%= queue.name %>"} <%= format('%d', queue.size) %>
61
+ <% @queues_stats.each do |queue| %>
62
+ sidekiq_queue_enqueued_jobs{name="<%= queue.name %>"} <%= format('%d', queue.size) %>
48
63
  <% end %>
64
+
49
65
  # HELP sidekiq_queue_max_processing_time_seconds The number of seconds between oldest job of the queue being executed and current time.
50
66
  # TYPE sidekiq_queue_max_processing_time_seconds gauge
51
- <% @max_processing_times.each do |queue, max_processing_time| %>sidekiq_queue_max_processing_time_seconds{name="<%= queue %>"} <%= format('%i', max_processing_time) %>
67
+ <% @max_processing_times.each do |queue, max_processing_time| %>
68
+ sidekiq_queue_max_processing_time_seconds{name="<%= queue %>"} <%= format('%i', max_processing_time) %>
52
69
  <% end %>
70
+
53
71
  # HELP sidekiq_queue_workers The number of workers serving the queue.
54
72
  # TYPE sidekiq_queue_workers gauge
55
- <% @workers_stats.by_queue.each do |queue, stats| %>sidekiq_queue_workers{name="<%= queue %>"} <%= format('%i', stats.total_workers) %>
73
+ <% @workers_stats.by_queue.each do |queue, stats| %>
74
+ sidekiq_queue_workers{name="<%= queue %>"} <%= format('%i', stats.total_workers) %>
56
75
  <% end %>
76
+
57
77
  # HELP sidekiq_queue_processes The number of processes serving the queue.
58
78
  # TYPE sidekiq_queue_processes gauge
59
- <% @workers_stats.by_queue.each do |queue, stats| %>sidekiq_queue_processes{name="<%= queue %>"} <%= format('%i', stats.processes) %>
79
+ <% @workers_stats.by_queue.each do |queue, stats| %>
80
+ sidekiq_queue_processes{name="<%= queue %>"} <%= format('%i', stats.processes) %>
60
81
  <% end %>
82
+
61
83
  # HELP sidekiq_queue_busy_workers The number of workers performing the job for the queue.
62
84
  # TYPE sidekiq_queue_busy_workers gauge
63
- <% @workers_stats.by_queue.each do |queue, stats| %>sidekiq_queue_busy_workers{name="<%= queue %>"} <%= format('%i', stats.busy_workers) %>
85
+ <% @workers_stats.by_queue.each do |queue, stats| %>
86
+ sidekiq_queue_busy_workers{name="<%= queue %>"} <%= format('%i', stats.busy_workers) %>
87
+ <% end %>
88
+ <% if @workers_stats.leader_lifetime %>
89
+
90
+ # HELP sidekiq_leader_lifetime_seconds The number of seconds since the leader process has started.
91
+ # TYPE sidekiq_leader_lifetime_seconds gauge
92
+ sidekiq_leader_lifetime_seconds <%= format('%d', @workers_stats.leader_lifetime) %>
64
93
  <% end %>
@@ -5,7 +5,7 @@ module Sidekiq
5
5
  module Exporter
6
6
  # NOTE: Every version update dropds Docker patch version to 0
7
7
  # and every adjustment in Docker setup bumps it to +1
8
- VERSION = '0.2.0'.freeze
8
+ VERSION = '0.3.0'.freeze
9
9
  DOCKER_PATCH_VERSION = '0'.freeze
10
10
  end
11
11
  end
@@ -11,9 +11,10 @@ module Sidekiq
11
11
  REQUEST_METHOD = 'REQUEST_METHOD'.freeze
12
12
  NOT_FOUND_TEXT = 'Not Found'.freeze
13
13
  MOUNT_PATH = '/metrics'.freeze
14
- # rubocop:disable Style/MutableConstant
15
- HEADERS = {Rack::CONTENT_TYPE => 'text/plain; version=0.0.4', Rack::CACHE_CONTROL => 'no-cache'}
16
- # rubocop:enable Style/MutableConstant
14
+ HEADERS = {
15
+ Rack::CONTENT_TYPE => 'text/plain; version=0.0.4',
16
+ Rack::CACHE_CONTROL => 'no-cache'
17
+ }.freeze
17
18
  EXPORTERS = Exporters.new
18
19
 
19
20
  class << self
@@ -47,7 +48,7 @@ module Sidekiq
47
48
  def call(env)
48
49
  return [404, HEADERS, [NOT_FOUND_TEXT]] if env[REQUEST_METHOD] != REQUEST_VERB
49
50
 
50
- [200, HEADERS, [EXPORTERS.to_s]]
51
+ [200, HEADERS.dup, [EXPORTERS.to_s]]
51
52
  end
52
53
  end
53
54
  end
@@ -23,26 +23,13 @@ Gem::Specification.new do |spec|
23
23
  end
24
24
 
25
25
  spec.files = `git ls-files -z`.split("\x0").reject do |file|
26
- file.match(%r{^(test|spec|features)/})
26
+ file.match(%r{^(.github|docker|examples|gemfiles|helm|test|spec|features)/})
27
27
  end
28
28
  spec.bindir = 'exe'
29
29
  spec.executables = spec.files.grep(%r{^exe/}) { |file| File.basename(file) }
30
30
  spec.require_paths = %w(lib)
31
31
 
32
- spec.required_ruby_version = '>= 2.3'
32
+ spec.required_ruby_version = '>= 2.5'
33
33
  spec.add_dependency 'rack', '>= 1.6.0'
34
34
  spec.add_dependency 'sidekiq', '>= 4.1.0'
35
-
36
- spec.add_development_dependency 'appraisal', '~> 2.2'
37
- spec.add_development_dependency 'bundler', '~> 2.1'
38
- spec.add_development_dependency 'pry', '~> 0.14'
39
- spec.add_development_dependency 'pry-byebug', '~> 3.6'
40
- spec.add_development_dependency 'rack-test', '~> 1.1'
41
- spec.add_development_dependency 'rake', '~> 13.0'
42
- spec.add_development_dependency 'rspec', '~> 3.0'
43
- spec.add_development_dependency 'rubocop', '~> 1.22'
44
- spec.add_development_dependency 'rubocop-performance', '~> 1.12'
45
- spec.add_development_dependency 'rubocop-rake', '~> 0.6'
46
- spec.add_development_dependency 'rubocop-rspec', '~> 2.6'
47
- spec.add_development_dependency 'timecop', '~> 0.9'
48
35
  end