rollbar 2.8.3 → 3.6.0
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/.codeclimate.yml +18 -0
- data/.github/pull_request_template.md +34 -0
- data/.github/workflows/ci.yml +67 -0
- data/.gitignore +3 -1
- data/.rubocop.yml +206 -7
- data/Appraisals +10 -10
- data/CHANGELOG.md +257 -3
- data/Gemfile +74 -13
- data/README.md +38 -833
- data/Rakefile +0 -0
- data/THANKS.md +1 -0
- data/data/rollbar.snippet.js +1 -1
- data/docs/configuration.md +64 -3
- data/docs/plugins.md +46 -0
- data/gemfiles/rails50.gemfile +56 -0
- data/gemfiles/rails51.gemfile +57 -0
- data/gemfiles/rails52.gemfile +56 -0
- data/gemfiles/rails60.gemfile +52 -0
- data/gemfiles/rails61.gemfile +52 -0
- data/gemfiles/rails70.gemfile +52 -0
- data/gemfiles/rails71.gemfile +52 -0
- data/lib/generators/rollbar/rollbar_generator.rb +24 -20
- data/lib/generators/rollbar/templates/{initializer.rb → initializer.erb} +19 -5
- data/lib/rails/rollbar_runner.rb +26 -22
- data/lib/rollbar/capistrano.rb +78 -38
- data/lib/rollbar/capistrano3.rb +62 -1
- data/lib/rollbar/capistrano_tasks.rb +166 -0
- data/lib/rollbar/configuration.rb +291 -71
- data/lib/rollbar/delay/active_job.rb +17 -0
- data/lib/rollbar/delay/delayed_job.rb +23 -0
- data/lib/rollbar/delay/girl_friday.rb +4 -9
- data/lib/rollbar/delay/resque.rb +3 -6
- data/lib/rollbar/delay/shoryuken.rb +36 -0
- data/lib/rollbar/delay/sidekiq.rb +6 -8
- data/lib/rollbar/delay/sucker_punch.rb +17 -22
- data/lib/rollbar/delay/thread.rb +74 -3
- data/lib/rollbar/deploy.rb +91 -0
- data/lib/rollbar/encoding/encoder.rb +22 -11
- data/lib/rollbar/encoding.rb +2 -7
- data/lib/rollbar/exception_reporter.rb +36 -12
- data/lib/rollbar/item/backtrace.rb +118 -0
- data/lib/rollbar/item/frame.rb +121 -0
- data/lib/rollbar/item/locals.rb +103 -0
- data/lib/rollbar/item.rb +314 -0
- data/lib/rollbar/js.rb +0 -28
- data/lib/rollbar/json.rb +7 -55
- data/lib/rollbar/language_support.rb +7 -19
- data/lib/rollbar/lazy_store.rb +8 -12
- data/lib/rollbar/logger.rb +71 -0
- data/lib/rollbar/logger_proxy.rb +18 -1
- data/lib/rollbar/middleware/js/json_value.rb +36 -0
- data/lib/rollbar/middleware/js.rb +297 -0
- data/lib/rollbar/middleware/rack/builder.rb +4 -4
- data/lib/rollbar/middleware/rack/test_session.rb +4 -4
- data/lib/rollbar/middleware/rack.rb +52 -0
- data/lib/rollbar/middleware/rails/rollbar.rb +19 -7
- data/lib/rollbar/middleware/rails/show_exceptions.rb +21 -9
- data/lib/rollbar/middleware/sinatra.rb +2 -40
- data/lib/rollbar/notifier/trace_with_bindings.rb +75 -0
- data/lib/rollbar/notifier.rb +913 -0
- data/lib/rollbar/plugin.rb +126 -0
- data/lib/rollbar/plugins/active_job.rb +54 -0
- data/lib/rollbar/plugins/basic_socket.rb +31 -0
- data/lib/rollbar/plugins/delayed_job/job_data.rb +50 -0
- data/lib/rollbar/plugins/delayed_job/plugin.rb +88 -0
- data/lib/rollbar/plugins/delayed_job.rb +12 -0
- data/lib/rollbar/plugins/error_context.rb +11 -0
- data/lib/rollbar/plugins/goalie.rb +65 -0
- data/lib/rollbar/plugins/rack.rb +18 -0
- data/lib/rollbar/plugins/rails/controller_methods.rb +56 -0
- data/lib/rollbar/plugins/rails/error_subscriber.rb +12 -0
- data/lib/rollbar/plugins/rails/railtie30.rb +18 -0
- data/lib/rollbar/plugins/rails/railtie32.rb +18 -0
- data/lib/rollbar/plugins/rails/railtie_mixin.rb +37 -0
- data/lib/rollbar/plugins/rails.rb +89 -0
- data/lib/rollbar/plugins/rake.rb +73 -0
- data/lib/rollbar/plugins/resque/failure.rb +39 -0
- data/lib/rollbar/plugins/resque.rb +11 -0
- data/lib/rollbar/plugins/sidekiq/plugin.rb +77 -0
- data/lib/rollbar/plugins/sidekiq.rb +37 -0
- data/lib/rollbar/plugins/thread.rb +14 -0
- data/lib/rollbar/plugins/validations.rb +45 -0
- data/lib/rollbar/plugins.rb +47 -0
- data/lib/rollbar/rails.rb +0 -1
- data/lib/rollbar/rake_tasks.rb +4 -66
- data/lib/rollbar/request_data_extractor.rb +157 -117
- data/lib/rollbar/rollbar_test.rb +38 -0
- data/lib/rollbar/scrubbers/params.rb +133 -0
- data/lib/rollbar/scrubbers/url.rb +90 -35
- data/lib/rollbar/scrubbers.rb +13 -0
- data/lib/rollbar/truncation/frames_strategy.rb +2 -1
- data/lib/rollbar/truncation/min_body_strategy.rb +3 -4
- data/lib/rollbar/truncation/mixin.rb +1 -1
- data/lib/rollbar/truncation/remove_any_key_strategy.rb +126 -0
- data/lib/rollbar/truncation/remove_extra_strategy.rb +37 -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 +10 -4
- data/lib/rollbar/util/hash.rb +37 -6
- data/lib/rollbar/util/ip_anonymizer.rb +33 -0
- data/lib/rollbar/util/ip_obfuscator.rb +1 -1
- data/lib/rollbar/util.rb +101 -55
- data/lib/rollbar/version.rb +1 -1
- data/lib/rollbar.rb +91 -879
- data/lib/tasks/benchmark.rake +104 -0
- data/lib/tasks/tasks.rake +3 -3
- data/rollbar.gemspec +21 -32
- data/spec/support/rollbar_api.rb +67 -0
- metadata +78 -439
- data/.travis.yml +0 -155
- data/gemfiles/rails30.gemfile +0 -20
- data/gemfiles/rails31.gemfile +0 -16
- data/gemfiles/rails32.gemfile +0 -17
- data/gemfiles/rails40.gemfile +0 -17
- data/gemfiles/rails41.gemfile +0 -15
- data/gemfiles/rails42.gemfile +0 -15
- data/lib/rollbar/active_job.rb +0 -11
- data/lib/rollbar/active_record_extension.rb +0 -14
- data/lib/rollbar/core_ext/basic_socket.rb +0 -7
- data/lib/rollbar/core_ext/thread.rb +0 -9
- data/lib/rollbar/delayed_job.rb +0 -78
- data/lib/rollbar/encoding/legacy_encoder.rb +0 -20
- data/lib/rollbar/goalie.rb +0 -33
- data/lib/rollbar/js/frameworks/rails.rb +0 -29
- data/lib/rollbar/js/frameworks.rb +0 -6
- data/lib/rollbar/js/middleware.rb +0 -129
- data/lib/rollbar/js/version.rb +0 -5
- data/lib/rollbar/json/default.rb +0 -11
- data/lib/rollbar/json/oj.rb +0 -15
- data/lib/rollbar/rack.rb +0 -9
- data/lib/rollbar/rails/controller_methods.rb +0 -40
- data/lib/rollbar/railtie.rb +0 -46
- data/lib/rollbar/rake.rb +0 -38
- data/lib/rollbar/sidekiq.rb +0 -40
- data/lib/rollbar/tasks/rollbar.cap +0 -45
- data/spec/cacert.pem +0 -3988
- data/spec/controllers/home_controller_spec.rb +0 -455
- data/spec/delay/sidekiq_spec.rb +0 -61
- data/spec/delay/sucker_punch_spec.rb +0 -25
- data/spec/delayed/backend/test.rb +0 -139
- 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/user.rb +0 -7
- 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/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 -23
- 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.ru +0 -4
- 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/schema.rb +0 -35
- 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/generators/rollbar/rollbar_generator_spec.rb +0 -24
- data/spec/requests/home_spec.rb +0 -49
- data/spec/rollbar/active_job_spec.rb +0 -33
- data/spec/rollbar/configuration_spec.rb +0 -24
- 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/delayed_job/job_data.rb +0 -35
- data/spec/rollbar/delayed_job_spec.rb +0 -90
- data/spec/rollbar/encoding/encoder_spec.rb +0 -63
- data/spec/rollbar/js/frameworks/rails_spec.rb +0 -19
- data/spec/rollbar/js/middleware_spec.rb +0 -162
- 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 -34
- data/spec/rollbar/middleware/rack/builder_spec.rb +0 -151
- data/spec/rollbar/middleware/sinatra_spec.rb +0 -197
- data/spec/rollbar/rake_spec.rb +0 -34
- data/spec/rollbar/request_data_extractor_spec.rb +0 -82
- data/spec/rollbar/scrubbers/url_spec.rb +0 -111
- data/spec/rollbar/sidekiq_spec.rb +0 -90
- 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_spec.rb +0 -19
- data/spec/rollbar_bc_spec.rb +0 -380
- data/spec/rollbar_spec.rb +0 -2067
- data/spec/spec_helper.rb +0 -49
- 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/notifier_helpers.rb +0 -36
- data/spec/support/shared_contexts.rb +0 -12
data/lib/rollbar/item.rb
ADDED
@@ -0,0 +1,314 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'securerandom'
|
6
|
+
rescue LoadError
|
7
|
+
nil
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'rollbar/item/backtrace'
|
11
|
+
require 'rollbar/util'
|
12
|
+
require 'rollbar/encoding'
|
13
|
+
require 'rollbar/truncation'
|
14
|
+
require 'rollbar/json'
|
15
|
+
require 'rollbar/scrubbers/params'
|
16
|
+
|
17
|
+
module Rollbar
|
18
|
+
# This class represents the payload to be sent to the API.
|
19
|
+
# It contains the logic to build the payload, trucante it
|
20
|
+
# and dump the JSON.
|
21
|
+
class Item
|
22
|
+
extend Forwardable
|
23
|
+
|
24
|
+
attr_writer :payload
|
25
|
+
|
26
|
+
attr_reader :level, :message, :exception, :extra, :configuration, :scope, :logger,
|
27
|
+
:notifier, :context
|
28
|
+
|
29
|
+
def_delegators :payload, :[]
|
30
|
+
|
31
|
+
class << self
|
32
|
+
def build_with(payload, options = {})
|
33
|
+
new(options).tap do |item|
|
34
|
+
item.payload = item.add_access_token_to_payload(payload)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def initialize(options)
|
40
|
+
@level = options[:level]
|
41
|
+
@message = options[:message]
|
42
|
+
@exception = options[:exception]
|
43
|
+
@extra = options[:extra]
|
44
|
+
@configuration = options[:configuration]
|
45
|
+
@logger = options[:logger]
|
46
|
+
@scope = options[:scope]
|
47
|
+
@payload = nil
|
48
|
+
@notifier = options[:notifier]
|
49
|
+
@context = options[:context]
|
50
|
+
end
|
51
|
+
|
52
|
+
def payload
|
53
|
+
@payload ||= build
|
54
|
+
end
|
55
|
+
|
56
|
+
def build
|
57
|
+
data = build_data
|
58
|
+
self.payload = add_access_token_to_payload({ 'data' => data })
|
59
|
+
|
60
|
+
enforce_valid_utf8
|
61
|
+
transform
|
62
|
+
payload
|
63
|
+
end
|
64
|
+
|
65
|
+
def build_data
|
66
|
+
data = initial_data
|
67
|
+
|
68
|
+
build_optional_data(data)
|
69
|
+
|
70
|
+
Util.deep_merge(data, configuration.payload_options)
|
71
|
+
Util.deep_merge(data, scope)
|
72
|
+
|
73
|
+
# Our API doesn't allow null context values, so just delete
|
74
|
+
# the key if value is nil.
|
75
|
+
data.delete(:context) unless data[:context]
|
76
|
+
|
77
|
+
data
|
78
|
+
end
|
79
|
+
|
80
|
+
def initial_data
|
81
|
+
{
|
82
|
+
:timestamp => Time.now.to_i,
|
83
|
+
:environment => build_environment,
|
84
|
+
:level => level,
|
85
|
+
:language => 'ruby',
|
86
|
+
:framework => configuration.framework,
|
87
|
+
:server => server_data,
|
88
|
+
:notifier => {
|
89
|
+
:name => 'rollbar-gem',
|
90
|
+
:version => VERSION,
|
91
|
+
:configured_options => configured_options
|
92
|
+
},
|
93
|
+
:body => build_body
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
def build_optional_data(data)
|
98
|
+
if configuration.project_gem_paths.any?
|
99
|
+
data[:project_package_paths] = configuration.project_gem_paths
|
100
|
+
end
|
101
|
+
|
102
|
+
data[:code_version] = configuration.code_version if configuration.code_version
|
103
|
+
|
104
|
+
return unless defined?(SecureRandom) && SecureRandom.respond_to?(:uuid)
|
105
|
+
|
106
|
+
data[:uuid] = SecureRandom.uuid
|
107
|
+
end
|
108
|
+
|
109
|
+
def configured_options
|
110
|
+
if Gem.loaded_specs['activesupport'] &&
|
111
|
+
Gem.loaded_specs['activesupport'].version < Gem::Version.new('4.1')
|
112
|
+
# There are too many types that crash ActiveSupport JSON serialization,
|
113
|
+
# and not worth the risk just to send this diagnostic object.
|
114
|
+
# In versions < 4.1, ActiveSupport hooks Ruby's JSON.generate so deeply
|
115
|
+
# that there's no workaround.
|
116
|
+
'not serialized in ActiveSupport < 4.1'
|
117
|
+
elsif configuration.use_async && !configuration.async_json_payload
|
118
|
+
# The setting allows serialization to be performed by each handler,
|
119
|
+
# and this usually means it is actually performed by ActiveSupport,
|
120
|
+
# which cannot safely serialize this key.
|
121
|
+
'not serialized when async_json_payload is not set'
|
122
|
+
else
|
123
|
+
scrub(configuration.configured_options.configured)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def dump
|
128
|
+
# Ensure all keys are strings since we can receive the payload inline or
|
129
|
+
# from an async handler job, which can be serialized.
|
130
|
+
stringified_payload = Util::Hash.deep_stringify_keys(payload)
|
131
|
+
attempts = []
|
132
|
+
result = Truncation.truncate(stringified_payload, attempts)
|
133
|
+
|
134
|
+
return result unless Truncation.truncate?(result)
|
135
|
+
|
136
|
+
handle_too_large_payload(stringified_payload, result, attempts)
|
137
|
+
|
138
|
+
nil
|
139
|
+
end
|
140
|
+
|
141
|
+
def handle_too_large_payload(stringified_payload, _final_payload, attempts)
|
142
|
+
uuid = stringified_payload['data']['uuid']
|
143
|
+
host = stringified_payload['data'].fetch('server', {})['host']
|
144
|
+
|
145
|
+
original_error = {
|
146
|
+
:message => message,
|
147
|
+
:exception => exception,
|
148
|
+
:configuration => configuration,
|
149
|
+
:uuid => uuid,
|
150
|
+
:host => host
|
151
|
+
}
|
152
|
+
|
153
|
+
notifier.send_failsafe(too_large_payload_string(attempts), nil, original_error)
|
154
|
+
|
155
|
+
logger.error('[Rollbar] Payload too large to be sent for UUID ' \
|
156
|
+
"#{uuid}: #{Rollbar::JSON.dump(payload)}")
|
157
|
+
end
|
158
|
+
|
159
|
+
def too_large_payload_string(attempts)
|
160
|
+
'Could not send payload due to it being too large after truncating attempts. ' \
|
161
|
+
"Original size: #{attempts.first} Attempts: #{attempts.join(', ')} " \
|
162
|
+
"Final size: #{attempts.last}"
|
163
|
+
end
|
164
|
+
|
165
|
+
def ignored?
|
166
|
+
data = payload['data']
|
167
|
+
|
168
|
+
return unless data[:person]
|
169
|
+
|
170
|
+
person_id = data[:person][configuration.person_id_method.to_sym]
|
171
|
+
configuration.ignored_person_ids.include?(person_id)
|
172
|
+
end
|
173
|
+
|
174
|
+
def add_access_token_to_payload(payload)
|
175
|
+
# Some use cases remain where the token is needed in the payload. For example:
|
176
|
+
#
|
177
|
+
# When using async senders, if the access token is changed dynamically in
|
178
|
+
# the main process config, the sender process won't see that change.
|
179
|
+
#
|
180
|
+
# Until the delayed sender interface is changed to allow passing dynamic
|
181
|
+
# config options, this workaround allows the main process to set the token
|
182
|
+
# by adding it to the payload.
|
183
|
+
if configuration && configuration.use_payload_access_token
|
184
|
+
payload['access_token'] ||= configuration.access_token
|
185
|
+
end
|
186
|
+
|
187
|
+
payload
|
188
|
+
end
|
189
|
+
|
190
|
+
private
|
191
|
+
|
192
|
+
def build_environment
|
193
|
+
env = configuration.environment
|
194
|
+
env = 'unspecified' if env.nil? || env.empty?
|
195
|
+
|
196
|
+
env
|
197
|
+
end
|
198
|
+
|
199
|
+
def build_body
|
200
|
+
exception ? build_backtrace_body : build_message_body
|
201
|
+
end
|
202
|
+
|
203
|
+
def build_backtrace_body
|
204
|
+
backtrace = Backtrace.new(exception,
|
205
|
+
:message => message,
|
206
|
+
:extra => build_extra,
|
207
|
+
:configuration => configuration)
|
208
|
+
|
209
|
+
backtrace.to_h
|
210
|
+
end
|
211
|
+
|
212
|
+
def build_extra
|
213
|
+
merged_extra = Util.deep_merge(scrub(extra), scrub(error_context))
|
214
|
+
|
215
|
+
if custom_data_method? && !Rollbar::Util.method_in_stack(:custom_data, __FILE__)
|
216
|
+
Util.deep_merge(scrub(custom_data), merged_extra)
|
217
|
+
else
|
218
|
+
# avoid putting an empty {} in the payload.
|
219
|
+
merged_extra.empty? ? nil : merged_extra
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def error_context
|
224
|
+
exception.respond_to?(:rollbar_context) && exception.rollbar_context
|
225
|
+
end
|
226
|
+
|
227
|
+
def scrub(data)
|
228
|
+
return data unless data.is_a? Hash
|
229
|
+
|
230
|
+
options = {
|
231
|
+
:params => data,
|
232
|
+
:config => Rollbar.configuration.scrub_fields,
|
233
|
+
:whitelist => Rollbar.configuration.scrub_whitelist
|
234
|
+
}
|
235
|
+
Rollbar::Scrubbers::Params.call(options)
|
236
|
+
end
|
237
|
+
|
238
|
+
def custom_data_method?
|
239
|
+
!!configuration.custom_data_method
|
240
|
+
end
|
241
|
+
|
242
|
+
def custom_data
|
243
|
+
data = if configuration.custom_data_method.arity == 3
|
244
|
+
configuration.custom_data_method.call(message, exception, context)
|
245
|
+
else
|
246
|
+
configuration.custom_data_method.call
|
247
|
+
end
|
248
|
+
|
249
|
+
Rollbar::Util.deep_copy(data)
|
250
|
+
rescue StandardError => e
|
251
|
+
return {} if configuration.safely?
|
252
|
+
|
253
|
+
report_custom_data_error(e)
|
254
|
+
end
|
255
|
+
|
256
|
+
def report_custom_data_error(e)
|
257
|
+
data = notifier.safely.error(e)
|
258
|
+
|
259
|
+
return {} unless data.is_a?(Hash) && data[:uuid]
|
260
|
+
|
261
|
+
uuid_url = Util.uuid_rollbar_url(data, configuration)
|
262
|
+
|
263
|
+
{ :_error_in_custom_data_method => uuid_url }
|
264
|
+
end
|
265
|
+
|
266
|
+
def build_message_body
|
267
|
+
extra = build_extra
|
268
|
+
result = { :body => message || 'Empty message' }
|
269
|
+
result[:extra] = extra if extra
|
270
|
+
|
271
|
+
{ :message => result }
|
272
|
+
end
|
273
|
+
|
274
|
+
def server_data
|
275
|
+
data = {
|
276
|
+
:host => configuration.host || Socket.gethostname
|
277
|
+
}
|
278
|
+
data[:root] = configuration.root.to_s if configuration.root
|
279
|
+
data[:branch] = configuration.branch if configuration.branch
|
280
|
+
data[:pid] = Process.pid
|
281
|
+
|
282
|
+
data
|
283
|
+
end
|
284
|
+
|
285
|
+
def enforce_valid_utf8
|
286
|
+
Util.enforce_valid_utf8(payload)
|
287
|
+
end
|
288
|
+
|
289
|
+
def transform
|
290
|
+
handlers = configuration.transform
|
291
|
+
|
292
|
+
handlers.each do |handler|
|
293
|
+
begin
|
294
|
+
handler.call(transform_options)
|
295
|
+
rescue StandardError => e
|
296
|
+
logger.error("[Rollbar] Error calling the `transform` hook: #{e}")
|
297
|
+
|
298
|
+
break
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
def transform_options
|
304
|
+
{
|
305
|
+
:level => level,
|
306
|
+
:scope => scope,
|
307
|
+
:exception => exception,
|
308
|
+
:message => message,
|
309
|
+
:extra => extra,
|
310
|
+
:payload => payload
|
311
|
+
}
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
data/lib/rollbar/js.rb
CHANGED
@@ -1,32 +1,4 @@
|
|
1
|
-
require "rollbar/js/version"
|
2
|
-
|
3
1
|
module Rollbar
|
4
2
|
module Js
|
5
|
-
extend self
|
6
|
-
|
7
|
-
attr_reader :framework
|
8
|
-
attr_reader :framework_loader
|
9
|
-
|
10
|
-
def prepare
|
11
|
-
@framework ||= detect_framework
|
12
|
-
@framework_loader ||= load_framework_class.new
|
13
|
-
|
14
|
-
@framework_loader.prepare
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def detect_framework
|
20
|
-
case
|
21
|
-
when defined?(::Rails::VERSION)
|
22
|
-
:rails
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def load_framework_class
|
27
|
-
require "rollbar/js/frameworks/#{framework}"
|
28
|
-
|
29
|
-
Rollbar::Js::Frameworks.const_get(framework.to_s.capitalize)
|
30
|
-
end
|
31
3
|
end
|
32
4
|
end
|
data/lib/rollbar/json.rb
CHANGED
@@ -1,66 +1,18 @@
|
|
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
|
13
|
-
|
14
|
-
|
15
|
-
attr_writer :options_module
|
5
|
+
module JSON # :nodoc:
|
6
|
+
module_function
|
16
7
|
|
17
8
|
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
|
9
|
+
Rollbar.plugins.get('basic_socket').load_scoped!(true) do
|
10
|
+
::JSON.generate(object)
|
51
11
|
end
|
52
12
|
end
|
53
13
|
|
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]
|
14
|
+
def load(string)
|
15
|
+
::JSON.parse(string)
|
63
16
|
end
|
64
17
|
end
|
65
18
|
end
|
66
|
-
|
@@ -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 version?(version)
|
@@ -31,5 +15,9 @@ module Rollbar
|
|
31
15
|
|
32
16
|
numbers == ::RUBY_VERSION.split('.')[0, numbers.size]
|
33
17
|
end
|
18
|
+
|
19
|
+
def timeout_exceptions
|
20
|
+
[Net::ReadTimeout, Net::OpenTimeout]
|
21
|
+
end
|
34
22
|
end
|
35
23
|
end
|
data/lib/rollbar/lazy_store.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
module Rollbar
|
2
2
|
class LazyStore
|
3
|
-
attr_reader :loaded_data
|
3
|
+
attr_reader :loaded_data, :raw
|
4
4
|
private :loaded_data
|
5
5
|
|
6
|
-
attr_reader :raw
|
7
|
-
|
8
6
|
def initialize(initial_data)
|
9
7
|
initial_data ||= {}
|
10
8
|
|
@@ -21,11 +19,11 @@ module Rollbar
|
|
21
19
|
end
|
22
20
|
|
23
21
|
def ==(other)
|
24
|
-
if other.is_a?(self.class)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
22
|
+
raw == if other.is_a?(self.class)
|
23
|
+
other.raw
|
24
|
+
else
|
25
|
+
other
|
26
|
+
end
|
29
27
|
end
|
30
28
|
|
31
29
|
# With this version of clone we ensure that the loaded_data is empty
|
@@ -41,8 +39,6 @@ module Rollbar
|
|
41
39
|
raw[key] = value
|
42
40
|
|
43
41
|
loaded_data.delete(key)
|
44
|
-
|
45
|
-
value
|
46
42
|
end
|
47
43
|
|
48
44
|
def data
|
@@ -76,8 +72,8 @@ module Rollbar
|
|
76
72
|
super
|
77
73
|
end
|
78
74
|
|
79
|
-
def
|
80
|
-
|
75
|
+
def respond_to_missing?(method_sym, include_all)
|
76
|
+
raw.respond_to?(method_sym, include_all)
|
81
77
|
end
|
82
78
|
end
|
83
79
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'rollbar'
|
3
|
+
|
4
|
+
module Rollbar
|
5
|
+
# This class provides logger interface that can be used to replace
|
6
|
+
# the application logger and send all the log messages to Rollbar
|
7
|
+
#
|
8
|
+
# Usage:
|
9
|
+
# require 'rollbar/logger'
|
10
|
+
# logger = Rollbar::Logger.new
|
11
|
+
# logger.error('Error processing purchase')
|
12
|
+
#
|
13
|
+
# If using Rails, you can extend the Rails logger so messages are logged
|
14
|
+
# normally and also to Rollbar:
|
15
|
+
#
|
16
|
+
# Rails.logger.extend(ActiveSupport::Logger.broadcast(Rollbar::Logger.new))
|
17
|
+
class Logger < ::Logger
|
18
|
+
class Error < RuntimeError; end
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
super(nil)
|
22
|
+
|
23
|
+
self.level = ERROR
|
24
|
+
end
|
25
|
+
|
26
|
+
def add(severity, message = nil, progname = nil)
|
27
|
+
return true if severity < @level
|
28
|
+
|
29
|
+
message ||= block_given? ? yield : progname
|
30
|
+
|
31
|
+
return true if blank?(message)
|
32
|
+
|
33
|
+
rollbar.log(rollbar_level(severity), message)
|
34
|
+
end
|
35
|
+
|
36
|
+
def <<(message)
|
37
|
+
error(message)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns a Rollbar::Notifier instance with the current global scope and
|
41
|
+
# with a logger writing to /dev/null so we don't have a infinite loop
|
42
|
+
# when Rollbar.configuration.logger is Rails.logger.
|
43
|
+
def rollbar
|
44
|
+
notifier = Rollbar.scope
|
45
|
+
notifier.configuration.logger = ::Logger.new('/dev/null')
|
46
|
+
|
47
|
+
notifier
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def blank?(message)
|
53
|
+
return message.blank? if message.respond_to?(:blank?)
|
54
|
+
|
55
|
+
message.respond_to?(:empty?) ? !!message.empty? : !message
|
56
|
+
end
|
57
|
+
|
58
|
+
# Find correct Rollbar level to use using the indexes in Logger::Severity
|
59
|
+
# DEBUG = 0
|
60
|
+
# INFO = 1
|
61
|
+
# WARN = 2
|
62
|
+
# ERROR = 3
|
63
|
+
# FATAL = 4
|
64
|
+
# UNKNOWN = 5
|
65
|
+
#
|
66
|
+
# If not found we'll use 'error' as the used level
|
67
|
+
def rollbar_level(severity)
|
68
|
+
[:debug, :info, :warning, :error, :critical, :error][severity] || :error
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/rollbar/logger_proxy.rb
CHANGED
@@ -23,10 +23,27 @@ module Rollbar
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def log(level, message)
|
26
|
+
unless Rollbar.configuration.enabled && acceptable_levels.include?(level.to_sym)
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
26
30
|
@object.send(level, message)
|
27
|
-
rescue
|
31
|
+
rescue StandardError
|
28
32
|
puts "[Rollbar] Error logging #{level}:"
|
29
33
|
puts "[Rollbar] #{message}"
|
30
34
|
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
def acceptable_levels
|
39
|
+
@acceptable_levels ||= begin
|
40
|
+
levels = [:debug, :info, :warn, :error]
|
41
|
+
if Rollbar.configuration.logger_level
|
42
|
+
levels[levels.find_index(Rollbar.configuration.logger_level)..-1]
|
43
|
+
else
|
44
|
+
[]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
31
48
|
end
|
32
49
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Allows a Ruby String to be used to pass native Javascript objects/functions
|
2
|
+
# when calling JSON#generate with a Rollbar::JSON::JsOptionsState instance.
|
3
|
+
#
|
4
|
+
# Example:
|
5
|
+
# JSON.generate(
|
6
|
+
# { foo: Rollbar::JSON::Value.new('function(){ alert("bar") }') },
|
7
|
+
# Rollbar::JSON::JsOptionsState.new
|
8
|
+
# )
|
9
|
+
#
|
10
|
+
# => '{"foo":function(){ alert(\"bar\") }}'
|
11
|
+
#
|
12
|
+
# MUST use the Ruby JSON encoder, as in the example. The ActiveSupport encoder,
|
13
|
+
# which is installed with Rails, is invoked when calling Hash#to_json and #as_json,
|
14
|
+
# and will not work.
|
15
|
+
#
|
16
|
+
module Rollbar
|
17
|
+
module JSON
|
18
|
+
class JsOptionsState < ::JSON::State; end
|
19
|
+
|
20
|
+
class Value # :nodoc:
|
21
|
+
attr_accessor :value
|
22
|
+
|
23
|
+
def initialize(value)
|
24
|
+
@value = value
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_json(opts = {})
|
28
|
+
# Return the raw value if this is from the js middleware
|
29
|
+
return value if opts.class == Rollbar::JSON::JsOptionsState
|
30
|
+
|
31
|
+
# Otherwise convert to a string
|
32
|
+
%Q["#{value}"]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|