rollbar 2.19.2 → 2.19.3

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.
Files changed (68) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +27 -0
  3. data/Appraisals +10 -10
  4. data/Gemfile +2 -0
  5. data/README.md +4 -1
  6. data/Rakefile +0 -0
  7. data/data/rollbar.snippet.js +1 -1
  8. data/gemfiles/rails30.gemfile +2 -0
  9. data/gemfiles/rails31.gemfile +2 -0
  10. data/gemfiles/rails32.gemfile +2 -0
  11. data/gemfiles/rails40.gemfile +2 -0
  12. data/gemfiles/rails41.gemfile +2 -0
  13. data/gemfiles/rails42.gemfile +2 -0
  14. data/gemfiles/rails50.gemfile +2 -0
  15. data/gemfiles/rails51.gemfile +2 -0
  16. data/gemfiles/rails52.gemfile +2 -0
  17. data/gemfiles/ruby_1_8_and_1_9_2.gemfile +2 -0
  18. data/lib/generators/rollbar/rollbar_generator.rb +1 -1
  19. data/lib/rails/rollbar_runner.rb +1 -1
  20. data/lib/rollbar.rb +2 -3
  21. data/lib/rollbar/capistrano3.rb +6 -3
  22. data/lib/rollbar/capistrano_tasks.rb +13 -15
  23. data/lib/rollbar/configuration.rb +10 -8
  24. data/lib/rollbar/delay/girl_friday.rb +2 -2
  25. data/lib/rollbar/delay/resque.rb +4 -6
  26. data/lib/rollbar/delay/sidekiq.rb +6 -10
  27. data/lib/rollbar/delay/sucker_punch.rb +17 -19
  28. data/lib/rollbar/delay/thread.rb +2 -2
  29. data/lib/rollbar/deploy.rb +47 -30
  30. data/lib/rollbar/encoding/encoder.rb +9 -9
  31. data/lib/rollbar/item.rb +7 -7
  32. data/lib/rollbar/item/backtrace.rb +4 -4
  33. data/lib/rollbar/item/frame.rb +7 -1
  34. data/lib/rollbar/item/locals.rb +56 -0
  35. data/lib/rollbar/json.rb +5 -2
  36. data/lib/rollbar/json/default.rb +1 -1
  37. data/lib/rollbar/json/oj.rb +1 -1
  38. data/lib/rollbar/language_support.rb +1 -1
  39. data/lib/rollbar/lazy_store.rb +5 -5
  40. data/lib/rollbar/logger.rb +1 -0
  41. data/lib/rollbar/logger_proxy.rb +1 -1
  42. data/lib/rollbar/middleware/js.rb +15 -15
  43. data/lib/rollbar/middleware/rack.rb +4 -1
  44. data/lib/rollbar/middleware/rails/rollbar.rb +10 -1
  45. data/lib/rollbar/notifier.rb +40 -15
  46. data/lib/rollbar/notifier/trace_with_bindings.rb +65 -0
  47. data/lib/rollbar/plugin.rb +54 -6
  48. data/lib/rollbar/plugins.rb +7 -1
  49. data/lib/rollbar/plugins/basic_socket.rb +21 -6
  50. data/lib/rollbar/plugins/delayed_job/job_data.rb +3 -3
  51. data/lib/rollbar/plugins/delayed_job/plugin.rb +2 -2
  52. data/lib/rollbar/plugins/goalie.rb +11 -3
  53. data/lib/rollbar/plugins/rails/controller_methods.rb +15 -3
  54. data/lib/rollbar/plugins/rake.rb +2 -2
  55. data/lib/rollbar/plugins/sidekiq/plugin.rb +5 -4
  56. data/lib/rollbar/rake_tasks.rb +2 -2
  57. data/lib/rollbar/request_data_extractor.rb +21 -18
  58. data/lib/rollbar/scrubbers.rb +7 -3
  59. data/lib/rollbar/scrubbers/params.rb +17 -16
  60. data/lib/rollbar/scrubbers/url.rb +8 -3
  61. data/lib/rollbar/truncation.rb +1 -1
  62. data/lib/rollbar/truncation/strings_strategy.rb +1 -1
  63. data/lib/rollbar/util/ip_anonymizer.rb +8 -7
  64. data/lib/rollbar/util/ip_obfuscator.rb +1 -1
  65. data/lib/rollbar/version.rb +1 -1
  66. data/lib/tasks/benchmark.rake +103 -0
  67. data/rollbar.gemspec +13 -4
  68. metadata +12 -5
@@ -1,7 +1,7 @@
1
1
  module Rollbar
2
2
  module JSON
3
3
  module Oj
4
- extend self
4
+ module_function
5
5
 
6
6
  def options
