rollbar 2.20.0 → 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 +4 -4
- data/.rubocop.yml +5 -0
- data/.travis.yml +42 -16
- data/Gemfile +19 -13
- data/data/rollbar.snippet.js +1 -1
- data/gemfiles/rails30.gemfile +1 -10
- data/gemfiles/rails31.gemfile +1 -9
- data/gemfiles/rails32.gemfile +1 -9
- data/gemfiles/rails40.gemfile +1 -9
- data/gemfiles/rails41.gemfile +1 -9
- data/gemfiles/rails42.gemfile +1 -11
- data/gemfiles/rails50.gemfile +1 -11
- data/gemfiles/rails51.gemfile +1 -11
- data/gemfiles/rails52.gemfile +1 -11
- data/gemfiles/rails60.gemfile +67 -0
- data/lib/rollbar/configuration.rb +35 -1
- data/lib/rollbar/item.rb +25 -7
- data/lib/rollbar/json.rb +2 -51
- data/lib/rollbar/language_support.rb +3 -19
- data/lib/rollbar/notifier.rb +4 -6
- data/lib/rollbar/plugins/basic_socket.rb +1 -1
- data/lib/rollbar/rake_tasks.rb +3 -147
- data/lib/rollbar/request_data_extractor.rb +1 -2
- data/lib/rollbar/rollbar_test.rb +147 -0
- data/lib/rollbar/scrubbers/url.rb +0 -1
- data/lib/rollbar/truncation.rb +7 -1
- 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 +2 -2
- data/lib/rollbar/util/hash.rb +15 -0
- data/lib/rollbar/version.rb +1 -1
- data/rollbar.gemspec +0 -2
- metadata +8 -20
- data/gemfiles/ruby_1_8_and_1_9_2.gemfile +0 -51
- data/lib/rollbar/json/default.rb +0 -11
- data/lib/rollbar/json/oj.rb +0 -16
@@ -210,8 +210,7 @@ module Rollbar
|
|
210
210
|
def json_request?(rack_req)
|
211
211
|
json_regex = /\bjson\b/
|
212
212
|
|
213
|
-
!!(rack_req.env['CONTENT_TYPE'] =~ json_regex
|
214
|
-
rack_req.env['HTTP_ACCEPT'] =~ json_regex)
|
213
|
+
!!(rack_req.env['CONTENT_TYPE'] =~ json_regex)
|
215
214
|
end
|
216
215
|
|
217
216
|
def rollbar_route_params(env)
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'rollbar'
|
2
|
+
begin
|
3
|
+
require 'rack/mock'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'Cannot load rack/mock'
|
6
|
+
end
|
7
|
+
require 'logger'
|
8
|
+
|
9
|
+
# Module to inject into the Rails controllers or rack apps
|
10
|
+
module RollbarTest # :nodoc:
|
11
|
+
def test_rollbar
|
12
|
+
puts 'Raising RollbarTestingException to simulate app failure.'
|
13
|
+
|
14
|
+
raise RollbarTestingException.new, ::RollbarTest.success_message
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.run
|
18
|
+
return unless confirmed_token?
|
19
|
+
|
20
|
+
configure_rails if defined?(Rails)
|
21
|
+
|
22
|
+
puts 'Testing manual report...'
|
23
|
+
Rollbar.error('Test error from rollbar:test')
|
24
|
+
|
25
|
+
return unless defined?(Rack::MockRequest)
|
26
|
+
|
27
|
+
protocol, app = setup_app
|
28
|
+
|
29
|
+
puts 'Processing...'
|
30
|
+
env = Rack::MockRequest.env_for("#{protocol}://www.example.com/verify", 'REMOTE_ADDR' => '127.0.0.1')
|
31
|
+
status, = app.call(env)
|
32
|
+
|
33
|
+
puts error_message unless status.to_i == 500
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.configure_rails
|
37
|
+
Rails.logger = if defined?(ActiveSupport::TaggedLogging)
|
38
|
+
ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
|
39
|
+
else
|
40
|
+
Logger.new(STDOUT)
|
41
|
+
end
|
42
|
+
|
43
|
+
Rails.logger.level = Logger::DEBUG
|
44
|
+
Rollbar.preconfigure do |config|
|
45
|
+
config.logger = Rails.logger
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.confirmed_token?
|
50
|
+
return true if Rollbar.configuration.access_token
|
51
|
+
|
52
|
+
puts token_error_message
|
53
|
+
|
54
|
+
false
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.authlogic_config
|
58
|
+
# from http://stackoverflow.com/questions/5270835/authlogic-activation-problems
|
59
|
+
return unless defined?(Authlogic)
|
60
|
+
|
61
|
+
Authlogic::Session::Base.controller = Authlogic::ControllerAdapters::RailsAdapter.new(self)
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.setup_app
|
65
|
+
puts 'Setting up the test app.'
|
66
|
+
|
67
|
+
if defined?(Rails)
|
68
|
+
app = rails_app
|
69
|
+
|
70
|
+
draw_rails_route(app)
|
71
|
+
|
72
|
+
authlogic_config
|
73
|
+
|
74
|
+
[rails_protocol(app), app]
|
75
|
+
else
|
76
|
+
['http', rack_app]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.rails_app
|
81
|
+
# The setup below is needed for Rails 5.x, but not for Rails 4.x and below.
|
82
|
+
# (And fails on Rails 4.x in various ways depending on the exact version.)
|
83
|
+
return Rails.application if Rails.version < '5.0.0'
|
84
|
+
|
85
|
+
# Spring now runs by default in development on all new Rails installs. This causes
|
86
|
+
# the new `/verify` route to not get picked up if `config.cache_classes == false`
|
87
|
+
# which is also a default in development env.
|
88
|
+
#
|
89
|
+
# `config.cache_classes` needs to be set, but the only possible time is at app load,
|
90
|
+
# so here we clone the default app with an updated config.
|
91
|
+
#
|
92
|
+
config = Rails.application.config
|
93
|
+
config.cache_classes = true
|
94
|
+
|
95
|
+
# Make a copy of the app, so the config can be updated.
|
96
|
+
Rails.application.class.name.constantize.new(:config => config)
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.draw_rails_route(app)
|
100
|
+
app.routes_reloader.execute_if_updated
|
101
|
+
app.routes.draw do
|
102
|
+
get 'verify' => 'rollbar_test#verify', :as => 'verify'
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.rails_protocol(app)
|
107
|
+
defined?(app.config.force_ssl && app.config.force_ssl) ? 'https' : 'http'
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.rack_app
|
111
|
+
Class.new do
|
112
|
+
include RollbarTest
|
113
|
+
|
114
|
+
def self.call(_env)
|
115
|
+
new.test_rollbar
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.token_error_message
|
121
|
+
'Rollbar needs an access token configured. Check the README for instructions.'
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.error_message
|
125
|
+
'Test failed! You may have a configuration issue, or you could be using a gem that\'s blocking the test. Contact support@rollbar.com if you need help troubleshooting.'
|
126
|
+
end
|
127
|
+
|
128
|
+
def self.success_message
|
129
|
+
'Testing rollbar with "rake rollbar:test". If you can see this, it works.'
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
class RollbarTestingException < RuntimeError; end
|
134
|
+
|
135
|
+
if defined?(Rails)
|
136
|
+
class RollbarTestController < ActionController::Base # :nodoc:
|
137
|
+
include RollbarTest
|
138
|
+
|
139
|
+
def verify
|
140
|
+
test_rollbar
|
141
|
+
end
|
142
|
+
|
143
|
+
def logger
|
144
|
+
nil
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
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,7 +16,10 @@ 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
24
|
def self.truncate(payload, attempts = [])
|
19
25
|
result = nil
|
@@ -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
data/lib/rollbar/util/hash.rb
CHANGED
@@ -5,6 +5,7 @@ module Rollbar
|
|
5
5
|
return if seen[hash.object_id]
|
6
6
|
|
7
7
|
seen[hash.object_id] = true
|
8
|
+
replace_seen_children(hash, seen)
|
8
9
|
|
9
10
|
hash.reduce({}) do |h, (key, value)|
|
10
11
|
h[key.to_s] = map_value(value, :deep_stringify_keys, seen)
|
@@ -22,12 +23,26 @@ module Rollbar
|
|
22
23
|
thing
|
23
24
|
else
|
24
25
|
seen[thing.object_id] = true
|
26
|
+
replace_seen_children(thing, seen)
|
25
27
|
thing.map { |v| map_value(v, meth, seen) }
|
26
28
|
end
|
27
29
|
else
|
28
30
|
thing
|
29
31
|
end
|
30
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
|
31
46
|
end
|
32
47
|
end
|
33
48
|
end
|