celerbrake-ruby 0.1.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/celerbrake-ruby/async_sender.rb +57 -0
- data/lib/celerbrake-ruby/backlog.rb +123 -0
- data/lib/celerbrake-ruby/backtrace.rb +197 -0
- data/lib/celerbrake-ruby/benchmark.rb +39 -0
- data/lib/celerbrake-ruby/code_hunk.rb +51 -0
- data/lib/celerbrake-ruby/config/processor.rb +77 -0
- data/lib/celerbrake-ruby/config/validator.rb +97 -0
- data/lib/celerbrake-ruby/config.rb +291 -0
- data/lib/celerbrake-ruby/context.rb +51 -0
- data/lib/celerbrake-ruby/deploy_notifier.rb +36 -0
- data/lib/celerbrake-ruby/file_cache.rb +54 -0
- data/lib/celerbrake-ruby/filter_chain.rb +112 -0
- data/lib/celerbrake-ruby/filters/context_filter.rb +28 -0
- data/lib/celerbrake-ruby/filters/dependency_filter.rb +32 -0
- data/lib/celerbrake-ruby/filters/exception_attributes_filter.rb +46 -0
- data/lib/celerbrake-ruby/filters/gem_root_filter.rb +34 -0
- data/lib/celerbrake-ruby/filters/git_last_checkout_filter.rb +92 -0
- data/lib/celerbrake-ruby/filters/git_repository_filter.rb +73 -0
- data/lib/celerbrake-ruby/filters/git_revision_filter.rb +68 -0
- data/lib/celerbrake-ruby/filters/keys_allowlist.rb +48 -0
- data/lib/celerbrake-ruby/filters/keys_blocklist.rb +49 -0
- data/lib/celerbrake-ruby/filters/keys_filter.rb +159 -0
- data/lib/celerbrake-ruby/filters/root_directory_filter.rb +29 -0
- data/lib/celerbrake-ruby/filters/sql_filter.rb +128 -0
- data/lib/celerbrake-ruby/filters/system_exit_filter.rb +24 -0
- data/lib/celerbrake-ruby/filters/thread_filter.rb +93 -0
- data/lib/celerbrake-ruby/grouppable.rb +12 -0
- data/lib/celerbrake-ruby/hash_keyable.rb +37 -0
- data/lib/celerbrake-ruby/ignorable.rb +43 -0
- data/lib/celerbrake-ruby/inspectable.rb +39 -0
- data/lib/celerbrake-ruby/loggable.rb +34 -0
- data/lib/celerbrake-ruby/mergeable.rb +12 -0
- data/lib/celerbrake-ruby/monotonic_time.rb +48 -0
- data/lib/celerbrake-ruby/nested_exception.rb +59 -0
- data/lib/celerbrake-ruby/notice.rb +157 -0
- data/lib/celerbrake-ruby/notice_notifier.rb +142 -0
- data/lib/celerbrake-ruby/performance_breakdown.rb +52 -0
- data/lib/celerbrake-ruby/performance_notifier.rb +177 -0
- data/lib/celerbrake-ruby/promise.rb +110 -0
- data/lib/celerbrake-ruby/query.rb +59 -0
- data/lib/celerbrake-ruby/queue.rb +65 -0
- data/lib/celerbrake-ruby/remote_settings/callback.rb +44 -0
- data/lib/celerbrake-ruby/remote_settings/settings_data.rb +116 -0
- data/lib/celerbrake-ruby/remote_settings.rb +128 -0
- data/lib/celerbrake-ruby/request.rb +48 -0
- data/lib/celerbrake-ruby/response.rb +125 -0
- data/lib/celerbrake-ruby/stashable.rb +15 -0
- data/lib/celerbrake-ruby/stat.rb +66 -0
- data/lib/celerbrake-ruby/sync_sender.rb +145 -0
- data/lib/celerbrake-ruby/tdigest.rb +379 -0
- data/lib/celerbrake-ruby/thread_pool.rb +139 -0
- data/lib/celerbrake-ruby/time_truncate.rb +17 -0
- data/lib/celerbrake-ruby/timed_trace.rb +56 -0
- data/lib/celerbrake-ruby/truncator.rb +121 -0
- data/lib/celerbrake-ruby/version.rb +16 -0
- data/lib/celerbrake-ruby.rb +592 -0
- metadata +251 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# We use Semantic Versioning v2.0.0
|
|
2
|
+
# More information: http://semver.org/
|
|
3
|
+
module Celerbrake
|
|
4
|
+
# @return [String] the library version
|
|
5
|
+
# @api public
|
|
6
|
+
CELERBRAKE_RUBY_VERSION = '0.1.0'.freeze
|
|
7
|
+
|
|
8
|
+
# @return [Hash{Symbol=>String}] the information about the notifier library
|
|
9
|
+
# @since v5.0.0
|
|
10
|
+
# @api public
|
|
11
|
+
NOTIFIER_INFO = {
|
|
12
|
+
name: 'celerbrake-ruby'.freeze,
|
|
13
|
+
version: Celerbrake::CELERBRAKE_RUBY_VERSION,
|
|
14
|
+
url: 'https://github.com/celerbrake/celerbrake-ruby'.freeze,
|
|
15
|
+
}.freeze
|
|
16
|
+
end
|
|
@@ -0,0 +1,592 @@
|
|
|
1
|
+
require 'net/https'
|
|
2
|
+
require 'logger'
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'set'
|
|
5
|
+
require 'socket'
|
|
6
|
+
require 'time'
|
|
7
|
+
|
|
8
|
+
require 'celerbrake-ruby/version'
|
|
9
|
+
require 'celerbrake-ruby/loggable'
|
|
10
|
+
require 'celerbrake-ruby/stashable'
|
|
11
|
+
require 'celerbrake-ruby/mergeable'
|
|
12
|
+
require 'celerbrake-ruby/grouppable'
|
|
13
|
+
require 'celerbrake-ruby/config'
|
|
14
|
+
require 'celerbrake-ruby/config/validator'
|
|
15
|
+
require 'celerbrake-ruby/config/processor'
|
|
16
|
+
require 'celerbrake-ruby/remote_settings/callback'
|
|
17
|
+
require 'celerbrake-ruby/remote_settings/settings_data'
|
|
18
|
+
require 'celerbrake-ruby/remote_settings'
|
|
19
|
+
require 'celerbrake-ruby/promise'
|
|
20
|
+
require 'celerbrake-ruby/thread_pool'
|
|
21
|
+
require 'celerbrake-ruby/response'
|
|
22
|
+
require 'celerbrake-ruby/sync_sender'
|
|
23
|
+
require 'celerbrake-ruby/async_sender'
|
|
24
|
+
require 'celerbrake-ruby/nested_exception'
|
|
25
|
+
require 'celerbrake-ruby/ignorable'
|
|
26
|
+
require 'celerbrake-ruby/inspectable'
|
|
27
|
+
require 'celerbrake-ruby/notice'
|
|
28
|
+
require 'celerbrake-ruby/backtrace'
|
|
29
|
+
require 'celerbrake-ruby/truncator'
|
|
30
|
+
require 'celerbrake-ruby/filters/keys_filter'
|
|
31
|
+
require 'celerbrake-ruby/filters/keys_allowlist'
|
|
32
|
+
require 'celerbrake-ruby/filters/keys_blocklist'
|
|
33
|
+
require 'celerbrake-ruby/filters/gem_root_filter'
|
|
34
|
+
require 'celerbrake-ruby/filters/system_exit_filter'
|
|
35
|
+
require 'celerbrake-ruby/filters/root_directory_filter'
|
|
36
|
+
require 'celerbrake-ruby/filters/thread_filter'
|
|
37
|
+
require 'celerbrake-ruby/filters/context_filter'
|
|
38
|
+
require 'celerbrake-ruby/filters/exception_attributes_filter'
|
|
39
|
+
require 'celerbrake-ruby/filters/dependency_filter'
|
|
40
|
+
require 'celerbrake-ruby/filters/git_revision_filter'
|
|
41
|
+
require 'celerbrake-ruby/filters/git_repository_filter'
|
|
42
|
+
require 'celerbrake-ruby/filters/git_last_checkout_filter'
|
|
43
|
+
require 'celerbrake-ruby/filters/sql_filter'
|
|
44
|
+
require 'celerbrake-ruby/filter_chain'
|
|
45
|
+
require 'celerbrake-ruby/code_hunk'
|
|
46
|
+
require 'celerbrake-ruby/file_cache'
|
|
47
|
+
require 'celerbrake-ruby/hash_keyable'
|
|
48
|
+
require 'celerbrake-ruby/performance_notifier'
|
|
49
|
+
require 'celerbrake-ruby/notice_notifier'
|
|
50
|
+
require 'celerbrake-ruby/deploy_notifier'
|
|
51
|
+
require 'celerbrake-ruby/stat'
|
|
52
|
+
require 'celerbrake-ruby/time_truncate'
|
|
53
|
+
require 'celerbrake-ruby/tdigest'
|
|
54
|
+
require 'celerbrake-ruby/query'
|
|
55
|
+
require 'celerbrake-ruby/request'
|
|
56
|
+
require 'celerbrake-ruby/performance_breakdown'
|
|
57
|
+
require 'celerbrake-ruby/benchmark'
|
|
58
|
+
require 'celerbrake-ruby/monotonic_time'
|
|
59
|
+
require 'celerbrake-ruby/timed_trace'
|
|
60
|
+
require 'celerbrake-ruby/queue'
|
|
61
|
+
require 'celerbrake-ruby/context'
|
|
62
|
+
require 'celerbrake-ruby/backlog'
|
|
63
|
+
|
|
64
|
+
# Celerbrake is a thin wrapper around instances of the notifier classes (such as
|
|
65
|
+
# notice, performance & deploy notifiers). It creates a way to access them via a
|
|
66
|
+
# consolidated global interface.
|
|
67
|
+
#
|
|
68
|
+
# Prior to using it, you must {configure} it.
|
|
69
|
+
#
|
|
70
|
+
# @example
|
|
71
|
+
# Celerbrake.configure do |c|
|
|
72
|
+
# c.project_id = 113743
|
|
73
|
+
# c.project_key = 'fd04e13d806a90f96614ad8e529b2822'
|
|
74
|
+
# end
|
|
75
|
+
#
|
|
76
|
+
# Celerbrake.notify('Oops!')
|
|
77
|
+
#
|
|
78
|
+
# @since v1.0.0
|
|
79
|
+
# @api public
|
|
80
|
+
# rubocop:disable Metrics/ModuleLength
|
|
81
|
+
module Celerbrake
|
|
82
|
+
# The general error that this library uses when it wants to raise.
|
|
83
|
+
Error = Class.new(StandardError)
|
|
84
|
+
|
|
85
|
+
# @return [String] the label to be prepended to the log output
|
|
86
|
+
LOG_LABEL = '**Celerbrake:'.freeze
|
|
87
|
+
|
|
88
|
+
# @return [Boolean] true if current Ruby is JRuby. The result is used for
|
|
89
|
+
# special cases where we need to work around older implementations
|
|
90
|
+
JRUBY = (RUBY_ENGINE == 'jruby')
|
|
91
|
+
|
|
92
|
+
# @return [Boolean] true if this Ruby supports safe levels and tainting,
|
|
93
|
+
# to guard against using deprecated or unsupported features.
|
|
94
|
+
HAS_SAFE_LEVEL = (
|
|
95
|
+
RUBY_ENGINE == 'ruby' &&
|
|
96
|
+
Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7')
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
class << self
|
|
100
|
+
# @since v4.2.3
|
|
101
|
+
# @api private
|
|
102
|
+
attr_writer :performance_notifier
|
|
103
|
+
|
|
104
|
+
# @since v4.2.3
|
|
105
|
+
# @api private
|
|
106
|
+
attr_writer :notice_notifier
|
|
107
|
+
|
|
108
|
+
# @since v4.2.3
|
|
109
|
+
# @api private
|
|
110
|
+
attr_writer :deploy_notifier
|
|
111
|
+
|
|
112
|
+
# Configures the Celerbrake notifier.
|
|
113
|
+
#
|
|
114
|
+
# @example
|
|
115
|
+
# Celerbrake.configure do |c|
|
|
116
|
+
# c.project_id = 113743
|
|
117
|
+
# c.project_key = 'fd04e13d806a90f96614ad8e529b2822'
|
|
118
|
+
# end
|
|
119
|
+
#
|
|
120
|
+
# @yield [config]
|
|
121
|
+
# @yieldparam config [Celerbrake::Config]
|
|
122
|
+
# @return [void]
|
|
123
|
+
def configure
|
|
124
|
+
yield config = Celerbrake::Config.instance
|
|
125
|
+
Celerbrake::Loggable.instance = config.logger
|
|
126
|
+
|
|
127
|
+
config_processor = Celerbrake::Config::Processor.new(config)
|
|
128
|
+
|
|
129
|
+
config_processor.process_blocklist(notice_notifier)
|
|
130
|
+
config_processor.process_allowlist(notice_notifier)
|
|
131
|
+
|
|
132
|
+
@remote_settings ||= config_processor.process_remote_configuration
|
|
133
|
+
|
|
134
|
+
config_processor.add_filters(notice_notifier)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# @since v4.2.3
|
|
138
|
+
# @api private
|
|
139
|
+
def performance_notifier
|
|
140
|
+
@performance_notifier ||= PerformanceNotifier.new
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# @since v4.2.3
|
|
144
|
+
# @api private
|
|
145
|
+
def notice_notifier
|
|
146
|
+
@notice_notifier ||= NoticeNotifier.new
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# @since v4.2.3
|
|
150
|
+
# @api private
|
|
151
|
+
def deploy_notifier
|
|
152
|
+
@deploy_notifier ||= DeployNotifier.new
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# @return [Boolean] true if the notifier was configured, false otherwise
|
|
156
|
+
# @since v2.3.0
|
|
157
|
+
def configured?
|
|
158
|
+
@notice_notifier && @notice_notifier.configured?
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Sends an exception to Celerbrake asynchronously.
|
|
162
|
+
#
|
|
163
|
+
# @example Sending an exception
|
|
164
|
+
# Celerbrake.notify(RuntimeError.new('Oops!'))
|
|
165
|
+
# @example Sending a string
|
|
166
|
+
# # Converted to RuntimeError.new('Oops!') internally
|
|
167
|
+
# Celerbrake.notify('Oops!')
|
|
168
|
+
# @example Sending a Notice
|
|
169
|
+
# notice = celerbrake.build_notice(RuntimeError.new('Oops!'))
|
|
170
|
+
# celerbrake.notify(notice)
|
|
171
|
+
#
|
|
172
|
+
# @param [Exception, String, Celerbrake::Notice] exception The exception to be
|
|
173
|
+
# sent to Celerbrake
|
|
174
|
+
# @param [Hash] params The additional payload to be sent to Celerbrake. Can
|
|
175
|
+
# contain any values. The provided values will be displayed in the Params
|
|
176
|
+
# tab in your project's dashboard
|
|
177
|
+
# @yield [notice] The notice to filter
|
|
178
|
+
# @yieldparam [Celerbrake::Notice]
|
|
179
|
+
# @yieldreturn [void]
|
|
180
|
+
# @return [Celerbrake::Promise]
|
|
181
|
+
# @see .notify_sync
|
|
182
|
+
def notify(exception, params = {}, &block)
|
|
183
|
+
notice_notifier.notify(exception, params, &block)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Sends an exception to Celerbrake synchronously.
|
|
187
|
+
#
|
|
188
|
+
# @example
|
|
189
|
+
# Celerbrake.notify_sync('App crashed!')
|
|
190
|
+
# #=> {"id"=>"123", "url"=>"https://celerbrake.com/locate/321"}
|
|
191
|
+
#
|
|
192
|
+
# @param [Exception, String, Celerbrake::Notice] exception The exception to be
|
|
193
|
+
# sent to Celerbrake
|
|
194
|
+
# @param [Hash] params The additional payload to be sent to Celerbrake. Can
|
|
195
|
+
# contain any values. The provided values will be displayed in the Params
|
|
196
|
+
# tab in your project's dashboard
|
|
197
|
+
# @yield [notice] The notice to filter
|
|
198
|
+
# @yieldparam [Celerbrake::Notice]
|
|
199
|
+
# @yieldreturn [void]
|
|
200
|
+
# @return [Celerbrake::Promise] the reponse from the server
|
|
201
|
+
# @see .notify
|
|
202
|
+
def notify_sync(exception, params = {}, &block)
|
|
203
|
+
notice_notifier.notify_sync(exception, params, &block)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Runs a callback before {.notify} or {.notify_sync} kicks in. This is
|
|
207
|
+
# useful if you want to ignore specific notices or filter the data the
|
|
208
|
+
# notice contains.
|
|
209
|
+
#
|
|
210
|
+
# @example Ignore all notices
|
|
211
|
+
# Celerbrake.add_filter(&:ignore!)
|
|
212
|
+
# @example Ignore based on some condition
|
|
213
|
+
# Celerbrake.add_filter do |notice|
|
|
214
|
+
# notice.ignore! if notice[:error_class] == 'StandardError'
|
|
215
|
+
# end
|
|
216
|
+
# @example Ignore with help of a class
|
|
217
|
+
# class MyFilter
|
|
218
|
+
# def call(notice)
|
|
219
|
+
# # ...
|
|
220
|
+
# end
|
|
221
|
+
# end
|
|
222
|
+
#
|
|
223
|
+
# Celerbrake.add_filter(MyFilter.new)
|
|
224
|
+
#
|
|
225
|
+
# @param [#call] filter The filter object
|
|
226
|
+
# @yield [notice] The notice to filter
|
|
227
|
+
# @yieldparam [Celerbrake::Notice]
|
|
228
|
+
# @yieldreturn [void]
|
|
229
|
+
# @return [void]
|
|
230
|
+
def add_filter(filter = nil, &block)
|
|
231
|
+
notice_notifier.add_filter(filter, &block)
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# Deletes a filter added via {Celerbrake#add_filter}.
|
|
235
|
+
#
|
|
236
|
+
# @example
|
|
237
|
+
# # Add a MyFilter filter (we pass an instance here).
|
|
238
|
+
# Celerbrake.add_filter(MyFilter.new)
|
|
239
|
+
#
|
|
240
|
+
# # Delete the filter (we pass class name here).
|
|
241
|
+
# Celerbrake.delete_filter(MyFilter)
|
|
242
|
+
#
|
|
243
|
+
# @param [Class] filter_class The class of the filter you want to delete
|
|
244
|
+
# @return [void]
|
|
245
|
+
# @since v3.1.0
|
|
246
|
+
# @note This method cannot delete filters assigned via the Proc form.
|
|
247
|
+
def delete_filter(filter_class)
|
|
248
|
+
notice_notifier.delete_filter(filter_class)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# Builds an Celerbrake notice. This is useful, if you want to add or modify a
|
|
252
|
+
# value only for a specific notice. When you're done modifying the notice,
|
|
253
|
+
# send it with {.notify} or {.notify_sync}.
|
|
254
|
+
#
|
|
255
|
+
# @example
|
|
256
|
+
# notice = celerbrake.build_notice('App crashed!')
|
|
257
|
+
# notice[:params][:username] = user.name
|
|
258
|
+
# celerbrake.notify_sync(notice)
|
|
259
|
+
#
|
|
260
|
+
# @param [Exception] exception The exception on top of which the notice
|
|
261
|
+
# should be built
|
|
262
|
+
# @param [Hash] params The additional params attached to the notice
|
|
263
|
+
# @return [Celerbrake::Notice] the notice built with help of the given
|
|
264
|
+
# arguments
|
|
265
|
+
def build_notice(exception, params = {})
|
|
266
|
+
notice_notifier.build_notice(exception, params)
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# Makes the notice notifier a no-op, which means you cannot use the
|
|
270
|
+
# {.notify} and {.notify_sync} methods anymore. It also stops the notice
|
|
271
|
+
# notifier's worker threads.
|
|
272
|
+
#
|
|
273
|
+
# @example
|
|
274
|
+
# Celerbrake.close
|
|
275
|
+
# Celerbrake.notify('App crashed!') #=> raises Celerbrake::Error
|
|
276
|
+
#
|
|
277
|
+
# @return [nil]
|
|
278
|
+
# rubocop:disable Style/IfUnlessModifier
|
|
279
|
+
def close
|
|
280
|
+
if defined?(@notice_notifier) && @notice_notifier
|
|
281
|
+
@notice_notifier.close
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
if defined?(@performance_notifier) && @performance_notifier
|
|
285
|
+
@performance_notifier.close
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
if defined?(@remote_settings) && @remote_settings
|
|
289
|
+
@remote_settings.stop_polling
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
nil
|
|
293
|
+
end
|
|
294
|
+
# rubocop:enable Style/IfUnlessModifier
|
|
295
|
+
|
|
296
|
+
# Pings the Celerbrake Deploy API endpoint about the occurred deploy.
|
|
297
|
+
#
|
|
298
|
+
# @param [Hash{Symbol=>String}] deploy_info The params for the API
|
|
299
|
+
# @option deploy_info [Symbol] :environment
|
|
300
|
+
# @option deploy_info [Symbol] :username
|
|
301
|
+
# @option deploy_info [Symbol] :repository
|
|
302
|
+
# @option deploy_info [Symbol] :revision
|
|
303
|
+
# @option deploy_info [Symbol] :version
|
|
304
|
+
# @return [void]
|
|
305
|
+
def notify_deploy(deploy_info)
|
|
306
|
+
deploy_notifier.notify(deploy_info)
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
# Merges +context+ with the current context.
|
|
310
|
+
#
|
|
311
|
+
# The context will be attached to the notice object upon a notify call and
|
|
312
|
+
# cleared after it's attached. The context data is attached to the
|
|
313
|
+
# `params/celerbrake_context` key.
|
|
314
|
+
#
|
|
315
|
+
# @example
|
|
316
|
+
# class MerryGrocer
|
|
317
|
+
# def load_fruits(fruits)
|
|
318
|
+
# Celerbrake.merge_context(fruits: fruits)
|
|
319
|
+
# end
|
|
320
|
+
#
|
|
321
|
+
# def deliver_fruits
|
|
322
|
+
# Celerbrake.notify('fruitception')
|
|
323
|
+
# end
|
|
324
|
+
#
|
|
325
|
+
# def load_veggies(veggies)
|
|
326
|
+
# Celerbrake.merge_context(veggies: veggies)
|
|
327
|
+
# end
|
|
328
|
+
#
|
|
329
|
+
# def deliver_veggies
|
|
330
|
+
# Celerbrake.notify('veggieboom!')
|
|
331
|
+
# end
|
|
332
|
+
# end
|
|
333
|
+
#
|
|
334
|
+
# grocer = MerryGrocer.new
|
|
335
|
+
#
|
|
336
|
+
# # Load some fruits to the context.
|
|
337
|
+
# grocer.load_fruits(%w(mango banana apple))
|
|
338
|
+
#
|
|
339
|
+
# # Deliver the fruits. Note that we are not passing anything,
|
|
340
|
+
# # `deliver_fruits` knows that we loaded something.
|
|
341
|
+
# grocer.deliver_fruits
|
|
342
|
+
#
|
|
343
|
+
# # Load some vegetables and deliver them to Celerbrake. Note that the
|
|
344
|
+
# # fruits have been delivered and therefore the grocer doesn't have them
|
|
345
|
+
# # anymore. We merge veggies with the new context.
|
|
346
|
+
# grocer.load_veggies(%w(cabbage carrot onion))
|
|
347
|
+
# grocer.deliver_veggies
|
|
348
|
+
#
|
|
349
|
+
# # The context is empty again, feel free to load more.
|
|
350
|
+
#
|
|
351
|
+
# @param [Hash{Symbol=>Object}] context
|
|
352
|
+
# @return [void]
|
|
353
|
+
def merge_context(context)
|
|
354
|
+
notice_notifier.merge_context(context)
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
# Increments request statistics of a certain +route+ invoked with +method+,
|
|
358
|
+
# which returned +status_code+.
|
|
359
|
+
#
|
|
360
|
+
# After a certain amount of time (n seconds) the aggregated route
|
|
361
|
+
# information will be sent to Celerbrake.
|
|
362
|
+
#
|
|
363
|
+
# @example
|
|
364
|
+
# Celerbrake.notify_request(
|
|
365
|
+
# method: 'POST',
|
|
366
|
+
# route: '/thing/:id/create',
|
|
367
|
+
# status_code: 200,
|
|
368
|
+
# timing: 123.45 # ms
|
|
369
|
+
# )
|
|
370
|
+
#
|
|
371
|
+
# @param [Hash{Symbol=>Object}] request_info
|
|
372
|
+
# @option request_info [String] :method The HTTP method that was invoked
|
|
373
|
+
# @option request_info [String] :route The route that was invoked
|
|
374
|
+
# @option request_info [Integer] :status_code The response code that the
|
|
375
|
+
# route returned
|
|
376
|
+
# @option request_info [Float] :timing How much time it took to process the
|
|
377
|
+
# request (in ms)
|
|
378
|
+
# @param [Hash] stash What needs to be appeneded to the stash, so it's
|
|
379
|
+
# available in filters
|
|
380
|
+
# @return [void]
|
|
381
|
+
# @since v3.0.0
|
|
382
|
+
# @see Celerbrake::PerformanceNotifier#notify
|
|
383
|
+
def notify_request(request_info, stash = {})
|
|
384
|
+
request = Request.new(**request_info)
|
|
385
|
+
request.stash.merge!(stash)
|
|
386
|
+
performance_notifier.notify(request)
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
# Synchronously increments request statistics of a certain +route+ invoked
|
|
390
|
+
# with +method+, which returned +status_code+.
|
|
391
|
+
# @since v4.10.0
|
|
392
|
+
# @see .notify_request
|
|
393
|
+
def notify_request_sync(request_info, stash = {})
|
|
394
|
+
request = Request.new(**request_info)
|
|
395
|
+
request.stash.merge!(stash)
|
|
396
|
+
performance_notifier.notify_sync(request)
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
# Increments SQL statistics of a certain +query+. When +method+ and +route+
|
|
400
|
+
# are provided, the query is grouped by these parameters.
|
|
401
|
+
#
|
|
402
|
+
# After a certain amount of time (n seconds) the aggregated query
|
|
403
|
+
# information will be sent to Celerbrake.
|
|
404
|
+
#
|
|
405
|
+
# @example
|
|
406
|
+
# Celerbrake.notify_query(
|
|
407
|
+
# method: 'GET',
|
|
408
|
+
# route: '/things',
|
|
409
|
+
# query: 'SELECT * FROM things',
|
|
410
|
+
# func: 'do_stuff',
|
|
411
|
+
# file: 'app/models/foo.rb',
|
|
412
|
+
# line: 452,
|
|
413
|
+
# timing: 123.45 # ms
|
|
414
|
+
# )
|
|
415
|
+
#
|
|
416
|
+
# @param [Hash{Symbol=>Object}] query_info
|
|
417
|
+
# @option query_info [String] :method The HTTP method that triggered this
|
|
418
|
+
# SQL query (optional)
|
|
419
|
+
# @option query_info [String] :route The route that triggered this SQL
|
|
420
|
+
# query (optional)
|
|
421
|
+
# @option query_info [String] :query The query that was executed
|
|
422
|
+
# @option request_info [String] :func The function that called the query
|
|
423
|
+
# (optional)
|
|
424
|
+
# @option request_info [String] :file The file that has the function that
|
|
425
|
+
# called the query (optional)
|
|
426
|
+
# @option request_info [Integer] :line The line that executes the query
|
|
427
|
+
# (optional)
|
|
428
|
+
# @option query_info [Float] :timing How much time it took to process the
|
|
429
|
+
# query (in ms)
|
|
430
|
+
# @param [Hash] stash What needs to be appeneded to the stash, so it's
|
|
431
|
+
# available in filters
|
|
432
|
+
# @return [void]
|
|
433
|
+
# @since v3.2.0
|
|
434
|
+
# @see Celerbrake::PerformanceNotifier#notify
|
|
435
|
+
def notify_query(query_info, stash = {})
|
|
436
|
+
query = Query.new(**query_info)
|
|
437
|
+
query.stash.merge!(stash)
|
|
438
|
+
performance_notifier.notify(query)
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
# Synchronously increments SQL statistics of a certain +query+. When
|
|
442
|
+
# +method+ and +route+ are provided, the query is grouped by these
|
|
443
|
+
# parameters.
|
|
444
|
+
# @since v4.10.0
|
|
445
|
+
# @see .notify_query
|
|
446
|
+
def notify_query_sync(query_info, stash = {})
|
|
447
|
+
query = Query.new(**query_info)
|
|
448
|
+
query.stash.merge!(stash)
|
|
449
|
+
performance_notifier.notify_sync(query)
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
# Increments performance breakdown statistics of a certain route.
|
|
453
|
+
#
|
|
454
|
+
# @example
|
|
455
|
+
# Celerbrake.notify_performance_breakdown(
|
|
456
|
+
# method: 'POST',
|
|
457
|
+
# route: '/thing/:id/create',
|
|
458
|
+
# response_type: 'json',
|
|
459
|
+
# groups: { db: 24.0, view: 0.4 }, # ms
|
|
460
|
+
# timing: 123.45 # ms
|
|
461
|
+
# )
|
|
462
|
+
#
|
|
463
|
+
# @param [Hash{Symbol=>Object}] breakdown_info
|
|
464
|
+
# @option breakdown_info [String] :method HTTP method
|
|
465
|
+
# @option breakdown_info [String] :route
|
|
466
|
+
# @option breakdown_info [String] :response_type
|
|
467
|
+
# @option breakdown_info [Array<Hash{Symbol=>Float}>] :groups
|
|
468
|
+
# @option breakdown_info [Float] :timing How much time it took to process
|
|
469
|
+
# the performance breakdown (in ms)
|
|
470
|
+
# @param [Hash] stash What needs to be appeneded to the stash, so it's
|
|
471
|
+
# available in filters
|
|
472
|
+
# @return [void]
|
|
473
|
+
# @since v4.2.0
|
|
474
|
+
def notify_performance_breakdown(breakdown_info, stash = {})
|
|
475
|
+
performance_breakdown = PerformanceBreakdown.new(**breakdown_info)
|
|
476
|
+
performance_breakdown.stash.merge!(stash)
|
|
477
|
+
performance_notifier.notify(performance_breakdown)
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
# Increments performance breakdown statistics of a certain route
|
|
481
|
+
# synchronously.
|
|
482
|
+
# @since v4.10.0
|
|
483
|
+
# @see .notify_performance_breakdown
|
|
484
|
+
def notify_performance_breakdown_sync(breakdown_info, stash = {})
|
|
485
|
+
performance_breakdown = PerformanceBreakdown.new(**breakdown_info)
|
|
486
|
+
performance_breakdown.stash.merge!(stash)
|
|
487
|
+
performance_notifier.notify_sync(performance_breakdown)
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
# Increments statistics of a certain queue (worker).
|
|
491
|
+
#
|
|
492
|
+
# @example
|
|
493
|
+
# Celerbrake.notify_queue(
|
|
494
|
+
# queue: 'emails',
|
|
495
|
+
# error_count: 1,
|
|
496
|
+
# groups: { redis: 24.0, sql: 0.4 } # ms
|
|
497
|
+
# )
|
|
498
|
+
#
|
|
499
|
+
# @param [Hash{Symbol=>Object}] queue_info
|
|
500
|
+
# @option queue_info [String] :queue The name of the queue/worker
|
|
501
|
+
# @option queue_info [Integer] :error_count How many times this worker
|
|
502
|
+
# failed
|
|
503
|
+
# @option queue_info [Array<Hash{Symbol=>Float}>] :groups Where the job
|
|
504
|
+
# spent its time
|
|
505
|
+
# @option breakdown_info [Float] :timing How much time it took to process
|
|
506
|
+
# the queue (in ms)
|
|
507
|
+
# @param [Hash] stash What needs to be appended to the stash, so it's
|
|
508
|
+
# available in filters
|
|
509
|
+
# @return [void]
|
|
510
|
+
# @since v4.9.0
|
|
511
|
+
# @see .notify_queue_sync
|
|
512
|
+
def notify_queue(queue_info, stash = {})
|
|
513
|
+
queue = Queue.new(**queue_info)
|
|
514
|
+
queue.stash.merge!(stash)
|
|
515
|
+
performance_notifier.notify(queue)
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
# Increments statistics of a certain queue (worker) synchronously.
|
|
519
|
+
# @since v4.10.0
|
|
520
|
+
# @see .notify_queue
|
|
521
|
+
def notify_queue_sync(queue_info, stash = {})
|
|
522
|
+
queue = Queue.new(**queue_info)
|
|
523
|
+
queue.stash.merge!(stash)
|
|
524
|
+
performance_notifier.notify_sync(queue)
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
# Runs a callback before {.notify_request}, {.notify_query}, {.notify_queue}
|
|
528
|
+
# or {.notify_performance_breakdown} kicks in. This is useful if you want to
|
|
529
|
+
# ignore specific metrics or filter the data the metric contains.
|
|
530
|
+
#
|
|
531
|
+
# @example Ignore all metrics
|
|
532
|
+
# Celerbrake.add_performance_filter(&:ignore!)
|
|
533
|
+
# @example Filter sensitive data
|
|
534
|
+
# Celerbrake.add_performance_filter do |metric|
|
|
535
|
+
# case metric
|
|
536
|
+
# when Celerbrake::Query
|
|
537
|
+
# metric.route = '[Filtered]'
|
|
538
|
+
# when Celerbrake::Request
|
|
539
|
+
# metric.query = '[Filtered]'
|
|
540
|
+
# end
|
|
541
|
+
# end
|
|
542
|
+
# @example Filter with help of a class
|
|
543
|
+
# class MyFilter
|
|
544
|
+
# def call(metric)
|
|
545
|
+
# # ...
|
|
546
|
+
# end
|
|
547
|
+
# end
|
|
548
|
+
#
|
|
549
|
+
# Celerbrake.add_performance_filter(MyFilter.new)
|
|
550
|
+
#
|
|
551
|
+
# @param [#call] filter The filter object
|
|
552
|
+
# @yield [metric] The metric to filter
|
|
553
|
+
# @yieldparam [Celerbrake::Query, Celerbrake::Request]
|
|
554
|
+
# @yieldreturn [void]
|
|
555
|
+
# @return [void]
|
|
556
|
+
# @since v3.2.0
|
|
557
|
+
# @see Celerbrake::PerformanceNotifier#add_filter
|
|
558
|
+
def add_performance_filter(filter = nil, &block)
|
|
559
|
+
performance_notifier.add_filter(filter, &block)
|
|
560
|
+
end
|
|
561
|
+
|
|
562
|
+
# Deletes a filter added via {Celerbrake#add_performance_filter}.
|
|
563
|
+
#
|
|
564
|
+
# @example
|
|
565
|
+
# # Add a MyFilter filter (we pass an instance here).
|
|
566
|
+
# Celerbrake.add_performance_filter(MyFilter.new)
|
|
567
|
+
#
|
|
568
|
+
# # Delete the filter (we pass class name here).
|
|
569
|
+
# Celerbrake.delete_performance_filter(MyFilter)
|
|
570
|
+
#
|
|
571
|
+
# @param [Class] filter_class The class of the filter you want to delete
|
|
572
|
+
# @return [void]
|
|
573
|
+
# @since v3.2.0
|
|
574
|
+
# @note This method cannot delete filters assigned via the Proc form.
|
|
575
|
+
# @see Celerbrake::PerformanceNotifier#delete_filter
|
|
576
|
+
def delete_performance_filter(filter_class)
|
|
577
|
+
performance_notifier.delete_filter(filter_class)
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
# Resets all notifiers, including its filters
|
|
581
|
+
# @return [void]
|
|
582
|
+
# @since v4.2.2
|
|
583
|
+
def reset
|
|
584
|
+
close
|
|
585
|
+
|
|
586
|
+
self.performance_notifier = PerformanceNotifier.new
|
|
587
|
+
self.notice_notifier = NoticeNotifier.new
|
|
588
|
+
self.deploy_notifier = DeployNotifier.new
|
|
589
|
+
end
|
|
590
|
+
end
|
|
591
|
+
end
|
|
592
|
+
# rubocop:enable Metrics/ModuleLength
|