honeybadger 5.12.0 → 5.13.1

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: b3af996859bb642a3538e9d55e4a0e69bfa6221c7096f3d27c6729bd2ab7cb6b
4
- data.tar.gz: '06482049c556f1723d29aa07a392867760f58cc751abfc3cc9dd23e2f70702bb'
3
+ metadata.gz: 49f0e76e4da63a4398fcb71cc8fb153f5a854cd13a0d163924adc41473460401
4
+ data.tar.gz: f8adacb9335c3d42f3fa2991eb05453551cb546b1d439e504fff32d5c41703b5
5
5
  SHA512:
6
- metadata.gz: c6a336e2b8a4934e2a052a738f6b413cf6c9909daec09c465ac5d25ff7a324dfa89455e3103ea20231a8cf07e9ab65fe4bead675954cf5f5bf069def03c205f8
7
- data.tar.gz: 627d74ee326242416ab420d46690b2813f35a608347c2b2cf5f8e1ec3618d446edee4ed925cf2274caa97b65759f1d6584770fa8889bed077f35fa7ee5456c16
6
+ metadata.gz: e5022f0122bb51b147f6014e25f204250906b33c4e0e25c9699302e8e8a1bc97bad41497546f93c2d8cb9442de53d207309003699dfc55ae6190e14c2b110cff
7
+ data.tar.gz: dc28062240092dd136fb22ccd54b45882e850a6982f13225924606ff4e7805451e12a9516a9deba75ee83c71d0f2fcae400c70df2be191d8d5b1b402c8a71365
data/CHANGELOG.md CHANGED
@@ -1,6 +1,22 @@
1
1
  # Change Log
2
2
 
3
3
 
