airbrake-ruby 4.1.0 → 5.0.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 +5 -5
- data/lib/airbrake-ruby/async_sender.rb +22 -96
- data/lib/airbrake-ruby/backtrace.rb +8 -7
- data/lib/airbrake-ruby/benchmark.rb +39 -0
- data/lib/airbrake-ruby/code_hunk.rb +1 -1
- data/lib/airbrake-ruby/config/processor.rb +84 -0
- data/lib/airbrake-ruby/config/validator.rb +9 -3
- data/lib/airbrake-ruby/config.rb +76 -20
- data/lib/airbrake-ruby/deploy_notifier.rb +1 -1
- data/lib/airbrake-ruby/file_cache.rb +6 -0
- data/lib/airbrake-ruby/filter_chain.rb +16 -1
- data/lib/airbrake-ruby/filters/dependency_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +2 -2
- data/lib/airbrake-ruby/filters/gem_root_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +5 -5
- data/lib/airbrake-ruby/filters/git_repository_filter.rb +3 -0
- data/lib/airbrake-ruby/filters/git_revision_filter.rb +2 -0
- data/lib/airbrake-ruby/filters/{keys_whitelist.rb → keys_allowlist.rb} +3 -3
- data/lib/airbrake-ruby/filters/{keys_blacklist.rb → keys_blocklist.rb} +3 -3
- data/lib/airbrake-ruby/filters/keys_filter.rb +39 -20
- data/lib/airbrake-ruby/filters/root_directory_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/sql_filter.rb +30 -6
- data/lib/airbrake-ruby/filters/system_exit_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/thread_filter.rb +4 -2
- data/lib/airbrake-ruby/grouppable.rb +12 -0
- data/lib/airbrake-ruby/ignorable.rb +1 -0
- data/lib/airbrake-ruby/inspectable.rb +2 -2
- data/lib/airbrake-ruby/loggable.rb +2 -2
- data/lib/airbrake-ruby/mergeable.rb +12 -0
- data/lib/airbrake-ruby/monotonic_time.rb +48 -0
- data/lib/airbrake-ruby/notice.rb +10 -20
- data/lib/airbrake-ruby/notice_notifier.rb +23 -42
- data/lib/airbrake-ruby/performance_breakdown.rb +52 -0
- data/lib/airbrake-ruby/performance_notifier.rb +126 -49
- data/lib/airbrake-ruby/promise.rb +1 -0
- data/lib/airbrake-ruby/query.rb +26 -11
- data/lib/airbrake-ruby/queue.rb +65 -0
- data/lib/airbrake-ruby/remote_settings/settings_data.rb +120 -0
- data/lib/airbrake-ruby/remote_settings.rb +145 -0
- data/lib/airbrake-ruby/request.rb +20 -6
- data/lib/airbrake-ruby/stashable.rb +15 -0
- data/lib/airbrake-ruby/stat.rb +34 -24
- data/lib/airbrake-ruby/sync_sender.rb +3 -2
- data/lib/airbrake-ruby/tdigest.rb +43 -58
- data/lib/airbrake-ruby/thread_pool.rb +138 -0
- data/lib/airbrake-ruby/timed_trace.rb +58 -0
- data/lib/airbrake-ruby/truncator.rb +10 -4
- data/lib/airbrake-ruby/version.rb +11 -1
- data/lib/airbrake-ruby.rb +219 -53
- data/spec/airbrake_spec.rb +428 -9
- data/spec/async_sender_spec.rb +26 -110
- data/spec/backtrace_spec.rb +44 -44
- data/spec/benchmark_spec.rb +33 -0
- data/spec/code_hunk_spec.rb +11 -11
- data/spec/config/processor_spec.rb +209 -0
- data/spec/config/validator_spec.rb +23 -6
- data/spec/config_spec.rb +77 -7
- data/spec/deploy_notifier_spec.rb +2 -2
- data/spec/{file_cache.rb → file_cache_spec.rb} +2 -4
- data/spec/filter_chain_spec.rb +28 -1
- data/spec/filters/dependency_filter_spec.rb +1 -1
- data/spec/filters/gem_root_filter_spec.rb +9 -9
- data/spec/filters/git_last_checkout_filter_spec.rb +21 -4
- data/spec/filters/git_repository_filter.rb +1 -1
- data/spec/filters/git_revision_filter_spec.rb +13 -11
- data/spec/filters/{keys_whitelist_spec.rb → keys_allowlist_spec.rb} +29 -28
- data/spec/filters/{keys_blacklist_spec.rb → keys_blocklist_spec.rb} +39 -29
- data/spec/filters/root_directory_filter_spec.rb +9 -9
- data/spec/filters/sql_filter_spec.rb +110 -55
- data/spec/filters/system_exit_filter_spec.rb +1 -1
- data/spec/filters/thread_filter_spec.rb +33 -31
- data/spec/fixtures/project_root/code.rb +9 -9
- data/spec/loggable_spec.rb +17 -0
- data/spec/monotonic_time_spec.rb +23 -0
- data/spec/{notice_notifier_spec → notice_notifier}/options_spec.rb +19 -21
- data/spec/notice_notifier_spec.rb +20 -80
- data/spec/notice_spec.rb +9 -11
- data/spec/performance_breakdown_spec.rb +11 -0
- data/spec/performance_notifier_spec.rb +360 -85
- data/spec/query_spec.rb +11 -0
- data/spec/queue_spec.rb +18 -0
- data/spec/remote_settings/settings_data_spec.rb +365 -0
- data/spec/remote_settings_spec.rb +230 -0
- data/spec/request_spec.rb +9 -0
- data/spec/response_spec.rb +8 -8
- data/spec/spec_helper.rb +9 -13
- data/spec/stashable_spec.rb +23 -0
- data/spec/stat_spec.rb +17 -15
- data/spec/sync_sender_spec.rb +14 -12
- data/spec/tdigest_spec.rb +6 -6
- data/spec/thread_pool_spec.rb +187 -0
- data/spec/timed_trace_spec.rb +125 -0
- data/spec/truncator_spec.rb +12 -12
- metadata +55 -18
@@ -0,0 +1,58 @@
|
|
1
|
+
module Airbrake
|
2
|
+
# TimedTrace represents a chunk of code performance of which was measured and
|
3
|
+
# stored under a label. The chunk is called a "span".
|
4
|
+
#
|
5
|
+
# @example
|
6
|
+
# timed_trace = TimedTrace.new
|
7
|
+
# timed_trace.span('http request') do
|
8
|
+
# http.get('example.com')
|
9
|
+
# end
|
10
|
+
# timed_trace.spans #=> { 'http request' => 0.123 }
|
11
|
+
#
|
12
|
+
# @api public
|
13
|
+
# @since v4.3.0
|
14
|
+
class TimedTrace
|
15
|
+
# @param [String] label
|
16
|
+
# @return [Airbrake::TimedTrace]
|
17
|
+
def self.span(label, &block)
|
18
|
+
new.tap { |timed_trace| timed_trace.span(label, &block) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@spans = {}
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param [String] label
|
26
|
+
# @return [Boolean]
|
27
|
+
def span(label)
|
28
|
+
start_span(label)
|
29
|
+
yield
|
30
|
+
stop_span(label)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param [String] label
|
34
|
+
# @return [Boolean]
|
35
|
+
def start_span(label)
|
36
|
+
return false if @spans.key?(label)
|
37
|
+
|
38
|
+
@spans[label] = Airbrake::Benchmark.new
|
39
|
+
true
|
40
|
+
end
|
41
|
+
|
42
|
+
# @param [String] label
|
43
|
+
# @return [Boolean]
|
44
|
+
def stop_span(label)
|
45
|
+
return false unless @spans.key?(label)
|
46
|
+
|
47
|
+
@spans[label].stop
|
48
|
+
true
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return [Hash<String=>Float>]
|
52
|
+
def spans
|
53
|
+
@spans.each_with_object({}) do |(label, benchmark), new_spans|
|
54
|
+
new_spans[label] = benchmark.duration
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -12,6 +12,10 @@ module Airbrake
|
|
12
12
|
# strings with +ENCODING_OPTIONS+
|
13
13
|
TEMP_ENCODING = 'utf-16'.freeze
|
14
14
|
|
15
|
+
# @return [Array<Encoding>] encodings that are eligible for fixing invalid
|
16
|
+
# characters
|
17
|
+
SUPPORTED_ENCODINGS = [Encoding::UTF_8, Encoding::ASCII].freeze
|
18
|
+
|
15
19
|
# @return [String] what to append when something is a circular reference
|
16
20
|
CIRCULAR = '[Circular]'.freeze
|
17
21
|
|
@@ -35,6 +39,7 @@ module Airbrake
|
|
35
39
|
def truncate(object, seen = Set.new)
|
36
40
|
if seen.include?(object.object_id)
|
37
41
|
return CIRCULAR if CIRCULAR_TYPES.any? { |t| object.is_a?(t) }
|
42
|
+
|
38
43
|
return object
|
39
44
|
end
|
40
45
|
truncate_object(object, seen << object.object_id)
|
@@ -63,6 +68,7 @@ module Airbrake
|
|
63
68
|
def truncate_string(str)
|
64
69
|
fixed_str = replace_invalid_characters(str)
|
65
70
|
return fixed_str if fixed_str.length <= @max_size
|
71
|
+
|
66
72
|
(fixed_str.slice(0, @max_size) + TRUNCATED).freeze
|
67
73
|
end
|
68
74
|
|
@@ -76,6 +82,7 @@ module Airbrake
|
|
76
82
|
truncated_hash = {}
|
77
83
|
hash.each_with_index do |(key, val), idx|
|
78
84
|
break if idx + 1 > @max_size
|
85
|
+
|
79
86
|
truncated_hash[key] = truncate(val, seen)
|
80
87
|
end
|
81
88
|
|
@@ -103,13 +110,12 @@ module Airbrake
|
|
103
110
|
# @return [String] a UTF-8 encoded string
|
104
111
|
# @see https://github.com/flori/json/commit/3e158410e81f94dbbc3da6b7b35f4f64983aa4e3
|
105
112
|
def replace_invalid_characters(str)
|
106
|
-
|
107
|
-
utf8_string = (encoding == Encoding::UTF_8 || encoding == Encoding::ASCII)
|
113
|
+
utf8_string = SUPPORTED_ENCODINGS.include?(str.encoding)
|
108
114
|
return str if utf8_string && str.valid_encoding?
|
109
115
|
|
110
116
|
temp_str = str.dup
|
111
|
-
temp_str.encode!(TEMP_ENCODING, ENCODING_OPTIONS) if utf8_string
|
112
|
-
temp_str.encode!('utf-8', ENCODING_OPTIONS)
|
117
|
+
temp_str.encode!(TEMP_ENCODING, **ENCODING_OPTIONS) if utf8_string
|
118
|
+
temp_str.encode!('utf-8', **ENCODING_OPTIONS)
|
113
119
|
end
|
114
120
|
end
|
115
121
|
end
|
@@ -2,5 +2,15 @@
|
|
2
2
|
# More information: http://semver.org/
|
3
3
|
module Airbrake
|
4
4
|
# @return [String] the library version
|
5
|
-
|
5
|
+
# @api public
|
6
|
+
AIRBRAKE_RUBY_VERSION = '5.0.0'.freeze
|
7
|
+
|
8
|
+
# @return [Hash{Symbol=>String}] the information about the notifier library
|
9
|
+
# @since 5.0.0
|
10
|
+
# @api public
|
11
|
+
NOTIFIER_INFO = {
|
12
|
+
name: 'airbrake-ruby'.freeze,
|
13
|
+
version: Airbrake::AIRBRAKE_RUBY_VERSION,
|
14
|
+
url: 'https://github.com/airbrake/airbrake-ruby'.freeze,
|
15
|
+
}.freeze
|
6
16
|
end
|
data/lib/airbrake-ruby.rb
CHANGED
@@ -1,16 +1,22 @@
|
|
1
1
|
require 'net/https'
|
2
2
|
require 'logger'
|
3
3
|
require 'json'
|
4
|
-
require 'thread'
|
5
4
|
require 'set'
|
6
5
|
require 'socket'
|
7
6
|
require 'time'
|
8
7
|
|
9
8
|
require 'airbrake-ruby/version'
|
10
9
|
require 'airbrake-ruby/loggable'
|
10
|
+
require 'airbrake-ruby/stashable'
|
11
|
+
require 'airbrake-ruby/mergeable'
|
12
|
+
require 'airbrake-ruby/grouppable'
|
11
13
|
require 'airbrake-ruby/config'
|
12
14
|
require 'airbrake-ruby/config/validator'
|
15
|
+
require 'airbrake-ruby/config/processor'
|
16
|
+
require 'airbrake-ruby/remote_settings/settings_data'
|
17
|
+
require 'airbrake-ruby/remote_settings'
|
13
18
|
require 'airbrake-ruby/promise'
|
19
|
+
require 'airbrake-ruby/thread_pool'
|
14
20
|
require 'airbrake-ruby/sync_sender'
|
15
21
|
require 'airbrake-ruby/async_sender'
|
16
22
|
require 'airbrake-ruby/response'
|
@@ -21,8 +27,8 @@ require 'airbrake-ruby/notice'
|
|
21
27
|
require 'airbrake-ruby/backtrace'
|
22
28
|
require 'airbrake-ruby/truncator'
|
23
29
|
require 'airbrake-ruby/filters/keys_filter'
|
24
|
-
require 'airbrake-ruby/filters/
|
25
|
-
require 'airbrake-ruby/filters/
|
30
|
+
require 'airbrake-ruby/filters/keys_allowlist'
|
31
|
+
require 'airbrake-ruby/filters/keys_blocklist'
|
26
32
|
require 'airbrake-ruby/filters/gem_root_filter'
|
27
33
|
require 'airbrake-ruby/filters/system_exit_filter'
|
28
34
|
require 'airbrake-ruby/filters/root_directory_filter'
|
@@ -46,6 +52,11 @@ require 'airbrake-ruby/time_truncate'
|
|
46
52
|
require 'airbrake-ruby/tdigest'
|
47
53
|
require 'airbrake-ruby/query'
|
48
54
|
require 'airbrake-ruby/request'
|
55
|
+
require 'airbrake-ruby/performance_breakdown'
|
56
|
+
require 'airbrake-ruby/benchmark'
|
57
|
+
require 'airbrake-ruby/monotonic_time'
|
58
|
+
require 'airbrake-ruby/timed_trace'
|
59
|
+
require 'airbrake-ruby/queue'
|
49
60
|
|
50
61
|
# Airbrake is a thin wrapper around instances of the notifier classes (such as
|
51
62
|
# notice, performance & deploy notifiers). It creates a way to access them via a
|
@@ -63,6 +74,7 @@ require 'airbrake-ruby/request'
|
|
63
74
|
#
|
64
75
|
# @since v1.0.0
|
65
76
|
# @api public
|
77
|
+
# rubocop:disable Metrics/ModuleLength
|
66
78
|
module Airbrake
|
67
79
|
# The general error that this library uses when it wants to raise.
|
68
80
|
Error = Class.new(StandardError)
|
@@ -74,14 +86,26 @@ module Airbrake
|
|
74
86
|
# special cases where we need to work around older implementations
|
75
87
|
JRUBY = (RUBY_ENGINE == 'jruby')
|
76
88
|
|
77
|
-
#
|
78
|
-
#
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
89
|
+
# @return [Boolean] true if this Ruby supports safe levels and tainting,
|
90
|
+
# to guard against using deprecated or unsupported features.
|
91
|
+
HAS_SAFE_LEVEL = (
|
92
|
+
RUBY_ENGINE == 'ruby' &&
|
93
|
+
Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7')
|
94
|
+
)
|
83
95
|
|
84
96
|
class << self
|
97
|
+
# @since v4.2.3
|
98
|
+
# @api private
|
99
|
+
attr_writer :performance_notifier
|
100
|
+
|
101
|
+
# @since v4.2.3
|
102
|
+
# @api private
|
103
|
+
attr_writer :notice_notifier
|
104
|
+
|
105
|
+
# @since v4.2.3
|
106
|
+
# @api private
|
107
|
+
attr_writer :deploy_notifier
|
108
|
+
|
85
109
|
# Configures the Airbrake notifier.
|
86
110
|
#
|
87
111
|
# @example
|
@@ -90,28 +114,45 @@ module Airbrake
|
|
90
114
|
# c.project_key = 'fd04e13d806a90f96614ad8e529b2822'
|
91
115
|
# end
|
92
116
|
#
|
93
|
-
# @yield [config]
|
117
|
+
# @yield [config]
|
94
118
|
# @yieldparam config [Airbrake::Config]
|
95
119
|
# @return [void]
|
96
|
-
# @raise [Airbrake::Error] when trying to reconfigure already
|
97
|
-
# existing notifier
|
98
|
-
# @raise [Airbrake::Error] when either +project_id+ or +project_key+
|
99
|
-
# is missing (or both)
|
100
|
-
# @note There's no way to read config values outside of this library
|
101
120
|
def configure
|
102
121
|
yield config = Airbrake::Config.instance
|
122
|
+
Airbrake::Loggable.instance = config.logger
|
103
123
|
|
104
|
-
|
105
|
-
raise Airbrake::Error, result.value['error']
|
106
|
-
end
|
124
|
+
config_processor = Airbrake::Config::Processor.new(config)
|
107
125
|
|
108
|
-
|
126
|
+
config_processor.process_blocklist(notice_notifier)
|
127
|
+
config_processor.process_allowlist(notice_notifier)
|
128
|
+
|
129
|
+
@remote_settings ||= config_processor.process_remote_configuration
|
130
|
+
|
131
|
+
config_processor.add_filters(notice_notifier)
|
132
|
+
end
|
133
|
+
|
134
|
+
# @since v4.2.3
|
135
|
+
# @api private
|
136
|
+
def performance_notifier
|
137
|
+
@performance_notifier ||= PerformanceNotifier.new
|
138
|
+
end
|
139
|
+
|
140
|
+
# @since v4.2.3
|
141
|
+
# @api private
|
142
|
+
def notice_notifier
|
143
|
+
@notice_notifier ||= NoticeNotifier.new
|
144
|
+
end
|
145
|
+
|
146
|
+
# @since v4.2.3
|
147
|
+
# @api private
|
148
|
+
def deploy_notifier
|
149
|
+
@deploy_notifier ||= DeployNotifier.new
|
109
150
|
end
|
110
151
|
|
111
152
|
# @return [Boolean] true if the notifier was configured, false otherwise
|
112
153
|
# @since v2.3.0
|
113
154
|
def configured?
|
114
|
-
@notice_notifier.configured?
|
155
|
+
@notice_notifier && @notice_notifier.configured?
|
115
156
|
end
|
116
157
|
|
117
158
|
# Sends an exception to Airbrake asynchronously.
|
@@ -136,7 +177,7 @@ module Airbrake
|
|
136
177
|
# @return [Airbrake::Promise]
|
137
178
|
# @see .notify_sync
|
138
179
|
def notify(exception, params = {}, &block)
|
139
|
-
|
180
|
+
notice_notifier.notify(exception, params, &block)
|
140
181
|
end
|
141
182
|
|
142
183
|
# Sends an exception to Airbrake synchronously.
|
@@ -156,7 +197,7 @@ module Airbrake
|
|
156
197
|
# @return [Airbrake::Promise] the reponse from the server
|
157
198
|
# @see .notify
|
158
199
|
def notify_sync(exception, params = {}, &block)
|
159
|
-
|
200
|
+
notice_notifier.notify_sync(exception, params, &block)
|
160
201
|
end
|
161
202
|
|
162
203
|
# Runs a callback before {.notify} or {.notify_sync} kicks in. This is
|
@@ -184,7 +225,7 @@ module Airbrake
|
|
184
225
|
# @yieldreturn [void]
|
185
226
|
# @return [void]
|
186
227
|
def add_filter(filter = nil, &block)
|
187
|
-
|
228
|
+
notice_notifier.add_filter(filter, &block)
|
188
229
|
end
|
189
230
|
|
190
231
|
# Deletes a filter added via {Airbrake#add_filter}.
|
@@ -201,7 +242,7 @@ module Airbrake
|
|
201
242
|
# @since v3.1.0
|
202
243
|
# @note This method cannot delete filters assigned via the Proc form.
|
203
244
|
def delete_filter(filter_class)
|
204
|
-
|
245
|
+
notice_notifier.delete_filter(filter_class)
|
205
246
|
end
|
206
247
|
|
207
248
|
# Builds an Airbrake notice. This is useful, if you want to add or modify a
|
@@ -219,7 +260,7 @@ module Airbrake
|
|
219
260
|
# @return [Airbrake::Notice] the notice built with help of the given
|
220
261
|
# arguments
|
221
262
|
def build_notice(exception, params = {})
|
222
|
-
|
263
|
+
notice_notifier.build_notice(exception, params)
|
223
264
|
end
|
224
265
|
|
225
266
|
# Makes the notice notifier a no-op, which means you cannot use the
|
@@ -230,10 +271,24 @@ module Airbrake
|
|
230
271
|
# Airbrake.close
|
231
272
|
# Airbrake.notify('App crashed!') #=> raises Airbrake::Error
|
232
273
|
#
|
233
|
-
# @return [
|
274
|
+
# @return [nil]
|
275
|
+
# rubocop:disable Style/IfUnlessModifier, Metrics/CyclomaticComplexity
|
234
276
|
def close
|
235
|
-
@notice_notifier
|
277
|
+
if defined?(@notice_notifier) && @notice_notifier
|
278
|
+
@notice_notifier.close
|
279
|
+
end
|
280
|
+
|
281
|
+
if defined?(@performance_notifier) && @performance_notifier
|
282
|
+
@performance_notifier.close
|
283
|
+
end
|
284
|
+
|
285
|
+
if defined?(@remote_settings) && @remote_settings
|
286
|
+
@remote_settings.stop_polling
|
287
|
+
end
|
288
|
+
|
289
|
+
nil
|
236
290
|
end
|
291
|
+
# rubocop:enable Style/IfUnlessModifier, Metrics/CyclomaticComplexity
|
237
292
|
|
238
293
|
# Pings the Airbrake Deploy API endpoint about the occurred deploy.
|
239
294
|
#
|
@@ -245,7 +300,7 @@ module Airbrake
|
|
245
300
|
# @option deploy_info [Symbol] :version
|
246
301
|
# @return [void]
|
247
302
|
def notify_deploy(deploy_info)
|
248
|
-
|
303
|
+
deploy_notifier.notify(deploy_info)
|
249
304
|
end
|
250
305
|
|
251
306
|
# Merges +context+ with the current context.
|
@@ -293,12 +348,11 @@ module Airbrake
|
|
293
348
|
# @param [Hash{Symbol=>Object}] context
|
294
349
|
# @return [void]
|
295
350
|
def merge_context(context)
|
296
|
-
|
351
|
+
notice_notifier.merge_context(context)
|
297
352
|
end
|
298
353
|
|
299
|
-
# Increments request statistics of a certain +route+
|
300
|
-
#
|
301
|
-
# +status_code+.
|
354
|
+
# Increments request statistics of a certain +route+ invoked with +method+,
|
355
|
+
# which returned +status_code+.
|
302
356
|
#
|
303
357
|
# After a certain amount of time (n seconds) the aggregated route
|
304
358
|
# information will be sent to Airbrake.
|
@@ -311,8 +365,7 @@ module Airbrake
|
|
311
365
|
# func: 'do_stuff',
|
312
366
|
# file: 'app/models/foo.rb',
|
313
367
|
# line: 452,
|
314
|
-
#
|
315
|
-
# end_time: Time.now
|
368
|
+
# timing: 123.45 # ms
|
316
369
|
# )
|
317
370
|
#
|
318
371
|
# @param [Hash{Symbol=>Object}] request_info
|
@@ -326,18 +379,31 @@ module Airbrake
|
|
326
379
|
# called the query (optional)
|
327
380
|
# @option request_info [Integer] :line The line that executes the query
|
328
381
|
# (optional)
|
329
|
-
# @option request_info [
|
330
|
-
#
|
382
|
+
# @option request_info [Float] :timing How much time it took to process the
|
383
|
+
# request (in ms)
|
384
|
+
# @param [Hash] stash What needs to be appeneded to the stash, so it's
|
385
|
+
# available in filters
|
331
386
|
# @return [void]
|
332
387
|
# @since v3.0.0
|
333
388
|
# @see Airbrake::PerformanceNotifier#notify
|
334
|
-
def notify_request(request_info)
|
335
|
-
|
389
|
+
def notify_request(request_info, stash = {})
|
390
|
+
request = Request.new(**request_info)
|
391
|
+
request.stash.merge!(stash)
|
392
|
+
performance_notifier.notify(request)
|
393
|
+
end
|
394
|
+
|
395
|
+
# Synchronously increments request statistics of a certain +route+ invoked
|
396
|
+
# with +method+, which returned +status_code+.
|
397
|
+
# @since v4.10.0
|
398
|
+
# @see .notify_request
|
399
|
+
def notify_request_sync(request_info, stash = {})
|
400
|
+
request = Request.new(**request_info)
|
401
|
+
request.stash.merge!(stash)
|
402
|
+
performance_notifier.notify_sync(request)
|
336
403
|
end
|
337
404
|
|
338
|
-
# Increments SQL statistics of a certain +query
|
339
|
-
#
|
340
|
-
# provided, the query is grouped by these parameters.
|
405
|
+
# Increments SQL statistics of a certain +query+. When +method+ and +route+
|
406
|
+
# are provided, the query is grouped by these parameters.
|
341
407
|
#
|
342
408
|
# After a certain amount of time (n seconds) the aggregated query
|
343
409
|
# information will be sent to Airbrake.
|
@@ -347,24 +413,112 @@ module Airbrake
|
|
347
413
|
# method: 'GET',
|
348
414
|
# route: '/things',
|
349
415
|
# query: 'SELECT * FROM things',
|
350
|
-
#
|
351
|
-
# end_time: Time.now
|
416
|
+
# timing: 123.45 # ms
|
352
417
|
# )
|
353
418
|
#
|
354
419
|
# @param [Hash{Symbol=>Object}] query_info
|
355
|
-
# @option
|
356
|
-
# @option request_info [String] :method The HTTP method that triggered this
|
420
|
+
# @option query_info [String] :method The HTTP method that triggered this
|
357
421
|
# SQL query (optional)
|
358
|
-
# @option
|
422
|
+
# @option query_info [String] :route The route that triggered this SQL
|
359
423
|
# query (optional)
|
360
|
-
# @option
|
361
|
-
# @option
|
362
|
-
#
|
424
|
+
# @option query_info [String] :query The query that was executed
|
425
|
+
# @option query_info [Float] :timing How much time it took to process the
|
426
|
+
# query (in ms)
|
427
|
+
# @param [Hash] stash What needs to be appeneded to the stash, so it's
|
428
|
+
# available in filters
|
363
429
|
# @return [void]
|
364
430
|
# @since v3.2.0
|
365
431
|
# @see Airbrake::PerformanceNotifier#notify
|
366
|
-
def notify_query(query_info)
|
367
|
-
|
432
|
+
def notify_query(query_info, stash = {})
|
433
|
+
query = Query.new(**query_info)
|
434
|
+
query.stash.merge!(stash)
|
435
|
+
performance_notifier.notify(query)
|
436
|
+
end
|
437
|
+
|
438
|
+
# Synchronously increments SQL statistics of a certain +query+. When
|
439
|
+
# +method+ and +route+ are provided, the query is grouped by these
|
440
|
+
# parameters.
|
441
|
+
# @since v4.10.0
|
442
|
+
# @see .notify_query
|
443
|
+
def notify_query_sync(query_info, stash = {})
|
444
|
+
query = Query.new(**query_info)
|
445
|
+
query.stash.merge!(stash)
|
446
|
+
performance_notifier.notify_sync(query)
|
447
|
+
end
|
448
|
+
|
449
|
+
# Increments performance breakdown statistics of a certain route.
|
450
|
+
#
|
451
|
+
# @example
|
452
|
+
# Airbrake.notify_request(
|
453
|
+
# method: 'POST',
|
454
|
+
# route: '/thing/:id/create',
|
455
|
+
# response_type: 'json',
|
456
|
+
# groups: { db: 24.0, view: 0.4 }, # ms
|
457
|
+
# timing: 123.45 # ms
|
458
|
+
# )
|
459
|
+
#
|
460
|
+
# @param [Hash{Symbol=>Object}] breakdown_info
|
461
|
+
# @option breakdown_info [String] :method HTTP method
|
462
|
+
# @option breakdown_info [String] :route
|
463
|
+
# @option breakdown_info [String] :response_type
|
464
|
+
# @option breakdown_info [Array<Hash{Symbol=>Float}>] :groups
|
465
|
+
# @option breakdown_info [Float] :timing How much time it took to process
|
466
|
+
# the performance breakdown (in ms)
|
467
|
+
# @param [Hash] stash What needs to be appeneded to the stash, so it's
|
468
|
+
# available in filters
|
469
|
+
# @return [void]
|
470
|
+
# @since v4.2.0
|
471
|
+
def notify_performance_breakdown(breakdown_info, stash = {})
|
472
|
+
performance_breakdown = PerformanceBreakdown.new(**breakdown_info)
|
473
|
+
performance_breakdown.stash.merge!(stash)
|
474
|
+
performance_notifier.notify(performance_breakdown)
|
475
|
+
end
|
476
|
+
|
477
|
+
# Increments performance breakdown statistics of a certain route
|
478
|
+
# synchronously.
|
479
|
+
# @since v4.10.0
|
480
|
+
# @see .notify_performance_breakdown
|
481
|
+
def notify_performance_breakdown_sync(breakdown_info, stash = {})
|
482
|
+
performance_breakdown = PerformanceBreakdown.new(**breakdown_info)
|
483
|
+
performance_breakdown.stash.merge!(stash)
|
484
|
+
performance_notifier.notify_sync(performance_breakdown)
|
485
|
+
end
|
486
|
+
|
487
|
+
# Increments statistics of a certain queue (worker).
|
488
|
+
#
|
489
|
+
# @example
|
490
|
+
# Airbrake.notify_queue(
|
491
|
+
# queue: 'emails',
|
492
|
+
# error_count: 1,
|
493
|
+
# groups: { redis: 24.0, sql: 0.4 } # ms
|
494
|
+
# )
|
495
|
+
#
|
496
|
+
# @param [Hash{Symbol=>Object}] queue_info
|
497
|
+
# @option queue_info [String] :queue The name of the queue/worker
|
498
|
+
# @option queue_info [Integer] :error_count How many times this worker
|
499
|
+
# failed
|
500
|
+
# @option queue_info [Array<Hash{Symbol=>Float}>] :groups Where the job
|
501
|
+
# spent its time
|
502
|
+
# @option breakdown_info [Float] :timing How much time it took to process
|
503
|
+
# the queue (in ms)
|
504
|
+
# @param [Hash] stash What needs to be appended to the stash, so it's
|
505
|
+
# available in filters
|
506
|
+
# @return [void]
|
507
|
+
# @since v4.9.0
|
508
|
+
# @see .notify_queue_sync
|
509
|
+
def notify_queue(queue_info, stash = {})
|
510
|
+
queue = Queue.new(**queue_info)
|
511
|
+
queue.stash.merge!(stash)
|
512
|
+
performance_notifier.notify(queue)
|
513
|
+
end
|
514
|
+
|
515
|
+
# Increments statistics of a certain queue (worker) synchronously.
|
516
|
+
# @since v4.10.0
|
517
|
+
# @see .notify_queue
|
518
|
+
def notify_queue_sync(queue_info, stash = {})
|
519
|
+
queue = Queue.new(**queue_info)
|
520
|
+
queue.stash.merge!(stash)
|
521
|
+
performance_notifier.notify_sync(queue)
|
368
522
|
end
|
369
523
|
|
370
524
|
# Runs a callback before {.notify_request} or {.notify_query} kicks in. This
|
@@ -399,7 +553,7 @@ module Airbrake
|
|
399
553
|
# @since v3.2.0
|
400
554
|
# @see Airbrake::PerformanceNotifier#add_filter
|
401
555
|
def add_performance_filter(filter = nil, &block)
|
402
|
-
|
556
|
+
performance_notifier.add_filter(filter, &block)
|
403
557
|
end
|
404
558
|
|
405
559
|
# Deletes a filter added via {Airbrake#add_performance_filter}.
|
@@ -417,7 +571,19 @@ module Airbrake
|
|
417
571
|
# @note This method cannot delete filters assigned via the Proc form.
|
418
572
|
# @see Airbrake::PerformanceNotifier#delete_filter
|
419
573
|
def delete_performance_filter(filter_class)
|
420
|
-
|
574
|
+
performance_notifier.delete_filter(filter_class)
|
575
|
+
end
|
576
|
+
|
577
|
+
# Resets all notifiers, including its filters
|
578
|
+
# @return [void]
|
579
|
+
# @since v4.2.2
|
580
|
+
def reset
|
581
|
+
close
|
582
|
+
|
583
|
+
self.performance_notifier = PerformanceNotifier.new
|
584
|
+
self.notice_notifier = NoticeNotifier.new
|
585
|
+
self.deploy_notifier = DeployNotifier.new
|
421
586
|
end
|
422
587
|
end
|
423
588
|
end
|
589
|
+
# rubocop:enable Metrics/ModuleLength
|