yabeda-sidekiq 0.1.3 → 0.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 72f1df666e70373b15a7fc54732f14e6701a3fbfdd2a19e5a3703e542c6a13d4
4
- data.tar.gz: c38ed88429527e43edff2d445c8940d8bf52babd272fa5b1b7bbb37865b6ecff
3
+ metadata.gz: 660902666ec22bdc3a244a45bd15ac3a67b8dc2d13cd703c779453e689002b93
4
+ data.tar.gz: 5b45a914f585959fceceda65d95a72bf6415f9e6a3bb889f54243ac8f887adec
5
5
  SHA512:
6
- metadata.gz: 1d31f1bf0323344baf0e1a2707bd89661c09f14f664dabd8fa9fff347e308538608c9922d91d4f684b2a34d89ca95218dab7f29bfc0b359bd77057e34205a87a
7
- data.tar.gz: 3764a37a9aa8b9ccd715ca049e55af864324fe5927e2496825b1d0f222b63b452dbaa9f8b9e50ce4e29a9b044e5747cc711b4de4f27813a7b4e9796f6419e01a
6
+ metadata.gz: 22be4dea939719b79f230d80ddcf38269cc476d3cf51c6664938b5bab6e93e2e924dbebcdcbcbd9dde59e0822f28c33a58b83be483015dad9ed32000cb9fceeb
7
+ data.tar.gz: 3d3c314d83b3943fcbd5d110f44826abbad4beb50c61120f5f26d33c398cc02bf970c36a6272143f3ae27dd9adfc73f42e69f898460461f952519bb8de9a768f
@@ -1,17 +1,18 @@
1
1
  ---
2
2
  require:
3
- - rubocop-rspec
3
+ - rubocop-rspec
4
4
 
5
5
  AllCops:
6
6
  TargetRubyVersion: 2.3
7
7
 
8
8
  Metrics/BlockLength:
9
+ Enabled: false
9
10
  Exclude:
10
11
  - "Gemfile"
11
12
  - "spec/**/*"
12
13
 
13
- Style/BracesAroundHashParameters:
14
- EnforcedStyle: context_dependent
14
+ Layout/LineLength:
15
+ Max: 160
15
16
 
16
17
  Style/StringLiterals:
17
18
  EnforcedStyle: double_quotes
@@ -44,3 +45,23 @@ Style/TrailingCommaInHashLiteral:
44
45
  Enabled: true
45
46
  EnforcedStyleForMultiline: consistent_comma
46
47
 
