yabeda-sidekiq 0.9.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f287f1d10d316b33e5d56ea36a9d8dbcc9b1f520b0d3d21d72f11dd5bc40e90f
4
- data.tar.gz: a3809269e4d6011f7dab4ce89391fd2d14fc0775c1dac768a8105f1949a0205b
3
+ metadata.gz: ad8acaec8b59c1c088c6c924d5bbc777b1c87c346b56389045e4609b3920af11
4
+ data.tar.gz: 26e87dbce002e1053eb6f5c709a78642b002691cad1f69e7d1d02722dd692790
5
5
  SHA512:
6
- metadata.gz: 3cb86100524d1b8457caad978f1fcaaf299f27e27c74f787f8b9059b02682f6c4fd04017ad60f9e2b22c46d7d64d18b18cac935fea2586a38f886bd47a31e40c
7
- data.tar.gz: e536ccdca8b3a9e66eb6ebf3e3795e8083aa46295f9587f5d80e23bf3ab7634851719410d28518d843d44a9c68904e7b162258da1f94737892a6f38c5f69b5e3
6
+ metadata.gz: 880a85b150e20c3b78a330d7fa9a2ae578d7fba140adaf9d01e8fdae467c57f746607efa601404b9b9f20d8bbf0fb98b560177ef198095fa48176f79ccc5ce10
7
+ data.tar.gz: 720157c2e892d40ddd776e186055403d79162a8554c36a080003678f1f73d69a9cf924c5ef17bab42235b309506ef620eca80c6311e9af90f83b5c9460585d5a
@@ -15,10 +15,10 @@ jobs:
15
15
  name: RuboCop
16
16
  runs-on: ubuntu-latest
17
17
  steps:
18
- - uses: actions/checkout@v2
18
+ - uses: actions/checkout@v4
19
19
  - uses: ruby/setup-ruby@v1
20
20
  with:
21
- ruby-version: "3.0"
21
+ ruby-version: "3.2"
22
22
  bundler-cache: true
23
23
  - name: Lint Ruby code with RuboCop
24
24
  run: |
@@ -1,4 +1,4 @@
1
- name: Build and release gem to RubyGems
1
+ name: Build and release gem
2
2
 
3
3
  on:
4
4
  push:
@@ -8,13 +8,17 @@ on:
8
8
  jobs:
9
9
  release:
10
10
  runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: write
13
+ id-token: write
14
+ packages: write
11
15
  steps:
12
- - uses: actions/checkout@v2
16
+ - uses: actions/checkout@v4
13
17
  with:
14
18
  fetch-depth: 0 # Fetch current tag as annotated. See https://github.com/actions/checkout/issues/290
15
19
  - uses: ruby/setup-ruby@v1
16
20
  with:
17
- ruby-version: 2.7
21
+ ruby-version: "3.3"
18
22
  - name: "Extract data from tag: version, message, body"
19
23
  id: tag
20
24
  run: |
@@ -75,8 +79,8 @@ jobs:
75
79
  GEM_HOST_API_KEY: Bearer ${{ secrets.GITHUB_TOKEN }}
76
80
  run: |
77
81
  gem push yabeda-sidekiq-${{ steps.tag.outputs.version }}.gem --host https://rubygems.pkg.github.com/${{ github.repository_owner }}
82
+ - name: Configure RubyGems Credentials
83
+ uses: rubygems/configure-rubygems-credentials@main
78
84
  - name: Publish to RubyGems
79
- env:
80
- GEM_HOST_API_KEY: "${{ secrets.RUBYGEMS_API_KEY }}"
81
85
  run: |
82
86
  gem push yabeda-sidekiq-${{ steps.tag.outputs.version }}.gem
@@ -10,7 +10,7 @@ on:
10
10
 
11
11
  jobs:
12
12
  test:
13
- name: 'Ruby ${{ matrix.ruby }}'
13
+ name: 'Ruby ${{ matrix.ruby }} × Sidekiq v${{ matrix.sidekiq }} × ActiveJob v${{ matrix.activejob }}'
14
14
  # Skip running tests for local pull requests (use push event instead), run only for foreign ones
15
15
  if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.owner.login != github.event.pull_request.base.repo.owner.login
16
16
  runs-on: ubuntu-latest
@@ -18,30 +18,26 @@ jobs:
18
18
  fail-fast: false
