sidekiq-datadog-monitor 0.3.1 → 1.0.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: 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