rollbar 2.19.1 → 2.27.1
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/.github/pull_request_template.md +25 -0
- data/.rubocop.yml +168 -0
- data/.travis.yml +63 -34
- data/Appraisals +10 -10
- data/Gemfile +35 -14
- data/README.md +5 -2
- data/Rakefile +0 -0
- data/data/rollbar.snippet.js +1 -1
- data/docs/configuration.md +17 -0
- data/gemfiles/rails30.gemfile +10 -10
- data/gemfiles/rails31.gemfile +10 -9
- data/gemfiles/rails32.gemfile +10 -9
- data/gemfiles/rails40.gemfile +10 -9
- data/gemfiles/rails41.gemfile +10 -9
- data/gemfiles/rails42.gemfile +12 -9
- data/gemfiles/rails50.gemfile +21 -14
- data/gemfiles/rails51.gemfile +21 -14
- data/gemfiles/rails52.gemfile +15 -12
- data/gemfiles/rails60.gemfile +67 -0
- data/lib/generators/rollbar/rollbar_generator.rb +1 -1
- data/lib/rails/rollbar_runner.rb +4 -2
- data/lib/rollbar/capistrano.rb +1 -1
- data/lib/rollbar/capistrano3.rb +6 -3
- data/lib/rollbar/capistrano_tasks.rb +29 -21
- data/lib/rollbar/configuration.rb +86 -16
- data/lib/rollbar/delay/girl_friday.rb +4 -8
- data/lib/rollbar/delay/resque.rb +3 -6
- data/lib/rollbar/delay/sidekiq.rb +4 -10
- data/lib/rollbar/delay/sucker_punch.rb +16 -19
- data/lib/rollbar/delay/thread.rb +16 -2
- data/lib/rollbar/deploy.rb +52 -29
- data/lib/rollbar/encoding/encoder.rb +17 -10
- data/lib/rollbar/exception_reporter.rb +19 -5
- data/lib/rollbar/item/backtrace.rb +13 -3
- data/lib/rollbar/item/frame.rb +9 -1
- data/lib/rollbar/item/locals.rb +100 -0
- data/lib/rollbar/item.rb +56 -17
- data/lib/rollbar/json.rb +6 -51
- data/lib/rollbar/language_support.rb +4 -20
- data/lib/rollbar/lazy_store.rb +5 -5
- data/lib/rollbar/logger.rb +1 -0
- data/lib/rollbar/logger_proxy.rb +6 -2
- data/lib/rollbar/middleware/js.rb +28 -18
- data/lib/rollbar/middleware/rack.rb +4 -1
- data/lib/rollbar/middleware/rails/rollbar.rb +10 -1
- data/lib/rollbar/notifier/trace_with_bindings.rb +65 -0
- data/lib/rollbar/notifier.rb +225 -89
- data/lib/rollbar/plugin.rb +54 -6
- data/lib/rollbar/plugins/active_job.rb +6 -2
- data/lib/rollbar/plugins/basic_socket.rb +21 -6
- data/lib/rollbar/plugins/delayed_job/job_data.rb +3 -3
- data/lib/rollbar/plugins/delayed_job/plugin.rb +13 -3
- data/lib/rollbar/plugins/error_context.rb +11 -0
- data/lib/rollbar/plugins/goalie.rb +11 -3
- data/lib/rollbar/plugins/rails/controller_methods.rb +15 -3
- data/lib/rollbar/plugins/rake.rb +2 -2
- data/lib/rollbar/plugins/sidekiq/plugin.rb +5 -4
- data/lib/rollbar/plugins.rb +7 -1
- data/lib/rollbar/rake_tasks.rb +4 -148
- data/lib/rollbar/request_data_extractor.rb +31 -21
- data/lib/rollbar/rollbar_test.rb +36 -0
- data/lib/rollbar/scrubbers/params.rb +19 -18
- data/lib/rollbar/scrubbers/url.rb +18 -9
- data/lib/rollbar/scrubbers.rb +3 -3
- data/lib/rollbar/truncation/frames_strategy.rb +1 -1
- data/lib/rollbar/truncation/min_body_strategy.rb +2 -3
- data/lib/rollbar/truncation/mixin.rb +1 -1
- data/lib/rollbar/truncation/remove_any_key_strategy.rb +123 -0
- data/lib/rollbar/truncation/remove_extra_strategy.rb +35 -0
- data/lib/rollbar/truncation/remove_request_strategy.rb +21 -0
- data/lib/rollbar/truncation/strings_strategy.rb +6 -5
- data/lib/rollbar/truncation.rb +9 -2
- data/lib/rollbar/util/hash.rb +15 -0
- data/lib/rollbar/util/ip_anonymizer.rb +8 -7
- data/lib/rollbar/util/ip_obfuscator.rb +1 -1
- data/lib/rollbar/util.rb +6 -2
- data/lib/rollbar/version.rb +1 -1
- data/lib/rollbar.rb +2 -3
- data/lib/tasks/benchmark.rake +103 -0
- data/rollbar.gemspec +13 -5
- data/spec/support/rollbar_api.rb +67 -0
- metadata +21 -23
- data/gemfiles/ruby_1_8_and_1_9_2.gemfile +0 -49
- data/lib/rollbar/json/default.rb +0 -11
- data/lib/rollbar/json/oj.rb +0 -16
data/lib/rollbar/notifier.rb
CHANGED
@@ -8,6 +8,7 @@ require 'rollbar/delay/girl_friday'
|
|
8
8
|
require 'rollbar/delay/thread'
|
9
9
|
require 'rollbar/logger_proxy'
|
10
10
|
require 'rollbar/item'
|
11
|
+
require 'rollbar/notifier/trace_with_bindings'
|
11
12
|
require 'ostruct'
|
12
13
|
|
13
14
|
module Rollbar
|
@@ -18,7 +19,9 @@ module Rollbar
|
|
18
19
|
attr_accessor :last_report
|
19
20
|
attr_accessor :scope_object
|
20
21
|
|
21
|
-
|
22
|
+
MUTEX = Mutex.new
|
23
|
+
EXTENSION_REGEXP = /.rollbar\z/.freeze
|
24
|
+
FAILSAFE_STRING_LENGTH = 10_000
|
22
25
|
|
23
26
|
def initialize(parent_notifier = nil, payload_options = nil, scope = nil)
|
24
27
|
if parent_notifier
|
@@ -41,21 +44,21 @@ module Rollbar
|
|
41
44
|
# Similar to configure below, but used only internally within the gem
|
42
45
|
# to configure it without initializing any of the third party hooks
|
43
46
|
def preconfigure
|
44
|
-
yield(configuration)
|
47
|
+
yield(configuration.configured_options)
|
45
48
|
end
|
46
49
|
|
47
50
|
# Configures the notifier instance
|
48
51
|
def configure
|
49
52
|
configuration.enabled = true if configuration.enabled.nil?
|
50
53
|
|
51
|
-
yield(configuration)
|
54
|
+
yield(configuration.configured_options)
|
52
55
|
end
|
53
56
|
|
54
57
|
def reconfigure
|
55
58
|
self.configuration = Configuration.new
|
56
59
|
configuration.enabled = true
|
57
60
|
|
58
|
-
yield(configuration)
|
61
|
+
yield(configuration.configured_options)
|
59
62
|
end
|
60
63
|
|
61
64
|
def unconfigure
|
@@ -95,17 +98,17 @@ module Rollbar
|
|
95
98
|
# @yield Block which exceptions won't be reported.
|
96
99
|
def silenced
|
97
100
|
yield
|
98
|
-
rescue => e
|
101
|
+
rescue StandardError => e
|
99
102
|
e.instance_variable_set(:@_rollbar_do_not_report, true)
|
100
103
|
raise
|
101
104
|
end
|
102
105
|
|
103
106
|
# Sends a report to Rollbar.
|
104
107
|
#
|
105
|
-
# Accepts any number of arguments. The last String
|
106
|
-
# the message or description of the report. The last
|
107
|
-
# will become the associated exception for the report.
|
108
|
-
# argument will be used as the extra data for the report.
|
108
|
+
# Accepts a level string plus any number of arguments. The last String
|
109
|
+
# argument will become the message or description of the report. The last
|
110
|
+
# Exception argument will become the associated exception for the report.
|
111
|
+
# The last hash argument will be used as the extra data for the report.
|
109
112
|
#
|
110
113
|
# If the extra hash contains a symbol key :custom_data_method_context
|
111
114
|
# the value of the key will be used as the context for
|
@@ -116,17 +119,17 @@ module Rollbar
|
|
116
119
|
# begin
|
117
120
|
# foo = bar
|
118
121
|
# rescue => e
|
119
|
-
# Rollbar.log(e)
|
122
|
+
# Rollbar.log('error', e)
|
120
123
|
# end
|
121
124
|
#
|
122
125
|
# @example
|
123
|
-
# Rollbar.log('This is a simple log message')
|
126
|
+
# Rollbar.log('info', 'This is a simple log message')
|
124
127
|
#
|
125
128
|
# @example
|
126
|
-
# Rollbar.log(e, 'This is a description of the exception')
|
129
|
+
# Rollbar.log('error', e, 'This is a description of the exception')
|
127
130
|
#
|
128
131
|
def log(level, *args)
|
129
|
-
return 'disabled' unless
|
132
|
+
return 'disabled' unless enabled?
|
130
133
|
|
131
134
|
message, exception, extra, context = extract_arguments(args)
|
132
135
|
use_exception_level_filters = use_exception_level_filters?(extra)
|
@@ -146,13 +149,25 @@ module Rollbar
|
|
146
149
|
level = lookup_exception_level(level, exception,
|
147
150
|
use_exception_level_filters)
|
148
151
|
|
149
|
-
|
150
|
-
report(level, message, exception, extra, context)
|
151
|
-
rescue StandardError, SystemStackError => e
|
152
|
-
report_internal_error(e)
|
152
|
+
ret = report_with_rescue(level, message, exception, extra, context)
|
153
153
|
|
154
|
-
|
155
|
-
|
154
|
+
raise(exception) if configuration.raise_on_error && exception
|
155
|
+
|
156
|
+
ret
|
157
|
+
end
|
158
|
+
|
159
|
+
def report_with_rescue(level, message, exception, extra, context)
|
160
|
+
report(level, message, exception, extra, context)
|
161
|
+
rescue StandardError, SystemStackError => e
|
162
|
+
original_error = {
|
163
|
+
:message => message,
|
164
|
+
:exception => exception,
|
165
|
+
:configuration => configuration
|
166
|
+
}
|
167
|
+
|
168
|
+
report_internal_error(e, original_error)
|
169
|
+
|
170
|
+
'error'
|
156
171
|
end
|
157
172
|
|
158
173
|
# See log() above
|
@@ -185,21 +200,28 @@ module Rollbar
|
|
185
200
|
log('critical', *args)
|
186
201
|
end
|
187
202
|
|
203
|
+
def enabled?
|
204
|
+
# Require access_token so we don't try to send events when unconfigured.
|
205
|
+
configuration.enabled && configuration.access_token && !configuration.access_token.empty?
|
206
|
+
end
|
207
|
+
|
188
208
|
def process_item(item)
|
189
209
|
if configuration.write_to_file
|
190
210
|
if configuration.use_async
|
191
|
-
|
192
|
-
|
211
|
+
MUTEX.synchronize do
|
212
|
+
do_write_item(item)
|
193
213
|
end
|
194
214
|
else
|
195
|
-
|
215
|
+
do_write_item(item)
|
196
216
|
end
|
197
217
|
else
|
198
218
|
send_item(item)
|
199
219
|
end
|
200
|
-
rescue => e
|
220
|
+
rescue StandardError => e
|
201
221
|
log_error("[Rollbar] Error processing the item: #{e.class}, #{e.message}. Item: #{item.payload.inspect}")
|
202
|
-
raise e
|
222
|
+
raise e unless via_failsafe?(item)
|
223
|
+
|
224
|
+
log_error('[Rollbar] Item has already failed. Not re-raising')
|
203
225
|
end
|
204
226
|
|
205
227
|
# We will reraise exceptions in this method so async queues
|
@@ -226,17 +248,20 @@ module Rollbar
|
|
226
248
|
# Using Rollbar.silenced we avoid the above behavior but Sidekiq
|
227
249
|
# will have a chance to retry the original job.
|
228
250
|
def process_from_async_handler(payload)
|
229
|
-
payload = Rollbar::JSON.load(payload) if payload.is_a?(String)
|
230
|
-
|
231
|
-
item = Item.build_with(payload,
|
232
|
-
:notifier => self,
|
233
|
-
:configuration => configuration,
|
234
|
-
:logger => logger)
|
235
|
-
|
236
251
|
Rollbar.silenced do
|
237
252
|
begin
|
238
|
-
|
239
|
-
|
253
|
+
if payload.is_a?(String)
|
254
|
+
# The final payload has already been built.
|
255
|
+
send_body(payload)
|
256
|
+
else
|
257
|
+
item = Item.build_with(payload,
|
258
|
+
:notifier => self,
|
259
|
+
:configuration => configuration,
|
260
|
+
:logger => logger)
|
261
|
+
|
262
|
+
process_item(item)
|
263
|
+
end
|
264
|
+
rescue StandardError => e
|
240
265
|
report_internal_error(e)
|
241
266
|
|
242
267
|
raise
|
@@ -244,35 +269,34 @@ module Rollbar
|
|
244
269
|
end
|
245
270
|
end
|
246
271
|
|
247
|
-
def
|
248
|
-
|
249
|
-
|
250
|
-
log_error "[Rollbar] Sending failsafe response due to #{exception_reason}"
|
251
|
-
|
252
|
-
body = failsafe_body(exception_reason)
|
253
|
-
|
254
|
-
failsafe_data = {
|
272
|
+
def failsafe_initial_data(exception_reason)
|
273
|
+
{
|
255
274
|
:level => 'error',
|
256
275
|
:environment => configuration.environment.to_s,
|
257
276
|
:body => {
|
258
277
|
:message => {
|
259
|
-
:body =>
|
278
|
+
:body => failsafe_body(exception_reason)
|
260
279
|
}
|
261
280
|
},
|
262
281
|
:notifier => {
|
263
282
|
:name => 'rollbar-gem',
|
264
283
|
:version => VERSION
|
265
284
|
},
|
266
|
-
:custom => {
|
267
|
-
:orig_uuid => uuid,
|
268
|
-
:orig_host => host
|
269
|
-
},
|
270
285
|
:internal => true,
|
271
|
-
|
286
|
+
'failsafe' => true
|
272
287
|
}
|
288
|
+
end
|
289
|
+
|
290
|
+
def send_failsafe(message, exception, original_error = nil)
|
291
|
+
exception_reason = failsafe_reason(message, exception)
|
292
|
+
|
293
|
+
log_error "[Rollbar] Sending failsafe response due to #{exception_reason}"
|
294
|
+
|
295
|
+
failsafe_data = failsafe_initial_data(exception_reason)
|
296
|
+
|
297
|
+
failsafe_add_original_error_data(failsafe_data[:notifier], original_error)
|
273
298
|
|
274
299
|
failsafe_payload = {
|
275
|
-
'access_token' => configuration.access_token,
|
276
300
|
'data' => failsafe_data
|
277
301
|
}
|
278
302
|
|
@@ -281,16 +305,69 @@ module Rollbar
|
|
281
305
|
:notifier => self,
|
282
306
|
:configuration => configuration,
|
283
307
|
:logger => logger)
|
284
|
-
|
285
|
-
|
308
|
+
|
309
|
+
process_item(item)
|
310
|
+
log_and_return_item_data(item)
|
311
|
+
rescue StandardError => e
|
286
312
|
log_error "[Rollbar] Error sending failsafe : #{e}"
|
287
313
|
end
|
288
314
|
|
289
315
|
failsafe_payload
|
290
316
|
end
|
291
317
|
|
318
|
+
def failsafe_add_original_error_data(payload_notifier, original_error)
|
319
|
+
return unless original_error
|
320
|
+
|
321
|
+
payload_notifier[:diagnostic] ||= {}
|
322
|
+
|
323
|
+
add_original_host(payload_notifier[:diagnostic], original_error)
|
324
|
+
add_original_uuid(payload_notifier[:diagnostic], original_error)
|
325
|
+
add_original_message(payload_notifier[:diagnostic], original_error)
|
326
|
+
add_original_error(payload_notifier[:diagnostic], original_error)
|
327
|
+
add_configured_options(payload_notifier, original_error)
|
328
|
+
end
|
329
|
+
|
330
|
+
def add_original_message(diagnostic, original_error)
|
331
|
+
diagnostic[:original_message] = original_error[:message].truncate(FAILSAFE_STRING_LENGTH) if original_error[:message]
|
332
|
+
|
333
|
+
rescue StandardError => e
|
334
|
+
diagnostic[:original_message] = "Failed: #{e.message}"
|
335
|
+
end
|
336
|
+
|
337
|
+
def add_original_error(diagnostic, original_error)
|
338
|
+
if original_error[:exception]
|
339
|
+
backtrace = original_error[:exception].backtrace
|
340
|
+
message = original_error[:exception].message
|
341
|
+
diagnostic[:original_error] = {
|
342
|
+
:message => message && message.truncate(FAILSAFE_STRING_LENGTH),
|
343
|
+
:stack => backtrace && backtrace.join(', ').truncate(FAILSAFE_STRING_LENGTH)
|
344
|
+
}
|
345
|
+
end
|
346
|
+
|
347
|
+
rescue StandardError => e
|
348
|
+
diagnostic[:original_error] = "Failed: #{e.message}"
|
349
|
+
end
|
350
|
+
|
351
|
+
def add_configured_options(payload_notifier, original_error)
|
352
|
+
if original_error[:configuration]
|
353
|
+
configured = original_error[:configuration].configured_options.configured
|
354
|
+
payload_notifier[:configured_options] = ::JSON.generate(configured).truncate(FAILSAFE_STRING_LENGTH)
|
355
|
+
end
|
356
|
+
|
357
|
+
rescue StandardError => e
|
358
|
+
payload_notifier[:configured_options] = "Failed: #{e.message}"
|
359
|
+
end
|
360
|
+
|
361
|
+
def add_original_host(diagnostic, original_error)
|
362
|
+
diagnostic[:original_host] = original_error[:host] if original_error[:host]
|
363
|
+
end
|
364
|
+
|
365
|
+
def add_original_uuid(diagnostic, original_error)
|
366
|
+
diagnostic[:original_uuid] = original_error[:uuid] if original_error[:uuid]
|
367
|
+
end
|
368
|
+
|
292
369
|
## Logging
|
293
|
-
%w
|
370
|
+
%w[debug info warn error].each do |level|
|
294
371
|
define_method(:"log_#{level}") do |message|
|
295
372
|
logger.send(level, message)
|
296
373
|
end
|
@@ -300,6 +377,30 @@ module Rollbar
|
|
300
377
|
@logger ||= LoggerProxy.new(configuration.logger)
|
301
378
|
end
|
302
379
|
|
380
|
+
def trace_with_bindings
|
381
|
+
@trace_with_bindings ||= TraceWithBindings.new
|
382
|
+
end
|
383
|
+
|
384
|
+
def exception_bindings
|
385
|
+
trace_with_bindings.exception_frames
|
386
|
+
end
|
387
|
+
|
388
|
+
def current_bindings
|
389
|
+
trace_with_bindings.frames
|
390
|
+
end
|
391
|
+
|
392
|
+
def enable_locals?
|
393
|
+
configuration.locals[:enabled] && [:app, :all].include?(configuration.send_extra_frame_data)
|
394
|
+
end
|
395
|
+
|
396
|
+
def enable_locals
|
397
|
+
trace_with_bindings.enable if enable_locals?
|
398
|
+
end
|
399
|
+
|
400
|
+
def disable_locals
|
401
|
+
trace_with_bindings.disable if enable_locals?
|
402
|
+
end
|
403
|
+
|
303
404
|
private
|
304
405
|
|
305
406
|
def use_exception_level_filters?(options)
|
@@ -326,7 +427,7 @@ module Rollbar
|
|
326
427
|
return 'ignored' if status == 'ignored'
|
327
428
|
rescue Rollbar::Ignore
|
328
429
|
raise
|
329
|
-
rescue => e
|
430
|
+
rescue StandardError => e
|
330
431
|
log_error("[Rollbar] Error calling the `before_process` hook: #{e}")
|
331
432
|
|
332
433
|
break
|
@@ -399,43 +500,52 @@ module Rollbar
|
|
399
500
|
|
400
501
|
return 'ignored' if item.ignored?
|
401
502
|
|
402
|
-
schedule_item(item)
|
503
|
+
schedule_item(item) if configuration.transmit
|
504
|
+
|
505
|
+
log_and_return_item_data(item)
|
506
|
+
end
|
403
507
|
|
508
|
+
def log_and_return_item_data(item)
|
404
509
|
data = item['data']
|
405
510
|
log_instance_link(data)
|
406
511
|
Rollbar.last_report = data
|
512
|
+
log_data(data) if configuration.log_payload
|
407
513
|
|
408
514
|
data
|
409
515
|
end
|
410
516
|
|
517
|
+
def log_data(data)
|
518
|
+
log_info "[Rollbar] Data: #{data}"
|
519
|
+
end
|
520
|
+
|
411
521
|
# Reports an internal error in the Rollbar library. This will be reported within the configured
|
412
522
|
# Rollbar project. We'll first attempt to provide a report including the exception traceback.
|
413
523
|
# If that fails, we'll fall back to a more static failsafe response.
|
414
|
-
def report_internal_error(exception)
|
524
|
+
def report_internal_error(exception, original_error = nil)
|
415
525
|
log_error '[Rollbar] Reporting internal error encountered while sending data to Rollbar.'
|
416
526
|
|
417
527
|
configuration.execute_hook(:on_report_internal_error, exception)
|
418
528
|
|
419
529
|
begin
|
420
530
|
item = build_item('error', nil, exception, { :internal => true }, nil)
|
421
|
-
rescue => e
|
422
|
-
send_failsafe('build_item in exception_data', e)
|
531
|
+
rescue StandardError => e
|
532
|
+
send_failsafe('build_item in exception_data', e, original_error)
|
423
533
|
log_error "[Rollbar] Exception: #{exception}"
|
424
534
|
return
|
425
535
|
end
|
426
536
|
|
427
537
|
begin
|
428
538
|
process_item(item)
|
429
|
-
rescue => e
|
430
|
-
send_failsafe('error in process_item', e)
|
539
|
+
rescue StandardError => e
|
540
|
+
send_failsafe('error in process_item', e, original_error)
|
431
541
|
log_error "[Rollbar] Item: #{item}"
|
432
542
|
return
|
433
543
|
end
|
434
544
|
|
435
545
|
begin
|
436
546
|
log_instance_link(item['data'])
|
437
|
-
rescue => e
|
438
|
-
send_failsafe('error logging instance link', e)
|
547
|
+
rescue StandardError => e
|
548
|
+
send_failsafe('error logging instance link', e, original_error)
|
439
549
|
log_error "[Rollbar] Item: #{item}"
|
440
550
|
return
|
441
551
|
end
|
@@ -464,14 +574,18 @@ module Rollbar
|
|
464
574
|
|
465
575
|
## Delivery functions
|
466
576
|
|
467
|
-
def
|
468
|
-
|
469
|
-
return unless body
|
577
|
+
def send_using_eventmachine(body)
|
578
|
+
uri = URI.parse(configuration.endpoint)
|
470
579
|
|
471
|
-
headers = { 'X-Rollbar-Access-Token' =>
|
580
|
+
headers = { 'X-Rollbar-Access-Token' => configuration.access_token }
|
472
581
|
options = http_proxy_for_em(uri)
|
473
582
|
req = EventMachine::HttpRequest.new(uri.to_s, options).post(:body => body, :head => headers)
|
474
583
|
|
584
|
+
eventmachine_callback(req)
|
585
|
+
eventmachine_errback(req)
|
586
|
+
end
|
587
|
+
|
588
|
+
def eventmachine_callback(req)
|
475
589
|
req.callback do
|
476
590
|
if req.response_header.status == 200
|
477
591
|
log_info '[Rollbar] Success'
|
@@ -480,7 +594,9 @@ module Rollbar
|
|
480
594
|
log_info "[Rollbar] Response: #{req.response}"
|
481
595
|
end
|
482
596
|
end
|
597
|
+
end
|
483
598
|
|
599
|
+
def eventmachine_errback(req)
|
484
600
|
req.errback do
|
485
601
|
log_warning "[Rollbar] Call to API failed, status code: #{req.response_header.status}"
|
486
602
|
log_info "[Rollbar] Error's response: #{req.response}"
|
@@ -493,14 +609,20 @@ module Rollbar
|
|
493
609
|
body = item.dump
|
494
610
|
return unless body
|
495
611
|
|
496
|
-
uri = URI.parse(configuration.endpoint)
|
497
|
-
|
498
612
|
if configuration.use_eventmachine
|
499
|
-
|
613
|
+
send_using_eventmachine(body)
|
500
614
|
return
|
501
615
|
end
|
502
616
|
|
503
|
-
|
617
|
+
send_body(body)
|
618
|
+
end
|
619
|
+
|
620
|
+
def send_body(body)
|
621
|
+
log_info '[Rollbar] Sending json'
|
622
|
+
|
623
|
+
uri = URI.parse(configuration.endpoint)
|
624
|
+
|
625
|
+
handle_response(do_post(uri, body, configuration.access_token))
|
504
626
|
end
|
505
627
|
|
506
628
|
def do_post(uri, body, access_token)
|
@@ -512,8 +634,6 @@ module Rollbar
|
|
512
634
|
|
513
635
|
if uri.scheme == 'https'
|
514
636
|
http.use_ssl = true
|
515
|
-
# This is needed to have 1.8.7 passing tests
|
516
|
-
http.ca_file = ENV['ROLLBAR_SSL_CERT_FILE'] if ENV.key?('ROLLBAR_SSL_CERT_FILE')
|
517
637
|
http.verify_mode = ssl_verify_mode
|
518
638
|
end
|
519
639
|
|
@@ -594,7 +714,7 @@ module Rollbar
|
|
594
714
|
end
|
595
715
|
|
596
716
|
def skip_retries?
|
597
|
-
Rollbar::LanguageSupport.
|
717
|
+
Rollbar::LanguageSupport.ruby_19?
|
598
718
|
end
|
599
719
|
|
600
720
|
def handle_response(response)
|
@@ -615,27 +735,24 @@ module Rollbar
|
|
615
735
|
end
|
616
736
|
end
|
617
737
|
|
618
|
-
def write_item(item)
|
619
|
-
if configuration.use_async
|
620
|
-
@file_semaphore.synchronize do
|
621
|
-
do_write_item(item)
|
622
|
-
end
|
623
|
-
else
|
624
|
-
do_write_item(item)
|
625
|
-
end
|
626
|
-
end
|
627
|
-
|
628
738
|
def do_write_item(item)
|
629
739
|
log_info '[Rollbar] Writing item to file'
|
630
740
|
|
631
741
|
body = item.dump
|
632
742
|
return unless body
|
633
743
|
|
744
|
+
file_name = if configuration.files_with_pid_name_enabled
|
745
|
+
configuration.filepath.gsub(EXTENSION_REGEXP, "_#{Process.pid}\\0")
|
746
|
+
else
|
747
|
+
configuration.filepath
|
748
|
+
end
|
749
|
+
|
634
750
|
begin
|
635
|
-
@file ||= File.open(
|
751
|
+
@file ||= File.open(file_name, 'a')
|
636
752
|
|
637
753
|
@file.puts(body)
|
638
754
|
@file.flush
|
755
|
+
update_file(@file, file_name)
|
639
756
|
|
640
757
|
log_info '[Rollbar] Success'
|
641
758
|
rescue IOError => e
|
@@ -643,6 +760,18 @@ module Rollbar
|
|
643
760
|
end
|
644
761
|
end
|
645
762
|
|
763
|
+
def update_file(file, file_name)
|
764
|
+
return unless configuration.files_processed_enabled
|
765
|
+
|
766
|
+
time_now = Time.now
|
767
|
+
return if configuration.files_processed_duration > time_now - file.birthtime && file.size < configuration.files_processed_size
|
768
|
+
|
769
|
+
new_file_name = file_name.gsub(EXTENSION_REGEXP, "_processed_#{time_now.to_i}\\0")
|
770
|
+
File.rename(file, new_file_name)
|
771
|
+
file.close
|
772
|
+
@file = File.open(file_name, 'a')
|
773
|
+
end
|
774
|
+
|
646
775
|
def failsafe_reason(message, exception)
|
647
776
|
body = ''
|
648
777
|
|
@@ -653,17 +782,17 @@ module Rollbar
|
|
653
782
|
|
654
783
|
exception_info = exception.class.name
|
655
784
|
# #to_s and #message defaults to class.to_s. Add message only if add valuable info.
|
656
|
-
exception_info += %
|
785
|
+
exception_info += %[: "#{exception.message}"] if exception.message != exception.class.to_s
|
657
786
|
exception_info += " in #{nearest_frame}" if nearest_frame
|
658
787
|
|
659
788
|
body += "#{exception_info}: #{message}"
|
660
|
-
rescue
|
789
|
+
rescue StandardError
|
661
790
|
log_error('[Rollbar] Error building failsafe exception message')
|
662
791
|
end
|
663
792
|
else
|
664
793
|
begin
|
665
794
|
body += message.to_s
|
666
|
-
rescue
|
795
|
+
rescue StandardError
|
667
796
|
log_error('[Rollbar] Error building failsafe message')
|
668
797
|
end
|
669
798
|
end
|
@@ -694,9 +823,12 @@ module Rollbar
|
|
694
823
|
end
|
695
824
|
|
696
825
|
def process_async_item(item)
|
826
|
+
# Send async payloads as JSON string when async_json_payload is set.
|
827
|
+
payload = configuration.async_json_payload ? item.dump : item.payload
|
828
|
+
|
697
829
|
configuration.async_handler ||= default_async_handler
|
698
|
-
configuration.async_handler.call(
|
699
|
-
rescue
|
830
|
+
configuration.async_handler.call(payload)
|
831
|
+
rescue StandardError
|
700
832
|
if configuration.failover_handlers.empty?
|
701
833
|
log_error '[Rollbar] Async handler failed, and there are no failover handlers configured. See the docs for "failover_handlers"'
|
702
834
|
return
|
@@ -713,7 +845,7 @@ module Rollbar
|
|
713
845
|
failover_handlers.each do |handler|
|
714
846
|
begin
|
715
847
|
handler.call(item.payload)
|
716
|
-
rescue
|
848
|
+
rescue StandardError
|
717
849
|
next unless handler == failover_handlers.last
|
718
850
|
|
719
851
|
log_error "[Rollbar] All failover handlers failed while processing item: #{Rollbar::JSON.dump(item.payload)}"
|
@@ -721,7 +853,7 @@ module Rollbar
|
|
721
853
|
end
|
722
854
|
end
|
723
855
|
|
724
|
-
|
856
|
+
alias log_warning log_warn
|
725
857
|
|
726
858
|
def log_instance_link(data)
|
727
859
|
return unless data[:uuid]
|
@@ -729,5 +861,9 @@ module Rollbar
|
|
729
861
|
uuid_url = Util.uuid_rollbar_url(data, configuration)
|
730
862
|
log_info "[Rollbar] Details: #{uuid_url} (only available if report was successful)"
|
731
863
|
end
|
864
|
+
|
865
|
+
def via_failsafe?(item)
|
866
|
+
item.payload.fetch('data', {}).fetch('failsafe', false)
|
867
|
+
end
|
732
868
|
end
|
733
869
|
end
|
data/lib/rollbar/plugin.rb
CHANGED
@@ -7,6 +7,8 @@ module Rollbar
|
|
7
7
|
attr_reader :name
|
8
8
|
attr_reader :dependencies
|
9
9
|
attr_reader :callables
|
10
|
+
attr_reader :revert_callables
|
11
|
+
attr_accessor :on_demand
|
10
12
|
attr_accessor :loaded
|
11
13
|
|
12
14
|
private :loaded=
|
@@ -15,31 +17,73 @@ module Rollbar
|
|
15
17
|
@name = name
|
16
18
|
@dependencies = []
|
17
19
|
@callables = []
|
20
|
+
@revert_callables = []
|
18
21
|
@loaded = false
|
22
|
+
@on_demand = false
|
23
|
+
end
|
24
|
+
|
25
|
+
def load_on_demand
|
26
|
+
@on_demand = true
|
19
27
|
end
|
20
28
|
|
21
29
|
def configuration
|
22
30
|
Rollbar.configuration
|
23
31
|
end
|
24
32
|
|
33
|
+
def load_scoped!(transparent = false)
|
34
|
+
if transparent
|
35
|
+
load! if load?
|
36
|
+
|
37
|
+
result = yield
|
38
|
+
|
39
|
+
unload! if loaded
|
40
|
+
else
|
41
|
+
return unless load?
|
42
|
+
|
43
|
+
load!
|
44
|
+
|
45
|
+
result = yield
|
46
|
+
|
47
|
+
unload!
|
48
|
+
end
|
49
|
+
|
50
|
+
result
|
51
|
+
end
|
52
|
+
|
25
53
|
def load!
|
26
54
|
return unless load?
|
27
55
|
|
28
56
|
begin
|
29
57
|
callables.each(&:call)
|
30
|
-
rescue => e
|
58
|
+
rescue StandardError => e
|
31
59
|
log_loading_error(e)
|
32
60
|
ensure
|
33
61
|
self.loaded = true
|
34
62
|
end
|
35
63
|
end
|
36
64
|
|
65
|
+
def unload!
|
66
|
+
return unless loaded
|
67
|
+
|
68
|
+
begin
|
69
|
+
revert_callables.each(&:call)
|
70
|
+
rescue StandardError => e
|
71
|
+
log_unloading_error(e)
|
72
|
+
ensure
|
73
|
+
self.loaded = false
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
37
77
|
def execute(&block)
|
38
78
|
callables << block
|
39
79
|
end
|
40
80
|
|
41
|
-
def execute!
|
42
|
-
|
81
|
+
def execute!
|
82
|
+
yield if load?
|
83
|
+
end
|
84
|
+
|
85
|
+
def revert(&block)
|
86
|
+
revert_callables << block
|
43
87
|
end
|
44
88
|
|
45
89
|
private
|
@@ -61,7 +105,7 @@ module Rollbar
|
|
61
105
|
|
62
106
|
def load?
|
63
107
|
!loaded && dependencies_satisfy?
|
64
|
-
rescue => e
|
108
|
+
rescue StandardError => e
|
65
109
|
log_loading_error(e)
|
66
110
|
|
67
111
|
false
|
@@ -71,8 +115,12 @@ module Rollbar
|
|
71
115
|
dependencies.all?(&:call)
|
72
116
|
end
|
73
117
|
|
74
|
-
def log_loading_error(
|
75
|
-
Rollbar.log_error("Error trying to load plugin '#{name}': #{
|
118
|
+
def log_loading_error(error)
|
119
|
+
Rollbar.log_error("Error trying to load plugin '#{name}': #{error.class}, #{error.message}")
|
120
|
+
end
|
121
|
+
|
122
|
+
def log_unloading_error(error)
|
123
|
+
Rollbar.log_error("Error trying to unload plugin '#{name}': #{error.class}, #{error.message}")
|
76
124
|
end
|
77
125
|
end
|
78
126
|
end
|