honeybadger 5.19.1 → 5.22.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: 845eb3bb6f21901ea870b5da7124decc51c01a1f9902330608eb7c9d7d0f0e89
4
- data.tar.gz: '0388e922e33e0b116d23df7c53ef3b4d9bf047f319ce60f2548881a8328df758'
3
+ metadata.gz: 40136d87c293fee9689b5f11926a15bc98c225f34f6a7b75e4fcd8ede1cacc5f
4
+ data.tar.gz: '028f8549e380de8c248013f0ed7846f5fea5018f71c8ac1e0bc310a72d695fdd'
5
5
  SHA512:
6
- metadata.gz: 17282da0e828893e7b3bee7b34d9da1566eb1eba7843491f8b036db5e846a8641adcef3d923a78d817e9ab5f465b495b5e37aaba87b2d9c78eb9b6c5ce2b8dec
7
- data.tar.gz: 6bf054b890c44226db7d4b9d3eed2b2ed5f848a59b882fa0cd1ce0b788d488c492f05b937f673007d41ef2f05298470664efe94531e5a1447ba21a127b7cb929
6
+ metadata.gz: 1404e62cbc7b74d49e3a3881791c5cada2ab820e447efb0c7d2c83994cd81d54b32ca614b52a9fc47606d368c65c950ab5159e7e9342e7214c9d891a132d12e6
7
+ data.tar.gz: 737dc2abee3fef27ecd93034e6914eb0a6439a6fdcb35e803ceeb2bb74161f0dd19b08fc1661ea78723b7ecd6a8b984c8a1f2733288c63d446ca1c68fa3b335f
data/CHANGELOG.md CHANGED
@@ -1,6 +1,44 @@
1
1
  # Change Log
2
2
 
3
3
 