48
+ Style/HashEachMethods:
49
+ Enabled: true
50
+
51
+ Style/HashTransformKeys:
52
+ Enabled: true
53
+
54
+ Style/HashTransformValues:
55
+ Enabled: true
56
+
57
+ RSpec/ExampleLength:
58
+ Enabled: false
59
+
60
+ Style/Documentation:
61
+ Enabled: false
62
+
63
+ Metrics/MethodLength:
64
+ Max: 15
65
+
66
+ Metrics/AbcSize:
67
+ Max: 17
@@ -1,5 +1,7 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.5.1
5
- before_install: gem install bundler -v 1.16.1
4
+ - 2.7.1
5
+ - 2.6.6
6
+ - 2.5.8
7
+ before_install: gem install bundler -v '~> 2.0'
@@ -0,0 +1,65 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
6
+ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
7
+
8
+ ## 0.7.0 - 2020-07-15
9
+
10
+ ### Changed
11
+
12
+ - Tags from `yabeda_tags` method are applied to all metrics collected inside a job, not only sidekiq-specific. See [#14](https://github.com/yabeda-rb/yabeda-sidekiq/issues/14). @Envek
13
+
14
+ ## 0.6.0 - 2020-07-15
15
+
16
+ ### Added
17
+
18
+ - Ability to override or add tags for every job via `yabeda_tags` method. @Envek
19
+
20
+ ## 0.5.0 - 2020-02-20
21
+
22
+ ### Added
23
+
24
+ - New `sidekiq_job_latency` histogram to track latency statistics of different job classes. [#9](https://github.com/yabeda-rb/yabeda-sidekiq/pull/9) by [@asusikov]
25
+
26
+ ### Changed
27
+
28
+ - **BREAKING CHANGE!** Renamed `sidekiq_jobs_latency` gauge to `sidekiq_queue_latency` to better describe its purpose and differentiate with the new histogram. [#9](https://github.com/yabeda-rb/yabeda-sidekiq/pull/9) by [@asusikov]
29
+
30
+ ## 0.2.0 - 2020-01-14
31
+
32
+ ### Changed
33
+
34
+ - Added `tags` option to metric declarations for compatibility with yabeda and yabeda-prometheus 0.2. @Envek
35
+
36
+ ## 0.1.4 - 2019-10-07
37
+
38
+ ### Added
39
+
40
+ - Require of core yabeda gem [#4](https://github.com/yabeda-rb/yabeda-sidekiq/pull/4). [@dsalahutdinov]
41
+
42
+ ## 0.1.3 - 2018-10-25
43
+
44
+ ### Fixed
45
+
46
+ - Require of core yabeda gem [#1](https://github.com/yabeda-rb/yabeda-sidekiq/issues/1). @Envek
47
+
48
+ ## 0.1.2 - 2018-10-17
49
+
50
+ ### Changed
51
+
52
+ - Renamed evil-metrics-sidekiq gem to yabeda-sidekiq. @Envek
53
+
54
+ ## 0.1.1 - 2018-10-05
55
+
56
+ ### Changed
57
+
58
+ - Automatic add client and server middlewares to Sidekiq. @Envek
59
+
60
+ ## 0.1.0 - 2018-10-03
61
+
62
+ - Initial release of evil-metrics-sidekiq gem. @Envek
63
+
64
+ [@dsalahutdinov]: https://github.com/dsalahutdinov "Salahutdinov Dmitry"
65
+ [@asusikov]: https://github.com/asusikov "Alexander Susikov"
data/Gemfile CHANGED
@@ -11,6 +11,6 @@ group :development, :test do
11
11
  gem "pry"
12
12
  gem "pry-byebug", platform: :mri
13
13
 
14
- gem "rubocop"
14
+ gem "rubocop", "~> 0.80.0"
15
15
  gem "rubocop-rspec"
16
16
  end
data/README.md CHANGED
@@ -2,10 +2,12 @@
2
2
 
3
3
  Built-in metrics for [Sidekiq] monitoring out of the box! Part of the [yabeda] suite.
4
4
 
5
+ Sample Grafana dashboard ID: [11667](https://grafana.com/grafana/dashboards/11667)
6
+
5
7
  ## Installation
6
8
 
7
9
  ```ruby
8
- gem 'yabeda-rails'
10
+ gem 'yabeda-sidekiq'
9
11
  # Then add monitoring system adapter, e.g.:
10
12
  # gem 'yabeda-prometheus'
11
13
  ```
@@ -14,6 +16,14 @@ And then execute:
14
16
 
15
17
  $ bundle
16
18
 
19
+ If you're not on Rails then configure Yabeda after your application was initialized:
20
+
21
+ ```ruby
22
+ Yabeda.configure!
23
+ ```
24
+
25
+ _If you're using Ruby on Rails then Yabeda will configure itself automatically!_
26
+
17
27
  **And that is it!** Sidekiq metrics are being collected!
18
28
 
19
29
  Additionally, depending on your adapter, you may want to setup metrics export. E.g. for [yabeda-prometheus]:
@@ -31,6 +41,8 @@ end
31
41
  - Number of jobs have been finished successfully: `sidekiq_jobs_success_total` (segmented by queue and class name)
32
42
  - Number of jobs have been failed: `sidekiq_jobs_failed_total` (segmented by queue and class name)
33
43
  - Time of job run: `sidekiq_job_runtime` (seconds per job execution, segmented by queue and class name)
44
+ - Time of the queue latency `sidekiq_queue_latency` (the difference in seconds since the oldest job in the queue was enqueued)
45
+ - Time of the job latency `sidekiq_job_latency` (the difference in seconds since the enqueuing until running job)
34
46
  - Number of jobs in queues: `sidekiq_jobs_waiting_count` (segmented by queue)
35
47
  - Number of scheduled jobs:`sidekiq_jobs_scheduled_count`
36
48
  - Number of jobs in retry set: `sidekiq_jobs_retry_count`
@@ -38,6 +50,29 @@ end
38
50
  - Active workers count: `sidekiq_active_processes`
39
51
  - Active processes count: `sidekiq_active_workers_count`
40
52
 
53
+ ## Custom tags
54
+
55
+ You can add additional tags to these metrics by declaring `yabeda_tags` method in your worker.
56
+
57
+ ```ruby
58
+ # This block is optional but some adapters (like Prometheus) requires that all tags should be declared in advance
59
+ Yabeda.configure do
60
+ default_tag :importance, nil
61
+ end
62
+
63
+ class MyWorker
64
+ include Sidekiq::Worker
65
+
66
+ def yabeda_tags(*params) # This method will be called first, before +perform+
67
+ { importance: extract_importance(params) }
68
+ end
69
+
70
+ def perform(*params)
71
+ # Your logic here
72
+ end
73
+ end
74
+ ```
75
+
41
76
  # Roadmap (TODO or Help wanted)
42
77
 
43
78
  - Implement optional segmentation of retry/schedule/dead sets
data/Rakefile CHANGED
@@ -2,7 +2,10 @@
2
2
 
3
3
  require "bundler/gem_tasks"
4
4
  require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
6
+
7
+ RuboCop::RakeTask.new
5
8
 
6
9
  RSpec::Core::RakeTask.new(:spec)
7
10
 
8
- task default: :spec
11
+ task default: %i[rubocop spec]
@@ -12,26 +12,35 @@ module Yabeda
12
12
  module Sidekiq
13
13
  LONG_RUNNING_JOB_RUNTIME_BUCKETS = [
14
14
  0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, # standard (from Prometheus)
15
- 30, 60, 120, 300, 1800, 3600, 21_600 # Sidekiq tasks may be very long-running
15
+ 30, 60, 120, 300, 1800, 3600, 21_600, # Sidekiq tasks may be very long-running
16
16
  ].freeze
17
17
 
18
18
  Yabeda.configure do
19
19
  group :sidekiq
20
20
 
21
- counter :jobs_enqueued_total, comment: "A counter of the total number of jobs sidekiq enqueued."
21
+ counter :jobs_enqueued_total, tags: %i[queue worker], comment: "A counter of the total number of jobs sidekiq enqueued."
22
22
 
23
23
  next unless ::Sidekiq.server?
24
24
 
25
- counter :jobs_executed_total, comment: "A counter of the total number of jobs sidekiq executed."
26
- counter :jobs_success_total, comment: "A counter of the total number of jobs successfully processed by sidekiq."
27
- counter :jobs_failed_total, comment: "A counter of the total number of jobs failed in sidekiq."
28
- gauge :jobs_waiting_count, comment: "The number of jobs waiting to process in sidekiq."
29
- gauge :active_workers_count, comment: "The number of currently running machines with sidekiq workers."
30
- gauge :jobs_scheduled_count, comment: "The number of jobs scheduled for later execution."
31
- gauge :jobs_retry_count, comment: "The number of failed jobs waiting to be retried"
32
- gauge :jobs_dead_count, comment: "The number of jobs exceeded their retry count."
33
- gauge :active_processes, comment: "The number of active Sidekiq worker processes."
34
- histogram :job_runtime, unit: :seconds, per: :job, comment: "A histogram of the job execution time.",
25
+ counter :jobs_executed_total, tags: %i[queue worker], comment: "A counter of the total number of jobs sidekiq executed."
26
+ counter :jobs_success_total, tags: %i[queue worker], comment: "A counter of the total number of jobs successfully processed by sidekiq."
27
+ counter :jobs_failed_total, tags: %i[queue worker], comment: "A counter of the total number of jobs failed in sidekiq."
28
+
29
+ gauge :jobs_waiting_count, tags: %i[queue], comment: "The number of jobs waiting to process in sidekiq."
30
+ gauge :active_workers_count, tags: [], comment: "The number of currently running machines with sidekiq workers."
31
+ gauge :jobs_scheduled_count, tags: [], comment: "The number of jobs scheduled for later execution."
32
+ gauge :jobs_retry_count, tags: [], comment: "The number of failed jobs waiting to be retried"
33
+ gauge :jobs_dead_count, tags: [], comment: "The number of jobs exceeded their retry count."
34
+ gauge :active_processes, tags: [], comment: "The number of active Sidekiq worker processes."
35
+ gauge :queue_latency, tags: %i[queue], comment: "The queue latency, the difference in seconds since the oldest job in the queue was enqueued"
36
+
37
+ histogram :job_latency, comment: "The job latency, the difference in seconds between enqueued and running time",
38
+ unit: :seconds, per: :job,
39
+ tags: %i[queue worker],
40
+ buckets: LONG_RUNNING_JOB_RUNTIME_BUCKETS
41
+ histogram :job_runtime, comment: "A histogram of the job execution time.",
42
+ unit: :seconds, per: :job,
43
+ tags: %i[queue worker],
35
44
  buckets: LONG_RUNNING_JOB_RUNTIME_BUCKETS
36
45
 
37
46
  collect do
@@ -46,6 +55,10 @@ module Yabeda
46
55
  sidekiq_active_processes.set({}, stats.processes_size)
47
56
  sidekiq_jobs_retry_count.set({}, stats.retry_size)
48
57
 
58
+ ::Sidekiq::Queue.all.each do |queue|
59
+ sidekiq_queue_latency.set({ queue: queue.name }, queue.latency)
60
+ end
61
+
49
62
  # That is quite slow if your retry set is large
50
63
  # I don't want to enable it by default
51
64
  # retries_by_queues =
@@ -80,9 +93,17 @@ module Yabeda
80
93
 
81
94
  def worker_class(worker, job)
82
95
  if defined?(ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper)
83
- return job["wrapped"] if worker.is_a?(ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper)
96
+ if worker.is_a?(ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper) || worker == ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper
97
+ return job["wrapped"].to_s
98
+ end
84
99
  end
85
- (worker.is_a?(String) ? worker : worker.class).to_s
100
+ (worker.is_a?(String) || worker.is_a?(Class) ? worker : worker.class).to_s
101
+ end
102
+
103
+ def custom_tags(worker, job)
104
+ return {} unless worker.respond_to?(:yabeda_tags)
105
+
106
+ worker.method(:yabeda_tags).arity.zero? ? worker.yabeda_tags : worker.yabeda_tags(*job["args"])
86
107
  end
87
108
  end
88
109
  end
@@ -4,11 +4,17 @@ module Yabeda
4
4
  module Sidekiq
5
5
  # Sidekiq worker middleware
6
6
  class ServerMiddleware
7
+ # rubocop: disable Metrics/AbcSize, Metrics/MethodLength:
7
8
  def call(worker, job, queue)
8
- labels = Yabeda::Sidekiq.labelize(worker, job, queue)
9
- start = Time.now
9
+ custom_tags = Yabeda::Sidekiq.custom_tags(worker, job).to_h
10
+ labels = Yabeda::Sidekiq.labelize(worker, job, queue).merge(custom_tags)
11
+ start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
10
12
  begin
11
- yield
13
+ job_instance = ::Sidekiq::Job.new(job)
14
+ Yabeda.sidekiq_job_latency.measure(labels, job_instance.latency)
15
+ Yabeda.with_tags(**custom_tags) do
16
+ yield
17
+ end
12
18
  Yabeda.sidekiq_jobs_success_total.increment(labels)
13
19
  rescue Exception # rubocop: disable Lint/RescueException
14
20
  Yabeda.sidekiq_jobs_failed_total.increment(labels)
@@ -18,11 +24,12 @@ module Yabeda
18
24
  Yabeda.sidekiq_jobs_executed_total.increment(labels)
19
25
  end
20
26
  end
27
+ # rubocop: enable Metrics/AbcSize, Metrics/MethodLength:
21
28
 
22
29
  private
23
30
 
24
31
  def elapsed(start)
25
- (Time.now - start).round(3)
32
+ (Process.clock_gettime(Process::CLOCK_MONOTONIC) - start).round(3)
26
33
  end
27
34
  end
28
35
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Yabeda
4
4
  module Sidekiq
5
- VERSION = "0.1.3"
5
+ VERSION = "0.7.0"
6
6
  end
7
7
  end
@@ -22,10 +22,11 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ["lib"]
24
24
 
25
- spec.add_dependency "yabeda"
26
25
  spec.add_dependency "sidekiq"
26
+ spec.add_dependency "yabeda", "~> 0.6"
27
27
 
28
- spec.add_development_dependency "bundler", "~> 1.16"
29
- spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "activejob", ">= 6.0"
29
+ spec.add_development_dependency "bundler", "~> 2.0"
30
+ spec.add_development_dependency "rake", "~> 13.0"
30
31
  spec.add_development_dependency "rspec", "~> 3.0"
31
32
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yabeda-sidekiq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.7.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: 2018-10-25 00:00:00.000000000 Z
11
+ date: 2020-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: yabeda
14
+ name: sidekiq
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -25,47 +25,61 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: sidekiq
28
+ name: yabeda
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '0.6'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activejob
43
+ requirement: !ruby/object:Gem::Requirement
37
44
  requirements:
38
45
  - - ">="
39
46
  - !ruby/object:Gem::Version
40
- version: '0'
47
+ version: '6.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '6.0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: '1.16'
61
+ version: '2.0'
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: '1.16'
68
+ version: '2.0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - "~>"
60
74
  - !ruby/object:Gem::Version
61
- version: '10.0'
75
+ version: '13.0'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
- version: '10.0'
82
+ version: '13.0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rspec
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -92,6 +106,7 @@ files:
92
106
  - ".rspec"
93
107
  - ".rubocop.yml"
94
108
  - ".travis.yml"
109
+ - CHANGELOG.md
95
110
  - Gemfile
96
111
  - LICENSE.txt
97
112
  - README.md
@@ -122,8 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
137
  - !ruby/object:Gem::Version
123
138
  version: '0'
124
139
  requirements: []
125
- rubyforge_project:
126
- rubygems_version: 2.7.6
140
+ rubygems_version: 3.1.2
127
141
  signing_key:
128
142
  specification_version: 4
129
143
  summary: Extensible Prometheus exporter for monitoring your Sidekiq