7
7
  {
@@ -1,6 +1,6 @@
1
1
  module Rollbar
2
2
  module LanguageSupport
3
- extend self
3
+ module_function
4
4
 
5
5
  def const_defined?(mod, target, inherit = true)
6
6
  if ruby_18?
@@ -21,11 +21,11 @@ module Rollbar
21
21
  end
22
22
 
23
23
  def ==(other)
24
- if other.is_a?(self.class)
25
- raw == other.raw
26
- else
27
- raw == other
28
- end
24
+ raw == if other.is_a?(self.class)
25
+ other.raw
26
+ else
27
+ other
28
+ end
29
29
  end
30
30
 
31
31
  # With this version of clone we ensure that the loaded_data is empty
@@ -67,6 +67,7 @@ module Rollbar
67
67
 
68
68
  def blank?(message)
69
69
  return message.blank? if message.respond_to?(:blank?)
70
+
70
71
  message.respond_to?(:empty?) ? !!message.empty? : !message
71
72
  end
72
73
 
@@ -26,7 +26,7 @@ module Rollbar
26
26
  return unless Rollbar.configuration.enabled && acceptable_levels.include?(level.to_sym)
27
27
 
28
28
  @object.send(level, message)
29
- rescue
29
+ rescue StandardError
30
30
  puts "[Rollbar] Error logging #{level}:"
31
31
  puts "[Rollbar] #{message}"
32
32
  end
@@ -13,7 +13,7 @@ module Rollbar
13
13
  attr_reader :app
14
14
  attr_reader :config
15
15
 
16
- JS_IS_INJECTED_KEY = 'rollbar.js_is_injected'
16
+ JS_IS_INJECTED_KEY = 'rollbar.js_is_injected'.freeze
17
17
  SNIPPET = File.read(File.expand_path('../../../../data/rollbar.snippet.js', __FILE__))
18
18
 
19
19
  def initialize(app, config)
@@ -29,7 +29,7 @@ module Rollbar
29
29
 
30
30
  response_string = add_js(env, app_result[2])
31
31
  build_response(env, app_result, response_string)
32
- rescue => e
32
+ rescue StandardError => e
33
33
  Rollbar.log_error("[Rollbar] Rollbar.js could not be added because #{e} exception")
34
34
 
35
35
  app_result
@@ -71,7 +71,7 @@ module Rollbar
71
71
  return nil unless insert_after_idx
72
72
 
73
73
  build_body_with_js(env, body, insert_after_idx)
74
- rescue => e
74
+ rescue StandardError => e
75
75
  Rollbar.log_error("[Rollbar] Rollbar.js could not be added because #{e} exception")
76
76
  nil
77
77
  end
@@ -189,17 +189,17 @@ module Rollbar
189
189
 
190
190
  secure_headers_cls = nil
191
191
 
192
- if !::SecureHeaders::respond_to?(:content_security_policy_script_nonce)
193
- secure_headers_cls = SecureHeadersFalse
194
- elsif config.respond_to?(:get)
195
- secure_headers_cls = SecureHeaders3To5
196
- elsif config.dup.respond_to?(:csp)
197
- secure_headers_cls = SecureHeaders6
198
- else
199
- secure_headers_cls = SecureHeadersFalse
200
- end
201
-
202
- secure_headers_cls.new
192
+ secure_headers_cls = if !::SecureHeaders.respond_to?(:content_security_policy_script_nonce)
193
+ SecureHeadersFalse
194
+ elsif config.respond_to?(:get)
195
+ SecureHeaders3To5
196
+ elsif config.dup.respond_to?(:csp)
197
+ SecureHeaders6
198
+ else
199
+ SecureHeadersFalse
200
+ end
201
+
202
+ secure_headers_cls.new
203
203
  end
204
204
 
205
205
  class SecureHeadersResolver
@@ -217,7 +217,7 @@ module Rollbar
217
217
  !opt_out?(csp) && !unsafe_inline?(csp)
218
218
  end
219
219
 
220
- def opt_out?(csp)
220
+ def opt_out?(_csp)
221
221
  raise NotImplementedError
222
222
  end
223
223
 
@@ -17,12 +17,15 @@ module Rollbar
17
17
 
18
18
  Rollbar.scoped(fetch_scope(env)) do
19
19
  begin
20
+ Rollbar.notifier.enable_locals
20
21
  response = @app.call(env)
21
22
  report_exception_to_rollbar(env, framework_error(env)) if framework_error(env)
22
23
  response
23
24
  rescue Exception => e
24
25
  report_exception_to_rollbar(env, e)
25
26
  raise
27
+ ensure
28
+ Rollbar.notifier.disable_locals
26
29
  end
27
30
  end
28
31
  end
@@ -41,7 +44,7 @@ module Rollbar
41
44
  proc { extract_person_data_from_controller(env) }
42
45
  end
43
46
 
44
- def framework_error(env)
47
+ def framework_error(_env)
45
48
  nil
46
49
  end
47
50
  end
@@ -21,6 +21,7 @@ module Rollbar
21
21
 
22
22
  Rollbar.scoped(scope) do
23
23
  begin
24
+ Rollbar.notifier.enable_locals
24
25
  response = @app.call(env)
25
26
 
26
27
  if (framework_exception = env['action_dispatch.exception'])
@@ -31,6 +32,8 @@ module Rollbar
31
32
  rescue Exception => exception
32
33
  report_exception_to_rollbar(env, exception)
33
34
  raise
35
+ ensure
36
+ Rollbar.notifier.disable_locals
34
37
  end
35
38
  end
36
39
  end
@@ -62,7 +65,13 @@ module Rollbar
62
65
  block = proc { extract_person_data_from_controller(env) }
63
66
  return block unless defined?(ActiveRecord::Base) && ActiveRecord::Base.connected?
64
67
 
65
- proc { ActiveRecord::Base.connection_pool.with_connection(&block) }
68
+ proc do
69
+ begin
70
+ ActiveRecord::Base.connection_pool.with_connection(&block)
71
+ rescue ActiveRecord::ConnectionTimeoutError
72
+ {}
73
+ end
74
+ end
66
75
  end
67
76
 
68
77
  def context(request_data)
@@ -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
@@ -95,7 +96,7 @@ module Rollbar
95
96
  # @yield Block which exceptions won't be reported.
96
97
  def silenced
97
98
  yield
98
- rescue => e
99
+ rescue StandardError => e
99
100
  e.instance_variable_set(:@_rollbar_do_not_report, true)
100
101
  raise
101
102
  end
@@ -202,7 +203,7 @@ module Rollbar
202
203
  else
203
204
  send_item(item)
204
205
  end
205
- rescue => e
206
+ rescue StandardError => e
206
207
  log_error("[Rollbar] Error processing the item: #{e.class}, #{e.message}. Item: #{item.payload.inspect}")
207
208
  raise e
208
209
  end
@@ -241,7 +242,7 @@ module Rollbar
241
242
  Rollbar.silenced do
242
243
  begin
243
244
  process_item(item)
244
- rescue => e
245
+ rescue StandardError => e
245
246
  report_internal_error(e)
246
247
 
247
248
  raise
@@ -287,7 +288,7 @@ module Rollbar
287
288
  :configuration => configuration,
288
289
  :logger => logger)
