rollbar 2.16.2 → 2.22.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/.rubocop.yml +47 -0
- data/.travis.yml +182 -94
- data/Appraisals +10 -10
- data/Gemfile +45 -13
- data/README.md +20 -3
- data/Rakefile +0 -0
- data/data/rollbar.snippet.js +1 -1
- data/docs/configuration.md +15 -0
- data/gemfiles/rails30.gemfile +21 -14
- data/gemfiles/rails31.gemfile +21 -12
- data/gemfiles/rails32.gemfile +18 -8
- data/gemfiles/rails40.gemfile +18 -6
- data/gemfiles/rails41.gemfile +17 -6
- data/gemfiles/rails42.gemfile +24 -14
- data/gemfiles/rails50.gemfile +20 -11
- data/gemfiles/rails51.gemfile +20 -10
- data/gemfiles/rails52.gemfile +65 -0
- data/gemfiles/rails60.gemfile +67 -0
- data/lib/generators/rollbar/rollbar_generator.rb +1 -1
- data/lib/rails/rollbar_runner.rb +17 -2
- data/lib/rollbar.rb +2 -3
- data/lib/rollbar/capistrano.rb +71 -39
- data/lib/rollbar/capistrano3.rb +56 -1
- data/lib/rollbar/capistrano_tasks.rb +130 -0
- data/lib/rollbar/configuration.rb +95 -7
- data/lib/rollbar/delay/active_job.rb +17 -0
- data/lib/rollbar/delay/girl_friday.rb +2 -2
- data/lib/rollbar/delay/resque.rb +4 -6
- data/lib/rollbar/delay/shoryuken.rb +15 -9
- data/lib/rollbar/delay/sidekiq.rb +6 -8
- data/lib/rollbar/delay/sucker_punch.rb +17 -19
- data/lib/rollbar/delay/thread.rb +3 -3
- data/lib/rollbar/deploy.rb +90 -0
- data/lib/rollbar/encoding/encoder.rb +9 -9
- data/lib/rollbar/exception_reporter.rb +19 -5
- data/lib/rollbar/item.rb +62 -20
- data/lib/rollbar/item/backtrace.rb +4 -4
- data/lib/rollbar/item/frame.rb +7 -1
- data/lib/rollbar/item/locals.rb +56 -0
- data/lib/rollbar/json.rb +5 -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 +15 -2
- data/lib/rollbar/middleware/js.rb +110 -10
- data/lib/rollbar/middleware/js/json_value.rb +26 -0
- data/lib/rollbar/middleware/rack.rb +4 -1
- data/lib/rollbar/middleware/rails/rollbar.rb +10 -1
- data/lib/rollbar/notifier.rb +118 -49
- data/lib/rollbar/notifier/trace_with_bindings.rb +65 -0
- data/lib/rollbar/plugin.rb +54 -6
- data/lib/rollbar/plugins.rb +7 -1
- data/lib/rollbar/plugins/active_job.rb +5 -1
- 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 +3 -3
- data/lib/rollbar/plugins/goalie.rb +11 -3
- data/lib/rollbar/plugins/rails/controller_methods.rb +17 -4
- data/lib/rollbar/plugins/rails/railtie_mixin.rb +7 -3
- data/lib/rollbar/plugins/rake.rb +2 -2
- data/lib/rollbar/plugins/sidekiq/plugin.rb +10 -6
- data/lib/rollbar/rake_tasks.rb +3 -86
- data/lib/rollbar/request_data_extractor.rb +35 -21
- data/lib/rollbar/rollbar_test.rb +147 -0
- data/lib/rollbar/scrubbers.rb +7 -3
- data/lib/rollbar/scrubbers/params.rb +38 -20
- data/lib/rollbar/scrubbers/url.rb +27 -13
- data/lib/rollbar/truncation.rb +9 -2
- data/lib/rollbar/truncation/min_body_strategy.rb +2 -3
- 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 +3 -4
- data/lib/rollbar/util.rb +75 -45
- data/lib/rollbar/util/hash.rb +30 -6
- data/lib/rollbar/util/ip_anonymizer.rb +8 -7
- data/lib/rollbar/util/ip_obfuscator.rb +1 -1
- data/lib/rollbar/version.rb +1 -1
- data/lib/tasks/benchmark.rake +103 -0
- data/rollbar.gemspec +14 -8
- metadata +25 -277
- 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/tasks/rollbar.cap +0 -47
- data/spec/cacert.pem +0 -3988
- data/spec/controllers/home_controller_spec.rb +0 -480
- data/spec/delay/sidekiq_spec.rb +0 -61
- data/spec/delay/sucker_punch_spec.rb +0 -25
- data/spec/delayed/backend/test.rb +0 -140
- data/spec/delayed/serialization/test.rb +0 -0
- data/spec/dummyapp/.gitignore +0 -73
- data/spec/dummyapp/Rakefile +0 -7
- data/spec/dummyapp/app/assets/javascripts/application.js +0 -3
- data/spec/dummyapp/app/assets/stylesheets/application.css.scss +0 -37
- data/spec/dummyapp/app/controllers/application_controller.rb +0 -3
- data/spec/dummyapp/app/controllers/home_controller.rb +0 -60
- data/spec/dummyapp/app/controllers/users_controller.rb +0 -17
- data/spec/dummyapp/app/helpers/.gitkeep +0 -0
- data/spec/dummyapp/app/mailers/.gitkeep +0 -0
- data/spec/dummyapp/app/models/.gitkeep +0 -0
- data/spec/dummyapp/app/models/book.rb +0 -5
- data/spec/dummyapp/app/models/post.rb +0 -9
- data/spec/dummyapp/app/models/user.rb +0 -9
- data/spec/dummyapp/app/views/devise/registrations/edit.html.erb +0 -27
- data/spec/dummyapp/app/views/devise/registrations/new.html.erb +0 -20
- data/spec/dummyapp/app/views/devise/shared/_links.html.erb +0 -25
- data/spec/dummyapp/app/views/home/cause_exception.html.erb +0 -1
- data/spec/dummyapp/app/views/home/index.html.erb +0 -4
- data/spec/dummyapp/app/views/home/report_exception.html.erb +0 -1
- data/spec/dummyapp/app/views/js/test.html.erb +0 -1
- data/spec/dummyapp/app/views/layouts/_messages.html.erb +0 -5
- data/spec/dummyapp/app/views/layouts/_navigation.html.erb +0 -21
- data/spec/dummyapp/app/views/layouts/application.html.erb +0 -25
- data/spec/dummyapp/app/views/layouts/simple.html.erb +0 -18
- data/spec/dummyapp/app/views/users/index.html.erb +0 -8
- data/spec/dummyapp/app/views/users/show.html.erb +0 -3
- data/spec/dummyapp/config.ru +0 -4
- data/spec/dummyapp/config/application.rb +0 -59
- data/spec/dummyapp/config/boot.rb +0 -10
- data/spec/dummyapp/config/database.yml +0 -25
- data/spec/dummyapp/config/environment.rb +0 -5
- data/spec/dummyapp/config/environments/development.rb +0 -37
- data/spec/dummyapp/config/environments/production.rb +0 -67
- data/spec/dummyapp/config/environments/test.rb +0 -37
- data/spec/dummyapp/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/dummyapp/config/initializers/inflections.rb +0 -15
- data/spec/dummyapp/config/initializers/mime_types.rb +0 -5
- data/spec/dummyapp/config/initializers/rollbar.rb +0 -26
- data/spec/dummyapp/config/initializers/secret_token.rb +0 -7
- data/spec/dummyapp/config/initializers/session_store.rb +0 -8
- data/spec/dummyapp/config/initializers/wrap_parameters.rb +0 -16
- data/spec/dummyapp/config/locales/devise.en.yml +0 -58
- data/spec/dummyapp/config/locales/en.yml +0 -5
- data/spec/dummyapp/config/routes.rb +0 -17
- data/spec/dummyapp/config/secrets.yml +0 -2
- data/spec/dummyapp/db/migrate/20121121184652_devise_create_users.rb +0 -46
- data/spec/dummyapp/db/migrate/20121121184654_add_name_to_users.rb +0 -5
- data/spec/dummyapp/db/migrate/20161219184410_create_books.rb +0 -10
- data/spec/dummyapp/db/migrate/20161219185529_add_username_to_users.rb +0 -5
- data/spec/dummyapp/db/schema.rb +0 -41
- data/spec/dummyapp/db/seeds.rb +0 -12
- data/spec/dummyapp/lib/assets/.gitkeep +0 -0
- data/spec/dummyapp/public/404.html +0 -26
- data/spec/dummyapp/public/422.html +0 -26
- data/spec/dummyapp/public/500.html +0 -25
- data/spec/dummyapp/public/favicon.ico +0 -0
- data/spec/dummyapp/script/rails +0 -6
- data/spec/fixtures/file1 +0 -1
- data/spec/fixtures/file2 +0 -1
- data/spec/fixtures/payloads/message.json +0 -25
- data/spec/fixtures/payloads/sample.trace.json +0 -275
- data/spec/fixtures/payloads/sample.trace_chain.json +0 -530
- data/spec/fixtures/plugins/dummy1.rb +0 -5
- data/spec/fixtures/plugins/dummy2.rb +0 -5
- data/spec/generators/rollbar/rollbar_generator_rails30_spec.rb +0 -31
- data/spec/generators/rollbar/rollbar_generator_spec.rb +0 -51
- data/spec/requests/home_spec.rb +0 -49
- data/spec/rollbar/configuration_spec.rb +0 -46
- data/spec/rollbar/delay/delayed_job_spec.rb +0 -22
- data/spec/rollbar/delay/girl_friday_spec.rb +0 -41
- data/spec/rollbar/delay/resque_spec.rb +0 -37
- data/spec/rollbar/delay/thread_spec.rb +0 -27
- data/spec/rollbar/encoding/encoder_spec.rb +0 -63
- data/spec/rollbar/item/backtrace_spec.rb +0 -26
- data/spec/rollbar/item/frame_spec.rb +0 -267
- data/spec/rollbar/item_spec.rb +0 -736
- data/spec/rollbar/json/oj_spec.rb +0 -18
- data/spec/rollbar/json_spec.rb +0 -110
- data/spec/rollbar/lazy_store_spec.rb +0 -99
- data/spec/rollbar/logger_proxy_spec.rb +0 -50
- data/spec/rollbar/logger_spec.rb +0 -124
- data/spec/rollbar/middleware/js_spec.rb +0 -421
- data/spec/rollbar/middleware/sinatra_spec.rb +0 -197
- data/spec/rollbar/notifier_spec.rb +0 -56
- data/spec/rollbar/plugin_spec.rb +0 -209
- data/spec/rollbar/plugins/active_job_spec.rb +0 -38
- data/spec/rollbar/plugins/delayed_job/job_data_spec.rb +0 -48
- data/spec/rollbar/plugins/delayed_job_spec.rb +0 -129
- data/spec/rollbar/plugins/rack_spec.rb +0 -152
- data/spec/rollbar/plugins/rails_js_spec.rb +0 -19
- data/spec/rollbar/plugins/rake_spec.rb +0 -34
- data/spec/rollbar/plugins/resque/failure_spec.rb +0 -36
- data/spec/rollbar/plugins/sidekiq_spec.rb +0 -171
- data/spec/rollbar/plugins/validations_spec.rb +0 -56
- data/spec/rollbar/plugins_spec.rb +0 -68
- data/spec/rollbar/request_data_extractor_spec.rb +0 -270
- data/spec/rollbar/scrubbers/params_spec.rb +0 -314
- data/spec/rollbar/scrubbers/url_spec.rb +0 -136
- data/spec/rollbar/scrubbers_spec.rb +0 -31
- data/spec/rollbar/sidekig/clear_scope_spec.rb +0 -19
- data/spec/rollbar/truncation/frames_strategy_spec.rb +0 -70
- data/spec/rollbar/truncation/min_body_strategy_spec.rb +0 -57
- data/spec/rollbar/truncation/strings_strategy_spec.rb +0 -89
- data/spec/rollbar/truncation_spec.rb +0 -27
- data/spec/rollbar/util/hash_spec.rb +0 -22
- data/spec/rollbar/util/ip_anonymizer_spec.rb +0 -30
- data/spec/rollbar/util_spec.rb +0 -80
- data/spec/rollbar_bc_spec.rb +0 -380
- data/spec/rollbar_spec.rb +0 -1667
- data/spec/spec_helper.rb +0 -84
- data/spec/support/cause_exception.rb +0 -1
- data/spec/support/encoding_helpers.rb +0 -8
- data/spec/support/encodings/iso_8859_9 +0 -1
- data/spec/support/fixture_helpers.rb +0 -10
- data/spec/support/get_ip_raising.rb +0 -7
- data/spec/support/helpers.rb +0 -5
- data/spec/support/matchers.rb +0 -23
- data/spec/support/notifier_helpers.rb +0 -57
- data/spec/support/rollbar_api.rb +0 -57
- data/spec/support/shared_contexts.rb +0 -12
data/lib/rollbar/truncation.rb
CHANGED
|
@@ -4,6 +4,9 @@ require 'rollbar/truncation/raw_strategy'
|
|
|
4
4
|
require 'rollbar/truncation/frames_strategy'
|
|
5
5
|
require 'rollbar/truncation/strings_strategy'
|
|
6
6
|
require 'rollbar/truncation/min_body_strategy'
|
|
7
|
+
require 'rollbar/truncation/remove_request_strategy'
|
|
8
|
+
require 'rollbar/truncation/remove_extra_strategy'
|
|
9
|
+
require 'rollbar/truncation/remove_any_key_strategy'
|
|
7
10
|
|
|
8
11
|
module Rollbar
|
|
9
12
|
module Truncation
|
|
@@ -13,13 +16,17 @@ module Rollbar
|
|
|
13
16
|
STRATEGIES = [RawStrategy,
|
|
14
17
|
FramesStrategy,
|
|
15
18
|
StringsStrategy,
|
|
16
|
-
MinBodyStrategy
|
|
19
|
+
MinBodyStrategy,
|
|
20
|
+
RemoveRequestStrategy,
|
|
21
|
+
RemoveExtraStrategy,
|
|
22
|
+
RemoveAnyKeyStrategy].freeze
|
|
17
23
|
|
|
18
|
-
def self.truncate(payload)
|
|
24
|
+
def self.truncate(payload, attempts = [])
|
|
19
25
|
result = nil
|
|
20
26
|
|
|
21
27
|
STRATEGIES.each do |strategy|
|
|
22
28
|
result = strategy.call(payload)
|
|
29
|
+
attempts << result.bytesize
|
|
23
30
|
break unless truncate?(result)
|
|
24
31
|
end
|
|
25
32
|
|
|
@@ -11,8 +11,7 @@ module Rollbar
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def call(payload)
|
|
14
|
-
|
|
15
|
-
body = new_payload['data']['body']
|
|
14
|
+
body = payload['data']['body']
|
|
16
15
|
|
|
17
16
|
if body['trace_chain']
|
|
18
17
|
body['trace_chain'] = body['trace_chain'].map do |trace_data|
|
|
@@ -22,7 +21,7 @@ module Rollbar
|
|
|
22
21
|
body['trace'] = truncate_trace_data(body['trace'])
|
|
23
22
|
end
|
|
24
23
|
|
|
25
|
-
dump(
|
|
24
|
+
dump(payload)
|
|
26
25
|
end
|
|
27
26
|
|
|
28
27
|
def truncate_trace_data(trace_data)
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
require 'rollbar/util'
|
|
2
|
+
|
|
3
|
+
module Rollbar
|
|
4
|
+
module Truncation
|
|
5
|
+
class RemoveAnyKeyStrategy
|
|
6
|
+
include ::Rollbar::Truncation::Mixin
|
|
7
|
+
|
|
8
|
+
attr_accessor :payload, :data, :sizes, :extracted_title
|
|
9
|
+
|
|
10
|
+
def self.call(payload)
|
|
11
|
+
new(payload).call
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def initialize(payload)
|
|
15
|
+
@payload = payload
|
|
16
|
+
@data = payload['data']
|
|
17
|
+
@extracted_title = extract_title(data['body']) if data['body']
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def call
|
|
21
|
+
remove_unknown_root_keys
|
|
22
|
+
|
|
23
|
+
json_payload = remove_oversized_data_keys
|
|
24
|
+
|
|
25
|
+
return json_payload if json_payload
|
|
26
|
+
|
|
27
|
+
dump(payload)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def remove_unknown_root_keys
|
|
31
|
+
payload.keys.reject { |key| root_keys.include?(key) }.each do |key|
|
|
32
|
+
truncation_key['root'] ||= {}
|
|
33
|
+
size = dump(payload.delete(key)).bytesize
|
|
34
|
+
truncation_key['root'][key] = "unknown root key removed, size: #{size} bytes"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def remove_oversized_data_keys
|
|
39
|
+
data_keys.keys.sort { |a, b| data_keys[b] <=> data_keys[a] }.each do |key|
|
|
40
|
+
json_payload = remove_key_and_return_payload(key)
|
|
41
|
+
|
|
42
|
+
return json_payload unless truncate?(json_payload)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
false
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def remove_key_and_return_payload(key)
|
|
49
|
+
size = data_keys[key]
|
|
50
|
+
|
|
51
|
+
data.delete(key)
|
|
52
|
+
|
|
53
|
+
replace_message_body if key == 'body'
|
|
54
|
+
|
|
55
|
+
truncation_key[key] = "key removed, size: #{size} bytes"
|
|
56
|
+
|
|
57
|
+
dump(payload)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def replace_message_body
|
|
61
|
+
data['body'] = message_key
|
|
62
|
+
data['title'] ||= extracted_title if extracted_title
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def truncation_key
|
|
66
|
+
@truncation_key ||=
|
|
67
|
+
# initialize the diagnostic key for truncation
|
|
68
|
+
(data['notifier']['diagnostic'] ||= {}) &&
|
|
69
|
+
(data['notifier']['diagnostic']['truncation'] ||= {})
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def root_keys
|
|
73
|
+
# Valid keys in root of payload
|
|
74
|
+
%w[access_token data]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def skip_keys
|
|
78
|
+
# Don't try to truncate these data keys
|
|
79
|
+
%w[notifier uuid title platform language framework level]
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def message_key
|
|
83
|
+
# use this message if data.body gets removed
|
|
84
|
+
{
|
|
85
|
+
'message' => {
|
|
86
|
+
'body' => 'Payload keys removed due to oversized payload. See diagnostic key'
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def extract_title(body)
|
|
92
|
+
return body['message']['body'] if body['message'] && body['message']['body']
|
|
93
|
+
return extract_title_from_trace(body['trace']) if body['trace']
|
|
94
|
+
return extract_title_from_trace(body['trace_chain'][0]) if body['trace_chain'] && body['trace_chain'][0]
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def extract_title_from_trace(trace)
|
|
98
|
+
exception = trace['exception']
|
|
99
|
+
|
|
100
|
+
"#{exception['class']}: #{exception['message']}"
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def data_keys
|
|
104
|
+
@data_keys ||= {}.tap do |hash|
|
|
105
|
+
data.keys.reject { |key| skip_keys.include?(key) }.each do |key|
|
|
106
|
+
set_key_size(key, hash)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def set_key_size(key, hash)
|
|
112
|
+
size = dump(data[key]).bytesize
|
|
113
|
+
hash[key] = size
|
|
114
|
+
rescue ::JSON::GeneratorError
|
|
115
|
+
hash[key] = 0 # don't try to truncate non JSON object
|
|
116
|
+
|
|
117
|
+
# Log it
|
|
118
|
+
truncation_key['non_json_keys'] ||= {}
|
|
119
|
+
truncation_key['non_json_keys'][key] = data[key].class
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'rollbar/util'
|
|
2
|
+
|
|
3
|
+
module Rollbar
|
|
4
|
+
module Truncation
|
|
5
|
+
class RemoveExtraStrategy
|
|
6
|
+
include ::Rollbar::Truncation::Mixin
|
|
7
|
+
|
|
8
|
+
def self.call(payload)
|
|
9
|
+
new.call(payload)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def call(payload)
|
|
13
|
+
body = payload['data']['body']
|
|
14
|
+
|
|
15
|
+
delete_message_extra(body)
|
|
16
|
+
delete_trace_chain_extra(body)
|
|
17
|
+
delete_trace_extra(body)
|
|
18
|
+
|
|
19
|
+
dump(payload)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def delete_message_extra(body)
|
|
23
|
+
body['message'].delete('extra') if body['message'] && body['message']['extra']
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def delete_trace_chain_extra(body)
|
|
27
|
+
body['trace_chain'][0].delete('extra') if body['trace_chain'] && body['trace_chain'][0]['extra']
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def delete_trace_extra(body)
|
|
31
|
+
body['trace'].delete('extra') if body['trace'] && body['trace']['extra']
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'rollbar/util'
|
|
2
|
+
|
|
3
|
+
module Rollbar
|
|
4
|
+
module Truncation
|
|
5
|
+
class RemoveRequestStrategy
|
|
6
|
+
include ::Rollbar::Truncation::Mixin
|
|
7
|
+
|
|
8
|
+
def self.call(payload)
|
|
9
|
+
new.call(payload)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def call(payload)
|
|
13
|
+
data = payload['data']
|
|
14
|
+
|
|
15
|
+
data.delete('request') if data['request']
|
|
16
|
+
|
|
17
|
+
dump(payload)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -6,7 +6,7 @@ module Rollbar
|
|
|
6
6
|
class StringsStrategy
|
|
7
7
|
include ::Rollbar::Truncation::Mixin
|
|
8
8
|
|
|
9
|
-
STRING_THRESHOLDS = [1024, 512, 256]
|
|
9
|
+
STRING_THRESHOLDS = [1024, 512, 256].freeze
|
|
10
10
|
|
|
11
11
|
def self.call(payload)
|
|
12
12
|
new.call(payload)
|
|
@@ -14,13 +14,12 @@ module Rollbar
|
|
|
14
14
|
|
|
15
15
|
def call(payload)
|
|
16
16
|
result = nil
|
|
17
|
-
new_payload = Rollbar::Util.deep_copy(payload)
|
|
18
17
|
|
|
19
18
|
STRING_THRESHOLDS.each do |threshold|
|
|
20
19
|
truncate_proc = truncate_strings_proc(threshold)
|
|
21
20
|
|
|
22
|
-
::Rollbar::Util.iterate_and_update(
|
|
23
|
-
result = dump(
|
|
21
|
+
::Rollbar::Util.iterate_and_update(payload, truncate_proc)
|
|
22
|
+
result = dump(payload)
|
|
24
23
|
|
|
25
24
|
break unless truncate?(result)
|
|
26
25
|
end
|
data/lib/rollbar/util.rb
CHANGED
|
@@ -1,83 +1,101 @@
|
|
|
1
1
|
require 'rollbar/util/hash'
|
|
2
2
|
|
|
3
3
|
module Rollbar
|
|
4
|
-
module Util
|
|
5
|
-
def self.iterate_and_update(obj, block)
|
|
6
|
-
return if obj.frozen?
|
|
4
|
+
module Util # :nodoc:
|
|
5
|
+
def self.iterate_and_update(obj, block, seen = {})
|
|
6
|
+
return if obj.frozen? || seen[obj.object_id]
|
|
7
|
+
|
|
8
|
+
seen[obj.object_id] = true
|
|
9
|
+
|
|
7
10
|
if obj.is_a?(Array)
|
|
8
|
-
|
|
9
|
-
value = obj[i]
|
|
10
|
-
|
|
11
|
-
if value.is_a?(::Hash) || value.is_a?(Array)
|
|
12
|
-
self.iterate_and_update(value, block)
|
|
13
|
-
else
|
|
14
|
-
obj[i] = block.call(value)
|
|
15
|
-
end
|
|
16
|
-
end
|
|
11
|
+
iterate_and_update_array(obj, block, seen)
|
|
17
12
|
else
|
|
18
|
-
|
|
13
|
+
iterate_and_update_hash(obj, block, seen)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
19
16
|
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
def self.iterate_and_update_array(array, block, seen)
|
|
18
|
+
array.each_with_index do |value, i|
|
|
19
|
+
if value.is_a?(::Hash) || value.is_a?(Array)
|
|
20
|
+
iterate_and_update(value, block, seen)
|
|
21
|
+
else
|
|
22
|
+
array[i] = block.call(value)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
new_key = block.call(k)
|
|
28
|
-
obj[k] = block.call(v)
|
|
29
|
-
end
|
|
27
|
+
def self.iterate_and_update_hash(obj, block, seen)
|
|
28
|
+
obj.keys.each do |k|
|
|
29
|
+
v = obj[k]
|
|
30
|
+
new_key = block.call(k)
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
if v.is_a?(::Hash) || v.is_a?(Array)
|
|
33
|
+
iterate_and_update(v, block, seen)
|
|
34
|
+
else
|
|
35
|
+
obj[k] = block.call(v)
|
|
32
36
|
end
|
|
33
37
|
|
|
34
|
-
|
|
35
|
-
obj[new_key] = obj[
|
|
36
|
-
obj.delete(
|
|
38
|
+
if new_key != k
|
|
39
|
+
obj[new_key] = obj[k]
|
|
40
|
+
obj.delete(k)
|
|
37
41
|
end
|
|
38
42
|
end
|
|
39
43
|
end
|
|
40
44
|
|
|
41
|
-
def self.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
def self.deep_copy(obj, copied = {})
|
|
46
|
+
# if we've already made a copy, return it.
|
|
47
|
+
return copied[obj.object_id] if copied[obj.object_id]
|
|
48
|
+
|
|
49
|
+
result = clone_obj(obj)
|
|
50
|
+
|
|
51
|
+
# Memoize the cloned object before recursive calls to #deep_copy below.
|
|
52
|
+
# This is the point of doing the work in two steps.
|
|
53
|
+
copied[obj.object_id] = result
|
|
54
|
+
|
|
55
|
+
if obj.is_a?(::Hash)
|
|
56
|
+
obj.each { |k, v| result[k] = deep_copy(v, copied) }
|
|
57
|
+
elsif obj.is_a?(Array)
|
|
58
|
+
obj.each { |v| result << deep_copy(v, copied) }
|
|
48
59
|
end
|
|
60
|
+
|
|
61
|
+
result
|
|
49
62
|
end
|
|
50
63
|
|
|
51
|
-
def self.
|
|
64
|
+
def self.clone_obj(obj)
|
|
52
65
|
if obj.is_a?(::Hash)
|
|
53
|
-
|
|
54
|
-
obj.each { |k, v| result[k] = deep_copy(v)}
|
|
55
|
-
result
|
|
66
|
+
obj.dup
|
|
56
67
|
elsif obj.is_a?(Array)
|
|
57
|
-
|
|
58
|
-
result.clear
|
|
59
|
-
obj.each { |v| result << deep_copy(v)}
|
|
60
|
-
result
|
|
68
|
+
obj.dup.clear
|
|
61
69
|
else
|
|
62
70
|
obj
|
|
63
71
|
end
|
|
64
72
|
end
|
|
65
73
|
|
|
66
|
-
def self.deep_merge(hash1, hash2)
|
|
74
|
+
def self.deep_merge(hash1, hash2, merged = {})
|
|
67
75
|
hash1 ||= {}
|
|
68
76
|
hash2 ||= {}
|
|
69
77
|
|
|
78
|
+
# If we've already merged these two objects, return hash1 now.
|
|
79
|
+
return hash1 if merged[hash1.object_id] && merged[hash1.object_id].include?(hash2.object_id)
|
|
80
|
+
|
|
81
|
+
merged[hash1.object_id] ||= []
|
|
82
|
+
merged[hash1.object_id] << hash2.object_id
|
|
83
|
+
|
|
84
|
+
perform_deep_merge(hash1, hash2, merged)
|
|
85
|
+
|
|
86
|
+
hash1
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def self.perform_deep_merge(hash1, hash2, merged) # rubocop:disable Metrics/AbcSize
|
|
70
90
|
hash2.each_key do |k|
|
|
71
91
|
if hash1[k].is_a?(::Hash) && hash2[k].is_a?(::Hash)
|
|
72
|
-
hash1[k] = deep_merge(hash1[k], hash2[k])
|
|
92
|
+
hash1[k] = deep_merge(hash1[k], hash2[k], merged)
|
|
73
93
|
elsif hash1[k].is_a?(Array) && hash2[k].is_a?(Array)
|
|
74
94
|
hash1[k] += deep_copy(hash2[k])
|
|
75
95
|
elsif hash2[k]
|
|
76
96
|
hash1[k] = deep_copy(hash2[k])
|
|
77
97
|
end
|
|
78
98
|
end
|
|
79
|
-
|
|
80
|
-
hash1
|
|
81
99
|
end
|
|
82
100
|
|
|
83
101
|
def self.truncate(str, length)
|
|
@@ -97,5 +115,17 @@ module Rollbar
|
|
|
97
115
|
|
|
98
116
|
Util.iterate_and_update(payload, normalizer)
|
|
99
117
|
end
|
|
118
|
+
|
|
119
|
+
def self.count_method_in_stack(method_symbol, file_path = '')
|
|
120
|
+
caller.grep(/#{file_path}.*#{method_symbol.to_s}/).count
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def self.method_in_stack(method_symbol, file_path = '')
|
|
124
|
+
count_method_in_stack(method_symbol, file_path) > 0
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def self.method_in_stack_twice(method_symbol, file_path = '')
|
|
128
|
+
count_method_in_stack(method_symbol, file_path) > 1
|
|
129
|
+
end
|
|
100
130
|
end
|
|
101
131
|
end
|
data/lib/rollbar/util/hash.rb
CHANGED
|
@@ -1,24 +1,48 @@
|
|
|
1
1
|
module Rollbar
|
|
2
2
|
module Util
|
|
3
|
-
module Hash
|
|
4
|
-
def self.deep_stringify_keys(hash)
|
|
3
|
+
module Hash # :nodoc:
|
|
4
|
+
def self.deep_stringify_keys(hash, seen = {})
|
|
5
|
+
return if seen[hash.object_id]
|
|
6
|
+
|
|
7
|
+
seen[hash.object_id] = true
|
|
8
|
+
replace_seen_children(hash, seen)
|
|
9
|
+
|
|
5
10
|
hash.reduce({}) do |h, (key, value)|
|
|
6
|
-
h[key.to_s] = map_value(value, :deep_stringify_keys)
|
|
11
|
+
h[key.to_s] = map_value(value, :deep_stringify_keys, seen)
|
|
7
12
|
|
|
8
13
|
h
|
|
9
14
|
end
|
|
10
15
|
end
|
|
11
16
|
|
|
12
|
-
def self.map_value(thing,
|
|
17
|
+
def self.map_value(thing, meth, seen)
|
|
13
18
|
case thing
|
|
14
19
|
when ::Hash
|
|
15
|
-
send(
|
|
20
|
+
send(meth, thing, seen)
|
|
16
21
|
when Array
|
|
17
|
-
thing.
|
|
22
|
+
if seen[thing.object_id]
|
|
23
|
+
thing
|
|
24
|
+
else
|
|
25
|
+
seen[thing.object_id] = true
|
|
26
|
+
replace_seen_children(thing, seen)
|
|
27
|
+
thing.map { |v| map_value(v, meth, seen) }
|
|
28
|
+
end
|
|
18
29
|
else
|
|
19
30
|
thing
|
|
20
31
|
end
|
|
21
32
|
end
|
|
33
|
+
|
|
34
|
+
def self.replace_seen_children(thing, seen)
|
|
35
|
+
case thing
|
|
36
|
+
when ::Hash
|
|
37
|
+
thing.keys.each do |key|
|
|
38
|
+
thing[key] = "removed circular reference: #{thing[key]}" if seen[thing[key].object_id]
|
|
39
|
+
end
|
|
40
|
+
when Array
|
|
41
|
+
thing.each_with_index do |_, i|
|
|
42
|
+
thing[i] = "removed circular reference: #{thing[i]}" if seen[thing[i].object_id]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
22
46
|
end
|
|
23
47
|
end
|
|
24
48
|
end
|