Class: Rollbar::Notifier
- Inherits:
-
Object
- Object
- Rollbar::Notifier
- Defined in:
- lib/rollbar/notifier.rb,
lib/rollbar/notifier/trace_with_bindings.rb
Overview
The notifier class. It has the core functionality for sending reports to the API.
Defined Under Namespace
Classes: TraceWithBindings
Constant Summary collapse
- MUTEX =
Mutex.new
- EXTENSION_REGEXP =
/.rollbar\z/.freeze
- FAILSAFE_STRING_LENGTH =
10_000
Instance Attribute Summary collapse
-
#configuration ⇒ Object
Returns the value of attribute configuration.
-
#last_report ⇒ Object
Returns the value of attribute last_report.
-
#scope_object ⇒ Object
Returns the value of attribute scope_object.
Instance Method Summary collapse
- #add_configured_options(payload_notifier, original_error) ⇒ Object
- #add_original_error(diagnostic, original_error) ⇒ Object
- #add_original_host(diagnostic, original_error) ⇒ Object
- #add_original_message(diagnostic, original_error) ⇒ Object
- #add_original_uuid(diagnostic, original_error) ⇒ Object
- #build_item_with_payload(payload) ⇒ Object
-
#configure {|configuration.configured_options| ... } ⇒ Object
Configures the notifier instance.
-
#critical(*args) ⇒ Object
See log() above.
- #current_bindings ⇒ Object
-
#debug(*args) ⇒ Object
See log() above.
- #disable_locals ⇒ Object
- #enable_locals ⇒ Object
- #enable_locals? ⇒ Boolean
- #enabled? ⇒ Boolean
-
#error(*args) ⇒ Object
See log() above.
- #exception_bindings ⇒ Object
- #failsafe_add_original_error_data(payload_notifier, original_error) ⇒ Object
- #failsafe_initial_data(exception_reason) ⇒ Object
- #ignore_before_process?(level, exception, message, extra) ⇒ Boolean
-
#info(*args) ⇒ Object
See log() above.
-
#initialize(parent_notifier = nil, payload_options = nil, scope = nil) ⇒ Notifier
constructor
A new instance of Notifier.
-
#level ⇒ Object
Logging.
-
#log(level, *args) ⇒ Object
Sends a report to Rollbar.
- #logger ⇒ Object
-
#preconfigure {|configuration.configured_options| ... } ⇒ Object
Similar to configure below, but used only internally within the gem to configure it without initializing any of the third party hooks.
- #process_failsafe_item(failsafe_payload) ⇒ Object
-
#process_from_async_handler(payload) ⇒ Object
We will reraise exceptions in this method so async queues can retry the job or, in general, handle an error report some way.
- #process_item(item) ⇒ Object
- #reconfigure {|configuration.configured_options| ... } ⇒ Object
- #report_with_rescue(level, message, exception, extra, context) ⇒ Object
- #reset! ⇒ Object
-
#safely ⇒ Object
Returns a new notifier with same configuration options but it sets Configuration#safely to true.
- #scope(scope_overrides = {}, config_overrides = {}) ⇒ Object
- #scope!(options = {}, config_overrides = {}) ⇒ Object
- #send_failsafe(message, exception, original_error = nil) ⇒ Object
-
#silenced { ... } ⇒ Object
Turns off reporting for the given block.
- #trace_with_bindings ⇒ Object
- #unconfigure ⇒ Object
-
#warn(*args) ⇒ Object
See log() above.
-
#warning(*args) ⇒ Object
See log() above.
Constructor Details
#initialize(parent_notifier = nil, payload_options = nil, scope = nil) ⇒ Notifier
Returns a new instance of Notifier.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/rollbar/notifier.rb', line 24 def initialize(parent_notifier = nil, = nil, scope = nil) if parent_notifier self.configuration = parent_notifier.configuration.clone self.scope_object = parent_notifier.scope_object.clone Rollbar::Util.deep_merge(scope_object, scope) if scope else self.configuration = ::Rollbar::Configuration.new self.scope_object = ::Rollbar::LazyStore.new(scope) end return unless Rollbar::Util.deep_merge(configuration., ) end |
Instance Attribute Details
#configuration ⇒ Object
Returns the value of attribute configuration.
18 19 20 |
# File 'lib/rollbar/notifier.rb', line 18 def configuration @configuration end |
#last_report ⇒ Object
Returns the value of attribute last_report.
18 19 20 |
# File 'lib/rollbar/notifier.rb', line 18 def last_report @last_report end |
#scope_object ⇒ Object
Returns the value of attribute scope_object.
18 19 20 |
# File 'lib/rollbar/notifier.rb', line 18 def scope_object @scope_object end |
Instance Method Details
#add_configured_options(payload_notifier, original_error) ⇒ Object
352 353 354 355 356 357 358 359 360 |
# File 'lib/rollbar/notifier.rb', line 352 def (payload_notifier, original_error) if original_error[:configuration] configured = original_error[:configuration]..configured payload_notifier[:configured_options] = ::JSON.generate(configured).truncate(FAILSAFE_STRING_LENGTH) end rescue StandardError => e payload_notifier[:configured_options] = "Failed: #{e.}" end |
#add_original_error(diagnostic, original_error) ⇒ Object
339 340 341 342 343 344 345 346 347 348 349 350 |
# File 'lib/rollbar/notifier.rb', line 339 def add_original_error(diagnostic, original_error) if original_error[:exception] backtrace = original_error[:exception].backtrace = original_error[:exception]. diagnostic[:original_error] = { :message => && .truncate(FAILSAFE_STRING_LENGTH), :stack => backtrace && backtrace.join(', ').truncate(FAILSAFE_STRING_LENGTH) } end rescue StandardError => e diagnostic[:original_error] = "Failed: #{e.}" end |
#add_original_host(diagnostic, original_error) ⇒ Object
362 363 364 |
# File 'lib/rollbar/notifier.rb', line 362 def add_original_host(diagnostic, original_error) diagnostic[:original_host] = original_error[:host] if original_error[:host] end |
#add_original_message(diagnostic, original_error) ⇒ Object
330 331 332 333 334 335 336 337 |
# File 'lib/rollbar/notifier.rb', line 330 def (diagnostic, original_error) if original_error[:message] diagnostic[:original_message] = original_error[:message].truncate(FAILSAFE_STRING_LENGTH) end rescue StandardError => e diagnostic[:original_message] = "Failed: #{e.}" end |
#add_original_uuid(diagnostic, original_error) ⇒ Object
366 367 368 |
# File 'lib/rollbar/notifier.rb', line 366 def add_original_uuid(diagnostic, original_error) diagnostic[:original_uuid] = original_error[:uuid] if original_error[:uuid] end |
#build_item_with_payload(payload) ⇒ Object
268 269 270 271 272 |
# File 'lib/rollbar/notifier.rb', line 268 def build_item_with_payload(payload) Item.build_with(payload, :notifier => self, :configuration => configuration, :logger => logger) end |
#configure {|configuration.configured_options| ... } ⇒ Object
Configures the notifier instance
51 52 53 54 55 |
# File 'lib/rollbar/notifier.rb', line 51 def configure configuration.enabled = true if configuration.enabled.nil? yield(configuration.) end |
#critical(*args) ⇒ Object
See log() above
201 202 203 |
# File 'lib/rollbar/notifier.rb', line 201 def critical(*args) log('critical', *args) end |
#current_bindings ⇒ Object
389 390 391 |
# File 'lib/rollbar/notifier.rb', line 389 def current_bindings trace_with_bindings.frames end |
#debug(*args) ⇒ Object
See log() above
176 177 178 |
# File 'lib/rollbar/notifier.rb', line 176 def debug(*args) log('debug', *args) end |
#disable_locals ⇒ Object
402 403 404 |
# File 'lib/rollbar/notifier.rb', line 402 def disable_locals trace_with_bindings.disable if enable_locals? end |
#enable_locals ⇒ Object
398 399 400 |
# File 'lib/rollbar/notifier.rb', line 398 def enable_locals trace_with_bindings.enable if enable_locals? end |
#enable_locals? ⇒ Boolean
393 394 395 396 |
# File 'lib/rollbar/notifier.rb', line 393 def enable_locals? configuration.locals[:enabled] && [:app, :all].include?(configuration.send_extra_frame_data) end |
#enabled? ⇒ Boolean
205 206 207 208 209 210 |
# File 'lib/rollbar/notifier.rb', line 205 def enabled? # Require access_token so we don't try to send events when unconfigured. configuration.enabled && configuration.access_token && !configuration.access_token.empty? end |
#error(*args) ⇒ Object
See log() above
196 197 198 |
# File 'lib/rollbar/notifier.rb', line 196 def error(*args) log('error', *args) end |
#exception_bindings ⇒ Object
385 386 387 |
# File 'lib/rollbar/notifier.rb', line 385 def exception_bindings trace_with_bindings.exception_frames end |
#failsafe_add_original_error_data(payload_notifier, original_error) ⇒ Object
318 319 320 321 322 323 324 325 326 327 328 |
# File 'lib/rollbar/notifier.rb', line 318 def failsafe_add_original_error_data(payload_notifier, original_error) return unless original_error payload_notifier[:diagnostic] ||= {} add_original_host(payload_notifier[:diagnostic], original_error) add_original_uuid(payload_notifier[:diagnostic], original_error) (payload_notifier[:diagnostic], original_error) add_original_error(payload_notifier[:diagnostic], original_error) (payload_notifier, original_error) end |
#failsafe_initial_data(exception_reason) ⇒ Object
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
# File 'lib/rollbar/notifier.rb', line 274 def failsafe_initial_data(exception_reason) { :level => 'error', :environment => configuration.environment.to_s, :body => { :message => { :body => failsafe_body(exception_reason) } }, :notifier => { :name => 'rollbar-gem', :version => VERSION }, :internal => true, 'failsafe' => true } end |
#ignore_before_process?(level, exception, message, extra) ⇒ Boolean
150 151 152 153 154 155 156 157 158 159 |
# File 'lib/rollbar/notifier.rb', line 150 def ignore_before_process?(level, exception, , extra) status = call_before_process(:level => level, :exception => exception, :message => , :extra => extra) status == 'ignored' rescue Rollbar::Ignore true end |
#info(*args) ⇒ Object
See log() above
181 182 183 |
# File 'lib/rollbar/notifier.rb', line 181 def info(*args) log('info', *args) end |
#level ⇒ Object
Logging
371 372 373 374 375 |
# File 'lib/rollbar/notifier.rb', line 371 %w[debug info warn error].each do |level| define_method(:"log_#{level}") do || logger.send(level, ) end end |
#log(level, *args) ⇒ Object
Sends a report to Rollbar.
Accepts a level string plus any number of arguments. The last String argument will become the message or description of the report. The last Exception argument will become the associated exception for the report. The last hash argument will be used as the extra data for the report.
If the extra hash contains a symbol key :custom_data_method_context the value of the key will be used as the context for configuration.custom_data_method and will be removed from the extra hash.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/rollbar/notifier.rb', line 131 def log(level, *args) return 'disabled' unless enabled? , exception, extra, context = extract_arguments(args) use_exception_level_filters = use_exception_level_filters?(extra) return 'ignored' if ignored?(exception, use_exception_level_filters) || ignore_before_process?(level, exception, , extra) level = lookup_exception_level(level, exception, use_exception_level_filters) ret = report_with_rescue(level, , exception, extra, context) raise(exception) if configuration.raise_on_error && exception ret end |
#logger ⇒ Object
377 378 379 |
# File 'lib/rollbar/notifier.rb', line 377 def logger @logger ||= LoggerProxy.new(configuration.logger) end |
#preconfigure {|configuration.configured_options| ... } ⇒ Object
Similar to configure below, but used only internally within the gem to configure it without initializing any of the third party hooks
46 47 48 |
# File 'lib/rollbar/notifier.rb', line 46 def preconfigure yield(configuration.) end |
#process_failsafe_item(failsafe_payload) ⇒ Object
310 311 312 313 314 315 316 |
# File 'lib/rollbar/notifier.rb', line 310 def process_failsafe_item(failsafe_payload) item = build_item_with_payload(failsafe_payload) process_item(item) log_and_return_item_data(item) rescue StandardError => e log_error "[Rollbar] Error sending failsafe : #{e}" end |
#process_from_async_handler(payload) ⇒ Object
We will reraise exceptions in this method so async queues can retry the job or, in general, handle an error report some way.
At same time that exception is silenced so we don’t generate infinite reports. This example is what we want to avoid:
-
New exception in a the project is raised
-
That report enqueued to Sidekiq queue.
-
The Sidekiq job tries to send the report to our API
-
The report fails, for example cause a network failure, and a exception is raised
-
We report an internal error for that exception
-
We reraise the exception so Sidekiq job fails and Sidekiq can retry the job reporting the original exception
-
Because the job failed and Sidekiq can be managed by rollbar we’ll report a new exception.
-
Go to point 2.
We’ll then push to Sidekiq queue indefinitely until the network failure is fixed.
Using Rollbar.silenced we avoid the above behavior but Sidekiq will have a chance to retry the original job.
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/rollbar/notifier.rb', line 249 def process_from_async_handler(payload) Rollbar.silenced do begin if payload.is_a?(String) # The final payload has already been built. send_body(payload) else item = build_item_with_payload(payload) process_item(item) end rescue StandardError => e report_internal_error(e) raise end end end |
#process_item(item) ⇒ Object
212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/rollbar/notifier.rb', line 212 def process_item(item) return send_item(item) unless configuration.write_to_file return do_write_item(item) unless configuration.use_async MUTEX.synchronize { do_write_item(item) } rescue StandardError => e log_error '[Rollbar] Error processing the item: ' \ "#{e.class}, #{e.}. Item: #{item.payload.inspect}" raise e unless via_failsafe?(item) log_error('[Rollbar] Item has already failed. Not re-raising') end |
#reconfigure {|configuration.configured_options| ... } ⇒ Object
57 58 59 60 61 62 |
# File 'lib/rollbar/notifier.rb', line 57 def reconfigure self.configuration = Configuration.new configuration.enabled = true yield(configuration.) end |
#report_with_rescue(level, message, exception, extra, context) ⇒ Object
161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/rollbar/notifier.rb', line 161 def report_with_rescue(level, , exception, extra, context) report(level, , exception, extra, context) rescue StandardError, SystemStackError => e original_error = { :message => , :exception => exception, :configuration => configuration } report_internal_error(e, original_error) 'error' end |
#reset! ⇒ Object
40 41 42 |
# File 'lib/rollbar/notifier.rb', line 40 def reset! self.scope_object = ::Rollbar::LazyStore.new({}) end |
#safely ⇒ Object
Returns a new notifier with same configuration options but it sets Configuration#safely to true. We are using this flag to avoid having inifite loops when evaluating some custom user methods.
86 87 88 89 90 91 |
# File 'lib/rollbar/notifier.rb', line 86 def safely new_notifier = scope new_notifier.configuration.safely = true new_notifier end |
#scope(scope_overrides = {}, config_overrides = {}) ⇒ Object
68 69 70 71 72 73 |
# File 'lib/rollbar/notifier.rb', line 68 def scope(scope_overrides = {}, config_overrides = {}) new_notifier = self.class.new(self, nil, scope_overrides) new_notifier.configuration = configuration.merge(config_overrides) new_notifier end |
#scope!(options = {}, config_overrides = {}) ⇒ Object
75 76 77 78 79 80 |
# File 'lib/rollbar/notifier.rb', line 75 def scope!( = {}, config_overrides = {}) Rollbar::Util.deep_merge(scope_object, ) configuration.merge!(config_overrides) self end |
#send_failsafe(message, exception, original_error = nil) ⇒ Object
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
# File 'lib/rollbar/notifier.rb', line 292 def send_failsafe(, exception, original_error = nil) exception_reason = failsafe_reason(, exception) log_error "[Rollbar] Sending failsafe response due to #{exception_reason}" failsafe_data = failsafe_initial_data(exception_reason) failsafe_add_original_error_data(failsafe_data[:notifier], original_error) failsafe_payload = { 'data' => failsafe_data } process_failsafe_item(failsafe_payload) failsafe_payload end |
#silenced { ... } ⇒ Object
Turns off reporting for the given block.
99 100 101 102 103 104 |
# File 'lib/rollbar/notifier.rb', line 99 def silenced yield rescue StandardError => e e.instance_variable_set(:@_rollbar_do_not_report, true) raise end |
#trace_with_bindings ⇒ Object
381 382 383 |
# File 'lib/rollbar/notifier.rb', line 381 def trace_with_bindings @trace_with_bindings ||= TraceWithBindings.new end |
#unconfigure ⇒ Object
64 65 66 |
# File 'lib/rollbar/notifier.rb', line 64 def unconfigure self.configuration = nil end |
#warn(*args) ⇒ Object
See log() above
186 187 188 |
# File 'lib/rollbar/notifier.rb', line 186 def warn(*args) log('warning', *args) end |
#warning(*args) ⇒ Object
See log() above
191 192 193 |
# File 'lib/rollbar/notifier.rb', line 191 def warning(*args) log('warning', *args) end |