airbrake-ruby 4.6.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 +7 -0
- data/lib/airbrake-ruby.rb +513 -0
- data/lib/airbrake-ruby/async_sender.rb +142 -0
- data/lib/airbrake-ruby/backtrace.rb +196 -0
- data/lib/airbrake-ruby/benchmark.rb +39 -0
- data/lib/airbrake-ruby/code_hunk.rb +51 -0
- data/lib/airbrake-ruby/config.rb +229 -0
- data/lib/airbrake-ruby/config/validator.rb +91 -0
- data/lib/airbrake-ruby/deploy_notifier.rb +36 -0
- data/lib/airbrake-ruby/file_cache.rb +48 -0
- data/lib/airbrake-ruby/filter_chain.rb +95 -0
- data/lib/airbrake-ruby/filters/context_filter.rb +29 -0
- data/lib/airbrake-ruby/filters/dependency_filter.rb +31 -0
- data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +46 -0
- data/lib/airbrake-ruby/filters/gem_root_filter.rb +33 -0
- data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +92 -0
- data/lib/airbrake-ruby/filters/git_repository_filter.rb +64 -0
- data/lib/airbrake-ruby/filters/git_revision_filter.rb +66 -0
- data/lib/airbrake-ruby/filters/keys_blacklist.rb +49 -0
- data/lib/airbrake-ruby/filters/keys_filter.rb +140 -0
- data/lib/airbrake-ruby/filters/keys_whitelist.rb +48 -0
- data/lib/airbrake-ruby/filters/root_directory_filter.rb +28 -0
- data/lib/airbrake-ruby/filters/sql_filter.rb +104 -0
- data/lib/airbrake-ruby/filters/system_exit_filter.rb +23 -0
- data/lib/airbrake-ruby/filters/thread_filter.rb +92 -0
- data/lib/airbrake-ruby/hash_keyable.rb +37 -0
- data/lib/airbrake-ruby/ignorable.rb +44 -0
- data/lib/airbrake-ruby/inspectable.rb +39 -0
- data/lib/airbrake-ruby/loggable.rb +34 -0
- data/lib/airbrake-ruby/monotonic_time.rb +43 -0
- data/lib/airbrake-ruby/nested_exception.rb +38 -0
- data/lib/airbrake-ruby/notice.rb +162 -0
- data/lib/airbrake-ruby/notice_notifier.rb +134 -0
- data/lib/airbrake-ruby/performance_breakdown.rb +45 -0
- data/lib/airbrake-ruby/performance_notifier.rb +125 -0
- data/lib/airbrake-ruby/promise.rb +109 -0
- data/lib/airbrake-ruby/query.rb +53 -0
- data/lib/airbrake-ruby/request.rb +45 -0
- data/lib/airbrake-ruby/response.rb +74 -0
- data/lib/airbrake-ruby/stashable.rb +15 -0
- data/lib/airbrake-ruby/stat.rb +73 -0
- data/lib/airbrake-ruby/sync_sender.rb +113 -0
- data/lib/airbrake-ruby/tdigest.rb +393 -0
- data/lib/airbrake-ruby/time_truncate.rb +17 -0
- data/lib/airbrake-ruby/timed_trace.rb +58 -0
- data/lib/airbrake-ruby/truncator.rb +115 -0
- data/lib/airbrake-ruby/version.rb +6 -0
- data/spec/airbrake_spec.rb +324 -0
- data/spec/async_sender_spec.rb +155 -0
- data/spec/backtrace_spec.rb +427 -0
- data/spec/benchmark_spec.rb +33 -0
- data/spec/code_hunk_spec.rb +115 -0
- data/spec/config/validator_spec.rb +184 -0
- data/spec/config_spec.rb +154 -0
- data/spec/deploy_notifier_spec.rb +48 -0
- data/spec/file_cache.rb +36 -0
- data/spec/filter_chain_spec.rb +92 -0
- data/spec/filters/context_filter_spec.rb +23 -0
- data/spec/filters/dependency_filter_spec.rb +12 -0
- data/spec/filters/exception_attributes_filter_spec.rb +50 -0
- data/spec/filters/gem_root_filter_spec.rb +41 -0
- data/spec/filters/git_last_checkout_filter_spec.rb +46 -0
- data/spec/filters/git_repository_filter.rb +61 -0
- data/spec/filters/git_revision_filter_spec.rb +126 -0
- data/spec/filters/keys_blacklist_spec.rb +225 -0
- data/spec/filters/keys_whitelist_spec.rb +194 -0
- data/spec/filters/root_directory_filter_spec.rb +39 -0
- data/spec/filters/sql_filter_spec.rb +219 -0
- data/spec/filters/system_exit_filter_spec.rb +14 -0
- data/spec/filters/thread_filter_spec.rb +277 -0
- data/spec/fixtures/notroot.txt +7 -0
- data/spec/fixtures/project_root/code.rb +221 -0
- data/spec/fixtures/project_root/empty_file.rb +0 -0
- data/spec/fixtures/project_root/long_line.txt +1 -0
- data/spec/fixtures/project_root/short_file.rb +3 -0
- data/spec/fixtures/project_root/vendor/bundle/ignored_file.rb +5 -0
- data/spec/helpers.rb +9 -0
- data/spec/ignorable_spec.rb +14 -0
- data/spec/inspectable_spec.rb +45 -0
- data/spec/monotonic_time_spec.rb +12 -0
- data/spec/nested_exception_spec.rb +73 -0
- data/spec/notice_notifier_spec.rb +356 -0
- data/spec/notice_notifier_spec/options_spec.rb +259 -0
- data/spec/notice_spec.rb +296 -0
- data/spec/performance_breakdown_spec.rb +12 -0
- data/spec/performance_notifier_spec.rb +435 -0
- data/spec/promise_spec.rb +197 -0
- data/spec/query_spec.rb +11 -0
- data/spec/request_spec.rb +11 -0
- data/spec/response_spec.rb +88 -0
- data/spec/spec_helper.rb +100 -0
- data/spec/stashable_spec.rb +23 -0
- data/spec/stat_spec.rb +47 -0
- data/spec/sync_sender_spec.rb +133 -0
- data/spec/tdigest_spec.rb +230 -0
- data/spec/time_truncate_spec.rb +13 -0
- data/spec/timed_trace_spec.rb +125 -0
- data/spec/truncator_spec.rb +238 -0
- metadata +213 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: cf81123734caec939f2b487e0ca743ea26659f46
|
4
|
+
data.tar.gz: ba8e315a20b3f59d0863d027010e54311ba15d9d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 551704a67996c2064820507d4fb3dd0218df863e7433d77356dd45bc62ecab112508372125a98c8d2f651c2693716e96c86b8e0172ffd265b60de0258d1b7acf
|
7
|
+
data.tar.gz: c32da13a83d385bc91b7cc2f236324ae29918005bac9450076d03fc0b707f49b2474049dac7c13fb78f1b0c848c2a1e95579f3c5f1c2315581c8db7d8c1eb3e0
|
@@ -0,0 +1,513 @@
|
|
1
|
+
require 'net/https'
|
2
|
+
require 'logger'
|
3
|
+
require 'json'
|
4
|
+
require 'thread'
|
5
|
+
require 'set'
|
6
|
+
require 'socket'
|
7
|
+
require 'time'
|
8
|
+
|
9
|
+
require 'airbrake-ruby/version'
|
10
|
+
require 'airbrake-ruby/loggable'
|
11
|
+
require 'airbrake-ruby/stashable'
|
12
|
+
require 'airbrake-ruby/config'
|
13
|
+
require 'airbrake-ruby/config/validator'
|
14
|
+
require 'airbrake-ruby/promise'
|
15
|
+
require 'airbrake-ruby/sync_sender'
|
16
|
+
require 'airbrake-ruby/async_sender'
|
17
|
+
require 'airbrake-ruby/response'
|
18
|
+
require 'airbrake-ruby/nested_exception'
|
19
|
+
require 'airbrake-ruby/ignorable'
|
20
|
+
require 'airbrake-ruby/inspectable'
|
21
|
+
require 'airbrake-ruby/notice'
|
22
|
+
require 'airbrake-ruby/backtrace'
|
23
|
+
require 'airbrake-ruby/truncator'
|
24
|
+
require 'airbrake-ruby/filters/keys_filter'
|
25
|
+
require 'airbrake-ruby/filters/keys_whitelist'
|
26
|
+
require 'airbrake-ruby/filters/keys_blacklist'
|
27
|
+
require 'airbrake-ruby/filters/gem_root_filter'
|
28
|
+
require 'airbrake-ruby/filters/system_exit_filter'
|
29
|
+
require 'airbrake-ruby/filters/root_directory_filter'
|
30
|
+
require 'airbrake-ruby/filters/thread_filter'
|
31
|
+
require 'airbrake-ruby/filters/context_filter'
|
32
|
+
require 'airbrake-ruby/filters/exception_attributes_filter'
|
33
|
+
require 'airbrake-ruby/filters/dependency_filter'
|
34
|
+
require 'airbrake-ruby/filters/git_revision_filter'
|
35
|
+
require 'airbrake-ruby/filters/git_repository_filter'
|
36
|
+
require 'airbrake-ruby/filters/git_last_checkout_filter'
|
37
|
+
require 'airbrake-ruby/filters/sql_filter'
|
38
|
+
require 'airbrake-ruby/filter_chain'
|
39
|
+
require 'airbrake-ruby/code_hunk'
|
40
|
+
require 'airbrake-ruby/file_cache'
|
41
|
+
require 'airbrake-ruby/hash_keyable'
|
42
|
+
require 'airbrake-ruby/performance_notifier'
|
43
|
+
require 'airbrake-ruby/notice_notifier'
|
44
|
+
require 'airbrake-ruby/deploy_notifier'
|
45
|
+
require 'airbrake-ruby/stat'
|
46
|
+
require 'airbrake-ruby/time_truncate'
|
47
|
+
require 'airbrake-ruby/tdigest'
|
48
|
+
require 'airbrake-ruby/query'
|
49
|
+
require 'airbrake-ruby/request'
|
50
|
+
require 'airbrake-ruby/performance_breakdown'
|
51
|
+
require 'airbrake-ruby/benchmark'
|
52
|
+
require 'airbrake-ruby/monotonic_time'
|
53
|
+
require 'airbrake-ruby/timed_trace'
|
54
|
+
|
55
|
+
# Airbrake is a thin wrapper around instances of the notifier classes (such as
|
56
|
+
# notice, performance & deploy notifiers). It creates a way to access them via a
|
57
|
+
# consolidated global interface.
|
58
|
+
#
|
59
|
+
# Prior to using it, you must {configure} it.
|
60
|
+
#
|
61
|
+
# @example
|
62
|
+
# Airbrake.configure do |c|
|
63
|
+
# c.project_id = 113743
|
64
|
+
# c.project_key = 'fd04e13d806a90f96614ad8e529b2822'
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# Airbrake.notify('Oops!')
|
68
|
+
#
|
69
|
+
# @since v1.0.0
|
70
|
+
# @api public
|
71
|
+
module Airbrake
|
72
|
+
# The general error that this library uses when it wants to raise.
|
73
|
+
Error = Class.new(StandardError)
|
74
|
+
|
75
|
+
# @return [String] the label to be prepended to the log output
|
76
|
+
LOG_LABEL = '**Airbrake:'.freeze
|
77
|
+
|
78
|
+
# @return [Boolean] true if current Ruby is JRuby. The result is used for
|
79
|
+
# special cases where we need to work around older implementations
|
80
|
+
JRUBY = (RUBY_ENGINE == 'jruby')
|
81
|
+
|
82
|
+
class << self
|
83
|
+
# @since v4.2.3
|
84
|
+
# @api private
|
85
|
+
attr_writer :performance_notifier
|
86
|
+
|
87
|
+
# @since v4.2.3
|
88
|
+
# @api private
|
89
|
+
attr_writer :notice_notifier
|
90
|
+
|
91
|
+
# @since v4.2.3
|
92
|
+
# @api private
|
93
|
+
attr_writer :deploy_notifier
|
94
|
+
|
95
|
+
# Configures the Airbrake notifier.
|
96
|
+
#
|
97
|
+
# @example
|
98
|
+
# Airbrake.configure do |c|
|
99
|
+
# c.project_id = 113743
|
100
|
+
# c.project_key = 'fd04e13d806a90f96614ad8e529b2822'
|
101
|
+
# end
|
102
|
+
#
|
103
|
+
# @yield [config]
|
104
|
+
# @yieldparam config [Airbrake::Config]
|
105
|
+
# @return [void]
|
106
|
+
def configure
|
107
|
+
yield config = Airbrake::Config.instance
|
108
|
+
Airbrake::Loggable.instance = config.logger
|
109
|
+
process_config_options(config)
|
110
|
+
end
|
111
|
+
|
112
|
+
# @since v4.2.3
|
113
|
+
# @api private
|
114
|
+
def performance_notifier
|
115
|
+
@performance_notifier ||= PerformanceNotifier.new
|
116
|
+
end
|
117
|
+
|
118
|
+
# @since v4.2.3
|
119
|
+
# @api private
|
120
|
+
def notice_notifier
|
121
|
+
@notice_notifier ||= NoticeNotifier.new
|
122
|
+
end
|
123
|
+
|
124
|
+
# @since v4.2.3
|
125
|
+
# @api private
|
126
|
+
def deploy_notifier
|
127
|
+
@deploy_notifier ||= DeployNotifier.new
|
128
|
+
end
|
129
|
+
|
130
|
+
# @return [Boolean] true if the notifier was configured, false otherwise
|
131
|
+
# @since v2.3.0
|
132
|
+
def configured?
|
133
|
+
notice_notifier.configured?
|
134
|
+
end
|
135
|
+
|
136
|
+
# Sends an exception to Airbrake asynchronously.
|
137
|
+
#
|
138
|
+
# @example Sending an exception
|
139
|
+
# Airbrake.notify(RuntimeError.new('Oops!'))
|
140
|
+
# @example Sending a string
|
141
|
+
# # Converted to RuntimeError.new('Oops!') internally
|
142
|
+
# Airbrake.notify('Oops!')
|
143
|
+
# @example Sending a Notice
|
144
|
+
# notice = airbrake.build_notice(RuntimeError.new('Oops!'))
|
145
|
+
# airbrake.notify(notice)
|
146
|
+
#
|
147
|
+
# @param [Exception, String, Airbrake::Notice] exception The exception to be
|
148
|
+
# sent to Airbrake
|
149
|
+
# @param [Hash] params The additional payload to be sent to Airbrake. Can
|
150
|
+
# contain any values. The provided values will be displayed in the Params
|
151
|
+
# tab in your project's dashboard
|
152
|
+
# @yield [notice] The notice to filter
|
153
|
+
# @yieldparam [Airbrake::Notice]
|
154
|
+
# @yieldreturn [void]
|
155
|
+
# @return [Airbrake::Promise]
|
156
|
+
# @see .notify_sync
|
157
|
+
def notify(exception, params = {}, &block)
|
158
|
+
notice_notifier.notify(exception, params, &block)
|
159
|
+
end
|
160
|
+
|
161
|
+
# Sends an exception to Airbrake synchronously.
|
162
|
+
#
|
163
|
+
# @example
|
164
|
+
# Airbrake.notify_sync('App crashed!')
|
165
|
+
# #=> {"id"=>"123", "url"=>"https://airbrake.io/locate/321"}
|
166
|
+
#
|
167
|
+
# @param [Exception, String, Airbrake::Notice] exception The exception to be
|
168
|
+
# sent to Airbrake
|
169
|
+
# @param [Hash] params The additional payload to be sent to Airbrake. Can
|
170
|
+
# contain any values. The provided values will be displayed in the Params
|
171
|
+
# tab in your project's dashboard
|
172
|
+
# @yield [notice] The notice to filter
|
173
|
+
# @yieldparam [Airbrake::Notice]
|
174
|
+
# @yieldreturn [void]
|
175
|
+
# @return [Airbrake::Promise] the reponse from the server
|
176
|
+
# @see .notify
|
177
|
+
def notify_sync(exception, params = {}, &block)
|
178
|
+
notice_notifier.notify_sync(exception, params, &block)
|
179
|
+
end
|
180
|
+
|
181
|
+
# Runs a callback before {.notify} or {.notify_sync} kicks in. This is
|
182
|
+
# useful if you want to ignore specific notices or filter the data the
|
183
|
+
# notice contains.
|
184
|
+
#
|
185
|
+
# @example Ignore all notices
|
186
|
+
# Airbrake.add_filter(&:ignore!)
|
187
|
+
# @example Ignore based on some condition
|
188
|
+
# Airbrake.add_filter do |notice|
|
189
|
+
# notice.ignore! if notice[:error_class] == 'StandardError'
|
190
|
+
# end
|
191
|
+
# @example Ignore with help of a class
|
192
|
+
# class MyFilter
|
193
|
+
# def call(notice)
|
194
|
+
# # ...
|
195
|
+
# end
|
196
|
+
# end
|
197
|
+
#
|
198
|
+
# Airbrake.add_filter(MyFilter.new)
|
199
|
+
#
|
200
|
+
# @param [#call] filter The filter object
|
201
|
+
# @yield [notice] The notice to filter
|
202
|
+
# @yieldparam [Airbrake::Notice]
|
203
|
+
# @yieldreturn [void]
|
204
|
+
# @return [void]
|
205
|
+
def add_filter(filter = nil, &block)
|
206
|
+
notice_notifier.add_filter(filter, &block)
|
207
|
+
end
|
208
|
+
|
209
|
+
# Deletes a filter added via {Airbrake#add_filter}.
|
210
|
+
#
|
211
|
+
# @example
|
212
|
+
# # Add a MyFilter filter (we pass an instance here).
|
213
|
+
# Airbrake.add_filter(MyFilter.new)
|
214
|
+
#
|
215
|
+
# # Delete the filter (we pass class name here).
|
216
|
+
# Airbrake.delete_filter(MyFilter)
|
217
|
+
#
|
218
|
+
# @param [Class] filter_class The class of the filter you want to delete
|
219
|
+
# @return [void]
|
220
|
+
# @since v3.1.0
|
221
|
+
# @note This method cannot delete filters assigned via the Proc form.
|
222
|
+
def delete_filter(filter_class)
|
223
|
+
notice_notifier.delete_filter(filter_class)
|
224
|
+
end
|
225
|
+
|
226
|
+
# Builds an Airbrake notice. This is useful, if you want to add or modify a
|
227
|
+
# value only for a specific notice. When you're done modifying the notice,
|
228
|
+
# send it with {.notify} or {.notify_sync}.
|
229
|
+
#
|
230
|
+
# @example
|
231
|
+
# notice = airbrake.build_notice('App crashed!')
|
232
|
+
# notice[:params][:username] = user.name
|
233
|
+
# airbrake.notify_sync(notice)
|
234
|
+
#
|
235
|
+
# @param [Exception] exception The exception on top of which the notice
|
236
|
+
# should be built
|
237
|
+
# @param [Hash] params The additional params attached to the notice
|
238
|
+
# @return [Airbrake::Notice] the notice built with help of the given
|
239
|
+
# arguments
|
240
|
+
def build_notice(exception, params = {})
|
241
|
+
notice_notifier.build_notice(exception, params)
|
242
|
+
end
|
243
|
+
|
244
|
+
# Makes the notice notifier a no-op, which means you cannot use the
|
245
|
+
# {.notify} and {.notify_sync} methods anymore. It also stops the notice
|
246
|
+
# notifier's worker threads.
|
247
|
+
#
|
248
|
+
# @example
|
249
|
+
# Airbrake.close
|
250
|
+
# Airbrake.notify('App crashed!') #=> raises Airbrake::Error
|
251
|
+
#
|
252
|
+
# @return [void]
|
253
|
+
def close
|
254
|
+
notice_notifier.close
|
255
|
+
end
|
256
|
+
|
257
|
+
# Pings the Airbrake Deploy API endpoint about the occurred deploy.
|
258
|
+
#
|
259
|
+
# @param [Hash{Symbol=>String}] deploy_info The params for the API
|
260
|
+
# @option deploy_info [Symbol] :environment
|
261
|
+
# @option deploy_info [Symbol] :username
|
262
|
+
# @option deploy_info [Symbol] :repository
|
263
|
+
# @option deploy_info [Symbol] :revision
|
264
|
+
# @option deploy_info [Symbol] :version
|
265
|
+
# @return [void]
|
266
|
+
def notify_deploy(deploy_info)
|
267
|
+
deploy_notifier.notify(deploy_info)
|
268
|
+
end
|
269
|
+
|
270
|
+
# Merges +context+ with the current context.
|
271
|
+
#
|
272
|
+
# The context will be attached to the notice object upon a notify call and
|
273
|
+
# cleared after it's attached. The context data is attached to the
|
274
|
+
# `params/airbrake_context` key.
|
275
|
+
#
|
276
|
+
# @example
|
277
|
+
# class MerryGrocer
|
278
|
+
# def load_fruits(fruits)
|
279
|
+
# Airbrake.merge_context(fruits: fruits)
|
280
|
+
# end
|
281
|
+
#
|
282
|
+
# def deliver_fruits
|
283
|
+
# Airbrake.notify('fruitception')
|
284
|
+
# end
|
285
|
+
#
|
286
|
+
# def load_veggies(veggies)
|
287
|
+
# Airbrake.merge_context(veggies: veggies)
|
288
|
+
# end
|
289
|
+
#
|
290
|
+
# def deliver_veggies
|
291
|
+
# Airbrake.notify('veggieboom!')
|
292
|
+
# end
|
293
|
+
# end
|
294
|
+
#
|
295
|
+
# grocer = MerryGrocer.new
|
296
|
+
#
|
297
|
+
# # Load some fruits to the context.
|
298
|
+
# grocer.load_fruits(%w(mango banana apple))
|
299
|
+
#
|
300
|
+
# # Deliver the fruits. Note that we are not passing anything,
|
301
|
+
# # `deliver_fruits` knows that we loaded something.
|
302
|
+
# grocer.deliver_fruits
|
303
|
+
#
|
304
|
+
# # Load some vegetables and deliver them to Airbrake. Note that the
|
305
|
+
# # fruits have been delivered and therefore the grocer doesn't have them
|
306
|
+
# # anymore. We merge veggies with the new context.
|
307
|
+
# grocer.load_veggies(%w(cabbage carrot onion))
|
308
|
+
# grocer.deliver_veggies
|
309
|
+
#
|
310
|
+
# # The context is empty again, feel free to load more.
|
311
|
+
#
|
312
|
+
# @param [Hash{Symbol=>Object}] context
|
313
|
+
# @return [void]
|
314
|
+
def merge_context(context)
|
315
|
+
notice_notifier.merge_context(context)
|
316
|
+
end
|
317
|
+
|
318
|
+
# Increments request statistics of a certain +route+ that was invoked on
|
319
|
+
# +start_time+ and ended on +end_time+ with +method+, and returned
|
320
|
+
# +status_code+.
|
321
|
+
#
|
322
|
+
# After a certain amount of time (n seconds) the aggregated route
|
323
|
+
# information will be sent to Airbrake.
|
324
|
+
#
|
325
|
+
# @example
|
326
|
+
# Airbrake.notify_request(
|
327
|
+
# method: 'POST',
|
328
|
+
# route: '/thing/:id/create',
|
329
|
+
# status_code: 200,
|
330
|
+
# func: 'do_stuff',
|
331
|
+
# file: 'app/models/foo.rb',
|
332
|
+
# line: 452,
|
333
|
+
# start_time: timestamp,
|
334
|
+
# end_time: Time.now
|
335
|
+
# )
|
336
|
+
#
|
337
|
+
# @param [Hash{Symbol=>Object}] request_info
|
338
|
+
# @option request_info [String] :method The HTTP method that was invoked
|
339
|
+
# @option request_info [String] :route The route that was invoked
|
340
|
+
# @option request_info [Integer] :status_code The respose code that the
|
341
|
+
# route returned
|
342
|
+
# @option request_info [String] :func The function that called the query
|
343
|
+
# (optional)
|
344
|
+
# @option request_info [String] :file The file that has the function that
|
345
|
+
# called the query (optional)
|
346
|
+
# @option request_info [Integer] :line The line that executes the query
|
347
|
+
# (optional)
|
348
|
+
# @option request_info [Date] :start_time When the request started
|
349
|
+
# @option request_info [Time] :end_time When the request ended (optional)
|
350
|
+
# @param [Hash] stash What needs to be appeneded to the stash, so it's
|
351
|
+
# available in filters
|
352
|
+
# @return [void]
|
353
|
+
# @since v3.0.0
|
354
|
+
# @see Airbrake::PerformanceNotifier#notify
|
355
|
+
def notify_request(request_info, stash = {})
|
356
|
+
request = Request.new(request_info)
|
357
|
+
request.stash.merge!(stash)
|
358
|
+
performance_notifier.notify(request)
|
359
|
+
end
|
360
|
+
|
361
|
+
# Increments SQL statistics of a certain +query+ that was invoked on
|
362
|
+
# +start_time+ and finished on +end_time+. When +method+ and +route+ are
|
363
|
+
# provided, the query is grouped by these parameters.
|
364
|
+
#
|
365
|
+
# After a certain amount of time (n seconds) the aggregated query
|
366
|
+
# information will be sent to Airbrake.
|
367
|
+
#
|
368
|
+
# @example
|
369
|
+
# Airbrake.notify_query(
|
370
|
+
# method: 'GET',
|
371
|
+
# route: '/things',
|
372
|
+
# query: 'SELECT * FROM things',
|
373
|
+
# start_time: timestamp,
|
374
|
+
# end_time: Time.now
|
375
|
+
# )
|
376
|
+
#
|
377
|
+
# @param [Hash{Symbol=>Object}] query_info
|
378
|
+
# @option request_info [String] :method The HTTP method that triggered this
|
379
|
+
# SQL query (optional)
|
380
|
+
# @option request_info [String] :route The route that triggered this SQL
|
381
|
+
# query (optional)
|
382
|
+
# @option request_info [String] :query The query that was executed
|
383
|
+
# @option request_info [Date] :start_time When the query started executing
|
384
|
+
# @option request_info [Time] :end_time When the query finished (optional)
|
385
|
+
# @param [Hash] stash What needs to be appeneded to the stash, so it's
|
386
|
+
# available in filters
|
387
|
+
# @return [void]
|
388
|
+
# @since v3.2.0
|
389
|
+
# @see Airbrake::PerformanceNotifier#notify
|
390
|
+
def notify_query(query_info, stash = {})
|
391
|
+
query = Query.new(query_info)
|
392
|
+
query.stash.merge!(stash)
|
393
|
+
performance_notifier.notify(query)
|
394
|
+
end
|
395
|
+
|
396
|
+
# Increments performance breakdown statistics of a certain route.
|
397
|
+
#
|
398
|
+
# @example
|
399
|
+
# Airbrake.notify_request(
|
400
|
+
# method: 'POST',
|
401
|
+
# route: '/thing/:id/create',
|
402
|
+
# response_type: 'json',
|
403
|
+
# groups: { db: 24.0, view: 0.4 }, # ms
|
404
|
+
# start_time: timestamp,
|
405
|
+
# end_time: Time.now
|
406
|
+
# )
|
407
|
+
#
|
408
|
+
# @param [Hash{Symbol=>Object}] breakdown_info
|
409
|
+
# @option breakdown_info [String] :method HTTP method
|
410
|
+
# @option breakdown_info [String] :route
|
411
|
+
# @option breakdown_info [String] :response_type
|
412
|
+
# @option breakdown_info [Array<Hash{Symbol=>Float}>] :groups
|
413
|
+
# @option breakdown_info [Date] :start_time
|
414
|
+
# @param [Hash] stash What needs to be appeneded to the stash, so it's
|
415
|
+
# available in filters
|
416
|
+
# @return [void]
|
417
|
+
# @since v4.2.0
|
418
|
+
def notify_performance_breakdown(breakdown_info, stash = {})
|
419
|
+
performance_breakdown = PerformanceBreakdown.new(breakdown_info)
|
420
|
+
performance_breakdown.stash.merge!(stash)
|
421
|
+
performance_notifier.notify(performance_breakdown)
|
422
|
+
end
|
423
|
+
|
424
|
+
# Runs a callback before {.notify_request} or {.notify_query} kicks in. This
|
425
|
+
# is useful if you want to ignore specific resources or filter the data the
|
426
|
+
# resource contains.
|
427
|
+
#
|
428
|
+
# @example Ignore all resources
|
429
|
+
# Airbrake.add_performance_filter(&:ignore!)
|
430
|
+
# @example Filter sensitive data
|
431
|
+
# Airbrake.add_performance_filter do |resource|
|
432
|
+
# case resource
|
433
|
+
# when Airbrake::Query
|
434
|
+
# resource.route = '[Filtered]'
|
435
|
+
# when Airbrake::Request
|
436
|
+
# resource.query = '[Filtered]'
|
437
|
+
# end
|
438
|
+
# end
|
439
|
+
# @example Filter with help of a class
|
440
|
+
# class MyFilter
|
441
|
+
# def call(resource)
|
442
|
+
# # ...
|
443
|
+
# end
|
444
|
+
# end
|
445
|
+
#
|
446
|
+
# Airbrake.add_performance_filter(MyFilter.new)
|
447
|
+
#
|
448
|
+
# @param [#call] filter The filter object
|
449
|
+
# @yield [resource] The resource to filter
|
450
|
+
# @yieldparam [Airbrake::Query, Airbrake::Request]
|
451
|
+
# @yieldreturn [void]
|
452
|
+
# @return [void]
|
453
|
+
# @since v3.2.0
|
454
|
+
# @see Airbrake::PerformanceNotifier#add_filter
|
455
|
+
def add_performance_filter(filter = nil, &block)
|
456
|
+
performance_notifier.add_filter(filter, &block)
|
457
|
+
end
|
458
|
+
|
459
|
+
# Deletes a filter added via {Airbrake#add_performance_filter}.
|
460
|
+
#
|
461
|
+
# @example
|
462
|
+
# # Add a MyFilter filter (we pass an instance here).
|
463
|
+
# Airbrake.add_performance_filter(MyFilter.new)
|
464
|
+
#
|
465
|
+
# # Delete the filter (we pass class name here).
|
466
|
+
# Airbrake.delete_performance_filter(MyFilter)
|
467
|
+
#
|
468
|
+
# @param [Class] filter_class The class of the filter you want to delete
|
469
|
+
# @return [void]
|
470
|
+
# @since v3.2.0
|
471
|
+
# @note This method cannot delete filters assigned via the Proc form.
|
472
|
+
# @see Airbrake::PerformanceNotifier#delete_filter
|
473
|
+
def delete_performance_filter(filter_class)
|
474
|
+
performance_notifier.delete_filter(filter_class)
|
475
|
+
end
|
476
|
+
|
477
|
+
# Resets all notifiers, including its filters
|
478
|
+
# @return [void]
|
479
|
+
# @since v4.2.2
|
480
|
+
def reset
|
481
|
+
close if notice_notifier && configured?
|
482
|
+
|
483
|
+
self.performance_notifier = PerformanceNotifier.new
|
484
|
+
self.notice_notifier = NoticeNotifier.new
|
485
|
+
self.deploy_notifier = DeployNotifier.new
|
486
|
+
end
|
487
|
+
|
488
|
+
private
|
489
|
+
|
490
|
+
def process_config_options(config)
|
491
|
+
if config.blacklist_keys.any?
|
492
|
+
blacklist = Airbrake::Filters::KeysBlacklist.new(config.blacklist_keys)
|
493
|
+
notice_notifier.add_filter(blacklist)
|
494
|
+
end
|
495
|
+
|
496
|
+
if config.whitelist_keys.any?
|
497
|
+
whitelist = Airbrake::Filters::KeysWhitelist.new(config.whitelist_keys)
|
498
|
+
notice_notifier.add_filter(whitelist)
|
499
|
+
end
|
500
|
+
|
501
|
+
return unless config.root_directory
|
502
|
+
|
503
|
+
[
|
504
|
+
Airbrake::Filters::RootDirectoryFilter,
|
505
|
+
Airbrake::Filters::GitRevisionFilter,
|
506
|
+
Airbrake::Filters::GitRepositoryFilter,
|
507
|
+
Airbrake::Filters::GitLastCheckoutFilter
|
508
|
+
].each do |filter|
|
509
|
+
notice_notifier.add_filter(filter.new(config.root_directory))
|
510
|
+
end
|
511
|
+
end
|
512
|
+
end
|
513
|
+
end
|