289
290
  schedule_item(item)
290
- rescue => e
291
+ rescue StandardError => e
291
292
  log_error "[Rollbar] Error sending failsafe : #{e}"
292
293
  end
293
294
 
@@ -295,7 +296,7 @@ module Rollbar
295
296
  end
296
297
 
297
298
  ## Logging
298
- %w(debug info warn error).each do |level|
299
+ %w[debug info warn error].each do |level|
299
300
  define_method(:"log_#{level}") do |message|
300
301
  logger.send(level, message)
301
302
  end
@@ -305,6 +306,30 @@ module Rollbar
305
306
  @logger ||= LoggerProxy.new(configuration.logger)
306
307
  end
307
308
 
309
+ def trace_with_bindings
310
+ @trace_with_bindings ||= TraceWithBindings.new
311
+ end
312
+
313
+ def exception_bindings
314
+ trace_with_bindings.exception_frames
315
+ end
316
+
317
+ def current_bindings
318
+ trace_with_bindings.frames
319
+ end
320
+
321
+ def enable_locals?
322
+ configuration.locals[:enabled] && [:app, :all].include?(configuration.send_extra_frame_data)
323
+ end
324
+
325
+ def enable_locals
326
+ trace_with_bindings.enable if enable_locals?
327
+ end
328
+
329
+ def disable_locals
330
+ trace_with_bindings.disable if enable_locals?
331
+ end
332
+
308
333
  private
309
334
 
310
335
  def use_exception_level_filters?(options)
@@ -331,7 +356,7 @@ module Rollbar
331
356
  return 'ignored' if status == 'ignored'
332
357
  rescue Rollbar::Ignore
333
358
  raise
334
- rescue => e
359
+ rescue StandardError => e
335
360
  log_error("[Rollbar] Error calling the `before_process` hook: #{e}")
336
361
 
337
362
  break
@@ -423,7 +448,7 @@ module Rollbar
423
448
 
424
449
  begin
425
450
  item = build_item('error', nil, exception, { :internal => true }, nil)
426
- rescue => e
451
+ rescue StandardError => e
427
452
  send_failsafe('build_item in exception_data', e)
428
453
  log_error "[Rollbar] Exception: #{exception}"
429
454
  return