4
+ ## [5.22.0](https://github.com/honeybadger-io/honeybadger-ruby/compare/v5.21.0...v5.22.0) (2024-11-14)
5
+
6
+
7
+ ### Features
8
+
9
+ * only allow for insights to be enabled when public ([#642](https://github.com/honeybadger-io/honeybadger-ruby/issues/642)) ([2d3ab26](https://github.com/honeybadger-io/honeybadger-ruby/commit/2d3ab26ca3673b5b01082d55737bf7907c02e799))
10
+
11
+ ## [5.21.0](https://github.com/honeybadger-io/honeybadger-ruby/compare/v5.20.1...v5.21.0) (2024-11-14)
12
+
13
+
14
+ ### Features
15
+
16
+ * 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))
17
+ * 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))
18
+ * 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))
19
+
20
+ ## [5.20.1](https://github.com/honeybadger-io/honeybadger-ruby/compare/v5.20.0...v5.20.1) (2024-11-13)
21
+
22
+
23
+ ### Bug Fixes
24
+
25
+ * cli test for rails 8 ([#639](https://github.com/honeybadger-io/honeybadger-ruby/issues/639)) ([ec74cfd](https://github.com/honeybadger-io/honeybadger-ruby/commit/ec74cfd95519cd49509ff63fb34a7673f5c76323))
26
+
27
+ ## [5.20.0](https://github.com/honeybadger-io/honeybadger-ruby/compare/v5.19.2...v5.20.0) (2024-11-08)
28
+
29
+
30
+ ### Features
31
+
32
+ * add aggregated metrics for rails and more ([#630](https://github.com/honeybadger-io/honeybadger-ruby/issues/630)) ([12db5a4](https://github.com/honeybadger-io/honeybadger-ruby/commit/12db5a4d44a9597c0999d32a150283799d856d66))
33
+
34
+ ## [5.19.2](https://github.com/honeybadger-io/honeybadger-ruby/compare/v5.19.1...v5.19.2) (2024-11-05)
35
+
36
+
37
+ ### Bug Fixes
38
+
39
+ * don't run middleware in Sinatra when not configured ([#629](https://github.com/honeybadger-io/honeybadger-ruby/issues/629)) ([d84c2b1](https://github.com/honeybadger-io/honeybadger-ruby/commit/d84c2b15f61b1a019be6329981d8f5323115d1e9))
40
+ * pin rspec-its gem to 1.3.1 ([#631](https://github.com/honeybadger-io/honeybadger-ruby/issues/631)) ([5f78b8a](https://github.com/honeybadger-io/honeybadger-ruby/commit/5f78b8adfb1b86c233bf9ad3ddb69dc702341e11))
41
+
4
42
  ## [5.19.1](https://github.com/honeybadger-io/honeybadger-ruby/compare/v5.19.0...v5.19.1) (2024-11-02)
5
43
 
6
44
 
@@ -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
@@ -142,6 +142,7 @@ module Honeybadger
142
142
  end
143
143
  CONTROLLER
144
144
 
145
+ ::Rails.application.try(:reload_routes_unless_loaded)
145
146
  ::Rails.application.routes.tap do |r|
146
147
  # RouteSet#disable_clear_and_finalize prevents existing routes from
147
148
  # being cleared. We'll set it back to the original value when we're
@@ -32,6 +32,7 @@ module Honeybadger
32
32
  'Sidekiq::JobRetry::Skip'].map(&:freeze).freeze
33
33
 
34
34
  IGNORE_EVENTS_DEFAULT = [
35
+ { event_type: 'metric.hb', metric_name: 'duration.sql.active_record', query: /^(begin|commit)( transaction)?$/i },
35
36
  { event_type: 'sql.active_record', query: /^(begin|commit)( transaction)?$/i },
36
37
  { event_type: 'sql.active_record', query: /(solid_queue|good_job)/i },
37
38
  { event_type: 'sql.active_record', name: /^GoodJob/ },
@@ -343,6 +344,21 @@ module Honeybadger
343
344
  default: true,
344
345
  type: Boolean
345
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
+ },
346
362
  :'sidekiq.insights.cluster_collection' => {
347
363
  description: 'Collect cluster based metrics for Sidekiq.',
348
364
  default: true,
@@ -350,9 +366,24 @@ module Honeybadger
350
366
  },
351
367
  :'sidekiq.insights.collection_interval' => {
352
368
  description: 'The frequency in which Sidekiq cluster metrics are sampled.',
353
- default: 60,
369
+ default: 5,
354
370
  type: Integer
355
371
  },
372
+ :'solid_queue.insights.enabled' => {
373
+ description: 'Enable automatic data collection for SolidQueue.',
374
+ default: true,
375
+ type: Boolean
376
+ },
377
+ :'solid_queue.insights.events' => {
378
+ description: 'Enable automatic event capturing for SolidQueue.',
379
+ default: true,
380
+ type: Boolean
381
+ },
382
+ :'solid_queue.insights.metrics' => {
383
+ description: 'Enable automatic metric data collection for SolidQueue.',
384
+ default: false,
385
+ type: Boolean
386
+ },
356
387
  :'solid_queue.insights.cluster_collection' => {
357
388
  description: 'Collect cluster based metrics for SolidQueue.',
358
389
  default: true,
@@ -360,9 +391,24 @@ module Honeybadger
360
391
  },
361
392
  :'solid_queue.insights.collection_interval' => {
362
393
  description: 'The frequency in which SolidQueue cluster metrics are sampled.',
363
- default: 60,
394
+ default: 5,
364
395
  type: Integer
365
396
  },
397
+ :'rails.insights.enabled' => {
398
+ description: 'Enable automatic data collection for Ruby on Rails.',
399
+ default: true,
400
+ type: Boolean
401
+ },
402
+ :'rails.insights.events' => {
403
+ description: 'Enable automatic event capturing for Ruby on Rails.',
404
+ default: true,
405
+ type: Boolean
406
+ },
407
+ :'rails.insights.metrics' => {
408
+ description: 'Enable automatic metric data collection for Ruby on Rails.',
409
+ default: false,
410
+ type: Boolean
411
+ },
366
412
  :'karafka.insights.enabled' => {
367
413
  description: 'Enable automatic data collection for Karafka.',
368
414
  default: true,
@@ -375,7 +421,7 @@ module Honeybadger
375
421
  },
376
422
  :'karafka.insights.metrics' => {
377
423
  description: 'Enable automatic metric data collection for Karafka.',
378
- default: true,
424
+ default: false,
379
425
  type: Boolean
380
426
  },
381
427
  :'net_http.insights.enabled' => {
@@ -383,6 +429,16 @@ module Honeybadger
383
429
  default: true,
384
430
  type: Boolean
385
431
  },
432
+ :'net_http.insights.events' => {
433
+ description: 'Enable automatic event capturing for Net::HTTP requests.',
434
+ default: true,
435
+ type: Boolean
436
+ },
437
+ :'net_http.insights.metrics' => {
438
+ description: 'Enable automatic metric data collection for Net::HTTP requests.',
439
+ default: false,
440
+ type: Boolean
441
+ },
386
442
  :'net_http.insights.full_url' => {
387
443
  description: 'Record the full request url during instrumentation.',
388
444
  default: false,
@@ -289,7 +289,7 @@ module Honeybadger
289
289
  end
290
290
 
291
291
  def insights_enabled?
292
- !!self[:'insights.enabled']
292
+ public? && !!self[:'insights.enabled']
293
293
  end
294
294
 
295
295
  def cluster_collection?(name)
@@ -19,6 +19,7 @@ module Honeybadger
19
19
  def payloads
20
20
  [
21
21
  {
22
+ total: @total,
22
23
  min: @min,
23
24
  max: @max,
24
25
  avg: @avg,
@@ -34,6 +34,7 @@ module Honeybadger
34
34
 
35
35
  def payloads
36
36
  [{
37
+ total: @total,
37
38
  min: @min,
38
39
  max: @max,
39
40
  avg: @avg,
@@ -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
@@ -31,8 +31,8 @@ module Honeybadger
31
31
  if config[:'exceptions.enabled']
32
32
  # These two must come before the ErrorNotifier, since an error/response
33
33
  # passes through middleware from inner to outer (bottom to top)
34
- install_honeybadger_middleware(Honeybadger::Rack::UserFeedback)
35
- install_honeybadger_middleware(Honeybadger::Rack::UserInformer)
34
+ install_honeybadger_middleware(Honeybadger::Rack::UserFeedback) if config[:'feedback.enabled']
35
+ install_honeybadger_middleware(Honeybadger::Rack::UserInformer) if config[:'user_informer.enabled']
36
36
  install_honeybadger_middleware(Honeybadger::Rack::ErrorNotifier)
37
37
  end
38
38
  end
@@ -134,7 +134,7 @@ module Honeybadger
134
134
  elsif block_given?
135
135
  value = yield
136
136
  else
137
- value = attributes.delete(:value)
137
+ value = attributes.delete(:duration) || attributes.delete(:value)
138
138
  end
139
139
 
140
140
  Honeybadger::Gauge.register(registry, name, attributes).tap do |gauge|
@@ -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
@@ -3,6 +3,8 @@ require 'honeybadger/util/sql'
3
3
 
4
4
  module Honeybadger
5
5
  class NotificationSubscriber
6
+ include Honeybadger::InstrumentationHelper
7
+
6
8
  def start(name, id, payload)
7
9
  @start_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
8
10
  end
@@ -21,7 +23,29 @@ module Honeybadger
21
23
  end
22
24
 
23
25
  def record(name, payload)
24
- Honeybadger.event(name, payload)
26
+ if Honeybadger.config.load_plugin_insights_events?(:rails)
27
+ Honeybadger.event(name, payload)
28
+ end
29
+
30
+ if Honeybadger.config.load_plugin_insights_metrics?(:rails)
31
+ metric_source 'rails'
32
+ record_metrics(name, payload)
33
+ end
34
+ end
35
+
36
+ def record_metrics(name, payload)
37
+ case name
38
+ when 'sql.active_record'
39
+ gauge('duration.sql.active_record', value: payload[:duration], **payload.slice(:query))
40
+ when 'process_action.action_controller'
41
+ gauge('duration.process_action.action_controller', value: payload[:duration], **payload.slice(:method, :controller, :action, :format, :status))
42
+ gauge('db_runtime.process_action.action_controller', value: payload[:db_runtime], **payload.slice(:method, :controller, :action, :format, :status))
43
+ gauge('view_runtime.process_action.action_controller', value: payload[:view_runtime], **payload.slice(:method, :controller, :action, :format, :status))
44
+ when 'perform.active_job'
45
+ gauge('duration.perform.active_job', value: payload[:duration], **payload.slice(:job_class, :queue_name))
46
+ when /^cache_.*.active_support$/
47
+ gauge("duration.#{name}", value: payload[:duration], **payload.slice(:store, :key))
48
+ end
25
49
  end
26
50
 
27
51
  def process?(event, payload)
@@ -109,22 +133,6 @@ module Honeybadger
109
133
  end
110
134
  end
111
135
 
112
- class ActiveJobMetricsSubscriber < NotificationSubscriber
113
- include Honeybadger::InstrumentationHelper
114
-
115
- def format_payload(payload)
116
- {
117
- job_class: payload[:job].class.to_s,
118
- queue_name: payload[:job].queue_name
119
- }
120
- end
121
-
122
- def record(name, payload)
123
- metric_source 'active_job'
124
- histogram name, { bins: [30, 60, 120, 300, 1800, 3600, 21_600] }.merge(payload)
125
- end
126
- end
127
-
128
136
  class ActionMailerSubscriber < NotificationSubscriber
129
137
  end
130
138
 
@@ -55,7 +55,6 @@ module Honeybadger
55
55
 
56
56
  if config.load_plugin_insights?(:active_job)
57
57
  ::ActiveSupport::Notifications.subscribe(/(enqueue_at|enqueue|enqueue_retry|enqueue_all|perform|retry_stopped|discard)\.active_job/, Honeybadger::ActiveJobSubscriber.new)
58
- ::ActiveSupport::Notifications.subscribe('perform.active_job', Honeybadger::ActiveJobMetricsSubscriber.new)
59
58
  end
60
59
  end
61
60
  end
@@ -7,6 +7,12 @@ module Honeybadger
7
7
  module Plugins
8
8
  module Net
9
9
  module HTTP
10
+ @@hb_config = ::Honeybadger.config
11
+
12
+ def self.set_hb_config(config)
13
+ @@hb_config = config
14
+ end
15
+
10
16
  def request(request_data, body = nil, &block)
11
17
  return super unless started?
12
18
  return super if hb?
@@ -18,19 +24,26 @@ module Honeybadger
18
24
  status: response_data.code.to_i
19
25
  }.merge(parsed_uri_data(request_data))
20
26
 
21
- Honeybadger.event('request.net_http', context)
27
+ if @@hb_config.load_plugin_insights_events?(:net_http)
28
+ Honeybadger.event('request.net_http', context)
29
+ end
30
+
31
+ if @@hb_config.load_plugin_insights_metrics?(:net_http)
32
+ context.delete(:url)
33
+ Honeybadger.gauge('duration.request', context.merge(metric_source: 'net_http'))
34
+ end
22
35
  end[1] # return the response data only
23
36
  end
24
37
 
25
38
  def hb?
26
- address.to_s[/#{Honeybadger.config[:'connection.host'].to_s}/]
39
+ address.to_s[/#{@@hb_config[:'connection.host'].to_s}/]
27
40
  end
28
41
 
29
42
  def parsed_uri_data(request_data)
30
43
  uri = request_data.uri || build_uri(request_data)
31
44
  {}.tap do |uri_data|
32
45
  uri_data[:host] = uri.host
33
- uri_data[:url] = uri.to_s if Honeybadger.config[:'net_http.insights.full_url']
46
+ uri_data[:url] = uri.to_s if @@hb_config[:'net_http.insights.full_url']
34
47
  end
35
48
  end
36
49
 
@@ -43,6 +56,7 @@ module Honeybadger
43
56
  requirement { config.load_plugin_insights?(:net_http) }
44
57
 
45
58
  execution do
59
+ Honeybadger::Plugins::Net::HTTP.set_hb_config(config)
46
60
  ::Net::HTTP.send(:prepend, Honeybadger::Plugins::Net::HTTP)
47
61
  end
48
62
  end
@@ -38,10 +38,14 @@ module Honeybadger
38
38
  raise
39
39
  ensure
40
40
  context.merge!(duration: duration, status: status)
41
- Honeybadger.event('perform.sidekiq', context)
41
+ if Honeybadger.config.load_plugin_insights_events?(:sidekiq)
42
+ Honeybadger.event('perform.sidekiq', context)
43
+ end
42
44
 
43
- metric_source 'sidekiq'
44
- histogram 'perform', { bins: [30, 60, 120, 300, 1800, 3600, 21_600] }.merge(context.slice(:worker, :queue, :duration))
45
+ if Honeybadger.config.load_plugin_insights_metrics?(:sidekiq)
46
+ metric_source 'sidekiq'
47
+ gauge 'perform', context.slice(:worker, :queue, :duration)
48
+ end
45
49
  end
46
50
  end
47
51
  end
@@ -55,7 +59,9 @@ module Honeybadger
55
59
  queue: queue
56
60
  }
57
61
 
58
- Honeybadger.event('enqueue.sidekiq', context)
62
+ if Honeybadger.config.load_plugin_insights_events?(:sidekiq)
63
+ Honeybadger.event('enqueue.sidekiq', context)
64
+ end
59
65
 
60
66
  yield
61
67
  end
@@ -161,47 +167,67 @@ module Honeybadger
161
167
  end
162
168
  end
163
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
+
164
208
  collect do
165
209
  if config.cluster_collection?(:sidekiq) && (leader_checker.nil? || leader_checker.collect?)
166
- metric_source 'sidekiq'
167
-
168
- stats = ::Sidekiq::Stats.new
169
-
170
- gauge 'active_workers', ->{ stats.workers_size }
171
- gauge 'active_processes', ->{ stats.processes_size }
172
- gauge 'jobs_processed', ->{ stats.processed }
173
- gauge 'jobs_failed', ->{ stats.failed }
174
- gauge 'jobs_scheduled', ->{ stats.scheduled_size }
175
- gauge 'jobs_enqueued', ->{ stats.enqueued }
176
- gauge 'jobs_dead', ->{ stats.dead_size }
177
- gauge 'jobs_retry', ->{ stats.retry_size }
178
-
179
- ::Sidekiq::Queue.all.each do |queue|
180
- gauge 'queue_latency', { queue: queue.name }, ->{ (queue.latency * 1000).ceil }
181
- gauge 'queue_depth', { queue: queue.name }, ->{ queue.size }
182
- end
210
+ stats = collect_sidekiq_stats.call
183
211
 
184
- Hash.new(0).tap do |busy_counts|
185
- ::Sidekiq::Workers.new.each do |_pid, _tid, work|
186
- payload = work.respond_to?(:payload) ? work.payload : work["payload"]
187
- payload = JSON.parse(payload) if payload.is_a?(String)
188
- busy_counts[payload["queue"]] += 1
189
- end
190
- end.each do |queue_name, busy_count|
191
- 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']))
192
214
  end
193
215
 
194
- processes = ::Sidekiq::ProcessSet.new.to_enum(:each).to_a
195
- 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
196
222
 
197
- process_utilizations = processes.map do |process|
198
- next unless process["concurrency"].to_f > 0
199
- process["busy"] / process["concurrency"].to_f
200
- 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
201
228
 
202
- if process_utilizations.any?
203
- utilization = process_utilizations.sum / process_utilizations.length.to_f
204
- gauge 'utilization', ->{ utilization }
229
+ gauge 'capacity', value: stats[:capacity] if stats[:capacity]
230
+ gauge 'utilization', value: stats[:utilization] if stats[:utilization]
205
231
  end
206
232
  end
207
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.19.1'.freeze
3
+ VERSION = '5.22.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.19.1
4
+ version: 5.22.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-02 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
@@ -194,7 +194,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
194
  - !ruby/object:Gem::Version
195
195
  version: '0'
196
196
  requirements: []
197
- rubygems_version: 3.5.16
197
+ rubygems_version: 3.5.22
198
198
  signing_key:
199
199
  specification_version: 4
200
200
  summary: Error reports you can be happy about.