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
@@ -1,9 +1,8 @@
|
|
1
1
|
module Rollbar
|
2
2
|
module Encoding
|
3
3
|
class Encoder
|
4
|
-
ALL_ENCODINGS = [::Encoding::UTF_8, ::Encoding::ISO_8859_1, ::Encoding::ASCII_8BIT, ::Encoding::US_ASCII]
|
5
|
-
ASCII_ENCODINGS = [::Encoding::US_ASCII, ::Encoding::ASCII_8BIT, ::Encoding::ISO_8859_1]
|
6
|
-
ENCODING_OPTIONS = { :invalid => :replace, :undef => :replace, :replace => '' }
|
4
|
+
ALL_ENCODINGS = [::Encoding::UTF_8, ::Encoding::ISO_8859_1, ::Encoding::ASCII_8BIT, ::Encoding::US_ASCII].freeze
|
5
|
+
ASCII_ENCODINGS = [::Encoding::US_ASCII, ::Encoding::ASCII_8BIT, ::Encoding::ISO_8859_1].freeze
|
7
6
|
UTF8 = 'UTF-8'.freeze
|
8
7
|
BINARY = 'binary'.freeze
|
9
8
|
|
@@ -18,13 +17,22 @@ module Rollbar
|
|
18
17
|
encoding = value.encoding
|
19
18
|
|
20
19
|
# This will be most of cases so avoid force anything for them
|
21
|
-
if encoding == ::Encoding::UTF_8 && value.valid_encoding?
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
encoded_value = if encoding == ::Encoding::UTF_8 && value.valid_encoding?
|
21
|
+
value
|
22
|
+
else
|
23
|
+
force_encoding(value).encode(
|
24
|
+
*encoding_args(value),
|
25
|
+
# Ruby 2.7 requires this to look like keyword args,
|
26
|
+
# and Ruby 1.9.3 doesn't understand keyword args, so
|
27
|
+
# don't use hash rockets here and both will be happy.
|
28
|
+
invalid: :replace, undef: :replace, replace: '' # rubocop:disable Style/HashSyntax
|
29
|
+
)
|
30
|
+
end
|
26
31
|
|
27
32
|
object.is_a?(Symbol) ? encoded_value.to_sym : encoded_value
|
33
|
+
rescue StandardError => e
|
34
|
+
# If encoding fails for any reason, replace the string with a diagnostic error.
|
35
|
+
"error encoding string: #{e.class}: #{e.message}"
|
28
36
|
end
|
29
37
|
|
30
38
|
private
|
@@ -45,7 +53,7 @@ module Rollbar
|
|
45
53
|
# Seems #codepoints is faster than #valid_encoding?
|
46
54
|
value.force_encoding(encoding).encode(::Encoding::UTF_8).codepoints
|
47
55
|
true
|
48
|
-
rescue
|
56
|
+
rescue StandardError
|
49
57
|
false
|
50
58
|
end
|
51
59
|
end
|
@@ -54,7 +62,6 @@ module Rollbar
|
|
54
62
|
def encoding_args(value)
|
55
63
|
args = [UTF8]
|
56
64
|
args << BINARY if ASCII_ENCODINGS.include?(value.encoding)
|
57
|
-
args << ENCODING_OPTIONS
|
58
65
|
|
59
66
|
args
|
60
67
|
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
module Rollbar
|
2
|
-
module ExceptionReporter
|
2
|
+
module ExceptionReporter # :nodoc:
|
3
3
|
def report_exception_to_rollbar(env, exception)
|
4
|
-
|
5
|
-
|
4
|
+
return unless capture_uncaught?
|
5
|
+
|
6
|
+
log_exception_message(exception)
|
6
7
|
|
7
|
-
exception_data =
|
8
|
+
exception_data = exception_data(exception)
|
8
9
|
|
9
10
|
if exception_data.is_a?(Hash)
|
10
11
|
env['rollbar.exception_uuid'] = exception_data[:uuid]
|
@@ -14,8 +15,21 @@ module Rollbar
|
|
14
15
|
elsif exception_data == 'ignored'
|
15
16
|
Rollbar.log_debug '[Rollbar] Exception not reported because it was ignored'
|
16
17
|
end
|
17
|
-
rescue => e
|
18
|
+
rescue StandardError => e
|
18
19
|
Rollbar.log_warning "[Rollbar] Exception while reporting exception to Rollbar: #{e.message}"
|
19
20
|
end
|
21
|
+
|
22
|
+
def capture_uncaught?
|
23
|
+
Rollbar.configuration.capture_uncaught != false
|
24
|
+
end
|
25
|
+
|
26
|
+
def log_exception_message(exception)
|
27
|
+
exception_message = exception.respond_to?(:message) ? exception.message : 'No Exception Message'
|
28
|
+
Rollbar.log_debug "[Rollbar] Reporting exception: #{exception_message}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def exception_data(exception)
|
32
|
+
Rollbar.log(Rollbar.configuration.uncaught_exception_level, exception, :use_exception_level_filters => true)
|
33
|
+
end
|
20
34
|
end
|
21
35
|
end
|
@@ -32,7 +32,7 @@ module Rollbar
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
|
35
|
+
alias build to_h
|
36
36
|
|
37
37
|
def get_file_lines(filename)
|
38
38
|
files[filename] ||= read_file(filename)
|
@@ -44,7 +44,7 @@ module Rollbar
|
|
44
44
|
return unless File.exist?(filename)
|
45
45
|
|
46
46
|
File.read(filename).split("\n")
|
47
|
-
rescue
|
47
|
+
rescue StandardError
|
48
48
|
nil
|
49
49
|
end
|
50
50
|
|
@@ -74,10 +74,20 @@ module Rollbar
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def map_frames(current_exception)
|
77
|
-
|
77
|
+
frames = cleaned_backtrace(current_exception).map do |frame|
|
78
78
|
Rollbar::Item::Frame.new(self, frame,
|
79
79
|
:configuration => configuration).to_h
|
80
80
|
end
|
81
|
+
frames.reverse!
|
82
|
+
end
|
83
|
+
|
84
|
+
def cleaned_backtrace(current_exception)
|
85
|
+
normalized_backtrace = exception_backtrace(current_exception)
|
86
|
+
if configuration.backtrace_cleaner
|
87
|
+
configuration.backtrace_cleaner.clean(normalized_backtrace)
|
88
|
+
else
|
89
|
+
normalized_backtrace
|
90
|
+
end
|
81
91
|
end
|
82
92
|
|
83
93
|
# Returns the backtrace to be sent to our API. There are 3 options:
|
data/lib/rollbar/item/frame.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# We want to use Gem.path
|
2
2
|
require 'rubygems'
|
3
|
+
require 'rollbar/item/locals'
|
3
4
|
|
4
5
|
module Rollbar
|
5
6
|
class Item
|
@@ -47,7 +48,8 @@ module Rollbar
|
|
47
48
|
|
48
49
|
{
|
49
50
|
:code => code_data(file_lines, lineno),
|
50
|
-
:context => context_data(file_lines, lineno)
|
51
|
+
:context => context_data(file_lines, lineno),
|
52
|
+
:locals => locals_data(filename, lineno)
|
51
53
|
}
|
52
54
|
end
|
53
55
|
|
@@ -94,6 +96,12 @@ module Rollbar
|
|
94
96
|
}
|
95
97
|
end
|
96
98
|
|
99
|
+
def locals_data(filename, lineno)
|
100
|
+
return unless configuration.locals[:enabled]
|
101
|
+
|
102
|
+
::Rollbar::Item::Locals.locals_for_location(filename, lineno)
|
103
|
+
end
|
104
|
+
|
97
105
|
def post_data(file_lines, lineno)
|
98
106
|
from_line = lineno
|
99
107
|
number_of_lines = [from_line + MAX_CONTEXT_LENGTH, file_lines.size].min - from_line
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'rollbar/notifier'
|
2
|
+
require 'rollbar/scrubbers/params'
|
3
|
+
require 'rollbar/util'
|
4
|
+
|
5
|
+
module Rollbar
|
6
|
+
class Item
|
7
|
+
class Locals # :nodoc:
|
8
|
+
class << self
|
9
|
+
def exception_frames
|
10
|
+
Rollbar.notifier.exception_bindings
|
11
|
+
end
|
12
|
+
|
13
|
+
def locals_for_location(filename, lineno)
|
14
|
+
if (frame = frame_for_location(filename, lineno))
|
15
|
+
scrub(locals_for(frame[:binding]))
|
16
|
+
else
|
17
|
+
{}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def frame_for_location(filename, lineno)
|
22
|
+
while (frame = exception_frames.pop)
|
23
|
+
return nil unless frame
|
24
|
+
return frame if matching_frame?(frame, filename, lineno)
|
25
|
+
end
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def matching_frame?(frame, filename, lineno)
|
32
|
+
frame[:path] == filename && frame[:lineno].to_i <= lineno.to_i
|
33
|
+
end
|
34
|
+
|
35
|
+
def locals_for(frame)
|
36
|
+
{}.tap do |hash|
|
37
|
+
frame.local_variables.map do |var|
|
38
|
+
hash[var] = prepare_value(frame.local_variable_get(var))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Prepare objects to be handled by the payload serializer.
|
44
|
+
#
|
45
|
+
# Hashes and Arrays are traversed. Then all types execpt strings and
|
46
|
+
# immediates are exported using #inspect. Sending the object itself to the
|
47
|
+
# serializer can result in large recursive expansions, especially in Rails
|
48
|
+
# environments with ActiveRecord, ActiveSupport, etc. on the stack.
|
49
|
+
# Other export options could be #to_s, #to_h, and #as_json. Several of these
|
50
|
+
# will omit the class name, or are not implemented for many types.
|
51
|
+
#
|
52
|
+
# #inspect has the advantage that it is specifically intended for debugging
|
53
|
+
# output. If the user wants more or different information in the payload
|
54
|
+
# about a specific type, #inspect is the correct place to implement it.
|
55
|
+
# Likewise the default implementation should be oriented toward usefulness
|
56
|
+
# in debugging.
|
57
|
+
#
|
58
|
+
# Because #inspect outputs a string, it can be handled well by the string
|
59
|
+
# truncation strategy for large payloads.
|
60
|
+
#
|
61
|
+
def prepare_value(value)
|
62
|
+
return simple_value?(value) ? value : value.inspect unless value.is_a?(Hash) || value.is_a?(Array)
|
63
|
+
|
64
|
+
cloned_value = ::Rollbar::Util.deep_copy(value)
|
65
|
+
::Rollbar::Util.iterate_and_update_with_block(cloned_value) do |v|
|
66
|
+
simple_value?(v) ? v : v.inspect
|
67
|
+
end
|
68
|
+
|
69
|
+
cloned_value
|
70
|
+
end
|
71
|
+
|
72
|
+
def simple_classes
|
73
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
|
74
|
+
[String, Symbol, Integer, Float, TrueClass, FalseClass, NilClass]
|
75
|
+
else
|
76
|
+
[String, Symbol, Fixnum, Bignum, Float, TrueClass, FalseClass, NilClass] # rubocop:disable Lint/UnifiedInteger
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def simple_value?(value)
|
81
|
+
simple_classes.each do |klass|
|
82
|
+
# Use instance_of? so that subclasses and module containers will
|
83
|
+
# be treated like complex object types, not simple values.
|
84
|
+
return true if value.instance_of?(klass)
|
85
|
+
end
|
86
|
+
|
87
|
+
false
|
88
|
+
end
|
89
|
+
|
90
|
+
def scrub(hash)
|
91
|
+
Rollbar::Scrubbers::Params.call(
|
92
|
+
:params => hash,
|
93
|
+
:config => Rollbar.configuration.scrub_fields,
|
94
|
+
:whitelist => Rollbar.configuration.scrub_whitelist
|
95
|
+
)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/lib/rollbar/item.rb
CHANGED
@@ -12,6 +12,7 @@ require 'rollbar/util'
|
|
12
12
|
require 'rollbar/encoding'
|
13
13
|
require 'rollbar/truncation'
|
14
14
|
require 'rollbar/json'
|
15
|
+
require 'rollbar/scrubbers/params'
|
15
16
|
|
16
17
|
module Rollbar
|
17
18
|
# This class represents the payload to be sent to the API.
|
@@ -64,7 +65,6 @@ module Rollbar
|
|
64
65
|
def build
|
65
66
|
data = build_data
|
66
67
|
self.payload = {
|
67
|
-
'access_token' => configuration.access_token,
|
68
68
|
'data' => data
|
69
69
|
}
|
70
70
|
|
@@ -83,7 +83,8 @@ module Rollbar
|
|
83
83
|
:server => server_data,
|
84
84
|
:notifier => {
|
85
85
|
:name => 'rollbar-gem',
|
86
|
-
:version => VERSION
|
86
|
+
:version => VERSION,
|
87
|
+
:configured_options => configured_options
|
87
88
|
},
|
88
89
|
:body => build_body
|
89
90
|
}
|
@@ -101,29 +102,61 @@ module Rollbar
|
|
101
102
|
data
|
102
103
|
end
|
103
104
|
|
105
|
+
def configured_options
|
106
|
+
if Gem.loaded_specs['activesupport'] && Gem.loaded_specs['activesupport'].version < Gem::Version.new('4.1')
|
107
|
+
# There are too many types that crash ActiveSupport JSON serialization, and not worth
|
108
|
+
# the risk just to send this diagnostic object. In versions < 4.1, ActiveSupport hooks
|
109
|
+
# Ruby's JSON.generate so deeply there's no workaround.
|
110
|
+
'not serialized in ActiveSupport < 4.1'
|
111
|
+
elsif configuration.use_async && !configuration.async_json_payload
|
112
|
+
# The setting allows serialization to be performed by each handler,
|
113
|
+
# and this usually means it is actually performed by ActiveSupport,
|
114
|
+
# which cannot safely serialize this key.
|
115
|
+
'not serialized when async_json_payload is not set'
|
116
|
+
else
|
117
|
+
scrub(configuration.configured_options.configured)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
104
121
|
def dump
|
105
122
|
# Ensure all keys are strings since we can receive the payload inline or
|
106
123
|
# from an async handler job, which can be serialized.
|
107
124
|
stringified_payload = Util::Hash.deep_stringify_keys(payload)
|
108
|
-
|
125
|
+
attempts = []
|
126
|
+
result = Truncation.truncate(stringified_payload, attempts)
|
109
127
|
|
110
128
|
return result unless Truncation.truncate?(result)
|
111
129
|
|
112
|
-
handle_too_large_payload(stringified_payload, result)
|
130
|
+
handle_too_large_payload(stringified_payload, result, attempts)
|
113
131
|
|
114
132
|
nil
|
115
133
|
end
|
116
134
|
|
117
|
-
def handle_too_large_payload(stringified_payload, final_payload)
|
118
|
-
original_size = Rollbar::JSON.dump(stringified_payload).bytesize
|
119
|
-
final_size = final_payload.bytesize
|
135
|
+
def handle_too_large_payload(stringified_payload, final_payload, attempts)
|
120
136
|
uuid = stringified_payload['data']['uuid']
|
121
137
|
host = stringified_payload['data'].fetch('server', {})['host']
|
122
138
|
|
123
|
-
|
139
|
+
original_error = {
|
140
|
+
:message => message,
|
141
|
+
:exception => exception,
|
142
|
+
:configuration => configuration,
|
143
|
+
:uuid => uuid,
|
144
|
+
:host => host
|
145
|
+
}
|
146
|
+
|
147
|
+
notifier.send_failsafe(
|
148
|
+
too_large_payload_string(attempts),
|
149
|
+
nil,
|
150
|
+
original_error
|
151
|
+
)
|
124
152
|
logger.error("[Rollbar] Payload too large to be sent for UUID #{uuid}: #{Rollbar::JSON.dump(payload)}")
|
125
153
|
end
|
126
154
|
|
155
|
+
def too_large_payload_string(attempts)
|
156
|
+
'Could not send payload due to it being too large after truncating attempts. ' \
|
157
|
+
"Original size: #{attempts.first} Attempts: #{attempts.join(', ')} Final size: #{attempts.last}"
|
158
|
+
end
|
159
|
+
|
127
160
|
def ignored?
|
128
161
|
data = payload['data']
|
129
162
|
|
@@ -156,13 +189,19 @@ module Rollbar
|
|
156
189
|
end
|
157
190
|
|
158
191
|
def build_extra
|
192
|
+
merged_extra = Util.deep_merge(scrub(extra), scrub(error_context))
|
193
|
+
|
159
194
|
if custom_data_method? && !Rollbar::Util.method_in_stack(:custom_data, __FILE__)
|
160
|
-
Util.deep_merge(scrub(custom_data),
|
195
|
+
Util.deep_merge(scrub(custom_data), merged_extra)
|
161
196
|
else
|
162
|
-
|
197
|
+
merged_extra.empty? ? nil : merged_extra # avoid putting an empty {} in the payload.
|
163
198
|
end
|
164
199
|
end
|
165
200
|
|
201
|
+
def error_context
|
202
|
+
exception.respond_to?(:rollbar_context) && exception.rollbar_context
|
203
|
+
end
|
204
|
+
|
166
205
|
def scrub(data)
|
167
206
|
return data unless data.is_a? Hash
|
168
207
|
|
@@ -179,14 +218,14 @@ module Rollbar
|
|
179
218
|
end
|
180
219
|
|
181
220
|
def custom_data
|
182
|
-
if configuration.custom_data_method.arity == 3
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
221
|
+
data = if configuration.custom_data_method.arity == 3
|
222
|
+
configuration.custom_data_method.call(message, exception, context)
|
223
|
+
else
|
224
|
+
configuration.custom_data_method.call
|
225
|
+
end
|
187
226
|
|
188
227
|
Rollbar::Util.deep_copy(data)
|
189
|
-
rescue => e
|
228
|
+
rescue StandardError => e
|
190
229
|
return {} if configuration.safely?
|
191
230
|
|
192
231
|
report_custom_data_error(e)
|
@@ -231,7 +270,7 @@ module Rollbar
|
|
231
270
|
handlers.each do |handler|
|
232
271
|
begin
|
233
272
|
handler.call(transform_options)
|
234
|
-
rescue => e
|
273
|
+
rescue StandardError => e
|
235
274
|
logger.error("[Rollbar] Error calling the `transform` hook: #{e}")
|
236
275
|
|
237
276
|
break
|
data/lib/rollbar/json.rb
CHANGED
@@ -1,65 +1,20 @@
|
|
1
|
-
require 'multi_json'
|
2
|
-
require 'rollbar/json/oj'
|
3
|
-
require 'rollbar/json/default'
|
4
1
|
require 'rollbar/language_support'
|
5
|
-
|
6
|
-
begin
|
7
|
-
require 'oj'
|
8
|
-
rescue LoadError
|
9
|
-
end
|
2
|
+
require 'json'
|
10
3
|
|
11
4
|
module Rollbar
|
12
|
-
module JSON
|
5
|
+
module JSON # :nodoc:
|
13
6
|
extend self
|
14
7
|
|
15
8
|
attr_writer :options_module
|
16
9
|
|
17
10
|
def dump(object)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
def load(string)
|
22
|
-
with_adapter { MultiJson.load(string, adapter_options) }
|
23
|
-
end
|
24
|
-
|
25
|
-
def with_adapter(&block)
|
26
|
-
MultiJson.with_adapter(detect_multi_json_adapter, &block)
|
27
|
-
end
|
28
|
-
|
29
|
-
def detect_multi_json_adapter
|
30
|
-
options = {}
|
31
|
-
options[:adapter] = :oj if defined?(::Oj)
|
32
|
-
|
33
|
-
MultiJson.current_adapter(options)
|
34
|
-
end
|
35
|
-
|
36
|
-
def adapter_options
|
37
|
-
options_module.options
|
38
|
-
end
|
39
|
-
|
40
|
-
def options_module
|
41
|
-
@options_module ||= find_options_module
|
42
|
-
end
|
43
|
-
|
44
|
-
def find_options_module
|
45
|
-
module_name = multi_json_adapter_module_name
|
46
|
-
|
47
|
-
if LanguageSupport.const_defined?(Rollbar::JSON, module_name, false)
|
48
|
-
LanguageSupport.const_get(Rollbar::JSON, module_name, false)
|
49
|
-
else
|
50
|
-
Default
|
11
|
+
Rollbar.plugins.get('basic_socket').load_scoped!(true) do
|
12
|
+
::JSON.generate(object)
|
51
13
|
end
|
52
14
|
end
|
53
15
|
|
54
|
-
|
55
|
-
|
56
|
-
#
|
57
|
-
# Ex: MultiJson::Adapters::Oj
|
58
|
-
# Ex: MultiJson::Adapters::JsonGem
|
59
|
-
#
|
60
|
-
# In this method we just get the last module name.
|
61
|
-
def multi_json_adapter_module_name
|
62
|
-
detect_multi_json_adapter.name[/^MultiJson::Adapters::(.*)$/, 1]
|
16
|
+
def load(string)
|
17
|
+
::JSON.parse(string)
|
63
18
|
end
|
64
19
|
end
|
65
20
|
end
|
@@ -1,29 +1,13 @@
|
|
1
1
|
module Rollbar
|
2
2
|
module LanguageSupport
|
3
|
-
|
3
|
+
module_function
|
4
4
|
|
5
5
|
def const_defined?(mod, target, inherit = true)
|
6
|
-
|
7
|
-
mod.const_defined?(target)
|
8
|
-
else
|
9
|
-
mod.const_defined?(target, inherit)
|
10
|
-
end
|
6
|
+
mod.const_defined?(target, inherit)
|
11
7
|
end
|
12
8
|
|
13
9
|
def const_get(mod, target, inherit = true)
|
14
|
-
|
15
|
-
mod.const_get(target)
|
16
|
-
else
|
17
|
-
mod.const_get(target, inherit)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def can_scrub_url?
|
22
|
-
!version?('1.8')
|
23
|
-
end
|
24
|
-
|
25
|
-
def ruby_18?
|
26
|
-
version?('1.8')
|
10
|
+
mod.const_get(target, inherit)
|
27
11
|
end
|
28
12
|
|
29
13
|
def ruby_19?
|
@@ -37,7 +21,7 @@ module Rollbar
|
|
37
21
|
end
|
38
22
|
|
39
23
|
def timeout_exceptions
|
40
|
-
return [] if
|
24
|
+
return [] if ruby_19?
|
41
25
|
|
42
26
|
[Net::ReadTimeout, Net::OpenTimeout]
|
43
27
|
end
|
data/lib/rollbar/lazy_store.rb
CHANGED
@@ -21,11 +21,11 @@ module Rollbar
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def ==(other)
|
24
|
-
if other.is_a?(self.class)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
data/lib/rollbar/logger.rb
CHANGED
data/lib/rollbar/logger_proxy.rb
CHANGED
@@ -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
|
@@ -36,7 +36,11 @@ module Rollbar
|
|
36
36
|
def acceptable_levels
|
37
37
|
@acceptable_levels ||= begin
|
38
38
|
levels = [:debug, :info, :warn, :error]
|
39
|
-
|
39
|
+
if Rollbar.configuration.logger_level
|
40
|
+
levels[levels.find_index(Rollbar.configuration.logger_level)..-1]
|
41
|
+
else
|
42
|
+
[]
|
43
|
+
end
|
40
44
|
end
|
41
45
|
end
|
42
46
|
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
|
@@ -80,10 +80,18 @@ module Rollbar
|
|
80
80
|
return app_result unless response_string
|
81
81
|
|
82
82
|
env[JS_IS_INJECTED_KEY] = true
|
83
|
-
response = ::Rack::Response.new(response_string, app_result[0],
|
84
|
-
app_result[1])
|
85
83
|
|
86
|
-
|
84
|
+
status, headers, = app_result
|
85
|
+
headers['Content-Length'] = response_string.bytesize.to_s if headers.key?('Content-Length')
|
86
|
+
|
87
|
+
response = ::Rack::Response.new(response_string, status, headers)
|
88
|
+
|
89
|
+
finished = response.finish
|
90
|
+
|
91
|
+
# Rack < 2.x Response#finish returns self in array[2]. Rack >= 2.x returns self.body.
|
92
|
+
# Always return with the response object here regardless of rack version.
|
93
|
+
finished[2] = response
|
94
|
+
finished
|
87
95
|
end
|
88
96
|
|
89
97
|
def build_body_with_js(env, body, head_open_end)
|
@@ -116,6 +124,8 @@ module Rollbar
|
|
116
124
|
end
|
117
125
|
|
118
126
|
def config_js_tag(env)
|
127
|
+
require 'json'
|
128
|
+
|
119
129
|
js_config = Rollbar::Util.deep_copy(config[:options])
|
120
130
|
|
121
131
|
add_person_data(js_config, env)
|
@@ -189,17 +199,17 @@ module Rollbar
|
|
189
199
|
|
190
200
|
secure_headers_cls = nil
|
191
201
|
|
192
|
-
if !::SecureHeaders
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
202
|
+
secure_headers_cls = if !::SecureHeaders.respond_to?(:content_security_policy_script_nonce)
|
203
|
+
SecureHeadersFalse
|
204
|
+
elsif config.respond_to?(:get)
|
205
|
+
SecureHeaders3To5
|
206
|
+
elsif config.dup.respond_to?(:csp)
|
207
|
+
SecureHeaders6
|
208
|
+
else
|
209
|
+
SecureHeadersFalse
|
210
|
+
end
|
211
|
+
|
212
|
+
secure_headers_cls.new
|
203
213
|
end
|
204
214
|
|
205
215
|
class SecureHeadersResolver
|
@@ -217,7 +227,7 @@ module Rollbar
|
|
217
227
|
!opt_out?(csp) && !unsafe_inline?(csp)
|
218
228
|
end
|
219
229
|
|
220
|
-
def opt_out?(
|
230
|
+
def opt_out?(_csp)
|
221
231
|
raise NotImplementedError
|
222
232
|
end
|
223
233
|
|