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, is_uncaught) ⇒ 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
354 355 356 357 358 359 360 361 362 |
# File 'lib/rollbar/notifier.rb', line 354 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
341 342 343 344 345 346 347 348 349 350 351 352 |
# File 'lib/rollbar/notifier.rb', line 341 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
364 365 366 |
# File 'lib/rollbar/notifier.rb', line 364 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
332 333 334 335 336 337 338 339 |
# File 'lib/rollbar/notifier.rb', line 332 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
368 369 370 |
# File 'lib/rollbar/notifier.rb', line 368 def add_original_uuid(diagnostic, original_error) diagnostic[:original_uuid] = original_error[:uuid] if original_error[:uuid] end |
#build_item_with_payload(payload) ⇒ Object
270 271 272 273 274 |
# File 'lib/rollbar/notifier.rb', line 270 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
203 204 205 |
# File 'lib/rollbar/notifier.rb', line 203 def critical(*args) log('critical', *args) end |
#current_bindings ⇒ Object
391 392 393 |
# File 'lib/rollbar/notifier.rb', line 391 def current_bindings trace_with_bindings.frames end |
#debug(*args) ⇒ Object
See log() above
178 179 180 |
# File 'lib/rollbar/notifier.rb', line 178 def debug(*args) log('debug', *args) end |
#disable_locals ⇒ Object
404 405 406 |
# File 'lib/rollbar/notifier.rb', line 404 def disable_locals trace_with_bindings.disable if enable_locals? end |
#enable_locals ⇒ Object
400 401 402 |
# File 'lib/rollbar/notifier.rb', line 400 def enable_locals trace_with_bindings.enable if enable_locals? end |
#enable_locals? ⇒ Boolean
395 396 397 398 |
# File 'lib/rollbar/notifier.rb', line 395 def enable_locals? configuration.locals[:enabled] && [:app, :all].include?(configuration.send_extra_frame_data) end |
#enabled? ⇒ Boolean
207 208 209 210 211 212 |
# File 'lib/rollbar/notifier.rb', line 207 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
198 199 200 |
# File 'lib/rollbar/notifier.rb', line 198 def error(*args) log('error', *args) end |
#exception_bindings ⇒ Object
387 388 389 |
# File 'lib/rollbar/notifier.rb', line 387 def exception_bindings trace_with_bindings.exception_frames end |
#failsafe_add_original_error_data(payload_notifier, original_error) ⇒ Object
320 321 322 323 324 325 326 327 328 329 330 |
# File 'lib/rollbar/notifier.rb', line 320 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
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
# File 'lib/rollbar/notifier.rb', line 276 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
152 153 154 155 156 157 158 159 160 161 |
# File 'lib/rollbar/notifier.rb', line 152 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
183 184 185 |
# File 'lib/rollbar/notifier.rb', line 183 def info(*args) log('info', *args) end |
#level ⇒ Object
Logging
373 374 375 376 377 |
# File 'lib/rollbar/notifier.rb', line 373 %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 148 149 150 |
# 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) is_uncaught = uncaught?(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, is_uncaught ) raise(exception) if configuration.raise_on_error && exception ret end |
#logger ⇒ Object
379 380 381 |
# File 'lib/rollbar/notifier.rb', line 379 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
312 313 314 315 316 317 318 |
# File 'lib/rollbar/notifier.rb', line 312 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.
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
# File 'lib/rollbar/notifier.rb', line 251 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
214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/rollbar/notifier.rb', line 214 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, is_uncaught) ⇒ Object
163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/rollbar/notifier.rb', line 163 def report_with_rescue(level, , exception, extra, context, is_uncaught) report(level, , exception, extra, context, is_uncaught) 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
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'lib/rollbar/notifier.rb', line 294 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
383 384 385 |
# File 'lib/rollbar/notifier.rb', line 383 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
188 189 190 |
# File 'lib/rollbar/notifier.rb', line 188 def warn(*args) log('warning', *args) end |
#warning(*args) ⇒ Object
See log() above
193 194 195 |
# File 'lib/rollbar/notifier.rb', line 193 def warning(*args) log('warning', *args) end |