sidekiq-datadog-monitor 0.3.0 → 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: a6e0e510899e6b233d1bb1d275f9d708c851567176894074ce1d83bc45f21a7a
4
- data.tar.gz: af4b6268dec084b4dbc9e3307fdeab2015a57544aaa51a058e9fc8e64f25434c
3
+ metadata.gz: 916092eba3887bd8efc9c819817ac2f971cafd3767fe5c801e412ba4e2eefa74
4
+ data.tar.gz: 5c110f7a204af943aadc0d6c8d7719d58bb98019f6d9fd1dd37df84b0e3c443d
5
5
  SHA512:
6
- metadata.gz: 3ad0a766f6d1648815271cd574da145e74599442c0611f8892ffc1c3f650ebf1375173e8600e9e7a30a4a4031c3eee3822d04e80a925fe663a214ccf908c4bf5
7
- data.tar.gz: 1291ed9981ad48deb2ccb0e52226f87f199fac0b7da85d892ee227eb34ea2dfa4aa366c9197a457ba013d9618edba5df64a02c1e71b70425eb0317fb5476c28a
6
+ metadata.gz: 506f09c420c679a9220d7da7805732b723c85fa3ccc93fd91fa94ff070f31d996ba150ef9f7558e86e02f86c38b8f2c1527bac5bf8ffd03fd985dff44272445f
7
+ data.tar.gz: 8e7a1ba96cec2599361ea43f0a770d7cd1c6da779a22cf85b3b80d621067df336ffa4a383a9cee3811bbc86018e16c4f74b7924bf63e3f3a279208431be238e1
data/README.md CHANGED
@@ -25,27 +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
- batch: false # optional, default: false
38
35
  )
39
36
  ```
40
- `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
41
39
 
42
- `queue` setting for background job that will gather and send Sidekiq metrics
40
+ ## How it works
43
41
 
44
- `tags` tags for datadog metrics
45
-
46
- `cron` - schedule settings for background job that will gather and send Sidekiq metrics
47
-
48
- `batch` turns on sending DD metrics in batches. Make sure you don't have too many queues before enabling this option. The message with all tags must fit into [8KB of default DataDog buffer](https://docs.datadoghq.com/developers/dogstatsd/high_throughput/#enable-buffering-on-your-client) size.
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.
49
45
 
50
46
 
51
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.0'.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.0
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-06-22 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