sidekiq-datadog-monitor 0.3.1 → 1.0.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: 3d290f211b5442dacf54899c28a0d6895a69015c058525a86afb9559ede8360c
4
- data.tar.gz: a99e837aa555e7d9b3ea561f258289c6d43db84e0072e47a429de7a7ff323cc1
3
+ metadata.gz: 916092eba3887bd8efc9c819817ac2f971cafd3767fe5c801e412ba4e2eefa74
4
+ data.tar.gz: 5c110f7a204af943aadc0d6c8d7719d58bb98019f6d9fd1dd37df84b0e3c443d
5
5
  SHA512:
6
- metadata.gz: 03ef0e2ae96aaad2cfe19627f6c37659568dd2a291691e6f5398704b8e4a66ceb180b040e01255defe02da250759d4b79edda9ede3feb12af759c4ad272617a8
7
- data.tar.gz: f395f9fa6f183f448da51d622c3e8c7e13c9decd7fcc2fc2d8b3faaa1c3e6c1dcd51361b90b07238d37ac8100baad554bde7a91a3093ee0f383b02c22a4b6ef6
6
+ metadata.gz: 506f09c420c679a9220d7da7805732b723c85fa3ccc93fd91fa94ff070f31d996ba150ef9f7558e86e02f86c38b8f2c1527bac5bf8ffd03fd985dff44272445f
7
+ data.tar.gz: 8e7a1ba96cec2599361ea43f0a770d7cd1c6da779a22cf85b3b80d621067df336ffa4a383a9cee3811bbc86018e16c4f74b7924bf63e3f3a279208431be238e1
data/README.md CHANGED
@@ -25,24 +25,23 @@ To start sending metrics
25
25
 
26
26
  ```ruby
27
27
  # Import the library
28
- require 'sidekiq/datadog/monitor/data'
28
+ require 'sidekiq/datadog/monitor'
29
29
 
30
- # Initiate a Sidekiq::Datadog::Monitor client instance.
31
- Sidekiq::Datadog::Monitor::Data.initialize!(
30
+ # Configure Sidekiq::Datadog::Monitor.
31
+ Sidekiq::Datadog::Monitor.configure!(
32
32
  agent_host: 'localhost',
33
33
  agent_port: 8125,
34
- queue: 'queue name',
35
34
  tags: ['env:production', 'product:product_name'], # optional
36
- cron: "*/30 * * * *" # default: "*/1 * * * *"
37
35
  )
38
36
  ```
39
- `agent_host` and `agent_port` instantiate DogStatsD client
37
+ - `agent_host` and `agent_port` instantiate DogStatsD client
38
+ - `tags` additional tags to be added for every metrics
40
39
 
41
- `queue` setting for background job that will gather and send Sidekiq metrics
40
+ ## How it works
42
41
 
43
- `tags` tags for datadog metrics
44
-
45
- `cron` - schedule settings for background job that will gather and send Sidekiq metrics
42
+ Gem using sidekiq lifecycle events to operate and send metrics to datadog.
43
+ Heartbeat event is used to send metrics every 5 seconds. Heartbeat event happens in every sidekiq process so metrics
44
+ will be sent multiple times but will be aggregated on datadog.
46
45
 
47
46
 
48
47
  ## Development
