rollbar 2.19.1 → 2.27.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|