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.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/rollbar/notifier.rb', line 23 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.
17 18 19 |
# File 'lib/rollbar/notifier.rb', line 17 def configuration @configuration end |
#last_report ⇒ Object
Returns the value of attribute last_report.
17 18 19 |
# File 'lib/rollbar/notifier.rb', line 17 def last_report @last_report end |
#scope_object ⇒ Object
Returns the value of attribute scope_object.
17 18 19 |
# File 'lib/rollbar/notifier.rb', line 17 def scope_object @scope_object end |
Instance Method Details
#add_configured_options(payload_notifier, original_error) ⇒ Object
351 352 353 354 355 356 357 358 359 |
# File 'lib/rollbar/notifier.rb', line 351 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
338 339 340 341 342 343 344 345 346 347 348 349 |
# File 'lib/rollbar/notifier.rb', line 338 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
361 362 363 |
# File 'lib/rollbar/notifier.rb', line 361 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
329 330 331 332 333 334 335 336 |
# File 'lib/rollbar/notifier.rb', line 329 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
365 366 367 |
# File 'lib/rollbar/notifier.rb', line 365 def add_original_uuid(diagnostic, original_error) diagnostic[:original_uuid] = original_error[:uuid] if original_error[:uuid] end |
#build_item_with_payload(payload) ⇒ Object
267 268 269 270 271 |
# File 'lib/rollbar/notifier.rb', line 267 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
50 51 52 53 54 |
# File 'lib/rollbar/notifier.rb', line 50 def configure configuration.enabled = true if configuration.enabled.nil? yield(configuration.) end |
#critical(*args) ⇒ Object
See log() above
200 201 202 |
# File 'lib/rollbar/notifier.rb', line 200 def critical(*args) log('critical', *args) end |
#current_bindings ⇒ Object
388 389 390 |
# File 'lib/rollbar/notifier.rb', line 388 def current_bindings trace_with_bindings.frames end |
#debug(*args) ⇒ Object
See log() above
175 176 177 |
# File 'lib/rollbar/notifier.rb', line 175 def debug(*args) log('debug', *args) end |
#disable_locals ⇒ Object
401 402 403 |
# File 'lib/rollbar/notifier.rb', line 401 def disable_locals trace_with_bindings.disable if enable_locals? end |
#enable_locals ⇒ Object
397 398 399 |
# File 'lib/rollbar/notifier.rb', line 397 def enable_locals trace_with_bindings.enable if enable_locals? end |
#enable_locals? ⇒ Boolean
392 393 394 395 |
# File 'lib/rollbar/notifier.rb', line 392 def enable_locals? configuration.locals[:enabled] && [:app, :all].include?(configuration.send_extra_frame_data) end |
#enabled? ⇒ Boolean
204 205 206 207 208 209 |
# File 'lib/rollbar/notifier.rb', line 204 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
195 196 197 |
# File 'lib/rollbar/notifier.rb', line 195 def error(*args) log('error', *args) end |
#exception_bindings ⇒ Object
384 385 386 |
# File 'lib/rollbar/notifier.rb', line 384 def exception_bindings trace_with_bindings.exception_frames end |
#failsafe_add_original_error_data(payload_notifier, original_error) ⇒ Object
317 318 319 320 321 322 323 324 325 326 327 |
# File 'lib/rollbar/notifier.rb', line 317 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
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
# File 'lib/rollbar/notifier.rb', line 273 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
149 150 151 152 153 154 155 156 157 158 |
# File 'lib/rollbar/notifier.rb', line 149 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
180 181 182 |
# File 'lib/rollbar/notifier.rb', line 180 def info(*args) log('info', *args) end |
#level ⇒ Object
Logging
370 371 372 373 374 |
# File 'lib/rollbar/notifier.rb', line 370 %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.
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/rollbar/notifier.rb', line 130 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
376 377 378 |
# File 'lib/rollbar/notifier.rb', line 376 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
45 46 47 |
# File 'lib/rollbar/notifier.rb', line 45 def preconfigure yield(configuration.) end |
#process_failsafe_item(failsafe_payload) ⇒ Object
309 310 311 312 313 314 315 |
# File 'lib/rollbar/notifier.rb', line 309 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.
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/rollbar/notifier.rb', line 248 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
211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/rollbar/notifier.rb', line 211 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
56 57 58 59 60 61 |
# File 'lib/rollbar/notifier.rb', line 56 def reconfigure self.configuration = Configuration.new configuration.enabled = true yield(configuration.) end |
#report_with_rescue(level, message, exception, extra, context) ⇒ Object
160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/rollbar/notifier.rb', line 160 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
39 40 41 |
# File 'lib/rollbar/notifier.rb', line 39 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.
85 86 87 88 89 90 |
# File 'lib/rollbar/notifier.rb', line 85 def safely new_notifier = scope new_notifier.configuration.safely = true new_notifier end |
#scope(scope_overrides = {}, config_overrides = {}) ⇒ Object
67 68 69 70 71 72 |
# File 'lib/rollbar/notifier.rb', line 67 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
74 75 76 77 78 79 |
# File 'lib/rollbar/notifier.rb', line 74 def scope!( = {}, config_overrides = {}) Rollbar::Util.deep_merge(scope_object, ) configuration.merge!(config_overrides) self end |
#send_failsafe(message, exception, original_error = nil) ⇒ Object
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
# File 'lib/rollbar/notifier.rb', line 291 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.
98 99 100 101 102 103 |
# File 'lib/rollbar/notifier.rb', line 98 def silenced yield rescue StandardError => e e.instance_variable_set(:@_rollbar_do_not_report, true) raise end |
#trace_with_bindings ⇒ Object
380 381 382 |
# File 'lib/rollbar/notifier.rb', line 380 def trace_with_bindings @trace_with_bindings ||= TraceWithBindings.new end |
#unconfigure ⇒ Object
63 64 65 |
# File 'lib/rollbar/notifier.rb', line 63 def unconfigure self.configuration = nil end |
#warn(*args) ⇒ Object
See log() above
185 186 187 |
# File 'lib/rollbar/notifier.rb', line 185 def warn(*args) log('warning', *args) end |
#warning(*args) ⇒ Object
See log() above
190 191 192 |
# File 'lib/rollbar/notifier.rb', line 190 def warning(*args) log('warning', *args) end |