4
+ ## [5.13.1](https://github.com/honeybadger-io/honeybadger-ruby/compare/v5.13.0...v5.13.1) (2024-07-01)
5
+
6
+
7
+ ### Bug Fixes
8
+
9
+ * do not check for rails console ([#574](https://github.com/honeybadger-io/honeybadger-ruby/issues/574)) ([ba74af8](https://github.com/honeybadger-io/honeybadger-ruby/commit/ba74af8b55393ea0a96962085ea48c4376380be3))
10
+ * ignore content-less SQL statements ([#572](https://github.com/honeybadger-io/honeybadger-ruby/issues/572)) ([e7ecd36](https://github.com/honeybadger-io/honeybadger-ruby/commit/e7ecd36969922496e276a246406fe7d792de00e3))
11
+ * sanitize SQL when reporting SQL queries ([#571](https://github.com/honeybadger-io/honeybadger-ruby/issues/571)) ([40d4a79](https://github.com/honeybadger-io/honeybadger-ruby/commit/40d4a79a5c1f758fe49779e63697d56599537235))
12
+
13
+ ## [5.13.0](https://github.com/honeybadger-io/honeybadger-ruby/compare/v5.12.0...v5.13.0) (2024-06-18)
14
+
15
+
16
+ ### Features
17
+
18
+ * add before_event hook for intercepting events ([#567](https://github.com/honeybadger-io/honeybadger-ruby/issues/567)) ([2f86728](https://github.com/honeybadger-io/honeybadger-ruby/commit/2f8672814af3b12b3bfbc775de63b7a34b5087ad))
19
+
4
20
  ## [5.12.0](https://github.com/honeybadger-io/honeybadger-ruby/compare/v5.11.2...v5.12.0) (2024-06-17)
5
21
 
6
22
 
@@ -4,6 +4,7 @@ require 'honeybadger/version'
4
4
  require 'honeybadger/config'
5
5
  require 'honeybadger/context_manager'
6
6
  require 'honeybadger/notice'
7
+ require 'honeybadger/event'
7
8
  require 'honeybadger/plugin'
8
9
  require 'honeybadger/logging'
9
10
  require 'honeybadger/worker'
@@ -392,28 +393,21 @@ module Honeybadger
392
393
  def event(event_type, payload = {})
393
394
  init_events_worker
394
395
 
395
- ts = Time.now.utc.strftime("%FT%T.%LZ")
396
- merged = {ts: ts}
397
-
398
- if event_type.is_a?(String)
399
- merged[:event_type] = event_type
400
- else
401
- merged.merge!(Hash(event_type))
396
+ extra_payload = {}.tap do |p|
397
+ p[:request_id] = context_manager.get_request_id if context_manager.get_request_id
398
+ p[:hostname] = config[:hostname].to_s if config[:'events.attach_hostname']
402
399
  end
403
400
 
404
- if (request_id = context_manager.get_request_id)
405
- merged[:request_id] = request_id
406
- end
401
+ event = Event.new(event_type, extra_payload.merge(payload))
407
402
 
408
- if config[:'events.attach_hostname']
409
- merged[:hostname] = config[:hostname].to_s
403
+ config.before_event_hooks.each do |hook|
404
+ with_error_handling { hook.call(event) }
410
405
  end
411
406
 
412
- merged.merge!(Hash(payload))
413
-
414
- return if config.ignored_events.any? { |check| merged[:event_type]&.match?(check) }
407
+ return if config.ignored_events.any? { |check| event.event_type&.match?(check) }
408
+ return if event.halted?
415
409
 
416
- events_worker.push(merged)
410
+ events_worker.push(event.as_json)
417
411
  end
418
412
 
419
413
  # @api private
@@ -590,7 +584,7 @@ module Honeybadger
590
584
  def with_error_handling
591
585
  yield
592
586
  rescue => ex
593
- error { "Rescued an error in a before notify hook: #{ex.message}" }
587
+ error { "Rescued an error in a before hook: #{ex.message}" }
594
588
  end
595
589
 
596
590
  @instance = new(Config.new)
@@ -89,15 +89,27 @@ module Honeybadger
89
89
  def before_notify(action = nil, &block)
90
90
  hooks = Array(get(:before_notify)).dup
91
91
 
92
- if action && validate_before_action(action)
92
+ if action && validate_before_action(action, 'notify')
93
93
  hooks << action
94
- elsif block_given? && validate_before_action(block)
94
+ elsif block_given? && validate_before_action(block, 'notify')
95
95
  hooks << block
96
96
  end
97
97
 
98
98
  hash[:before_notify] = hooks
99
99
  end
100
100
 
101
+ def before_event(action = nil, &block)
102
+ hooks = Array(get(:before_event)).dup
103
+
104
+ if action && validate_before_action(action, 'event')
105
+ hooks << action
106
+ elsif block_given? && validate_before_action(block, 'event')
107
+ hooks << block
108
+ end
109
+
110
+ hash[:before_event] = hooks
111
+ end
112
+
101
113
  def backtrace_filter(&block)
102
114
  if block_given?
103
115
  logger.warn('DEPRECATED: backtrace_filter is deprecated. Please use before_notify instead. See https://docs.honeybadger.io/ruby/support/v4-upgrade#backtrace_filter')
@@ -127,17 +139,17 @@ module Honeybadger
127
139
 
128
140
  private
129
141
 
130
- def validate_before_action(action)
142
+ def validate_before_action(action, type)
131
143
  if !action.respond_to?(:call)
132
144
  logger.warn(
133
- 'You attempted to add a before notify hook that does not respond ' \
145
+ "You attempted to add a before #{type} hook that does not respond " \
134
146
  'to #call. We are discarding this hook so your intended behavior ' \
135
147
  'will not occur.'
136
148
  )
137
149
  false
138
150
  elsif action.arity != 1
139
151
  logger.warn(
140
- 'You attempted to add a before notify hook that has an arity ' \
152
+ "You attempted to add a before #{type} hook that has an arity " \
141
153
  'other than one. We are discarding this hook so your intended ' \
142
154
  'behavior will not occur.'
143
155
  )
@@ -92,6 +92,10 @@ module Honeybadger
92
92
  (ruby[:before_notify] || []).clone
93
93
  end
94
94
 
95
+ def before_event_hooks
96
+ (ruby[:before_event] || []).clone
97
+ end
98
+
95
99
  def exception_filter(&block)
96
100
  if block_given?
97
101
  warn('DEPRECATED: exception_filter is deprecated. Please use before_notify instead. See https://docs.honeybadger.io/ruby/support/v4-upgrade#exception_filter')
@@ -273,7 +277,6 @@ module Honeybadger
273
277
  end
274
278
 
275
279
  def insights_enabled?
276
- return false if defined?(::Rails.application) && ::Rails.const_defined?("Console")
277
280
  !!self[:'insights.enabled']
278
281
  end
279
282
 
@@ -0,0 +1,56 @@
1
+ require 'forwardable'
2
+
3
+ module Honeybadger
4
+ class Event
5
+ extend Forwardable
6
+
7
+ # The timestamp of the event
8
+ attr_reader :ts
9
+
10
+ # The event_type of the event
11
+ attr_reader :event_type
12
+
13
+ # The payload data of the event
14
+ attr_reader :payload
15
+
16
+ def_delegator :payload, :[]
17
+
18
+ # @api private
19
+ def initialize(event_type_or_payload, payload={})
20
+ if event_type_or_payload.is_a?(String)
21
+ @event_type = event_type_or_payload
22
+ @payload = payload
23
+ elsif event_type_or_payload.is_a?(Hash)
24
+ @event_type = event_type_or_payload[:event_type] || event_type_or_payload["event_type"]
25
+ @payload = event_type_or_payload
26
+ end
27
+
28
+ @ts = payload[:ts] || Time.now.utc.strftime("%FT%T.%LZ")
29
+ @halted = false
30
+ end
31
+
32
+ # Halts the event and the before_event callback chain.
33
+ #
34
+ # Returns nothing.
35
+ def halt!
36
+ @halted ||= true
37
+ end
38
+
39
+ # @api private
40
+ # Determines if this event will be discarded.
41
+ def halted?
42
+ !!@halted
43
+ end
44
+
45
+ # @api private
46
+ # Template used to create JSON payload.
47
+ #
48
+ # @return [Hash] JSON representation of the event.
49
+ def as_json(*args)
50
+ payload.tap do |p|
51
+ p[:ts] = ts
52
+ p[:event_type] = event_type if event_type
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,4 +1,5 @@
1
1
  require 'honeybadger/instrumentation_helper'
2
+ require 'honeybadger/util/sql'
2
3
 
3
4
  module Honeybadger
4
5
  class NotificationSubscriber
@@ -9,7 +10,7 @@ module Honeybadger
9
10
  def finish(name, id, payload)
10
11
  @finish_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
11
12
 
12
- return unless process?(name)
13
+ return unless process?(name, payload)
13
14
 
14
15
  payload = {
15
16
  instrumenter_id: id,
@@ -23,7 +24,7 @@ module Honeybadger
23
24
  Honeybadger.event(name, payload)
24
25
  end
25
26
 
26
- def process?(event)
27
+ def process?(event, payload)
27
28
  true
28
29
  end
29
30
 
@@ -58,10 +59,16 @@ module Honeybadger
58
59
  class ActiveRecordSubscriber < NotificationSubscriber
59
60
  def format_payload(payload)
60
61
  {
61
- query: payload[:sql].to_s.gsub(/\s+/, ' ').strip,
62
+ query: Util::SQL.obfuscate(payload[:sql], payload[:connection].adapter_name),
62
63
  async: payload[:async]
63
64
  }
64
65
  end
66
+
67
+ def process?(event, payload)
68
+ return false if payload[:name] == "SCHEMA"
69
+ return false if payload[:sql]&.match?(/^(begin|commit)( transaction)?$/i)
70
+ true
71
+ end
65
72
  end
66
73
 
67
74
  class ActiveJobSubscriber < NotificationSubscriber
@@ -71,16 +71,18 @@ module Honeybadger
71
71
  end
72
72
 
73
73
  Plugin.register :rails do
74
- requirement { config.load_plugin_insights?(:rails_metrics) && defined?(::Rails.application) && ::Rails.application }
74
+ requirement { defined?(::Rails.application) && ::Rails.application }
75
75
 
76
76
  execution do
77
- ::ActiveSupport::Notifications.subscribe(/(process_action|send_file|redirect_to|halted_callback|unpermitted_parameters)\.action_controller/, Honeybadger::ActionControllerSubscriber.new)
78
- ::ActiveSupport::Notifications.subscribe(/(write_fragment|read_fragment|expire_fragment|exist_fragment\?)\.action_controller/, Honeybadger::ActionControllerCacheSubscriber.new)
79
- ::ActiveSupport::Notifications.subscribe(/cache_(read|read_multi|generate|fetch_hit|write|write_multi|increment|decrement|delete|delete_multi|cleanup|prune|exist\?)\.active_support/, Honeybadger::ActiveSupportCacheSubscriber.new)
80
- ::ActiveSupport::Notifications.subscribe(/^render_(template|partial|collection)\.action_view/, Honeybadger::ActionViewSubscriber.new)
81
- ::ActiveSupport::Notifications.subscribe("sql.active_record", Honeybadger::ActiveRecordSubscriber.new)
82
- ::ActiveSupport::Notifications.subscribe("process.action_mailer", Honeybadger::ActionMailerSubscriber.new)
83
- ::ActiveSupport::Notifications.subscribe(/(service_upload|service_download)\.active_storage/, Honeybadger::ActiveStorageSubscriber.new)
77
+ if config.load_plugin_insights?(:rails)
78
+ ::ActiveSupport::Notifications.subscribe(/(process_action|send_file|redirect_to|halted_callback|unpermitted_parameters)\.action_controller/, Honeybadger::ActionControllerSubscriber.new)
79
+ ::ActiveSupport::Notifications.subscribe(/(write_fragment|read_fragment|expire_fragment|exist_fragment\?)\.action_controller/, Honeybadger::ActionControllerCacheSubscriber.new)
80
+ ::ActiveSupport::Notifications.subscribe(/cache_(read|read_multi|generate|fetch_hit|write|write_multi|increment|decrement|delete|delete_multi|cleanup|prune|exist\?)\.active_support/, Honeybadger::ActiveSupportCacheSubscriber.new)
81
+ ::ActiveSupport::Notifications.subscribe(/^render_(template|partial|collection)\.action_view/, Honeybadger::ActionViewSubscriber.new)
82
+ ::ActiveSupport::Notifications.subscribe("sql.active_record", Honeybadger::ActiveRecordSubscriber.new)
83
+ ::ActiveSupport::Notifications.subscribe("process.action_mailer", Honeybadger::ActionMailerSubscriber.new)
84
+ ::ActiveSupport::Notifications.subscribe(/(service_upload|service_download)\.active_storage/, Honeybadger::ActiveStorageSubscriber.new)
85
+ end
84
86
  end
85
87
  end
86
88
  end
@@ -1,32 +1,29 @@
1
1
  module Honeybadger
2
2
  module Util
3
3
  class SQL
4
- EscapedQuotes = /(\\"|\\')/.freeze
5
- SQuotedData = /'(?:[^']|'')*'/.freeze
6
- DQuotedData = /"(?:[^"]|"")*"/.freeze
7
- NumericData = /\b\d+\b/.freeze
8
- Newline = /\n/.freeze
9
- Replacement = "?".freeze
10
- EmptyReplacement = "".freeze
11
- DoubleQuoters = /(postgres|sqlite|postgis)/.freeze
4
+ ESCAPE_QUOTES = /(\\"|\\')/
5
+ SQUOTE_DATA = /'(?:[^']|'')*'/
6
+ DQUOTE_DATA = /"(?:[^"]|"")*"/
7
+ NUMBER_DATA = /\b\d+\b/
8
+ DOUBLE_QUOTERS = /(postgres|sqlite|postgis)/i
12
9
 
13
10
  def self.obfuscate(sql, adapter)
14
- force_utf_8(sql.dup).tap do |s|
15
- s.gsub!(EscapedQuotes, EmptyReplacement)
16
- s.gsub!(SQuotedData, Replacement)
17
- s.gsub!(DQuotedData, Replacement) if adapter =~ DoubleQuoters
18
- s.gsub!(NumericData, Replacement)
19
- s.gsub!(Newline, EmptyReplacement)
20
- s.squeeze!(' ')
11
+ force_utf_8(sql.to_s.dup).tap do |s|
12
+ s.gsub!(/\s+/, " ")
13
+ s.gsub!(ESCAPE_QUOTES, "".freeze)
14
+ s.gsub!(SQUOTE_DATA, "'?'".freeze)
15
+ s.gsub!(DQUOTE_DATA, '"?"'.freeze) unless adapter.to_s.match?(DOUBLE_QUOTERS)
16
+ s.gsub!(NUMBER_DATA, "?".freeze)
17
+ s.strip!
21
18
  end
22
19
  end
23
20
 
24
21
  def self.force_utf_8(string)
25
22
  string.encode(
26
- Encoding.find('UTF-8'),
27
- invalid: :replace,
28
- undef: :replace,
29
- replace: ''
23
+ Encoding.find("UTF-8"),
24
+ invalid: :replace,
25
+ undef: :replace,
26
+ replace: ""
30
27
  )
31
28
  end
32
29
  end
@@ -1,4 +1,4 @@
1
1
  module Honeybadger
2
2
  # The current String Honeybadger version.
3
- VERSION = '5.12.0'.freeze
3
+ VERSION = '5.13.1'.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.12.0
4
+ version: 5.13.1
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-06-17 00:00:00.000000000 Z
11
+ date: 2024-07-01 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Make managing application errors a more pleasant experience.
14
14
  email:
@@ -56,6 +56,7 @@ files:
56
56
  - lib/honeybadger/context_manager.rb
57
57
  - lib/honeybadger/conversions.rb
58
58
  - lib/honeybadger/counter.rb
59
+ - lib/honeybadger/event.rb
59
60
  - lib/honeybadger/events_worker.rb
60
61
  - lib/honeybadger/gauge.rb
61
62
  - lib/honeybadger/histogram.rb