honeybadger 5.20.1 → 5.21.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: ae2f44eb9962db4e28c9dde0605afddce6d9f5e45a5edd4717df5ee29c3721f7
4
- data.tar.gz: 1b8a54201362718397a65381a1acae5075d981e8ec456a83c88c738842fbd61a
3
+ metadata.gz: e746a9e39d4877eded4a48b69d790795996af59c9971279b1f72b09a80260524
4
+ data.tar.gz: 1308d295339f52d2db9cc1b6ce39896c231e38c248d565419e330bde3f4cdf1c
5
5
  SHA512:
6
- metadata.gz: 120f89c79192559358b22bc4b2834e511974f2021faf94001f8ac535cabd5ad4d544093381053ee056b824e47bcc3b2365e41bbf4828c4dfe77a7503f9baea16
7
- data.tar.gz: 05d48ae81cc6e01c1ea0686d8f8a3c6d76c532afd8d286aa2920c8c19ba12cd0b2e56041837d77c3926c1c0f172c98504ccd647d7c70e86d86ad9272c88bec38
6
+ metadata.gz: c383d2a638d1e11d89d809a86f92427540268a3fecb5748cd662a8e0a2017a9c778d5d0ed094e453566488e54696eb434dc0243d3829ee9b8494c8becc6cb44c
7
+ data.tar.gz: 2ffc7ed5a9d72fc47742dbf9c787101bf2ac86593fb08e6095f115379b78efec4a89a41a106d5d23d217ffc5c443d386c81eaa2c19f1dcc7be4f30b73a2112fe
data/CHANGELOG.md CHANGED
@@ -1,6 +1,15 @@
1
1
  # Change Log
2
2
 
3
3
 