@@ -0,0 +1,41 @@
1
+ require 'sidekiq/api'
2
+
3
+ module Sidekiq
4
+ module Datadog
5
+ module Monitor
6
+ class MetricsSender
7
+ attr_reader :statsd, :tags_builder
8
+ def initialize(statsd, tags_builder)
9
+ @statsd = statsd
10
+ @tags_builder = tags_builder
11
+ end
12
+
13
+ def send_metrics
14
+ Sidekiq::Stats.new.queues.each_pair do |queue_name, size|
15
+ post_queue_stats(statsd, queue_name, size)
16
+ end
17
+ Sidekiq::ProcessSet.new.each do |process|
18
+ post_process_stats(process)
19
+ end
20
+ end
21
+
22
+ protected
23
+
24
+ def post_queue_stats(statsd, queue_name, size)
25
+ latency = Sidekiq::Queue.new(queue_name).latency
26
+ tags = tags_builder.build(queue_name: queue_name)
27
+
28
+ statsd.gauge('sidekiq.queue.size', size, tags: tags)
29
+ statsd.gauge('sidekiq.queue.latency', latency, tags: tags)
30
+ end
31
+
32
+ def post_process_stats(process)
33
+ utilization = process['busy'] / process['concurrency'].to_f
34
+ tags = tags_builder.build(process_id: process['identity'], process_tag: process['tag'])
35
+
36
+ statsd.gauge('sidekiq.process.utilization', utilization, tags: tags)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,24 @@
1
+ module Sidekiq
2
+ module Datadog
3
+ module Monitor
4
+ class TagBuilder
5
+ SPECIAL_SYMBOLS = /[\/\.:]/i.freeze
6
+ def initialize(common_tags)
7
+ @common_tags = common_tags
8
+ end
9
+
10
+ def build(tags_hash)
11
+ custom_tags = tags_hash.map { |key, value| [key, value] if value.to_s != '' }.compact
12
+ custom_tags = custom_tags.map { |key, value| "#{key}:#{normalize_value(value)}" }
13
+ custom_tags + @common_tags
14
+ end
15
+
16
+ protected
17
+
18
+ def normalize_value(value)
19
+ value.to_s.gsub(SPECIAL_SYMBOLS, '_')
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,7 +1,7 @@
1
1
  module Sidekiq
2
2
  module Datadog
3
3
  module Monitor
4
- VERSION = '0.3.1'.freeze
4
+ VERSION = '1.0.0'.freeze
5
5
  end
6
6
  end
7
7
  end
@@ -1,12 +1,67 @@
1
- require 'sidekiq/api'
2
- require 'sidekiq-scheduler'
3
- require 'sidekiq/datadog/monitor/data'
4
- require 'sidekiq/datadog/monitor/metrics_worker'
1
+ require 'datadog/statsd'
2
+ require 'sidekiq/datadog/monitor/metrics_sender'
3
+ require 'sidekiq/datadog/monitor/tag_builder'
5
4
 
6
5
  module Sidekiq
7
6
  module Datadog
8
7
  module Monitor
9
8
  class Error < StandardError; end
9
+
10
+ class << self
11
+ attr_accessor :agent_port, :agent_host, :tags_builder, :statsd, :sender
12
+
13
+ def configure!(options)
14
+ raise Sidekiq::Datadog::Monitor::Error, "Can't configure two times" if configured?
15
+
16
+ @agent_host, @agent_port = options.fetch_values(:agent_host, :agent_port)
17
+ @tags_builder = Sidekiq::Datadog::Monitor::TagBuilder.new(options[:tags] || [])
18
+
19
+ add_sidekiq_listeners
20
+ rescue KeyError => e
21
+ raise Sidekiq::Datadog::Monitor::Error, "Required param is missing: #{e.message}"
22
+ end
23
+
24
+ def configured?
25
+ agent_host && agent_port
26
+ end
27
+
28
+ def initialize!
29
+ @statsd = ::Datadog::Statsd.new(agent_host, agent_port)
30
+ @sender = Sidekiq::Datadog::Monitor::MetricsSender.new(statsd, tags_builder)
31
+ end
32
+
33
+ def send_metrics
34
+ sender.call
35
+ end
36
+
37
+ def shutdown!
38
+ statsd.close
39
+ end
40
+
41
+
42
+ private
43
+
44
+ def reset!
45
+ @agent_host = nil
46
+ @agent_port = nil
47
+ @statsd = nil
48
+ @sender = nil
49
+ end
50
+
51
+ def add_sidekiq_listeners
52
+ Sidekiq.configure_server do |config|
53
+ config.on(:startup) do
54
+ Sidekiq::Datadog::Monitor.initialize!
55
+ end
56
+ config.on(:heartbeat) do
57
+ Sidekiq::Datadog::Monitor.send_metrics
58
+ end
59
+ config.on(:shutdown) do
60
+ Sidekiq::Datadog::Monitor.shutdown!
61
+ end
62
+ end
63
+ end
64
+ end
10
65
  end