19
19
  matrix:
20
20
  include:
21
+ - ruby: '3.3'
22
+ sidekiq: '7'
23
+ activejob: '7.1'
24
+ - ruby: '3.2'
25
+ sidekiq: '7'
26
+ activejob: '7.0'
21
27
  - ruby: '3.1'
28
+ sidekiq: '6'
29
+ activejob: '6.1'
22
30
  - ruby: '3.0'
23
- - ruby: '2.7'
24
- - ruby: '2.6'
25
- - ruby: '2.5'
26
- container:
27
- image: ruby:${{ matrix.ruby }}
28
- env:
29
- CI: true
31
+ sidekiq: '5'
32
+ activejob: '6.0'
33
+ env:
34
+ SIDEKIQ_VERSION: '${{ matrix.sidekiq }}'
35
+ ACTIVEJOB_VERSION: '${{ matrix.activejob }}'
30
36
  steps:
31
- - uses: actions/checkout@v2
32
- - uses: actions/cache@v2
37
+ - uses: actions/checkout@v4
38
+ - uses: ruby/setup-ruby@v1
33
39
  with:
34
- path: vendor/bundle
35
- key: bundle-${{ matrix.ruby }}-${{ hashFiles('**/*.gemspec') }}-${{ hashFiles('**/Gemfile') }}
36
- restore-keys: |
37
- bundle-${{ matrix.ruby }}-${{ hashFiles('**/*.gemspec') }}-${{ hashFiles('**/Gemfile') }}
38
- bundle-${{ matrix.ruby }}-
39
- - name: Upgrade Bundler to 2.0 (for older Rubies)
40
- run: gem install bundler -v '~> 2.0'
41
- - name: Bundle install
42
- run: |
43
- bundle config path vendor/bundle
44
- bundle install
45
- bundle update
40
+ ruby-version: ${{ matrix.ruby }}
41
+ bundler-cache: true
46
42
  - name: Run RSpec
47
43
  run: bundle exec rspec
data/.rubocop.yml CHANGED
@@ -3,7 +3,7 @@ require:
3
3
  - rubocop-rspec
4
4
 
5
5
  AllCops:
6
- TargetRubyVersion: 2.3
6
+ TargetRubyVersion: 2.5
7
7
 
8
8
  Metrics/BlockLength:
9
9
  Enabled: false
@@ -65,3 +65,15 @@ Metrics/MethodLength:
65
65
 
66
66
  Metrics/AbcSize:
67
67
  Max: 17
68
+
69
+ Style/SoleNestedConditional:
70
+ Enabled: false
71
+
72
+ Style/ExplicitBlockArgument:
73
+ Enabled: false
74
+
75
+ Gemspec/RequiredRubyVersion:
76
+ Enabled: false
77
+
78
+ Metrics/ModuleLength:
79
+ Max: 200
data/CHANGELOG.md CHANGED
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
7
7
 
8
8
  ## Unreleased
9
9
 
