airbrake-ruby 4.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|