4
+ ## [5.21.0](https://github.com/honeybadger-io/honeybadger-ruby/compare/v5.20.1...v5.21.0) (2024-11-14)
5
+
6
+
7
+ ### Features
8
+
9
+ * add event stats for sidekiq and sq ([#638](https://github.com/honeybadger-io/honeybadger-ruby/issues/638)) ([0d15bf5](https://github.com/honeybadger-io/honeybadger-ruby/commit/0d15bf543d4c425a2d9f6000d328dc0e71261647))
10
+ * disable all workers in rails console ([#636](https://github.com/honeybadger-io/honeybadger-ruby/issues/636)) ([d0bcb42](https://github.com/honeybadger-io/honeybadger-ruby/commit/d0bcb4278ad84d02e3706766269582067bc76e29))
11
+ * emit an event for karafka stats ([#637](https://github.com/honeybadger-io/honeybadger-ruby/issues/637)) ([e7e74b5](https://github.com/honeybadger-io/honeybadger-ruby/commit/e7e74b51324f7c718b1adc634cee4233d0c91813))
12
+
4
13
  ## [5.20.1](https://github.com/honeybadger-io/honeybadger-ruby/compare/v5.20.0...v5.20.1) (2024-11-13)
5
14
 
6
15
 
@@ -377,6 +377,16 @@ module Honeybadger
377
377
  true
378
378
  end
379
379
 
380
+ # Stops the Honeybadger Insights related services.
381
+ #
382
+ # @example
383
+ # Honeybadger.stop_insights # => nil
384
+ def stop_insights(force = false)
385
+ events_worker&.shutdown(force)
386
+ metrics_worker&.shutdown(force)
387
+ true
388
+ end
389
+
380
390
  # Sends event to events backend
381
391
  #
382
392
  # @example
@@ -344,6 +344,21 @@ module Honeybadger
344
344
  default: true,
345
345
  type: Boolean
346
346
  },
347
+ :'sidekiq.insights.enabled' => {
348
+ description: 'Enable automatic data collection for Sidekiq.',
349
+ default: true,
350
+ type: Boolean
351
+ },
352
+ :'sidekiq.insights.events' => {
353
+ description: 'Enable automatic event capturing for Sidekiq.',
354
+ default: true,
355
+ type: Boolean
356
+ },
357
+ :'sidekiq.insights.metrics' => {
358
+ description: 'Enable automatic metric data collection for Sidekiq.',
359
+ default: false,
360
+ type: Boolean
361
+ },
347
362
  :'sidekiq.insights.cluster_collection' => {
348
363
  description: 'Collect cluster based metrics for Sidekiq.',
349
364
  default: true,
@@ -351,34 +366,34 @@ module Honeybadger
351
366
  },
352
367
  :'sidekiq.insights.collection_interval' => {
353
368
  description: 'The frequency in which Sidekiq cluster metrics are sampled.',
354
- default: 60,
369
+ default: 5,
355
370
  type: Integer
356
371
  },
357
- :'solid_queue.insights.cluster_collection' => {
358
- description: 'Collect cluster based metrics for SolidQueue.',
372
+ :'solid_queue.insights.enabled' => {
373
+ description: 'Enable automatic data collection for SolidQueue.',
359
374
  default: true,
360
375
  type: Boolean
361
376
  },
362
- :'solid_queue.insights.collection_interval' => {
363
- description: 'The frequency in which SolidQueue cluster metrics are sampled.',
364
- default: 60,
365
- type: Integer
366
- },
367
- :'sidekiq.insights.enabled' => {
368
- description: 'Enable automatic data collection for Sidekiq.',
377
+ :'solid_queue.insights.events' => {
378
+ description: 'Enable automatic event capturing for SolidQueue.',
369
379
  default: true,
370
380
  type: Boolean
371
381
  },
372
- :'sidekiq.insights.events' => {
373
- description: 'Enable automatic event capturing for Sidekiq.',
374
- default: true,
382
+ :'solid_queue.insights.metrics' => {
383
+ description: 'Enable automatic metric data collection for SolidQueue.',
384
+ default: false,
375
385
  type: Boolean
376
386
  },
377
- :'sidekiq.insights.metrics' => {
378
- description: 'Enable automatic metric data collection for Sidekiq.',
379
- default: false,
387
+ :'solid_queue.insights.cluster_collection' => {
388
+ description: 'Collect cluster based metrics for SolidQueue.',
389
+ default: true,
380
390
  type: Boolean
381
391
  },
392
+ :'solid_queue.insights.collection_interval' => {
393
+ description: 'The frequency in which SolidQueue cluster metrics are sampled.',
394
+ default: 5,
395
+ type: Integer
396
+ },
382
397
  :'rails.insights.enabled' => {
383
398
  description: 'Enable automatic data collection for Ruby on Rails.',
384
399
  default: true,
@@ -34,7 +34,10 @@ module Honeybadger
34
34
  end
35
35
 
36
36
  console do
37
- Honeybadger::Agent.instance.config[:'insights.enabled'] = Honeybadger::Agent.instance.config[:'insights.console.enabled']
37
+ unless Honeybadger::Agent.instance.config[:'insights.enabled'] = Honeybadger::Agent.instance.config[:'insights.console.enabled']
38
+ Honeybadger::Agent.instance.config.logger.debug("Rails console detected, shutting down Honeybadger Insights workers.")
39
+ Honeybadger::Agent.instance.stop_insights
40
+ end
38
41
  end
39
42
  end
40
43
  end
@@ -70,6 +70,10 @@ module Honeybadger
70
70
  #
71
71
  # @param event [Karafka::Core::Monitoring::Event]
72
72
  def on_statistics_emitted(event)
73
+ if Honeybadger.config.load_plugin_insights_events?(:karafka)
74
+ Honeybadger.event("statistics_emitted.karafka", event.payload)
75
+ end
76
+
73
77
  return unless Honeybadger.config.load_plugin_insights_metrics?(:karafka)
74
78
 
75
79
  statistics = event[:statistics]
@@ -138,9 +142,7 @@ module Honeybadger
138
142
  def on_connection_listener_fetch_loop_received(event)
139
143
  time_taken = event[:time]
140
144
  messages_count = event[:messages_buffer].size
141
-
142
145
  consumer_group_id = event[:subscription_group].consumer_group.id
143
-
144
146
  extra_tags = { consumer_group: consumer_group_id }
145
147
 
146
148
  if Honeybadger.config.load_plugin_insights_metrics?(:karafka)
@@ -191,9 +193,10 @@ module Honeybadger
191
193
  #
192
194
  # @param event [Karafka::Core::Monitoring::Event]
193
195
  def on_consumer_#{after}(event)
194
- tags = consumer_tags(event.payload[:caller])
195
-
196
- increment_counter('consumer_#{name}', value: 1, **tags)
196
+ if Honeybadger.config.load_plugin_insights_metrics?(:karafka)
197
+ tags = consumer_tags(event.payload[:caller])
198
+ increment_counter('consumer_#{name}', value: 1, **tags)
199
+ end
197
200
  end
198
201
  RUBY
199
202
  end
@@ -167,47 +167,67 @@ module Honeybadger
167
167
  end
168
168
  end
169
169
 
170
+ collect_sidekiq_stats = -> do
171
+ stats = ::Sidekiq::Stats.new
172
+ data = stats.as_json
173
+ data[:queues] = {}
174
+
175
+ ::Sidekiq::Queue.all.each do |queue|
176
+ data[:queues][queue.name] ||= {}
177
+ data[:queues][queue.name][:latency] = (queue.latency * 1000).ceil
178
+ data[:queues][queue.name][:depth] = queue.size
179
+ end
180
+
181
+ Hash.new(0).tap do |busy_counts|
182
+ ::Sidekiq::Workers.new.each do |_pid, _tid, work|
183
+ payload = work.respond_to?(:payload) ? work.payload : work["payload"]
184
+ payload = JSON.parse(payload) if payload.is_a?(String)
185
+ busy_counts[payload["queue"]] += 1
186
+ end
187
+ end.each do |queue_name, busy_count|
188
+ data[:queues][queue_name] ||= {}
189
+ data[:queues][queue_name][:busy] = busy_count
190
+ end
191
+
192
+ processes = ::Sidekiq::ProcessSet.new.to_enum(:each).to_a
193
+ data[:capacity] = processes.map { |process| process["concurrency"] }.sum
194
+
195
+ process_utilizations = processes.map do |process|
196
+ next unless process["concurrency"].to_f > 0
197
+ process["busy"] / process["concurrency"].to_f
198
+ end.compact
199
+
200
+ if process_utilizations.any?
201
+ utilization = process_utilizations.sum / process_utilizations.length.to_f
202
+ data[:utilization] = utilization
203
+ end
204
+
205
+ data
206
+ end
207
+
170
208
  collect do
171
209
  if config.cluster_collection?(:sidekiq) && (leader_checker.nil? || leader_checker.collect?)
172
- metric_source 'sidekiq'
173
-
174
- stats = ::Sidekiq::Stats.new
175
-
176
- gauge 'active_workers', ->{ stats.workers_size }
177
- gauge 'active_processes', ->{ stats.processes_size }
178
- gauge 'jobs_processed', ->{ stats.processed }
179
- gauge 'jobs_failed', ->{ stats.failed }
180
- gauge 'jobs_scheduled', ->{ stats.scheduled_size }
181
- gauge 'jobs_enqueued', ->{ stats.enqueued }
182
- gauge 'jobs_dead', ->{ stats.dead_size }
183
- gauge 'jobs_retry', ->{ stats.retry_size }
184
-
185
- ::Sidekiq::Queue.all.each do |queue|
186
- gauge 'queue_latency', { queue: queue.name }, ->{ (queue.latency * 1000).ceil }
187
- gauge 'queue_depth', { queue: queue.name }, ->{ queue.size }
188
- end
210
+ stats = collect_sidekiq_stats.call
189
211
 
190
- Hash.new(0).tap do |busy_counts|
191
- ::Sidekiq::Workers.new.each do |_pid, _tid, work|
192
- payload = work.respond_to?(:payload) ? work.payload : work["payload"]
193
- payload = JSON.parse(payload) if payload.is_a?(String)
194
- busy_counts[payload["queue"]] += 1
195
- end
196
- end.each do |queue_name, busy_count|
197
- gauge 'queue_busy', { queue: queue_name }, ->{ busy_count }
212
+ if Honeybadger.config.load_plugin_insights_events?(:sidekiq)
213
+ Honeybadger.event('stats.sidekiq', stats.except('stats').merge(stats['stats']))
198
214
  end
199
215
 
200
- processes = ::Sidekiq::ProcessSet.new.to_enum(:each).to_a
201
- gauge 'capacity', ->{ processes.map { |process| process["concurrency"] }.sum }
216
+ if Honeybadger.config.load_plugin_insights_metrics?(:sidekiq)
217
+ metric_source 'sidekiq'
218
+
219
+ stats['stats'].each do |name, value|
220
+ gauge name, value: value
221
+ end
202
222
 
203
- process_utilizations = processes.map do |process|
204
- next unless process["concurrency"].to_f > 0
205
- process["busy"] / process["concurrency"].to_f
206
- end.compact
223
+ stats[:queues].each do |queue_name, data|
224
+ data.each do |key, value|
225
+ gauge "queue_#{key}", queue: queue_name, value: value
226
+ end
227
+ end
207
228
 
208
- if process_utilizations.any?
209
- utilization = process_utilizations.sum / process_utilizations.length.to_f
210
- gauge 'utilization', ->{ utilization }
229
+ gauge 'capacity', value: stats[:capacity] if stats[:capacity]
230
+ gauge 'utilization', value: stats[:utilization] if stats[:utilization]
211
231
  end
212
232
  end
213
233
  end
@@ -4,20 +4,46 @@ module Honeybadger
4
4
  Plugin.register :solid_queue do
5
5
  requirement { config.load_plugin_insights?(:solid_queue) && defined?(::SolidQueue) }
6
6
 
7
+ collect_solid_queue_stats = -> do
8
+ data = {}
9
+ data[:stats] = {
10
+ jobs_in_progress: ::SolidQueue::ClaimedExecution.count,
11
+ jobs_blocked: ::SolidQueue::BlockedExecution.count,
12
+ jobs_failed: ::SolidQueue::FailedExecution.count,
13
+ jobs_scheduled: ::SolidQueue::ScheduledExecution.count,
14
+ jobs_processed: ::SolidQueue::Job.where.not(finished_at: nil).count,
15
+ active_workers: ::SolidQueue::Process.where(kind: "Worker").count,
16
+ active_dispatchers: ::SolidQueue::Process.where(kind: "Dispatcher").count
17
+ }
18
+
19
+ data[:queues] = {}
20
+
21
+ ::SolidQueue::Queue.all.each do |queue|
22
+ data[:queues][queue.name] = { depth: queue.size }
23
+ end
24
+
25
+ data
26
+ end
27
+
7
28
  collect do
29
+ stats = collect_solid_queue_stats.call
30
+
8
31
  if config.cluster_collection?(:solid_queue)
9
- metric_source 'solid_queue'
10
-
11
- gauge 'jobs_in_progress', ->{ ::SolidQueue::ClaimedExecution.count }
12
- gauge 'jobs_blocked', ->{ ::SolidQueue::BlockedExecution.count }
13
- gauge 'jobs_failed', ->{ ::SolidQueue::FailedExecution.count }
14
- gauge 'jobs_scheduled', ->{ ::SolidQueue::ScheduledExecution.count }
15
- gauge 'jobs_processed', ->{ ::SolidQueue::Job.where.not(finished_at: nil).count }
16
- gauge 'active_workers', ->{ ::SolidQueue::Process.where(kind: "Worker").count }
17
- gauge 'active_dispatchers', ->{ ::SolidQueue::Process.where(kind: "Dispatcher").count }
18
-
19
- ::SolidQueue::Queue.all.each do |queue|
20
- gauge 'queue_depth', { queue: queue.name }, ->{ queue.size }
32
+ if Honeybadger.config.load_plugin_insights_events?(:solid_queue)
33
+ Honeybadger.event('stats.solid_queue', stats.except(:stats).merge(stats[:stats]))
34
+ end
35
+
36
+ if Honeybadger.config.load_plugin_insights_metrics?(:solid_queue)
37
+ metric_source 'solid_queue'
38
+ stats[:stats].each do |stat_name, value|
39
+ gauge stat_name, value: value
40
+ end
41
+
42
+ stats[:queues].each do |queue_name, data|
43
+ data.each do |key, value|
44
+ gauge "queue_#{key}", queue: queue_name, value: value
45
+ end
46
+ end
21
47
  end
22
48
  end
23
49
  end
@@ -1,4 +1,4 @@
1
1
  module Honeybadger
2
2
  # The current String Honeybadger version.
3
- VERSION = '5.20.1'.freeze
3
+ VERSION = '5.21.0'.freeze
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honeybadger
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.20.1
4
+ version: 5.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Honeybadger Industries LLC
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-11-13 00:00:00.000000000 Z
11
+ date: 2024-11-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logger