Module: NewRelic::Agent::ErrorCollector::NoticeError

Included in:
NewRelic::Agent::ErrorCollector
Defined in:
lib/new_relic/agent/error_collector.rb

Overview

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

Instance Method Summary collapse

Instance Method Details

#add_to_error_queue(noticed_error) ⇒ Object

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.



201
202
203
204
205
# File 'lib/new_relic/agent/error_collector.rb', line 201

def add_to_error_queue(noticed_error)
  @lock.synchronize do
    @errors << noticed_error unless over_queue_limit?(noticed_error.message)
  end
end

#custom_params_from_opts(options) ⇒ Object

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



126
127
128
129
# File 'lib/new_relic/agent/error_collector.rb', line 126

def custom_params_from_opts(options)
  # If anything else is left over, treat it like a custom param:
  fetch_from_options(options, :custom_params, {}).merge(options)
end

#disabled?Boolean

Whether the error collector is disabled or not

Returns:

  • (Boolean)


69
70
71
# File 'lib/new_relic/agent/error_collector.rb', line 69

def disabled?
  !@enabled
end

#error_is_ignored?(error) ⇒ Boolean

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

Returns:

  • (Boolean)


87
88
89
# File 'lib/new_relic/agent/error_collector.rb', line 87

def error_is_ignored?(error)
  error && filtered_error?(error)
end

#error_params_from_options(options) ⇒ Object

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



154
155
156
# File 'lib/new_relic/agent/error_collector.rb', line 154

def error_params_from_options(options)
  uri_ref_and_root(options).merge(normalized_request_and_custom_params(options))
end

#exception_info(exception) ⇒ Object

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



180
181
182
183
184
185
186
187
# File 'lib/new_relic/agent/error_collector.rb', line 180

def exception_info(exception)
  {
    :file_name => sense_method(exception, 'file_name'),
    :line_number => sense_method(exception, 'line_number'),
    :source => extract_source(exception),
    :stack_trace => extract_stack_trace(exception)
  }
end

#extract_source(exception) ⇒ Object

extracts source from the exception, if the exception supports that method



167
168
169
# File 'lib/new_relic/agent/error_collector.rb', line 167

def extract_source(exception)
  sense_method(exception, 'source_extract') if @capture_source
end

#extract_stack_trace(exception) ⇒ Object

extracts a stack trace from the exception for debugging purposes



172
173
174
175
# File 'lib/new_relic/agent/error_collector.rb', line 172

def extract_stack_trace(exception)
  actual_exception = sense_method(exception, 'original_exception') || exception
  sense_method(actual_exception, 'backtrace') || '<no stack trace>'
end

#fetch_from_options(options, key, default = nil) ⇒ Object

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



111
112
113
# File 'lib/new_relic/agent/error_collector.rb', line 111

def fetch_from_options(options, key, default=nil)
  options.delete(key) || default
end

#filtered_by_error_filter?(error) ⇒ Boolean

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

Returns:

  • (Boolean)


75
76
77
78
# File 'lib/new_relic/agent/error_collector.rb', line 75

def filtered_by_error_filter?(error)
  return unless @ignore_filter
  !@ignore_filter.call(error)
end

#filtered_error?(error) ⇒ Boolean

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

Returns:

  • (Boolean)


82
83
84
# File 'lib/new_relic/agent/error_collector.rb', line 82

def filtered_error?(error)
  @ignore[error.class.name] || filtered_by_error_filter?(error)
end

#increment_error_count!Object

Increments a statistic that tracks total error rate



92
93
94
# File 'lib/new_relic/agent/error_collector.rb', line 92

def increment_error_count!
  NewRelic::Agent.get_stats("Errors/all").increment_count
end

#normalized_request_and_custom_params(options) ⇒ Object

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



145
146
147
148
149
150
# File 'lib/new_relic/agent/error_collector.rb', line 145

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) ⇒ Boolean

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.

Returns:

  • (Boolean)


191
192
193
194
195
# File 'lib/new_relic/agent/error_collector.rb', line 191

def over_queue_limit?(message)
  over_limit = (@errors.length >= MAX_ERROR_QUEUE_LENGTH)
  log.warn("The error reporting queue has reached #{MAX_ERROR_QUEUE_LENGTH}. The error detail for this and subsequent errors will not be transmitted to New Relic until the queued errors have been sent: #{message}") if over_limit
  over_limit
end

#request_params_from_opts(options) ⇒ Object

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



134
135
136
137
138
139
140
141
# File 'lib/new_relic/agent/error_collector.rb', line 134

def request_params_from_opts(options)
  value = options.delete(:request_params)
  if control.capture_params
    value
  else
    nil
  end
end

#sense_method(object, method) ⇒ Object

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



161
162
163
# File 'lib/new_relic/agent/error_collector.rb', line 161

def sense_method(object, method)
  object.send(method) if object.respond_to?(method)
end

#should_exit_notice_error?(exception) ⇒ Boolean

whether we should return early from the notice_error process

  • based on whether the error is ignored or the error

collector is disabled

Returns:

  • (Boolean)


99
100
101
102
103
104
105
106
107
108
# File 'lib/new_relic/agent/error_collector.rb', line 99

def should_exit_notice_error?(exception)
  if @enabled
    if !error_is_ignored?(exception)
      increment_error_count!
      return exception.nil? # exit early if the exception is nil
    end
  end
  # disabled or an ignored error, per above
  true
end

#uri_ref_and_root(options) ⇒ Object

returns some basic option defaults pulled from the provided options hash



117
118
119
120
121
122
123
# File 'lib/new_relic/agent/error_collector.rb', line 117

def uri_ref_and_root(options)
  {
    :request_uri => fetch_from_options(options, :uri, ''),
    :request_referer => fetch_from_options(options, :referer, ''),
    :rails_root => control.root
  }
end