@@ -431,7 +456,7 @@ module Rollbar
431
456
 
432
457
  begin
433
458
  process_item(item)
434
- rescue => e
459
+ rescue StandardError => e
435
460
  send_failsafe('error in process_item', e)
436
461
  log_error "[Rollbar] Item: #{item}"
437
462
  return
@@ -439,7 +464,7 @@ module Rollbar
439
464
 
440
465
  begin
441
466
  log_instance_link(item['data'])
442
- rescue => e
467
+ rescue StandardError => e
443
468
  send_failsafe('error logging instance link', e)
444
469
  log_error "[Rollbar] Item: #{item}"
445
470
  return
@@ -658,17 +683,17 @@ module Rollbar
658
683
 
659
684
  exception_info = exception.class.name
660
685
  # #to_s and #message defaults to class.to_s. Add message only if add valuable info.
661
- exception_info += %(: "#{exception.message}") if exception.message != exception.class.to_s
686
+ exception_info += %[: "#{exception.message}"] if exception.message != exception.class.to_s
662
687
  exception_info += " in #{nearest_frame}" if nearest_frame
663
688
 
664
689
  body += "#{exception_info}: #{message}"
665
- rescue
690
+ rescue StandardError
666
691
  log_error('[Rollbar] Error building failsafe exception message')
667
692
  end
668
693
  else
669
694
  begin
670
695
  body += message.to_s
671
- rescue
696
+ rescue StandardError
672
697
  log_error('[Rollbar] Error building failsafe message')
673
698
  end
674
699
  end
@@ -701,7 +726,7 @@ module Rollbar
701
726
  def process_async_item(item)
702
727
  configuration.async_handler ||= default_async_handler
703
728
  configuration.async_handler.call(item.payload)
704
- rescue
729
+ rescue StandardError
705
730
  if configuration.failover_handlers.empty?
706
731
  log_error '[Rollbar] Async handler failed, and there are no failover handlers configured. See the docs for "failover_handlers"'
707
732
  return
@@ -718,7 +743,7 @@ module Rollbar
718
743
  failover_handlers.each do |handler|
719
744
  begin
720
745
  handler.call(item.payload)
721
- rescue
746
+ rescue StandardError
722
747
  next unless handler == failover_handlers.last
723
748
 
724
749
  log_error "[Rollbar] All failover handlers failed while processing item: #{Rollbar::JSON.dump(item.payload)}"
@@ -726,7 +751,7 @@ module Rollbar
726
751
  end
727
752
  end
728
753
 
729
- alias_method :log_warning, :log_warn
754
+ alias log_warning log_warn
730
755
 
731
756
  def log_instance_link(data)
732
757
  return unless data[:uuid]
@@ -0,0 +1,65 @@
1
+ module Rollbar
2
+ class Notifier
3
+ class TraceWithBindings # :nodoc:
4
+ attr_reader :frames, :exception_frames
5
+
6
+ def initialize
7
+ reset
8
+ end
9
+
10
+ def reset
11
+ @frames = []
12
+ @exception_frames = []
13
+ @exception_signature = nil
14
+ end
15
+
16
+ def enable
17
+ reset
18
+ trace_point.enable if defined?(TracePoint)
19
+ end
20
+
21
+ def disable
22
+ trace_point.disable if defined?(TracePoint)
23
+ end
24
+
25
+ private
26
+
27
+ def exception_signature(trace)
28
+ # use the exception backtrace to detect reraised exception.
29
+ trace.raised_exception.backtrace.first
30
+ end
31
+
32
+ def detect_reraise(trace)
33
+ @exception_signature == exception_signature(trace)
34
+ end
35
+
36
+ def trace_point
37
+ return unless defined?(TracePoint)
38
+
39
+ @trace_point ||= TracePoint.new(:call, :return, :b_call, :b_return, :c_call, :c_return, :raise) do |tp|
40
+ case tp.event
41
+ when :call, :b_call, :c_call, :class
42
+ frames.push frame(tp)
43
+ when :return, :b_return, :c_return, :end
44
+ frames.pop
45
+ when :raise
46
+ unless detect_reraise(tp) # ignore reraised exceptions
47
+ @exception_frames = @frames.dup # may be possible to optimize better than #dup
48
+ @exception_signature = exception_signature(tp)
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ def frame(trace)
55
+ {
56
+ :binding => trace.binding,
57
+ :defined_class => trace.defined_class,
58
+ :method_id => trace.method_id,
59
+ :path => trace.path,
60
+ :lineno => trace.lineno
61
+ }
62
+ end
63
+ end
64
+ end
65
+ end
@@ -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!(&block)
42
- block.call if load?
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(e)
75
- Rollbar.log_error("Error trying to load plugin '#{name}': #{e.class}, #{e.message}")
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