rollbar 2.19.2 → 2.19.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +27 -0
- data/Appraisals +10 -10
- data/Gemfile +2 -0
- data/README.md +4 -1
- data/Rakefile +0 -0
- data/data/rollbar.snippet.js +1 -1
- data/gemfiles/rails30.gemfile +2 -0
- data/gemfiles/rails31.gemfile +2 -0
- data/gemfiles/rails32.gemfile +2 -0
- data/gemfiles/rails40.gemfile +2 -0
- data/gemfiles/rails41.gemfile +2 -0
- data/gemfiles/rails42.gemfile +2 -0
- data/gemfiles/rails50.gemfile +2 -0
- data/gemfiles/rails51.gemfile +2 -0
- data/gemfiles/rails52.gemfile +2 -0
- data/gemfiles/ruby_1_8_and_1_9_2.gemfile +2 -0
- data/lib/generators/rollbar/rollbar_generator.rb +1 -1
- data/lib/rails/rollbar_runner.rb +1 -1
- data/lib/rollbar.rb +2 -3
- data/lib/rollbar/capistrano3.rb +6 -3
- data/lib/rollbar/capistrano_tasks.rb +13 -15
- data/lib/rollbar/configuration.rb +10 -8
- data/lib/rollbar/delay/girl_friday.rb +2 -2
- data/lib/rollbar/delay/resque.rb +4 -6
- data/lib/rollbar/delay/sidekiq.rb +6 -10
- data/lib/rollbar/delay/sucker_punch.rb +17 -19
- data/lib/rollbar/delay/thread.rb +2 -2
- data/lib/rollbar/deploy.rb +47 -30
- data/lib/rollbar/encoding/encoder.rb +9 -9
- data/lib/rollbar/item.rb +7 -7
- 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 -2
- data/lib/rollbar/json/default.rb +1 -1
- data/lib/rollbar/json/oj.rb +1 -1
- data/lib/rollbar/language_support.rb +1 -1
- data/lib/rollbar/lazy_store.rb +5 -5
- data/lib/rollbar/logger.rb +1 -0
- data/lib/rollbar/logger_proxy.rb +1 -1
- data/lib/rollbar/middleware/js.rb +15 -15
- data/lib/rollbar/middleware/rack.rb +4 -1
- data/lib/rollbar/middleware/rails/rollbar.rb +10 -1
- data/lib/rollbar/notifier.rb +40 -15
- 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/basic_socket.rb +21 -6
- data/lib/rollbar/plugins/delayed_job/job_data.rb +3 -3
- data/lib/rollbar/plugins/delayed_job/plugin.rb +2 -2
- 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/rake_tasks.rb +2 -2
- data/lib/rollbar/request_data_extractor.rb +21 -18
- data/lib/rollbar/scrubbers.rb +7 -3
- data/lib/rollbar/scrubbers/params.rb +17 -16
- data/lib/rollbar/scrubbers/url.rb +8 -3
- data/lib/rollbar/truncation.rb +1 -1
- data/lib/rollbar/truncation/strings_strategy.rb +1 -1
- 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 +13 -4
- metadata +12 -5
data/lib/rollbar/delay/resque.rb
CHANGED
@@ -23,12 +23,10 @@ module Rollbar
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def perform(payload)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
raise
|
31
|
-
end
|
26
|
+
Rollbar.process_from_async_handler(payload)
|
27
|
+
rescue StandardError
|
28
|
+
# Raise the exception so Resque can track the errored job
|
29
|
+
raise
|
32
30
|
end
|
33
31
|
end
|
34
32
|
end
|
@@ -10,21 +10,17 @@ module Rollbar
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def call(payload)
|
13
|
-
if ::Sidekiq::Client.push(@options.merge('args' => [payload]))
|
14
|
-
raise StandardError.new "Unable to push the job to Sidekiq"
|
15
|
-
end
|
13
|
+
raise StandardError, 'Unable to push the job to Sidekiq' if ::Sidekiq::Client.push(@options.merge('args' => [payload])).nil?
|
16
14
|
end
|
17
15
|
|
18
16
|
include ::Sidekiq::Worker
|
19
17
|
|
20
18
|
def perform(*args)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
raise
|
27
|
-
end
|
19
|
+
Rollbar.process_from_async_handler(*args)
|
20
|
+
rescue StandardError
|
21
|
+
# Raise the exception so Sidekiq can track the errored job
|
22
|
+
# and retry it
|
23
|
+
raise
|
28
24
|
end
|
29
25
|
end
|
30
26
|
end
|
@@ -16,11 +16,11 @@ module Rollbar
|
|
16
16
|
def self.setup
|
17
17
|
major_version = ::SuckerPunch::VERSION.split.first.to_i
|
18
18
|
|
19
|
-
if major_version > 1
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
self.perform_proc = if major_version > 1
|
20
|
+
proc { |payload| perform_async(payload) }
|
21
|
+
else
|
22
|
+
proc { |payload| new.async.perform(payload) }
|
23
|
+
end
|
24
24
|
|
25
25
|
self.ready = true
|
26
26
|
end
|
@@ -32,20 +32,18 @@ module Rollbar
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def perform(*args)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
raise
|
48
|
-
end
|
35
|
+
Rollbar.process_from_async_handler(*args)
|
36
|
+
rescue StandardError
|
37
|
+
# SuckerPunch can configure an exception handler with:
|
38
|
+
#
|
39
|
+
# SuckerPunch.exception_handler { # do something here }
|
40
|
+
#
|
41
|
+
# This is just passed to Celluloid.exception_handler which will
|
42
|
+
# push the reiceved block to an array of handlers, by default empty, [].
|
43
|
+
#
|
44
|
+
# We reraise the exception here casue it's safe and users could have defined
|
45
|
+
# their own exception handler for SuckerPunch
|
46
|
+
raise
|
49
47
|
end
|
50
48
|
end
|
51
49
|
end
|
data/lib/rollbar/delay/thread.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'thread'
|
2
1
|
require 'timeout'
|
3
2
|
|
4
3
|
module Rollbar
|
@@ -29,6 +28,7 @@ module Rollbar
|
|
29
28
|
|
30
29
|
def spawn_threads_reaper
|
31
30
|
return if @spawned
|
31
|
+
|
32
32
|
@spawned = true
|
33
33
|
|
34
34
|
@reaper ||= build_reaper_thread
|
@@ -65,7 +65,7 @@ module Rollbar
|
|
65
65
|
::Thread.new do
|
66
66
|
begin
|
67
67
|
Rollbar.process_from_async_handler(payload)
|
68
|
-
rescue
|
68
|
+
rescue StandardError
|
69
69
|
# Here we swallow the exception:
|
70
70
|
# 1. The original report wasn't sent.
|
71
71
|
# 2. An internal error was sent and logged
|
data/lib/rollbar/deploy.rb
CHANGED
@@ -1,72 +1,89 @@
|
|
1
|
-
require 'capistrano'
|
2
|
-
|
3
1
|
module Rollbar
|
4
2
|
# Deploy Tracking API wrapper module
|
5
3
|
module Deploy
|
6
4
|
ENDPOINT = 'https://api.rollbar.com/api/1/deploy/'.freeze
|
7
5
|
|
8
|
-
def self.report(opts
|
6
|
+
def self.report(opts, access_token, environment, revision)
|
9
7
|
return {} unless access_token && !access_token.empty?
|
10
8
|
|
11
9
|
opts[:status] ||= :started
|
12
10
|
|
13
|
-
uri = URI.parse(::Rollbar::Deploy::ENDPOINT)
|
11
|
+
uri = ::URI.parse(::Rollbar::Deploy::ENDPOINT)
|
14
12
|
|
15
|
-
|
16
|
-
request.body = ::JSON.dump({
|
13
|
+
request_data = {
|
17
14
|
:access_token => access_token,
|
18
15
|
:environment => environment,
|
19
16
|
:revision => revision
|
20
|
-
}.merge(opts)
|
17
|
+
}.merge(opts)
|
18
|
+
request_data.delete(:proxy)
|
19
|
+
request_data.delete(:dry_run)
|
20
|
+
|
21
|
+
request = ::Net::HTTP::Post.new(uri.request_uri)
|
22
|
+
request.body = ::JSON.dump(request_data)
|
21
23
|
|
22
|
-
send_request(opts,
|
24
|
+
send_request(opts, uri, request)
|
23
25
|
end
|
24
26
|
|
25
|
-
def self.update(opts
|
27
|
+
def self.update(opts, access_token, deploy_id, status)
|
26
28
|
return {} unless access_token && !access_token.empty?
|
27
29
|
|
28
|
-
uri = URI.parse(
|
30
|
+
uri = ::URI.parse(
|
29
31
|
::Rollbar::Deploy::ENDPOINT +
|
30
32
|
deploy_id.to_s +
|
31
33
|
'?access_token=' + access_token
|
32
34
|
)
|
33
35
|
|
34
|
-
request = Net::HTTP::Patch.new(uri.request_uri)
|
36
|
+
request = ::Net::HTTP::Patch.new(uri.request_uri)
|
35
37
|
request.body = ::JSON.dump(:status => status.to_s, :comment => opts[:comment])
|
36
38
|
|
37
|
-
send_request(opts,
|
39
|
+
send_request(opts, uri, request)
|
38
40
|
end
|
39
41
|
|
40
42
|
class << self
|
41
43
|
private
|
42
44
|
|
43
|
-
def send_request(opts
|
44
|
-
Net::HTTP.start(uri.host, uri.port, opts[:proxy], :use_ssl => true) do |http|
|
45
|
+
def send_request(opts, uri, request)
|
46
|
+
::Net::HTTP.start(uri.host, uri.port, opts[:proxy], :use_ssl => true) do |http|
|
45
47
|
build_result(
|
46
|
-
|
47
|
-
|
48
|
-
|
48
|
+
uri,
|
49
|
+
request,
|
50
|
+
opts[:dry_run] ? nil : http.request(request),
|
51
|
+
opts[:dry_run]
|
49
52
|
)
|
50
53
|
end
|
51
54
|
end
|
52
55
|
|
53
|
-
def build_result(uri
|
54
|
-
result = {
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
56
|
+
def build_result(uri, request, response = nil, dry_run = false)
|
57
|
+
result = {}
|
58
|
+
result.merge!(request_result(uri, request))
|
59
|
+
result.merge!(response_result(response)) unless response.nil?
|
60
|
+
result[:success] = success?(result, dry_run)
|
61
|
+
result
|
62
|
+
end
|
59
63
|
|
60
|
-
|
61
|
-
|
62
|
-
result[:response_info] = build_response_info(result[:response])
|
63
|
-
end
|
64
|
+
def success?(result, dry_run = false)
|
65
|
+
return true if dry_run
|
64
66
|
|
65
|
-
result
|
67
|
+
result[:response] &&
|
68
|
+
result[:response].is_a?(::Net::HTTPSuccess) &&
|
69
|
+
result[:response].code == '200' &&
|
70
|
+
(result.key?('err') ? result['err'].to_i.zero? : true)
|
71
|
+
end
|
72
|
+
|
73
|
+
def request_result(uri, request)
|
74
|
+
{
|
75
|
+
:request_info => uri.inspect + ': ' + request.body,
|
76
|
+
:request => request
|
77
|
+
}
|
66
78
|
end
|
67
79
|
|
68
|
-
def
|
69
|
-
|
80
|
+
def response_result(response)
|
81
|
+
{
|
82
|
+
:response => response,
|
83
|
+
:response_info => response.code + '; ' +
|
84
|
+
response.message + '; ' +
|
85
|
+
response.body.delete("\n")
|
86
|
+
}.merge(::JSON.parse(response.body, :symbolize_names => true))
|
70
87
|
end
|
71
88
|
end
|
72
89
|
end
|
@@ -1,9 +1,9 @@
|
|
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
|
6
|
+
ENCODING_OPTIONS = { :invalid => :replace, :undef => :replace, :replace => '' }.freeze
|
7
7
|
UTF8 = 'UTF-8'.freeze
|
8
8
|
BINARY = 'binary'.freeze
|
9
9
|
|
@@ -18,11 +18,11 @@ module Rollbar
|
|
18
18
|
encoding = value.encoding
|
19
19
|
|
20
20
|
# 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
|
-
|
21
|
+
encoded_value = if encoding == ::Encoding::UTF_8 && value.valid_encoding?
|
22
|
+
value
|
23
|
+
else
|
24
|
+
force_encoding(value).encode(*encoding_args(value))
|
25
|
+
end
|
26
26
|
|
27
27
|
object.is_a?(Symbol) ? encoded_value.to_sym : encoded_value
|
28
28
|
end
|
@@ -45,7 +45,7 @@ module Rollbar
|
|
45
45
|
# Seems #codepoints is faster than #valid_encoding?
|
46
46
|
value.force_encoding(encoding).encode(::Encoding::UTF_8).codepoints
|
47
47
|
true
|
48
|
-
rescue
|
48
|
+
rescue StandardError
|
49
49
|
false
|
50
50
|
end
|
51
51
|
end
|
data/lib/rollbar/item.rb
CHANGED
@@ -180,14 +180,14 @@ module Rollbar
|
|
180
180
|
end
|
181
181
|
|
182
182
|
def custom_data
|
183
|
-
if configuration.custom_data_method.arity == 3
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
183
|
+
data = if configuration.custom_data_method.arity == 3
|
184
|
+
configuration.custom_data_method.call(message, exception, context)
|
185
|
+
else
|
186
|
+
configuration.custom_data_method.call
|
187
|
+
end
|
188
188
|
|
189
189
|
Rollbar::Util.deep_copy(data)
|
190
|
-
rescue => e
|
190
|
+
rescue StandardError => e
|
191
191
|
return {} if configuration.safely?
|
192
192
|
|
193
193
|
report_custom_data_error(e)
|
@@ -232,7 +232,7 @@ module Rollbar
|
|
232
232
|
handlers.each do |handler|
|
233
233
|
begin
|
234
234
|
handler.call(transform_options)
|
235
|
-
rescue => e
|
235
|
+
rescue StandardError => e
|
236
236
|
logger.error("[Rollbar] Error calling the `transform` hook: #{e}")
|
237
237
|
|
238
238
|
break
|
@@ -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,10 @@ module Rollbar
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def map_frames(current_exception)
|
77
|
-
exception_backtrace(current_exception).
|
77
|
+
exception_backtrace(current_exception).map do |frame|
|
78
78
|
Rollbar::Item::Frame.new(self, frame,
|
79
79
|
:configuration => configuration).to_h
|
80
|
-
end
|
80
|
+
end.reverse
|
81
81
|
end
|
82
82
|
|
83
83
|
# 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,10 @@ module Rollbar
|
|
94
96
|
}
|
95
97
|
end
|
96
98
|
|
99
|
+
def locals_data(filename, lineno)
|
100
|
+
::Rollbar::Item::Locals.locals_for_location(filename, lineno)
|
101
|
+
end
|
102
|
+
|
97
103
|
def post_data(file_lines, lineno)
|
98
104
|
from_line = lineno
|
99
105
|
number_of_lines = [from_line + MAX_CONTEXT_LENGTH, file_lines.size].min - from_line
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'rollbar/notifier'
|
2
|
+
require 'rollbar/scrubbers/params'
|
3
|
+
|
4
|
+
module Rollbar
|
5
|
+
class Item
|
6
|
+
class Locals # :nodoc:
|
7
|
+
class << self
|
8
|
+
def exception_frames
|
9
|
+
Rollbar.notifier.exception_bindings
|
10
|
+
end
|
11
|
+
|
12
|
+
def locals_for_location(filename, lineno)
|
13
|
+
if (frame = frame_for_location(filename, lineno))
|
14
|
+
scrub(locals_for(frame[:binding]))
|
15
|
+
else
|
16
|
+
{}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def frame_for_location(filename, lineno)
|
21
|
+
while (frame = exception_frames.pop)
|
22
|
+
return nil unless frame
|
23
|
+
return frame if matching_frame?(frame, filename, lineno)
|
24
|
+
end
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def matching_frame?(frame, filename, lineno)
|
31
|
+
frame[:path] == filename && frame[:lineno].to_i <= lineno.to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
def locals_for(frame)
|
35
|
+
{}.tap do |hash|
|
36
|
+
frame.local_variables.map do |var|
|
37
|
+
hash[var] = prepare_value(frame.local_variable_get(var))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def prepare_value(value)
|
43
|
+
value.to_s
|
44
|
+
end
|
45
|
+
|
46
|
+
def scrub(hash)
|
47
|
+
Rollbar::Scrubbers::Params.call(
|
48
|
+
:params => hash,
|
49
|
+
:config => Rollbar.configuration.scrub_fields,
|
50
|
+
:whitelist => Rollbar.configuration.scrub_whitelist
|
51
|
+
)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/rollbar/json.rb
CHANGED
@@ -9,13 +9,16 @@ rescue LoadError
|
|
9
9
|
end
|
10
10
|
|
11
11
|
module Rollbar
|
12
|
-
module JSON
|
12
|
+
module JSON # :nodoc:
|
13
13
|
extend self
|
14
14
|
|
15
15
|
attr_writer :options_module
|
16
16
|
|
17
17
|
def dump(object)
|
18
|
-
|
18
|
+
# `basic_socket` plugin addresses the following issue: https://github.com/rollbar/rollbar-gem/issues/845
|
19
|
+
Rollbar.plugins.get('basic_socket').load_scoped!(true) do
|
20
|
+
with_adapter { MultiJson.dump(object, adapter_options) }
|
21
|
+
end
|
19
22
|
end
|
20
23
|
|
21
24
|
def load(string)
|