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.rb
CHANGED
@@ -1,917 +1,96 @@
|
|
1
|
+
require 'net/protocol'
|
1
2
|
require 'net/https'
|
2
3
|
require 'socket'
|
3
|
-
require 'thread'
|
4
4
|
require 'uri'
|
5
|
+
require 'open-uri'
|
5
6
|
require 'forwardable'
|
6
7
|
|
7
8
|
begin
|
8
9
|
require 'securerandom'
|
9
10
|
rescue LoadError
|
11
|
+
# Skip loading
|
10
12
|
end
|
11
13
|
|
12
14
|
require 'rollbar/version'
|
13
|
-
require 'rollbar/
|
14
|
-
require 'rollbar/js'
|
15
|
+
require 'rollbar/plugins'
|
15
16
|
require 'rollbar/configuration'
|
16
|
-
require 'rollbar/encoding'
|
17
17
|
require 'rollbar/logger_proxy'
|
18
|
-
require 'rollbar/exception_reporter'
|
19
|
-
require 'rollbar/util'
|
20
|
-
require 'rollbar/railtie' if defined?(Rails::VERSION) && Rails::VERSION::MAJOR >= 3
|
21
|
-
require 'rollbar/delay/girl_friday' if defined?(GirlFriday)
|
22
|
-
require 'rollbar/delay/thread'
|
23
|
-
require 'rollbar/truncation'
|
24
18
|
require 'rollbar/exceptions'
|
25
19
|
require 'rollbar/lazy_store'
|
20
|
+
require 'rollbar/notifier'
|
26
21
|
|
22
|
+
# The Rollbar module. It stores a Rollbar::Notifier per thread and
|
23
|
+
# provides some module methods in order to use the current thread notifier.
|
27
24
|
module Rollbar
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
PUBLIC_NOTIFIER_METHODS = %w(debug info warn warning error critical log logger
|
33
|
-
process_payload process_from_async_handler scope send_failsafe log_info log_debug
|
34
|
-
log_warning log_error silenced)
|
35
|
-
|
36
|
-
class Notifier
|
37
|
-
attr_accessor :configuration
|
38
|
-
attr_accessor :last_report
|
39
|
-
attr_reader :scope_object
|
40
|
-
|
41
|
-
@file_semaphore = Mutex.new
|
42
|
-
|
43
|
-
def initialize(parent_notifier = nil, payload_options = nil, scope = nil)
|
44
|
-
if parent_notifier
|
45
|
-
@configuration = parent_notifier.configuration.clone
|
46
|
-
@scope_object = parent_notifier.scope_object.clone
|
47
|
-
|
48
|
-
Rollbar::Util.deep_merge(@configuration.payload_options, payload_options) if payload_options
|
49
|
-
Rollbar::Util.deep_merge(@scope_object, scope) if scope
|
50
|
-
else
|
51
|
-
@configuration = ::Rollbar::Configuration.new
|
52
|
-
@scope_object = ::Rollbar::LazyStore.new(scope)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# Similar to configure below, but used only internally within the gem
|
57
|
-
# to configure it without initializing any of the third party hooks
|
58
|
-
def preconfigure
|
59
|
-
yield(configuration)
|
60
|
-
end
|
61
|
-
|
62
|
-
# Configures the notifier instance
|
63
|
-
def configure
|
64
|
-
configuration.enabled = true if configuration.enabled.nil?
|
65
|
-
|
66
|
-
yield(configuration)
|
67
|
-
end
|
68
|
-
|
69
|
-
def scope(options = {})
|
70
|
-
self.class.new(self, nil, options)
|
71
|
-
end
|
72
|
-
|
73
|
-
def scope!(options = {})
|
74
|
-
Rollbar::Util.deep_merge(scope_object, options)
|
75
|
-
|
76
|
-
self
|
77
|
-
end
|
78
|
-
|
79
|
-
# Returns a new notifier with same configuration options
|
80
|
-
# but it sets Configuration#safely to true.
|
81
|
-
# We are using this flag to avoid having inifite loops
|
82
|
-
# when evaluating some custom user methods.
|
83
|
-
def safely
|
84
|
-
new_notifier = scope
|
85
|
-
new_notifier.configuration.safely = true
|
86
|
-
|
87
|
-
new_notifier
|
88
|
-
end
|
89
|
-
|
90
|
-
# Turns off reporting for the given block.
|
91
|
-
#
|
92
|
-
# @example
|
93
|
-
# Rollbar.silenced { raise }
|
94
|
-
#
|
95
|
-
# @yield Block which exceptions won't be reported.
|
96
|
-
def silenced
|
97
|
-
yield
|
98
|
-
rescue => e
|
99
|
-
e.instance_variable_set(:@_rollbar_do_not_report, true)
|
100
|
-
raise
|
101
|
-
end
|
102
|
-
|
103
|
-
# Sends a report to Rollbar.
|
104
|
-
#
|
105
|
-
# Accepts any number of arguments. The last String argument will become
|
106
|
-
# the message or description of the report. The last Exception argument
|
107
|
-
# will become the associated exception for the report. The last hash
|
108
|
-
# argument will be used as the extra data for the report.
|
109
|
-
#
|
110
|
-
# @example
|
111
|
-
# begin
|
112
|
-
# foo = bar
|
113
|
-
# rescue => e
|
114
|
-
# Rollbar.log(e)
|
115
|
-
# end
|
116
|
-
#
|
117
|
-
# @example
|
118
|
-
# Rollbar.log('This is a simple log message')
|
119
|
-
#
|
120
|
-
# @example
|
121
|
-
# Rollbar.log(e, 'This is a description of the exception')
|
122
|
-
#
|
123
|
-
def log(level, *args)
|
124
|
-
return 'disabled' unless configuration.enabled
|
125
|
-
|
126
|
-
message, exception, extra = extract_arguments(args)
|
127
|
-
use_exception_level_filters = extra && extra.delete(:use_exception_level_filters) == true
|
128
|
-
|
129
|
-
return 'ignored' if ignored?(exception, use_exception_level_filters)
|
130
|
-
|
131
|
-
begin
|
132
|
-
call_before_process(:level => level,
|
133
|
-
:exception => exception,
|
134
|
-
:message => message,
|
135
|
-
:extra => extra)
|
136
|
-
rescue Rollbar::Ignore
|
137
|
-
return 'ignored'
|
138
|
-
end
|
139
|
-
|
140
|
-
level = lookup_exception_level(level, exception,
|
141
|
-
use_exception_level_filters)
|
142
|
-
|
143
|
-
begin
|
144
|
-
report(level, message, exception, extra)
|
145
|
-
rescue Exception => e
|
146
|
-
report_internal_error(e)
|
147
|
-
|
148
|
-
'error'
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
# See log() above
|
153
|
-
def debug(*args)
|
154
|
-
log('debug', *args)
|
155
|
-
end
|
156
|
-
|
157
|
-
# See log() above
|
158
|
-
def info(*args)
|
159
|
-
log('info', *args)
|
160
|
-
end
|
161
|
-
|
162
|
-
# See log() above
|
163
|
-
def warn(*args)
|
164
|
-
log('warning', *args)
|
165
|
-
end
|
166
|
-
|
167
|
-
# See log() above
|
168
|
-
def warning(*args)
|
169
|
-
log('warning', *args)
|
170
|
-
end
|
171
|
-
|
172
|
-
# See log() above
|
173
|
-
def error(*args)
|
174
|
-
log('error', *args)
|
175
|
-
end
|
176
|
-
|
177
|
-
# See log() above
|
178
|
-
def critical(*args)
|
179
|
-
log('critical', *args)
|
180
|
-
end
|
181
|
-
|
182
|
-
def process_payload(payload)
|
183
|
-
if configuration.write_to_file
|
184
|
-
if configuration.use_async
|
185
|
-
@file_semaphore.synchronize {
|
186
|
-
write_payload(payload)
|
187
|
-
}
|
188
|
-
else
|
189
|
-
write_payload(payload)
|
190
|
-
end
|
191
|
-
else
|
192
|
-
send_payload(payload)
|
193
|
-
end
|
194
|
-
rescue => e
|
195
|
-
log_error("[Rollbar] Error processing the payload: #{e.class}, #{e.message}. Payload: #{payload.inspect}")
|
196
|
-
raise e
|
197
|
-
end
|
198
|
-
|
199
|
-
# We will reraise exceptions in this method so async queues
|
200
|
-
# can retry the job or, in general, handle an error report some way.
|
201
|
-
#
|
202
|
-
# At same time that exception is silenced so we don't generate
|
203
|
-
# infinite reports. This example is what we want to avoid:
|
204
|
-
#
|
205
|
-
# 1. New exception in a the project is raised
|
206
|
-
# 2. That report enqueued to Sidekiq queue.
|
207
|
-
# 3. The Sidekiq job tries to send the report to our API
|
208
|
-
# 4. The report fails, for example cause a network failure,
|
209
|
-
# and a exception is raised
|
210
|
-
# 5. We report an internal error for that exception
|
211
|
-
# 6. We reraise the exception so Sidekiq job fails and
|
212
|
-
# Sidekiq can retry the job reporting the original exception
|
213
|
-
# 7. Because the job failed and Sidekiq can be managed by rollbar we'll
|
214
|
-
# report a new exception.
|
215
|
-
# 8. Go to point 2.
|
216
|
-
#
|
217
|
-
# We'll then push to Sidekiq queue indefinitely until the network failure
|
218
|
-
# is fixed.
|
219
|
-
#
|
220
|
-
# Using Rollbar.silenced we avoid the above behavior but Sidekiq
|
221
|
-
# will have a chance to retry the original job.
|
222
|
-
def process_from_async_handler(payload)
|
223
|
-
Rollbar.silenced do
|
224
|
-
begin
|
225
|
-
process_payload(payload)
|
226
|
-
rescue => e
|
227
|
-
report_internal_error(e)
|
228
|
-
|
229
|
-
raise
|
230
|
-
end
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
def custom_data
|
235
|
-
data = configuration.custom_data_method.call
|
236
|
-
Rollbar::Util.deep_copy(data)
|
237
|
-
rescue => e
|
238
|
-
return {} if configuration.safely?
|
239
|
-
|
240
|
-
report_custom_data_error(e)
|
241
|
-
end
|
242
|
-
|
243
|
-
private
|
244
|
-
|
245
|
-
def call_before_process(options)
|
246
|
-
options = {
|
247
|
-
:level => options[:level],
|
248
|
-
:scope => scope_object,
|
249
|
-
:exception => options[:exception],
|
250
|
-
:message => options[:message],
|
251
|
-
:extra => options[:extra]
|
252
|
-
}
|
253
|
-
handlers = configuration.before_process
|
254
|
-
|
255
|
-
handlers.each do |handler|
|
256
|
-
begin
|
257
|
-
handler.call(options)
|
258
|
-
rescue Rollbar::Ignore
|
259
|
-
raise
|
260
|
-
rescue => e
|
261
|
-
log_error("[Rollbar] Error calling the `before_process` hook: #{e}")
|
262
|
-
|
263
|
-
break
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
def extract_arguments(args)
|
269
|
-
message = nil
|
270
|
-
exception = nil
|
271
|
-
extra = nil
|
272
|
-
|
273
|
-
args.each do |arg|
|
274
|
-
if arg.is_a?(String)
|
275
|
-
message = arg
|
276
|
-
elsif arg.is_a?(Exception)
|
277
|
-
exception = arg
|
278
|
-
elsif arg.is_a?(Hash)
|
279
|
-
extra = arg
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
|
-
[message, exception, extra]
|
284
|
-
end
|
285
|
-
|
286
|
-
def lookup_exception_level(orig_level, exception, use_exception_level_filters)
|
287
|
-
return orig_level unless use_exception_level_filters
|
288
|
-
|
289
|
-
exception_level = filtered_level(exception)
|
290
|
-
return exception_level if exception_level
|
291
|
-
|
292
|
-
orig_level
|
293
|
-
end
|
294
|
-
|
295
|
-
def ignored?(exception, use_exception_level_filters = false)
|
296
|
-
return false unless exception
|
297
|
-
return true if use_exception_level_filters && filtered_level(exception) == 'ignore'
|
298
|
-
return true if exception.instance_variable_get(:@_rollbar_do_not_report)
|
299
|
-
|
300
|
-
false
|
301
|
-
end
|
302
|
-
|
303
|
-
def filtered_level(exception)
|
304
|
-
return unless exception
|
305
|
-
|
306
|
-
filter = configuration.exception_level_filters[exception.class.name]
|
307
|
-
if filter.respond_to?(:call)
|
308
|
-
filter.call(exception)
|
309
|
-
else
|
310
|
-
filter
|
311
|
-
end
|
312
|
-
end
|
313
|
-
|
314
|
-
def report(level, message, exception, extra)
|
315
|
-
unless message || exception || extra
|
316
|
-
log_error "[Rollbar] Tried to send a report with no message, exception or extra data."
|
317
|
-
return 'error'
|
318
|
-
end
|
319
|
-
|
320
|
-
payload = build_payload(level, message, exception, extra)
|
321
|
-
data = payload['data']
|
322
|
-
|
323
|
-
if data[:person]
|
324
|
-
person_id = data[:person][configuration.person_id_method.to_sym]
|
325
|
-
return 'ignored' if configuration.ignored_person_ids.include?(person_id)
|
326
|
-
end
|
327
|
-
|
328
|
-
schedule_payload(payload)
|
329
|
-
|
330
|
-
log_instance_link(data)
|
331
|
-
|
332
|
-
Rollbar.last_report = data
|
333
|
-
|
334
|
-
data
|
335
|
-
end
|
336
|
-
|
337
|
-
# Reports an internal error in the Rollbar library. This will be reported within the configured
|
338
|
-
# Rollbar project. We'll first attempt to provide a report including the exception traceback.
|
339
|
-
# If that fails, we'll fall back to a more static failsafe response.
|
340
|
-
def report_internal_error(exception)
|
341
|
-
log_error "[Rollbar] Reporting internal error encountered while sending data to Rollbar."
|
342
|
-
|
343
|
-
begin
|
344
|
-
payload = build_payload('error', nil, exception, {:internal => true})
|
345
|
-
rescue => e
|
346
|
-
send_failsafe("build_payload in exception_data", e)
|
347
|
-
return
|
348
|
-
end
|
349
|
-
|
350
|
-
begin
|
351
|
-
process_payload(payload)
|
352
|
-
rescue => e
|
353
|
-
send_failsafe("error in process_payload", e)
|
354
|
-
return
|
355
|
-
end
|
356
|
-
|
357
|
-
begin
|
358
|
-
log_instance_link(payload['data'])
|
359
|
-
rescue => e
|
360
|
-
send_failsafe("error logging instance link", e)
|
361
|
-
return
|
362
|
-
end
|
363
|
-
end
|
364
|
-
|
365
|
-
## Payload building functions
|
366
|
-
|
367
|
-
def build_payload(level, message, exception, extra)
|
368
|
-
environment = configuration.environment
|
369
|
-
environment = 'unspecified' if environment.nil? || environment.empty?
|
370
|
-
|
371
|
-
data = {
|
372
|
-
:timestamp => Time.now.to_i,
|
373
|
-
:environment => environment,
|
374
|
-
:level => level,
|
375
|
-
:language => 'ruby',
|
376
|
-
:framework => configuration.framework,
|
377
|
-
:server => server_data,
|
378
|
-
:notifier => {
|
379
|
-
:name => 'rollbar-gem',
|
380
|
-
:version => VERSION
|
381
|
-
}
|
382
|
-
}
|
383
|
-
|
384
|
-
data[:body] = build_payload_body(message, exception, extra)
|
385
|
-
data[:project_package_paths] = configuration.project_gem_paths if configuration.project_gem_paths
|
386
|
-
data[:code_version] = configuration.code_version if configuration.code_version
|
387
|
-
data[:uuid] = SecureRandom.uuid if defined?(SecureRandom) && SecureRandom.respond_to?(:uuid)
|
388
|
-
|
389
|
-
Rollbar::Util.deep_merge(data, configuration.payload_options)
|
390
|
-
Rollbar::Util.deep_merge(data, scope_object)
|
391
|
-
|
392
|
-
# Our API doesn't allow null context values, so just delete
|
393
|
-
# the key if value is nil.
|
394
|
-
data.delete(:context) unless data[:context]
|
395
|
-
|
396
|
-
payload = {
|
397
|
-
'access_token' => configuration.access_token,
|
398
|
-
'data' => data
|
399
|
-
}
|
400
|
-
|
401
|
-
enforce_valid_utf8(payload)
|
402
|
-
|
403
|
-
call_transform(:level => level,
|
404
|
-
:exception => exception,
|
405
|
-
:message => message,
|
406
|
-
:extra => extra,
|
407
|
-
:payload => payload)
|
408
|
-
|
409
|
-
payload
|
410
|
-
end
|
411
|
-
|
412
|
-
def call_transform(options)
|
413
|
-
options = {
|
414
|
-
:level => options[:level],
|
415
|
-
:scope => scope_object,
|
416
|
-
:exception => options[:exception],
|
417
|
-
:message => options[:message],
|
418
|
-
:extra => options[:extra],
|
419
|
-
:payload => options[:payload]
|
420
|
-
}
|
421
|
-
handlers = configuration.transform
|
422
|
-
|
423
|
-
handlers.each do |handler|
|
424
|
-
begin
|
425
|
-
handler.call(options)
|
426
|
-
rescue => e
|
427
|
-
log_error("[Rollbar] Error calling the `transform` hook: #{e}")
|
428
|
-
|
429
|
-
break
|
430
|
-
end
|
431
|
-
end
|
432
|
-
end
|
433
|
-
|
434
|
-
def build_payload_body(message, exception, extra)
|
435
|
-
extra = Rollbar::Util.deep_merge(custom_data, extra || {}) if custom_data_method?
|
436
|
-
|
437
|
-
if exception
|
438
|
-
build_payload_body_exception(message, exception, extra)
|
439
|
-
else
|
440
|
-
build_payload_body_message(message, extra)
|
441
|
-
end
|
442
|
-
end
|
443
|
-
|
444
|
-
def custom_data_method?
|
445
|
-
!!configuration.custom_data_method
|
446
|
-
end
|
447
|
-
|
448
|
-
def report_custom_data_error(e)
|
449
|
-
data = safely.error(e)
|
450
|
-
|
451
|
-
return {} unless data.is_a?(Hash) && data[:uuid]
|
452
|
-
|
453
|
-
uuid_url = uuid_rollbar_url(data)
|
454
|
-
|
455
|
-
{ :_error_in_custom_data_method => uuid_url }
|
456
|
-
end
|
25
|
+
PUBLIC_NOTIFIER_METHODS = %w[debug info warn warning error critical log logger
|
26
|
+
process_item process_from_async_handler scope
|
27
|
+
send_failsafe log_info log_debug log_warning
|
28
|
+
log_error silenced scope_object].freeze
|
457
29
|
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
traces[0][:exception][:description] = message if message
|
462
|
-
traces[0][:extra] = extra if extra
|
463
|
-
|
464
|
-
if traces.size > 1
|
465
|
-
{ :trace_chain => traces }
|
466
|
-
elsif traces.size == 1
|
467
|
-
{ :trace => traces[0] }
|
468
|
-
end
|
469
|
-
end
|
470
|
-
|
471
|
-
def trace_data(exception)
|
472
|
-
frames = exception_backtrace(exception).map do |frame|
|
473
|
-
# parse the line
|
474
|
-
match = frame.match(/(.*):(\d+)(?::in `([^']+)')?/)
|
475
|
-
|
476
|
-
if match
|
477
|
-
{ :filename => match[1], :lineno => match[2].to_i, :method => match[3] }
|
478
|
-
else
|
479
|
-
{ :filename => "<unknown>", :lineno => 0, :method => frame }
|
480
|
-
end
|
481
|
-
end
|
482
|
-
|
483
|
-
# reverse so that the order is as rollbar expects
|
484
|
-
frames.reverse!
|
485
|
-
|
486
|
-
{
|
487
|
-
:frames => frames,
|
488
|
-
:exception => {
|
489
|
-
:class => exception.class.name,
|
490
|
-
:message => exception.message
|
491
|
-
}
|
492
|
-
}
|
493
|
-
end
|
494
|
-
|
495
|
-
# Returns the backtrace to be sent to our API. There are 3 options:
|
496
|
-
#
|
497
|
-
# 1. The exception received has a backtrace, then that backtrace is returned.
|
498
|
-
# 2. configuration.populate_empty_backtraces is disabled, we return [] here
|
499
|
-
# 3. The user has configuration.populate_empty_backtraces is enabled, then:
|
500
|
-
#
|
501
|
-
# We want to send the caller as backtrace, but the first lines of that array
|
502
|
-
# are those from the user's Rollbar.error line until this method. We want
|
503
|
-
# to remove those lines.
|
504
|
-
def exception_backtrace(exception)
|
505
|
-
return exception.backtrace if exception.backtrace.respond_to?( :map )
|
506
|
-
return [] unless configuration.populate_empty_backtraces
|
507
|
-
|
508
|
-
caller_backtrace = caller
|
509
|
-
caller_backtrace.shift while caller_backtrace[0].include?(rollbar_lib_gem_dir)
|
510
|
-
caller_backtrace
|
511
|
-
end
|
512
|
-
|
513
|
-
def rollbar_lib_gem_dir
|
514
|
-
Gem::Specification.find_by_name('rollbar').gem_dir + '/lib'
|
515
|
-
end
|
516
|
-
|
517
|
-
def trace_chain(exception)
|
518
|
-
traces = [trace_data(exception)]
|
519
|
-
visited = [exception]
|
520
|
-
|
521
|
-
while exception.respond_to?(:cause) && (cause = exception.cause) && cause.is_a?(Exception) && !visited.include?(cause)
|
522
|
-
traces << trace_data(cause)
|
523
|
-
visited << cause
|
524
|
-
exception = cause
|
525
|
-
end
|
526
|
-
|
527
|
-
traces
|
528
|
-
end
|
529
|
-
|
530
|
-
def build_payload_body_message(message, extra)
|
531
|
-
result = { :body => message || 'Empty message'}
|
532
|
-
result[:extra] = extra if extra
|
533
|
-
|
534
|
-
{ :message => result }
|
535
|
-
end
|
536
|
-
|
537
|
-
def server_data
|
538
|
-
data = {
|
539
|
-
:host => Socket.gethostname
|
540
|
-
}
|
541
|
-
data[:root] = configuration.root.to_s if configuration.root
|
542
|
-
data[:branch] = configuration.branch if configuration.branch
|
543
|
-
data[:pid] = Process.pid
|
544
|
-
|
545
|
-
data
|
546
|
-
end
|
547
|
-
|
548
|
-
def enforce_valid_utf8(payload)
|
549
|
-
normalizer = lambda { |object| Encoding.encode(object) }
|
550
|
-
|
551
|
-
Rollbar::Util.iterate_and_update(payload, normalizer)
|
552
|
-
end
|
553
|
-
|
554
|
-
# Walks the entire payload and truncates string values that
|
555
|
-
# are longer than the byte_threshold
|
556
|
-
def truncate_payload(payload, byte_threshold)
|
557
|
-
truncator = proc do |value|
|
558
|
-
if value.is_a?(String) && value.bytesize > byte_threshold
|
559
|
-
Rollbar::Util.truncate(value, byte_threshold)
|
560
|
-
else
|
561
|
-
value
|
562
|
-
end
|
563
|
-
end
|
564
|
-
|
565
|
-
Rollbar::Util.iterate_and_update(payload, truncator)
|
566
|
-
end
|
567
|
-
|
568
|
-
## Delivery functions
|
569
|
-
|
570
|
-
def send_payload_using_eventmachine(payload)
|
571
|
-
body = dump_payload(payload)
|
572
|
-
headers = { 'X-Rollbar-Access-Token' => payload['access_token'] }
|
573
|
-
req = EventMachine::HttpRequest.new(configuration.endpoint).post(:body => body, :head => headers)
|
574
|
-
|
575
|
-
req.callback do
|
576
|
-
if req.response_header.status == 200
|
577
|
-
log_info '[Rollbar] Success'
|
578
|
-
else
|
579
|
-
log_warning "[Rollbar] Got unexpected status code from Rollbar.io api: #{req.response_header.status}"
|
580
|
-
log_info "[Rollbar] Response: #{req.response}"
|
581
|
-
end
|
582
|
-
end
|
583
|
-
|
584
|
-
req.errback do
|
585
|
-
log_warning "[Rollbar] Call to API failed, status code: #{req.response_header.status}"
|
586
|
-
log_info "[Rollbar] Error's response: #{req.response}"
|
587
|
-
end
|
588
|
-
end
|
589
|
-
|
590
|
-
def send_payload(payload)
|
591
|
-
log_info '[Rollbar] Sending payload'
|
592
|
-
payload = Rollbar::JSON.load(payload) if payload.is_a?(String)
|
593
|
-
|
594
|
-
if configuration.use_eventmachine
|
595
|
-
send_payload_using_eventmachine(payload)
|
596
|
-
return
|
597
|
-
end
|
598
|
-
|
599
|
-
body = dump_payload(payload)
|
600
|
-
|
601
|
-
uri = URI.parse(configuration.endpoint)
|
602
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
603
|
-
http.read_timeout = configuration.request_timeout
|
604
|
-
|
605
|
-
if uri.scheme == 'https'
|
606
|
-
http.use_ssl = true
|
607
|
-
# This is needed to have 1.8.7 passing tests
|
608
|
-
http.ca_file = ENV['ROLLBAR_SSL_CERT_FILE'] if ENV.has_key?('ROLLBAR_SSL_CERT_FILE')
|
609
|
-
http.verify_mode = ssl_verify_mode
|
610
|
-
end
|
611
|
-
|
612
|
-
request = Net::HTTP::Post.new(uri.request_uri)
|
613
|
-
request.body = body
|
614
|
-
request.add_field('X-Rollbar-Access-Token', payload['access_token'])
|
615
|
-
response = http.request(request)
|
616
|
-
|
617
|
-
if response.code == '200'
|
618
|
-
log_info '[Rollbar] Success'
|
619
|
-
else
|
620
|
-
log_warning "[Rollbar] Got unexpected status code from Rollbar api: #{response.code}"
|
621
|
-
log_info "[Rollbar] Response: #{response.body}"
|
622
|
-
end
|
623
|
-
end
|
624
|
-
|
625
|
-
def ssl_verify_mode
|
626
|
-
if configuration.verify_ssl_peer
|
627
|
-
OpenSSL::SSL::VERIFY_PEER
|
628
|
-
else
|
629
|
-
OpenSSL::SSL::VERIFY_NONE
|
630
|
-
end
|
631
|
-
end
|
632
|
-
|
633
|
-
def write_payload(payload)
|
634
|
-
if configuration.use_async
|
635
|
-
@file_semaphore.synchronize {
|
636
|
-
do_write_payload(payload)
|
637
|
-
}
|
638
|
-
else
|
639
|
-
do_write_payload(payload)
|
640
|
-
end
|
641
|
-
end
|
642
|
-
|
643
|
-
def do_write_payload(payload)
|
644
|
-
log_info '[Rollbar] Writing payload to file'
|
645
|
-
|
646
|
-
body = dump_payload(payload)
|
647
|
-
|
648
|
-
begin
|
649
|
-
unless @file
|
650
|
-
@file = File.open(configuration.filepath, "a")
|
651
|
-
end
|
652
|
-
|
653
|
-
@file.puts(body)
|
654
|
-
@file.flush
|
655
|
-
log_info "[Rollbar] Success"
|
656
|
-
rescue IOError => e
|
657
|
-
log_error "[Rollbar] Error opening/writing to file: #{e}"
|
658
|
-
end
|
659
|
-
end
|
660
|
-
|
661
|
-
def send_failsafe(message, exception)
|
662
|
-
exception_reason = failsafe_reason(message, exception)
|
663
|
-
|
664
|
-
log_error "[Rollbar] Sending failsafe response due to #{exception_reason}"
|
665
|
-
|
666
|
-
body = failsafe_body(exception_reason)
|
667
|
-
|
668
|
-
failsafe_data = {
|
669
|
-
:level => 'error',
|
670
|
-
:environment => configuration.environment.to_s,
|
671
|
-
:body => {
|
672
|
-
:message => {
|
673
|
-
:body => body
|
674
|
-
}
|
675
|
-
},
|
676
|
-
:notifier => {
|
677
|
-
:name => 'rollbar-gem',
|
678
|
-
:version => VERSION
|
679
|
-
},
|
680
|
-
:internal => true,
|
681
|
-
:failsafe => true
|
682
|
-
}
|
683
|
-
|
684
|
-
failsafe_payload = {
|
685
|
-
'access_token' => configuration.access_token,
|
686
|
-
'data' => failsafe_data
|
687
|
-
}
|
688
|
-
|
689
|
-
begin
|
690
|
-
schedule_payload(failsafe_payload)
|
691
|
-
rescue => e
|
692
|
-
log_error "[Rollbar] Error sending failsafe : #{e}"
|
693
|
-
end
|
694
|
-
|
695
|
-
failsafe_payload
|
696
|
-
end
|
697
|
-
|
698
|
-
def failsafe_reason(message, exception)
|
699
|
-
body = ''
|
700
|
-
|
701
|
-
if exception
|
702
|
-
begin
|
703
|
-
backtrace = exception.backtrace || []
|
704
|
-
nearest_frame = backtrace[0]
|
705
|
-
|
706
|
-
exception_info = exception.class.name
|
707
|
-
# #to_s and #message defaults to class.to_s. Add message only if add valuable info.
|
708
|
-
exception_info += %Q{: "#{exception.message}"} if exception.message != exception.class.to_s
|
709
|
-
exception_info += " in #{nearest_frame}" if nearest_frame
|
710
|
-
|
711
|
-
body += "#{exception_info}: #{message}"
|
712
|
-
rescue
|
713
|
-
end
|
714
|
-
else
|
715
|
-
begin
|
716
|
-
body += message.to_s
|
717
|
-
rescue
|
718
|
-
end
|
719
|
-
end
|
720
|
-
|
721
|
-
body
|
722
|
-
end
|
723
|
-
|
724
|
-
def failsafe_body(reason)
|
725
|
-
"Failsafe from rollbar-gem. #{reason}"
|
726
|
-
end
|
727
|
-
|
728
|
-
def schedule_payload(payload)
|
729
|
-
return if payload.nil?
|
730
|
-
|
731
|
-
log_info '[Rollbar] Scheduling payload'
|
732
|
-
|
733
|
-
if configuration.use_async
|
734
|
-
process_async_payload(payload)
|
735
|
-
else
|
736
|
-
process_payload(payload)
|
737
|
-
end
|
738
|
-
end
|
739
|
-
|
740
|
-
def default_async_handler
|
741
|
-
return Rollbar::Delay::GirlFriday if defined?(GirlFriday)
|
742
|
-
|
743
|
-
Rollbar::Delay::Thread
|
744
|
-
end
|
745
|
-
|
746
|
-
def process_async_payload(payload)
|
747
|
-
configuration.async_handler ||= default_async_handler
|
748
|
-
configuration.async_handler.call(payload)
|
749
|
-
rescue => e
|
750
|
-
if configuration.failover_handlers.empty?
|
751
|
-
log_error '[Rollbar] Async handler failed, and there are no failover handlers configured. See the docs for "failover_handlers"'
|
752
|
-
return
|
753
|
-
end
|
754
|
-
|
755
|
-
async_failover(payload)
|
756
|
-
end
|
757
|
-
|
758
|
-
def async_failover(payload)
|
759
|
-
log_warning '[Rollbar] Primary async handler failed. Trying failovers...'
|
760
|
-
|
761
|
-
failover_handlers = configuration.failover_handlers
|
762
|
-
|
763
|
-
failover_handlers.each do |handler|
|
764
|
-
begin
|
765
|
-
handler.call(payload)
|
766
|
-
rescue
|
767
|
-
next unless handler == failover_handlers.last
|
768
|
-
|
769
|
-
log_error "[Rollbar] All failover handlers failed while processing payload: #{Rollbar::JSON.dump(payload)}"
|
770
|
-
end
|
771
|
-
end
|
772
|
-
end
|
773
|
-
|
774
|
-
def dump_payload(payload)
|
775
|
-
# Ensure all keys are strings since we can receive the payload inline or
|
776
|
-
# from an async handler job, which can be serialized.
|
777
|
-
stringified_payload = Rollbar::Util::Hash.deep_stringify_keys(payload)
|
778
|
-
result = Truncation.truncate(stringified_payload)
|
779
|
-
return result unless Truncation.truncate?(result)
|
780
|
-
|
781
|
-
original_size = Rollbar::JSON.dump(payload).bytesize
|
782
|
-
final_size = result.bytesize
|
783
|
-
send_failsafe("Could not send payload due to it being too large after truncating attempts. Original size: #{original_size} Final size: #{final_size}", nil)
|
784
|
-
log_error "[Rollbar] Payload too large to be sent: #{Rollbar::JSON.dump(payload)}"
|
785
|
-
|
786
|
-
nil
|
787
|
-
end
|
30
|
+
class << self
|
31
|
+
extend Forwardable
|
788
32
|
|
789
|
-
|
790
|
-
%w(debug info warn error).each do |level|
|
791
|
-
define_method(:"log_#{level}") do |message|
|
792
|
-
logger.send(level, message)
|
793
|
-
end
|
794
|
-
end
|
33
|
+
def_delegators :notifier, *PUBLIC_NOTIFIER_METHODS
|
795
34
|
|
796
|
-
|
35
|
+
attr_writer :plugins, :root_notifier
|
797
36
|
|
798
|
-
def
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
end
|
37
|
+
def notifier
|
38
|
+
# Use the global instance @root_notifier so we don't fall
|
39
|
+
# in a infinite loop
|
40
|
+
Thread.current[:_rollbar_notifier] ||= Notifier.new(@root_notifier)
|
803
41
|
end
|
804
42
|
|
805
|
-
def
|
806
|
-
|
43
|
+
def notifier=(notifier)
|
44
|
+
Thread.current[:_rollbar_notifier] = notifier
|
807
45
|
end
|
808
46
|
|
809
|
-
|
810
|
-
|
47
|
+
# It's the first notifier instantiated in the
|
48
|
+
# process. We store it so all the next per-thread
|
49
|
+
# notifiers can inherit its configuration
|
50
|
+
# The methods Rollbar.configure, Rollbar.reconfigure,
|
51
|
+
# Rollbar.preconfigure and Rollbar.unconfigure work
|
52
|
+
# on this notifier.
|
53
|
+
# Before v2.13.0 these methods worked on the global
|
54
|
+
# configuration, so in the practice the behavior is the same,
|
55
|
+
# since they work on the root notifier's configuration
|
56
|
+
def root_notifier
|
57
|
+
@root_notifier ||= notifier
|
811
58
|
end
|
812
|
-
end
|
813
|
-
|
814
|
-
class << self
|
815
|
-
extend Forwardable
|
816
|
-
|
817
|
-
def_delegators :notifier, *PUBLIC_NOTIFIER_METHODS
|
818
59
|
|
819
|
-
|
820
|
-
|
821
|
-
def preconfigure
|
822
|
-
yield(configuration)
|
823
|
-
|
824
|
-
reset_notifier!
|
60
|
+
def preconfigure(&block)
|
61
|
+
root_notifier.preconfigure(&block)
|
825
62
|
end
|
826
63
|
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
yield(configuration)
|
64
|
+
# Configures the root notifier and loads the plugins
|
65
|
+
def configure(&block)
|
66
|
+
root_notifier.configure(&block)
|
832
67
|
|
833
|
-
|
834
|
-
reset_notifier!
|
68
|
+
plugins.load!
|
835
69
|
end
|
836
70
|
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
yield(configuration)
|
841
|
-
|
842
|
-
reset_notifier!
|
71
|
+
# Reconfigures the root notifier
|
72
|
+
def reconfigure(&block)
|
73
|
+
root_notifier.reconfigure(&block)
|
843
74
|
end
|
844
75
|
|
76
|
+
# Unconfigures the root notifier
|
845
77
|
def unconfigure
|
846
|
-
|
78
|
+
root_notifier.unconfigure
|
847
79
|
end
|
848
80
|
|
81
|
+
# Returns the configuration for the current notifier.
|
82
|
+
# The current notifier is Rollbar.notifier and exists
|
83
|
+
# one per thread.
|
849
84
|
def configuration
|
850
|
-
|
851
|
-
end
|
852
|
-
|
853
|
-
def scope_object
|
854
|
-
@scope_obejct ||= ::Rollbar::LazyStore.new({})
|
85
|
+
notifier.configuration
|
855
86
|
end
|
856
87
|
|
857
88
|
def safely?
|
858
89
|
configuration.safely?
|
859
90
|
end
|
860
91
|
|
861
|
-
def
|
862
|
-
|
863
|
-
require_hooks
|
864
|
-
require_core_extensions
|
865
|
-
end
|
866
|
-
|
867
|
-
def prepare_js
|
868
|
-
::Rollbar::Js.prepare if configuration.js_enabled
|
869
|
-
end
|
870
|
-
|
871
|
-
def require_hooks
|
872
|
-
return if configuration.disable_monkey_patch
|
873
|
-
wrap_delayed_worker
|
874
|
-
|
875
|
-
if defined?(ActiveRecord)
|
876
|
-
require 'active_record/version'
|
877
|
-
require 'rollbar/active_record_extension' if ActiveRecord::VERSION::MAJOR >= 3
|
878
|
-
end
|
879
|
-
|
880
|
-
require 'rollbar/sidekiq' if defined?(Sidekiq)
|
881
|
-
require 'rollbar/active_job' if defined?(ActiveJob)
|
882
|
-
require 'rollbar/goalie' if defined?(Goalie)
|
883
|
-
require 'rollbar/rack' if defined?(Rack) unless configuration.disable_rack_monkey_patch
|
884
|
-
require 'rollbar/rake' if defined?(Rake)
|
885
|
-
end
|
886
|
-
|
887
|
-
def require_core_extensions
|
888
|
-
# This monkey patch is always needed in order
|
889
|
-
# to use Rollbar.scoped
|
890
|
-
require 'rollbar/core_ext/thread'
|
891
|
-
|
892
|
-
return if configuration.disable_core_monkey_patch
|
893
|
-
|
894
|
-
# Needed to avoid active_support (< 4.1.0) bug serializing JSONs
|
895
|
-
require 'rollbar/core_ext/basic_socket' if monkey_patch_socket?
|
896
|
-
end
|
897
|
-
|
898
|
-
def monkey_patch_socket?
|
899
|
-
defined?(ActiveSupport::VERSION::STRING)
|
900
|
-
end
|
901
|
-
|
902
|
-
def wrap_delayed_worker
|
903
|
-
return unless defined?(Delayed) && defined?(Delayed::Worker) && configuration.delayed_job_enabled
|
904
|
-
|
905
|
-
require 'rollbar/delayed_job'
|
906
|
-
Rollbar::Delayed.wrap_worker
|
907
|
-
end
|
908
|
-
|
909
|
-
def notifier
|
910
|
-
Thread.current[:_rollbar_notifier] ||= Notifier.new(self)
|
911
|
-
end
|
912
|
-
|
913
|
-
def notifier=(notifier)
|
914
|
-
Thread.current[:_rollbar_notifier] = notifier
|
92
|
+
def plugins
|
93
|
+
@plugins ||= Rollbar::Plugins.new
|
915
94
|
end
|
916
95
|
|
917
96
|
def last_report
|
@@ -922,8 +101,24 @@ module Rollbar
|
|
922
101
|
Thread.current[:_rollbar_last_report] = report
|
923
102
|
end
|
924
103
|
|
104
|
+
# Resets the scope for the current thread notifier. The notifier
|
105
|
+
# reference is kept so we reuse the notifier.
|
106
|
+
# This is a change from version 2.13.0. Before this version
|
107
|
+
# this method clears the notifier.
|
108
|
+
#
|
109
|
+
# It was used in order to reset the scope and reusing the global
|
110
|
+
# configuration Rollbar.configuration. Since now Rollbar.configuration
|
111
|
+
# points to the current notifier configuration, we can resue the
|
112
|
+
# notifier instance and just reset the scope.
|
925
113
|
def reset_notifier!
|
114
|
+
notifier.reset!
|
115
|
+
end
|
116
|
+
|
117
|
+
# Clears the current thread notifier and the root notifier.
|
118
|
+
# In the practice this should be used only on the specs
|
119
|
+
def clear_notifier!
|
926
120
|
self.notifier = nil
|
121
|
+
self.root_notifier = nil
|
927
122
|
end
|
928
123
|
|
929
124
|
# Create a new Notifier instance using the received options and
|
@@ -934,16 +129,18 @@ module Rollbar
|
|
934
129
|
# @example
|
935
130
|
#
|
936
131
|
# new_scope = { job_type: 'scheduled' }
|
937
|
-
#
|
132
|
+
# new_config = { use_async: false }
|
133
|
+
#
|
134
|
+
# Rollbar.scoped(new_scope, new_config) do
|
938
135
|
# begin
|
939
136
|
# # do stuff
|
940
137
|
# rescue => e
|
941
|
-
# Rollbar.
|
138
|
+
# Rollbar.error(e)
|
942
139
|
# end
|
943
140
|
# end
|
944
|
-
def scoped(options = {})
|
141
|
+
def scoped(options = {}, config_overrides = {})
|
945
142
|
old_notifier = notifier
|
946
|
-
self.notifier = old_notifier.scope(options)
|
143
|
+
self.notifier = old_notifier.scope(options, config_overrides)
|
947
144
|
|
948
145
|
result = yield
|
949
146
|
result
|
@@ -951,14 +148,22 @@ module Rollbar
|
|
951
148
|
self.notifier = old_notifier
|
952
149
|
end
|
953
150
|
|
151
|
+
# Create a new Notifier instance with a new configuration
|
152
|
+
# using the current one but merging the passed options.
|
153
|
+
def with_config(overrides, &block)
|
154
|
+
scoped(nil, overrides, &block)
|
155
|
+
end
|
156
|
+
|
954
157
|
def scope!(options = {})
|
955
158
|
notifier.scope!(options)
|
956
159
|
end
|
957
160
|
|
958
161
|
# Backwards compatibility methods
|
959
162
|
|
960
|
-
def report_exception(exception, request_data = nil, person_data = nil,
|
961
|
-
|
163
|
+
def report_exception(exception, request_data = nil, person_data = nil,
|
164
|
+
level = 'error')
|
165
|
+
Kernel.warn('[DEPRECATION] Rollbar.report_exception has been deprecated, ' \
|
166
|
+
'please use log() or one of the level functions')
|
962
167
|
|
963
168
|
scope = {}
|
964
169
|
scope[:request] = request_data if request_data
|
@@ -970,13 +175,16 @@ module Rollbar
|
|
970
175
|
end
|
971
176
|
|
972
177
|
def report_message(message, level = 'info', extra_data = nil)
|
973
|
-
Kernel.warn('[DEPRECATION] Rollbar.report_message has been deprecated,
|
178
|
+
Kernel.warn('[DEPRECATION] Rollbar.report_message has been deprecated, ' \
|
179
|
+
'please use log() or one of the level functions')
|
974
180
|
|
975
181
|
Rollbar.notifier.log(level, message, extra_data)
|
976
182
|
end
|
977
183
|
|
978
|
-
def report_message_with_request(message, level = 'info', request_data = nil,
|
979
|
-
|
184
|
+
def report_message_with_request(message, level = 'info', request_data = nil,
|
185
|
+
person_data = nil, extra_data = nil)
|
186
|
+
Kernel.warn('[DEPRECATION] Rollbar.report_message_with_request has been ' \
|
187
|
+
'deprecated, please use log() or one of the level functions')
|
980
188
|
|
981
189
|
scope = {}
|
982
190
|
scope[:request] = request_data if request_data
|
@@ -987,4 +195,8 @@ module Rollbar
|
|
987
195
|
end
|
988
196
|
end
|
989
197
|
end
|
198
|
+
|
199
|
+
self.root_notifier = nil
|
990
200
|
end
|
201
|
+
|
202
|
+
Rollbar.plugins.require_all
|