class NewRelic::Agent::ErrorFilter

Handles loading of ignored and expected errors from the agent configuration, and determining at runtime whether an exception is ignored or expected.

Public Class Methods

new() click to toggle source
# File lib/new_relic/agent/error_filter.rb, line 10
def initialize
  reset
end

Public Instance Methods

expect(*args) click to toggle source

See ignore above.

# File lib/new_relic/agent/error_filter.rb, line 96
def expect(*args)
  args.each do |errors|
    case errors
    when Array
      errors.each { |e| expect(e) }
    when Integer
      @expected_status_codes << errors
    when Hash
      @expected_messages.update(errors)
      log_filter(:expected_messages, errors)
    when String
      if /^[\d\,\-]+$/.match?(errors)
        @expected_status_codes |= parse_status_codes(errors)
        log_filter(:expected_status_codes, errors)
      else
        new_expected_classes = errors.split(',').map!(&:strip)
        @expected_classes |= new_expected_classes
        log_filter(:expected_classes, new_expected_classes)
      end
    end
  end
end
expected?(ex, status_code = nil) click to toggle source
# File lib/new_relic/agent/error_filter.rb, line 58
def expected?(ex, status_code = nil)
  @expected_classes.include?(ex.class.name) ||
    (@expected_messages.key?(ex.class.name) &&
    @expected_messages[ex.class.name].any? { |m| ex.message.include?(m) }) ||
    @expected_status_codes.include?(status_code.to_i)
end
fetch_agent_config(cfg) click to toggle source
# File lib/new_relic/agent/error_filter.rb, line 65
def fetch_agent_config(cfg)
  NewRelic::Agent.config[:"error_collector.#{cfg}"]
end
ignore(*args) click to toggle source

A generic method for adding ignore filters manually. This is kept for compatibility with the previous ErrorCollector#ignore method, and adds some flexibility for adding different ignore/expected error types by examining each argument.

# File lib/new_relic/agent/error_filter.rb, line 72
def ignore(*args)
  args.each do |errors|
    case errors
    when Array
      errors.each { |e| ignore(e) }
    when Integer
      @ignore_status_codes << errors
    when Hash
      @ignore_messages.update(errors)
      log_filter(:ignore_messages, errors)
    when String
      if /^[\d\,\-]+$/.match?(errors)
        @ignore_status_codes |= parse_status_codes(errors)
        log_filter(:ignore_status_codes, errors)
      else
        new_ignore_classes = errors.split(',').map!(&:strip)
        @ignore_classes |= new_ignore_classes
        log_filter(:ignore_classes, new_ignore_classes)
      end
    end
  end
end
ignore?(ex, status_code = nil) click to toggle source
# File lib/new_relic/agent/error_filter.rb, line 51
def ignore?(ex, status_code = nil)
  @ignore_classes.include?(ex.class.name) ||
    (@ignore_messages.key?(ex.class.name) &&
    @ignore_messages[ex.class.name].any? { |m| ex.message.include?(m) }) ||
    @ignore_status_codes.include?(status_code.to_i)
end
load_all() click to toggle source
# File lib/new_relic/agent/error_filter.rb, line 20
def load_all
  %i[
    ignore_classes ignore_messages ignore_status_codes
    expected_classes expected_messages expected_status_codes
  ].each { |setting| load_from_config(setting) }
end
load_from_config(setting, value = nil) click to toggle source
# File lib/new_relic/agent/error_filter.rb, line 27
def load_from_config(setting, value = nil)
  errors = nil
  new_value = value || fetch_agent_config(setting.to_sym)

  return if new_value.nil? || (new_value.respond_to?(:empty?) && new_value.empty?)

  case setting.to_sym
  when :ignore_classes
    new_value = new_value.split(',').map!(&:strip) if new_value.is_a?(String)
    errors = @ignore_classes = new_value
  when :ignore_messages
    errors = @ignore_messages = new_value || {}
  when :ignore_status_codes
    errors = @ignore_status_codes = parse_status_codes(new_value) || []
  when :expected_classes
    errors = @expected_classes = new_value || []
  when :expected_messages
    errors = @expected_messages = new_value || {}
  when :expected_status_codes
    errors = @expected_status_codes = parse_status_codes(new_value) || []
  end
  log_filter(setting, errors) if errors
end
reset() click to toggle source
# File lib/new_relic/agent/error_filter.rb, line 14
def reset
  @ignore_classes, @expected_classes = [], []
  @ignore_messages, @expected_messages = {}, {}
  @ignore_status_codes, @expected_status_codes = [], []
end

Private Instance Methods

log_filter(setting, errors) click to toggle source
# File lib/new_relic/agent/error_filter.rb, line 121
def log_filter(setting, errors)
  case setting
  when :ignore_classes
    errors.each do |error|
      ::NewRelic::Agent.logger.debug("Ignoring errors of type '#{error}'")
    end
  when :ignore_messages
    errors.each do |error, messages|
      ::NewRelic::Agent.logger.debug("Ignoring errors of type '#{error}' with messages: #{messages.join(',')}")
    end
  when :ignore_status_codes
    ::NewRelic::Agent.logger.debug("Ignoring errors associated with status codes: #{errors}")
  when :expected_classes
    errors.each do |error|
      ::NewRelic::Agent.logger.debug("Expecting errors of type '#{error}'")
    end
  when :expected_messages
    errors.each do |error, messages|
      ::NewRelic::Agent.logger.debug("Expecting errors of type '#{error}' with messages: #{messages.join(',')}")
    end
  when :expected_status_codes
    ::NewRelic::Agent.logger.debug("Expecting errors associated with status codes: #{errors}")
  end
end
parse_status_codes(codes) click to toggle source
# File lib/new_relic/agent/error_filter.rb, line 146
def parse_status_codes(codes)
  code_list = case codes
    when String
      codes.split(',')
    when Integer
      [codes]
    else
      codes
  end
  result = []
  code_list.each do |code|
    result << code && next if code.is_a?(Integer)

    m = code.match(/(\d{3})(-\d{3})?/)
    if m.nil? || m[1].nil?
      ::NewRelic::Agent.logger.warn("Invalid HTTP status code: '#{code}'; ignoring config")
      next
    end
    if m[2]
      result += (m[1]..m[2].tr('-', '')).to_a.map(&:to_i)
    else
      result << m[1].to_i
    end
  end
  result.uniq
end