10
+ ## 0.11.0 - 2024-02-07
11
+
12
+ ### Added
13
+
14
+ - `retries_segmented_by_queue` configuration setting to allow segmentation of retry count by queue.
15
+
16
+ It is disabled by default as it requires to iterate over all jobs in the retry set and may be very slow if number of retries is huge.
17
+
18
+ Pull request [#32](https://github.com/yabeda-rb/yabeda-sidekiq/pull/32) by [@SxDx]
19
+
20
+ ## 0.10.0 - 2022-10-25
21
+
22
+ ### Added
23
+
24
+ - New metric `sidekiq_jobs_rerouted_total_count` to measure jobs that on enqueue were pushed to different queue from the one specified in worker's `sidekiq_options`. See [#30](https://github.com/yabeda-rb/yabeda-sidekiq/pull/30). [@LukinEgor]
25
+
26
+ ### Fixed
27
+
28
+ - In `sidekiq_jobs_enqueued_total_count` track real queue that job was pushed into, not the one specified in `sidekiq_options` (sometimes they may be different). See [#30](https://github.com/yabeda-rb/yabeda-sidekiq/pull/30). [@LukinEgor]
29
+
10
30
  ## 0.9.0 - 2022-09-26
11
31
 
12
32
  ### Added
@@ -108,3 +128,5 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
108
128
  [@dsalahutdinov]: https://github.com/dsalahutdinov "Salahutdinov Dmitry"
109
129
  [@asusikov]: https://github.com/asusikov "Alexander Susikov"
110
130
  [@mrexox]: https://github.com/mrexox "Valentine Kiselev"
131
+ [@LukinEgor]: https://github.com/LukinEgor "Egor Lukin"
132
+ [@SxDx]: https://github.com/SxDx "René Koller"
data/Gemfile CHANGED
@@ -7,10 +7,36 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
7
7
  # Specify your gem's dependencies in yabeda-sidekiq.gemspec
8
8
  gemspec
9
9
 
10
+ # rubocop:disable Bundler/DuplicatedGem
11
+ sidekiq_version = ENV.fetch("SIDEKIQ_VERSION", "~> 7.2")
12
+ case sidekiq_version
13
+ when "HEAD"
14
+ gem "sidekiq", git: "https://github.com/sidekiq/sidekiq.git"
15
+ else
16
+ sidekiq_version = "~> #{sidekiq_version}.0" if sidekiq_version.match?(/^\d+(?:\.\d+)?$/)
17
+ gem "sidekiq", sidekiq_version
18
+ end
19
+
20
+ activejob_version = ENV.fetch("ACTIVEJOB_VERSION", "~> 7.1")
21
+ case activejob_version
22
+ when "HEAD"
23
+ git "https://github.com/rails/rails.git" do
24
+ gem "activejob"
25
+ gem "activesupport"
26
+ gem "rails"
27
+ end
28
+ else
29
+ activejob_version = "~> #{activejob_version}.0" if activejob_version.match?(/^\d+\.\d+$/)
30
+ gem "activejob", activejob_version
31
+ gem "activesupport", activejob_version
32
+ end
33
+ # rubocop:enable Bundler/DuplicatedGem
34
+
10
35
  group :development, :test do
11
36
  gem "pry"
12
37
  gem "pry-byebug", platform: :mri
13
38
 
14
- gem "rubocop", "~> 0.80.0"
39
+ gem "yabeda", github: "yabeda-rb/yabeda", branch: "master" # For RSpec matchers
40
+ gem "rubocop", "~> 1.0"
15
41
  gem "rubocop-rspec"
16
42
  end
data/README.md CHANGED
@@ -62,6 +62,16 @@ Metrics representing state of the whole Sidekiq installation (queues, processes,
62
62
 
63
63
  By default all sidekiq worker processes (servers) collects global metrics about whole Sidekiq installation. This can be overridden by setting `collect_cluster_metrics` config key to `true` for non-Sidekiq processes or to `false` for Sidekiq processes (e.g. by setting `YABEDA_SIDEKIQ_COLLECT_CLUSTER_METRICS` env variable to `no`, see other methods in [anyway_config] docs).
64
64
 
65
+ ### Client metrics
66
+
67
+ Metrics collected where jobs are being pushed to queues (everywhere):
68
+
69
+ - Total number of enqueued jobs: `sidekiq_jobs_enqueued_total_count` (segmented by `queue` and `worker` class name)
70
+
71
+ - Total number of rerouted jobs: `sidekiq_jobs_rerouted_total_count` (segmented by origin queue `from_queue`, rerouted queue `to_queue`, and `worker` class name).
72
+
73
+ Rerouted jobs are jobs that on enqueue were pushed to different queue from the one specified in worker's `sidekiq_options`, most probably by some middleware.
74
+
65
75
  ## Custom tags
66
76
 
67
77
  You can add additional tags to these metrics by declaring `yabeda_tags` method in your worker.
@@ -89,13 +99,15 @@ end
89
99
 
90
100
  Configuration is handled by [anyway_config] gem. With it you can load settings from environment variables (upcased and prefixed with `YABEDA_SIDEKIQ_`), YAML files, and other sources. See [anyway_config] docs for details.
91
101
 
92
- Config key | Type | Default | Description |
93
- ------------------------- | -------- | ------------------------------------------------------- | ----------- |
94
- `collect_cluster_metrics` | boolean | Enabled in Sidekiq worker processes, disabled otherwise | Defines whether this Ruby process should collect and expose metrics representing state of the whole Sidekiq installation (queues, processes, etc). |
102
+ Config key | Type | Default | Description |
103
+ ---------------------------- | -------- | ------------------------------------------------------- |----------------------------------------------------------------------------------------------------------------------------------------------------|
104
+ `collect_cluster_metrics` | boolean | Enabled in Sidekiq worker processes, disabled otherwise | Defines whether this Ruby process should collect and expose metrics representing state of the whole Sidekiq installation (queues, processes, etc). |
105
+ `declare_process_metrics` | boolean | Enabled in Sidekiq worker processes, disabled otherwise | Declare metrics that are only tracked inside worker process even outside of them. Useful for multiprocess metric collection. |
106
+ `retries_segmented_by_queue` | boolean | Disabled | Defines wheter retries are segemented by queue or reported as a single metric |
95
107
 
96
108
  # Roadmap (TODO or Help wanted)
97
109
 
98
- - Implement optional segmentation of retry/schedule/dead sets
110
+ - Implement optional segmentation of schedule/dead sets
99
111
 
100
112
  It should be disabled by default as it requires to iterate over all jobs in sets and may be very slow on large sets.
101
113
 
@@ -5,8 +5,14 @@ module Yabeda
5
5
  # Client middleware to count number of enqueued jobs
6
6
  class ClientMiddleware
7
7
  def call(worker, job, queue, _redis_pool)
8
- labels = Yabeda::Sidekiq.labelize(worker, job, queue)
8
+ labels = Yabeda::Sidekiq.labelize(worker, job, job["queue"] || queue)
9
9
  Yabeda.sidekiq_jobs_enqueued_total.increment(labels)
10
+
11
+ if job["queue"] && job["queue"] != queue
12
+ labels = Yabeda::Sidekiq.labelize(worker, job, queue)
13
+ Yabeda.sidekiq_jobs_rerouted_total.increment({ from_queue: queue, to_queue: job["queue"], **labels.except(:queue) })
14
+ end
15
+
10
16
  yield
11
17
  end
12
18
  end
@@ -16,6 +16,10 @@ module Yabeda
16
16
 
17
17
  # Declare metrics that are only tracked inside worker process even outside them
18
18
  attr_config declare_process_metrics: ::Sidekiq.server?
19
+
20
+ # Retries are tracked by default as a single metric. If you want to track them separately for each queue, set this to +true+
21
+ # Disabled by default because it is quite slow if the retry set is large
22
+ attr_config retries_segmented_by_queue: false
19
23
  end
20
24
  end
21
25
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Yabeda
4
4
  module Sidekiq
5
- VERSION = "0.9.0"
5
+ VERSION = "0.11.0"
6
6
  end
7
7
  end
@@ -26,6 +26,7 @@ module Yabeda
26
26
  group :sidekiq
27
27
 
28
28
  counter :jobs_enqueued_total, tags: %i[queue worker], comment: "A counter of the total number of jobs sidekiq enqueued."
29
+ counter :jobs_rerouted_total, tags: %i[from_queue to_queue worker], comment: "A counter of the total number of rerouted jobs sidekiq enqueued."
29
30
 
30
31
  if config.declare_process_metrics # defaults to +::Sidekiq.server?+
31
32
  counter :jobs_executed_total, tags: %i[queue worker], comment: "A counter of the total number of jobs sidekiq executed."
@@ -48,13 +49,17 @@ module Yabeda
48
49
  # Metrics not specific for current Sidekiq process, but representing state of the whole Sidekiq installation (queues, processes, etc)
49
50
  # You can opt-out from collecting these by setting YABEDA_SIDEKIQ_COLLECT_CLUSTER_METRICS to falsy value (+no+ or +false+)
50
51
  if config.collect_cluster_metrics # defaults to +::Sidekiq.server?+
51
- gauge :jobs_waiting_count, tags: %i[queue], aggregation: :most_recent, comment: "The number of jobs waiting to process in sidekiq."
52
- gauge :active_workers_count, tags: [], aggregation: :most_recent, comment: "The number of currently running machines with sidekiq workers."
53
- gauge :jobs_scheduled_count, tags: [], aggregation: :most_recent, comment: "The number of jobs scheduled for later execution."
54
- gauge :jobs_retry_count, tags: [], aggregation: :most_recent, comment: "The number of failed jobs waiting to be retried"
55
- gauge :jobs_dead_count, tags: [], aggregation: :most_recent, comment: "The number of jobs exceeded their retry count."
56
- gauge :active_processes, tags: [], aggregation: :most_recent, comment: "The number of active Sidekiq worker processes."
57
- gauge :queue_latency, tags: %i[queue], aggregation: :most_recent, comment: "The queue latency, the difference in seconds since the oldest job in the queue was enqueued"
52
+ retry_count_tags = config.retries_segmented_by_queue ? %i[queue] : []
53
+
54
+ gauge :jobs_waiting_count, tags: %i[queue], aggregation: :most_recent, comment: "The number of jobs waiting to process in sidekiq."
55
+ gauge :active_workers_count, tags: [], aggregation: :most_recent,
56
+ comment: "The number of currently running machines with sidekiq workers."
57
+ gauge :jobs_scheduled_count, tags: [], aggregation: :most_recent, comment: "The number of jobs scheduled for later execution."
58
+ gauge :jobs_retry_count, tags: retry_count_tags, aggregation: :most_recent, comment: "The number of failed jobs waiting to be retried"
59
+ gauge :jobs_dead_count, tags: [], aggregation: :most_recent, comment: "The number of jobs exceeded their retry count."
60
+ gauge :active_processes, tags: [], aggregation: :most_recent, comment: "The number of active Sidekiq worker processes."
61
+ gauge :queue_latency, tags: %i[queue], aggregation: :most_recent,
62
+ comment: "The queue latency, the difference in seconds since the oldest job in the queue was enqueued"
58
63
  end
59
64
 
60
65
  collect do
@@ -71,21 +76,22 @@ module Yabeda
71
76
  sidekiq_jobs_scheduled_count.set({}, stats.scheduled_size)
72
77
  sidekiq_jobs_dead_count.set({}, stats.dead_size)
73
78
  sidekiq_active_processes.set({}, stats.processes_size)
74
- sidekiq_jobs_retry_count.set({}, stats.retry_size)
75
79
 
76
80
  ::Sidekiq::Queue.all.each do |queue|
77
81
  sidekiq_queue_latency.set({ queue: queue.name }, queue.latency)
78
82
  end
79
83
 
80
- # That is quite slow if your retry set is large
81
- # I don't want to enable it by default
82
- # retries_by_queues =
83
- # ::Sidekiq::RetrySet.new.each_with_object(Hash.new(0)) do |job, cntr|
84
- # cntr[job["queue"]] += 1
85
- # end
86
- # retries_by_queues.each do |queue, count|
87
- # sidekiq_jobs_retry_count.set({ queue: queue }, count)
88
- # end
84
+ if config.retries_segmented_by_queue
85
+ retries_by_queues =
86
+ ::Sidekiq::RetrySet.new.each_with_object(Hash.new(0)) do |job, cntr|
87
+ cntr[job["queue"]] += 1
88
+ end
89
+ retries_by_queues.each do |queue, count|
90
+ sidekiq_jobs_retry_count.set({ queue: queue }, count)
91
+ end
92
+ else
93
+ sidekiq_jobs_retry_count.set({}, stats.retry_size)
94
+ end
89
95
  end
90
96
  end
91
97
 
@@ -110,11 +116,7 @@ module Yabeda
110
116
  end
111
117
 
112
118
  def worker_class(worker, job)
113
- if defined?(ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper)
114
- if worker.is_a?(ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper) || worker == ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper
115
- return job["wrapped"].to_s
116
- end
117
- end
119
+ worker = job["wrapped"] || worker
118
120
  (worker.is_a?(String) || worker.is_a?(Class) ? worker : worker.class).to_s
119
121
  end
120
122
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yabeda-sidekiq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Novikov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-09-26 00:00:00.000000000 Z
11
+ date: 2024-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: anyway_config
@@ -122,8 +122,8 @@ executables: []
122
122
  extensions: []
123
123
  extra_rdoc_files: []
124
124
  files:
125
- - ".github/workflows/build-release.yml"
126
125
  - ".github/workflows/lint.yml"
126
+ - ".github/workflows/release.yml"
127
127
  - ".github/workflows/test.yml"
128
128
  - ".gitignore"
129
129
  - ".rspec"
@@ -161,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
161
161
  - !ruby/object:Gem::Version
162
162
  version: '0'
163
163
  requirements: []
164
- rubygems_version: 3.1.6
164
+ rubygems_version: 3.5.3
165
165
  signing_key:
166
166
  specification_version: 4
167
167
  summary: Extensible Prometheus exporter for monitoring your Sidekiq