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

#initialize(agent = nil) ⇒ ErrorCollector

Returns a new instance of ErrorCollector.



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

def initialize(agent = nil)
  @agent = agent
  @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.



105
106
107
108
109
110
111
112
113
114
115
# File 'lib/new_relic/agent/error_collector.rb', line 105

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



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

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

#ignore_error_filter(&block) ⇒ Object



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

def ignore_error_filter(&block)
  @ignore_filter = block
end

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



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
96
97
98
99
100
# File 'lib/new_relic/agent/error_collector.rb', line 47

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
  
  error_stat.increment_count
  
  data = {}
  
  action_path ||= ''
  
  data[:request_params] = normalize_params(filtered_params) if NewRelic::Control.instance.capture_params

  data[:custom_params] = normalize_params(@agent.custom_params) if @agent
  
  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.backtrace
  
  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