honeybadger 5.20.1 → 5.21.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: 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