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 +4 -4
- data/CHANGELOG.md +16 -0
- data/lib/honeybadger/agent.rb +11 -17
- data/lib/honeybadger/config/ruby.rb +17 -5
- data/lib/honeybadger/config.rb +4 -1
- data/lib/honeybadger/event.rb +56 -0
- data/lib/honeybadger/notification_subscriber.rb +10 -3
- data/lib/honeybadger/plugins/rails.rb +10 -8
- data/lib/honeybadger/util/sql.rb +16 -19
- data/lib/honeybadger/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49f0e76e4da63a4398fcb71cc8fb153f5a854cd13a0d163924adc41473460401
|
4
|
+
data.tar.gz: f8adacb9335c3d42f3fa2991eb05453551cb546b1d439e504fff32d5c41703b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
|
data/lib/honeybadger/agent.rb
CHANGED
@@ -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
|
-
|
396
|
-
|
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
|
-
|
405
|
-
merged[:request_id] = request_id
|
406
|
-
end
|
401
|
+
event = Event.new(event_type, extra_payload.merge(payload))
|
407
402
|
|
408
|
-
|
409
|
-
|
403
|
+
config.before_event_hooks.each do |hook|
|
404
|
+
with_error_handling { hook.call(event) }
|
410
405
|
end
|
411
406
|
|
412
|
-
|
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(
|
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
|
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
|
-
|
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
|
-
|
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
|
)
|
data/lib/honeybadger/config.rb
CHANGED
@@ -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].
|
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 {
|
74
|
+
requirement { defined?(::Rails.application) && ::Rails.application }
|
75
75
|
|
76
76
|
execution do
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
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
|
data/lib/honeybadger/util/sql.rb
CHANGED
@@ -1,32 +1,29 @@
|
|
1
1
|
module Honeybadger
|
2
2
|
module Util
|
3
3
|
class SQL
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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!(
|
16
|
-
s.gsub!(
|
17
|
-
s.gsub!(
|
18
|
-
s.gsub!(
|
19
|
-
s.gsub!(
|
20
|
-
s.
|
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(
|
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
|
data/lib/honeybadger/version.rb
CHANGED
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.
|
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-
|
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
|