11
66
  end
12
67
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-datadog-monitor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - aleksa_castle
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-07-05 00:00:00.000000000 Z
11
+ date: 2023-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -108,20 +108,6 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: 2.2.1
111
- - !ruby/object:Gem::Dependency
112
- name: sidekiq-scheduler
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '3.0'
118
- type: :runtime
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '3.0'
125
111
  - !ruby/object:Gem::Dependency
126
112
  name: dogstatsd-ruby
127
113
  requirement: !ruby/object:Gem::Requirement
@@ -148,8 +134,8 @@ files:
148
134
  - bin/console
149
135
  - bin/setup
150
136
  - lib/sidekiq/datadog/monitor.rb
151
- - lib/sidekiq/datadog/monitor/data.rb
152
- - lib/sidekiq/datadog/monitor/metrics_worker.rb
137
+ - lib/sidekiq/datadog/monitor/metrics_sender.rb
138
+ - lib/sidekiq/datadog/monitor/tag_builder.rb
153
139
  - lib/sidekiq/datadog/monitor/version.rb
154
140
  homepage: https://github.com/matic-insurance/sidekiq-datadog-monitor
155
141
  licenses:
@@ -1,34 +0,0 @@
1
- module Sidekiq
2
- module Datadog
3
- module Monitor
4
- class Data
5
- class << self
6
- attr_reader :agent_port, :agent_host, :tags, :env, :queue, :cron
7
-
8
- def initialize!(options)
9
- @agent_port, @agent_host, @queue = options.fetch_values(:agent_port, :agent_host, :queue)
10
- @tags = options[:tags] || []
11
- @cron = options[:cron] || '*/1 * * * *'
12
-
13
- Sidekiq.configure_server do |config|
14
- SidekiqScheduler::Scheduler.dynamic = true
15
-
16
- config.on(:startup) do
17
- start
18
- end
19
- end
20
- rescue StandardError => e
21
- raise Sidekiq::Datadog::Monitor::Error, e.message
22
- end
23
-
24
- private
25
-
26
- def start
27
- Sidekiq.set_schedule('send_metrics',
28
- { 'cron' => cron, 'class' => 'Sidekiq::Datadog::Monitor::MetricsWorker', 'queue' => queue })
29
- end
30
- end
31
- end
32
- end
33
- end
34
- end
@@ -1,41 +0,0 @@
1
- require 'sidekiq/datadog/monitor/data'
2
- require 'datadog/statsd'
3
-
4
- module Sidekiq
5
- module Datadog
6
- module Monitor
7
- class MetricsWorker
8
- include Sidekiq::Worker
9
-
10
- sidekiq_options retry: false
11
-
12
- def perform
13
- statsd = ::Datadog::Statsd.new(Data.agent_host, Data.agent_port)
14
- send_metrics(statsd)
15
- statsd.close
16
- end
17
-
18
- private
19
-
20
- def send_metrics(statsd)
21
- Sidekiq::Stats.new.queues.each_pair do |queue_name, size|
22
- post_queue_size(statsd, queue_name, size)
23
-
24
- post_queue_latency(statsd, queue_name)
25
- end
26
- end
27
-
28
- def post_queue_size(statsd, queue_name, size)
29
- statsd.gauge('sidekiq.queue.size', size,
30
- tags: ["queue_name:#{queue_name}"].concat(Data.tags))
31
- end
32
-
33
- def post_queue_latency(statsd, queue_name)
34
- latency = Sidekiq::Queue.new(queue_name).latency
35
- statsd.gauge('sidekiq.queue.latency', latency,
36
- tags: ["queue_name:#{queue_name}"].concat(Data.tags))
37
- end
38
- end
39
- end
40
- end
41
- end