module OneApm::Collector::ErrorCollector::NoticeError

This module was extracted from the notice_error method - it is internally tested and can be refactored without major issues.

Public Instance Methods

add_to_error_queue(noticed_error) click to toggle source

Synchronizes adding an error to the error queue, and checks if the error queue is too long - if so, we drop the error on the floor after logging a warning.

# File lib/one_apm/collector/containers/error_collector.rb, line 258
def add_to_error_queue(noticed_error)
  @lock.synchronize do
    if !over_queue_limit?(noticed_error.message) && !@errors.include?(noticed_error)
      @errors << noticed_error
    end
  end
end
aggregated_metric_names(txn) click to toggle source
# File lib/one_apm/collector/containers/error_collector.rb, line 132
def aggregated_metric_names(txn)
  metric_names = ["Errors/all"]
  return metric_names unless txn

  if txn.recording_web_transaction?
    metric_names << "Errors/allWeb"
  else
    metric_names << "Errors/allOther"
  end

  metric_names
end
blamed_metric_name(txn, options) click to toggle source
# File lib/one_apm/collector/containers/error_collector.rb, line 124
def blamed_metric_name(txn, options)
  if options[:metric] && options[:metric] != OneApm::Transaction::OA_UNKNOWN_METRIC
    "Errors/#{options[:metric]}"
  else
    "Errors/#{txn.best_name}" if txn
  end
end
custom_params_from_opts(options) click to toggle source

If anything else is left over, we treat it like a custom param

# File lib/one_apm/collector/containers/error_collector.rb, line 182
def custom_params_from_opts(options)
  # If anything else is left over, treat it like a custom param:
  if OneApm::Manager.config[:'error_collector.capture_attributes']
    fetch_from_options(options, :custom_params, {}).merge(options)
  else
    {}
  end
end
error_is_ignored?(error) click to toggle source

an error is ignored if it is nil or if it is filtered

# File lib/one_apm/collector/containers/error_collector.rb, line 107
def error_is_ignored?(error)
  error && filtered_error?(error)
rescue => e
  OneApm::Manager.logger.error("Error '#{error}' will NOT be ignored. Exception '#{e}' while determining whether to ignore or not.", e)
  false
end
error_params_from_options(options) click to toggle source

Merges together many of the options into something that can actually be attached to the error

# File lib/one_apm/collector/containers/error_collector.rb, line 214
def error_params_from_options(options)
  uri_ref_and_root(options).merge(normalized_request_and_custom_params(options))
end
exception_info(exception) click to toggle source

extracts a bunch of information from the exception to include in the noticed error - some may or may not be available, but we try to include all of it

# File lib/one_apm/collector/containers/error_collector.rb, line 239
def exception_info(exception)
  {
    :file_name => sense_method(exception, 'file_name'),
    :line_number => sense_method(exception, 'line_number'),
    :stack_trace => extract_stack_trace(exception)
  }
end
extract_stack_trace(exception) click to toggle source

extracts a stack trace from the exception for debugging purposes

# File lib/one_apm/collector/containers/error_collector.rb, line 226
def extract_stack_trace(exception)
  actual_exception = sense_method(exception, 'original_exception') || exception
  if bt = sense_method(actual_exception, 'backtrace')
    bt.reject! { |t| t.include?('one_apm') }
    bt
  else
    '<no stack trace>'
  end
end
fetch_from_options(options, key, default=nil) click to toggle source

acts just like Hash#fetch, but deletes the key from the hash

# File lib/one_apm/collector/containers/error_collector.rb, line 167
def fetch_from_options(options, key, default=nil)
  options.delete(key) || default
end
filtered_by_error_filter?(error) click to toggle source

Checks the provided error against the error filter, if there is an error filter

# File lib/one_apm/collector/containers/error_collector.rb, line 96
def filtered_by_error_filter?(error)
  respond_to?(:ignore_filter_proc) && !ignore_filter_proc(error)
end
filtered_error?(error) click to toggle source

Checks the array of error names and the error filter against the provided error

# File lib/one_apm/collector/containers/error_collector.rb, line 102
def filtered_error?(error)
  @ignore[error.class.name] || filtered_by_error_filter?(error)
end
increment_error_count!(state, exception, options={}) click to toggle source

Increments a statistic that tracks total error rate

# File lib/one_apm/collector/containers/error_collector.rb, line 146
def increment_error_count!(state, exception, options={})
  txn = state.current_transaction

  metric_names  = aggregated_metric_names(txn)
  blamed_metric = blamed_metric_name(txn, options)
  metric_names << blamed_metric if blamed_metric

  stats_engine = OneApm::Manager.agent.stats_engine
  stats_engine.record_unscoped_metrics(state, metric_names) do |stats|
    stats.increment_count
  end
end
normalized_request_and_custom_params(options) click to toggle source

normalizes the request and custom parameters before attaching them to the error. See OneApm::CollectionHelper#normalize_params

# File lib/one_apm/collector/containers/error_collector.rb, line 205
def normalized_request_and_custom_params(options)
  {
    :request_params => normalize_params(request_params_from_opts(options)),
    :custom_params  => normalize_params(custom_params_from_opts(options))
  }
end
over_queue_limit?(message) click to toggle source

checks the size of the error queue to make sure we are under the maximum limit, and logs a warning if we are over the limit.

# File lib/one_apm/collector/containers/error_collector.rb, line 249
def over_queue_limit?(message)
  over_limit = (@errors.reject{|err| err.is_internal}.length >= OA_MAX_ERROR_QUEUE_LENGTH)
  OneApm::Manager.logger.warn("The error reporting queue has reached #{OA_MAX_ERROR_QUEUE_LENGTH}. The error detail for this and subsequent errors will not be transmitted to OneApm until the queued errors have been sent: #{message}") if over_limit
  over_limit
end
request_params_from_opts(options) click to toggle source

takes the request parameters out of the options hash, and returns them if we are capturing parameters, otherwise returns nil

# File lib/one_apm/collector/containers/error_collector.rb, line 194
def request_params_from_opts(options)
  value = options.delete(:request_params)
  if OneApm::Manager.config[:capture_params]
    value
  else
    nil
  end
end
seen?(txn, exception) click to toggle source
# File lib/one_apm/collector/containers/error_collector.rb, line 114
def seen?(txn, exception)
  error_ids = txn.nil? ? [] : txn.noticed_error_ids
  error_ids.include?(exception.object_id)
end
sense_method(object, method) click to toggle source

calls a method on an object, if it responds to it - used for detection and soft fail-safe. Returns nil if the method does not exist

# File lib/one_apm/collector/containers/error_collector.rb, line 221
def sense_method(object, method)
  object.send(method) if object.respond_to?(method)
end
skip_notice_error?(state, exception) click to toggle source
# File lib/one_apm/collector/containers/error_collector.rb, line 159
def skip_notice_error?(state, exception)
  disabled? ||
    error_is_ignored?(exception) ||
    exception.nil? ||
    seen?(state.current_transaction, exception)
end
tag_as_seen(state, exception) click to toggle source
# File lib/one_apm/collector/containers/error_collector.rb, line 119
def tag_as_seen(state, exception)
  txn = state.current_transaction
  txn.noticed_error_ids << exception.object_id if txn
end
uri_ref_and_root(options) click to toggle source

returns some basic option defaults pulled from the provided options hash

# File lib/one_apm/collector/containers/error_collector.rb, line 173
def uri_ref_and_root(options)
  {
    :request_uri => fetch_from_options(options, :uri, ''),
    :request_referer => fetch_from_options(options, :referer, ''),
    :rails_root => OneApm::Probe.instance.root
  }
end