Class: NewRelic::Agent::ErrorCollector

Inherits:
Object
  • Object
show all
Includes:
CollectionHelper
Defined in:
lib/new_relic/agent/error_collector.rb

Defined Under Namespace

Modules: Shim

Constant Summary collapse

MAX_ERROR_QUEUE_LENGTH =
20

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from CollectionHelper

#normalize_params, #strip_nr_from_backtrace

Constructor Details

#initializeErrorCollector

Returns a new instance of ErrorCollector.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/new_relic/agent/error_collector.rb', line 16

def initialize
  @errors = []
  # lookup of exception class names to ignore.  Hash for fast access
  @ignore = {}
  @ignore_filter = nil

  config = NewRelic::Control.instance.fetch('error_collector', {})
  
  @enabled = config.fetch('enabled', true)
  @capture_source = config.fetch('capture_source', true)
  
  ignore_errors = config.fetch('ignore_errors', "")
  ignore_errors = ignore_errors.split(",")
  ignore_errors.each { |error| error.strip! } 
  ignore(ignore_errors)
  @lock = Mutex.new
end

Instance Attribute Details

#enabledObject

Returns the value of attribute enabled.



14
15
16
# File 'lib/new_relic/agent/error_collector.rb', line 14

def enabled
  @enabled
end

Instance Method Details

#harvest_errors(unsent_errors) ⇒ Object

Get the errors currently queued up. Unsent errors are left over from a previous unsuccessful attempt to send them to the server. We first clear out all unsent errors before sending the newly queued errors.



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

def harvest_errors(unsent_errors)
  if unsent_errors && !unsent_errors.empty?
    return unsent_errors
  else
    @lock.synchronize do
      errors = @errors
      @errors = []
      return errors
    end
  end
end

#ignore(errors) ⇒ Object

errors is an array of Exception Class Names



41
42
43
# File 'lib/new_relic/agent/error_collector.rb', line 41

def ignore(errors)
  errors.each { |error| @ignore[error] = true; log.debug("Ignoring error: '#{error}'") }
end

#ignore_error_filter(&block) ⇒ Object



34
35
36
# File 'lib/new_relic/agent/error_collector.rb', line 34

def ignore_error_filter(&block)
  @ignore_filter = block
end

#notice_error(exception, request = nil, action_path = nil, filtered_params = {}) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/new_relic/agent/error_collector.rb', line 45

def notice_error(exception, request=nil, action_path=nil, filtered_params={})
  return unless @enabled
  return if @ignore[exception.class.name] 
  if @ignore_filter
    exception = @ignore_filter.call(exception)
    return if exception.nil?
  end
  NewRelic::Agent.get_stats("Errors/all").increment_count
  return unless NewRelic::Agent.instance.should_send_errors
  
  action_path ||= NewRelic::Agent.instance.stats_engine.scope_name || ''
  
  data = {}
  
  data[:request_params] = normalize_params(filtered_params) if NewRelic::Control.instance.capture_params

  data[:custom_params] = normalize_params(NewRelic::Agent.instance.custom_params) 
  
  data[:request_uri] = request.path if request
  data[:request_uri] ||= ""
  
  data[:request_referer] = request.referer if request
  data[:request_referer] ||= ""
  
  data[:rails_root] = NewRelic::Control.instance.root
  
  data[:file_name] = exception.file_name if exception.respond_to?('file_name')
  data[:line_number] = exception.line_number if exception.respond_to?('line_number')
  
  if @capture_source && exception.respond_to?('source_extract')
    data[:source] = exception.source_extract
  end
  
  if exception.respond_to? 'original_exception'
    inside_exception = exception.original_exception
  else
    inside_exception = exception
  end

  data[:stack_trace] = inside_exception ? inside_exception.backtrace : '<no stack trace>'
  
  noticed_error = NewRelic::NoticedError.new(action_path, data, exception)
  
  @lock.synchronize do
    if @errors.length >= MAX_ERROR_QUEUE_LENGTH
      log.info("The error reporting queue has reached #{MAX_ERROR_QUEUE_LENGTH}. This error will not be reported to RPM: #{exception.message}")
    else
      @errors << noticed_error
    end
  end
end