Class: TingYun::Agent::Collector::ErrorCollector

Inherits:
Object
  • Object
show all
Includes:
Metric, Tag
Defined in:
lib/ting_yun/agent/collector/error_collector.rb

Defined Under Namespace

Modules: Metric, Tag

Constant Summary collapse

ERRORS_ACTION =
"Errors/Count/".freeze
ERRORS_ALL =
"Errors/Count/All".freeze
ERRORS_ALL_WEB =
"Errors/Count/AllWeb".freeze
ERRORS_ALL_BACK_GROUND =
"Errors/Count/AllBackground".freeze
MAX_ERROR_QUEUE_LENGTH =

Maximum possible length of the queue - defaults to 20, may be

20
EMPTY_STRING =
''.freeze

Constants included from Tag

Tag::EXCEPTION_TAG_IVAR

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Metric

#action_metric_name, #aggregated_metric_names

Methods included from Tag

#exception_tagged?, #tag_exception

Constructor Details

#initializeErrorCollector

Returns a new instance of ErrorCollector.



66
67
68
69
# File 'lib/ting_yun/agent/collector/error_collector.rb', line 66

def initialize
  @error_trace_array = ::TingYun::Agent::Collector::ErrorTraceArray.new(MAX_ERROR_QUEUE_LENGTH)
  @external_error_array = ::TingYun::Agent::Collector::ErrorTraceArray.new(MAX_ERROR_QUEUE_LENGTH)
end

Instance Attribute Details

#error_trace_arrayObject (readonly)

Returns the value of attribute error_trace_array.



64
65
66
# File 'lib/ting_yun/agent/collector/error_collector.rb', line 64

def error_trace_array
  @error_trace_array
end

#external_error_arrayObject (readonly)

Returns the value of attribute external_error_array.



64
65
66
# File 'lib/ting_yun/agent/collector/error_collector.rb', line 64

def external_error_array
  @external_error_array
end

Instance Method Details

#create_noticed_error(exception, options) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/ting_yun/agent/collector/error_collector.rb', line 104

def create_noticed_error(exception, options)
  error_metric = options.delete(:metric_name) || EMPTY_STRING

  noticed_error = TingYun::Agent::Collector::NoticedError.new(error_metric, exception)
  noticed_error.request_uri = options.delete(:uri) || EMPTY_STRING
  noticed_error.request_port = options.delete(:port)
  noticed_error.attributes  = options.delete(:attributes)

  noticed_error.file_name   = sense_method(exception, :file_name)
  noticed_error.line_number = sense_method(exception, :line_number)
  noticed_error.stack_trace = extract_stack_trace(exception)

  noticed_error.attributes_from_notice_error = options.delete(:custom_params) || {}

  # Any options that are passed to notice_error which aren't known keys
  # get treated as custom attributes, so merge them into that hash.
  noticed_error.attributes_from_notice_error.merge!(options)

  noticed_error
end

#extract_stack_trace(exception) ⇒ Object

extracts a stack trace from the exception for debugging purposes



137
138
139
140
# File 'lib/ting_yun/agent/collector/error_collector.rb', line 137

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

#increment_error_count!(state, exception, options = {}) ⇒ Object

Increments a statistic that tracks total error rate



88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/ting_yun/agent/collector/error_collector.rb', line 88

def increment_error_count!(state, exception, options={})
  txn = state.current_transaction

  metric_names = aggregated_metric_names(txn)

  action_metric = action_metric_name(txn)
  metric_names << action_metric if action_metric

  stats_engine = TingYun::Agent.agent.stats_engine
  stats_engine.record_unscoped_metrics(state, metric_names) do |stats|
    stats.increment_count
  end
end

#notice_agent_error(exception) ⇒ Object

*Use sparingly for difficult to track bugs.*

Track internal agent errors for communication back to TingYun To use, make a specific subclass of TingYun::Support::Exception::InternalAgentError, then pass an instance of it to this method when your problem occurs.

Limits are treated differently for these errors. We only gather one per class per harvest, disregarding (and not impacting) the app error queue limit.



151
152
153
# File 'lib/ting_yun/agent/collector/error_collector.rb', line 151

def notice_agent_error(exception)
  error_trace_array.notice_agent_error(exception)
end

#notice_error(exception, options = {}) ⇒ Object

See TingYun::Agent.notice_error for options and commentary



72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/ting_yun/agent/collector/error_collector.rb', line 72

def notice_error(exception, options={})
  tag_exception(exception)
  state = ::TingYun::Agent::TransactionState.tl_get
  increment_error_count!(state, exception, options)
  noticed_error = create_noticed_error(exception, options)
  if noticed_error.is_external_error
    external_error_array.add_to_error_queue(noticed_error)
  else
    error_trace_array.add_to_error_queue(noticed_error)
  end
rescue => e
  ::TingYun::Agent.logger.warn("Failure when capturing error '#{exception}':", e)
  nil
end

#reset!Object



155
156
157
158
159
# File 'lib/ting_yun/agent/collector/error_collector.rb', line 155

def reset!
  @error_trace_array.reset!
  @external_error_array.reset!
  nil
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



132
133
134
# File 'lib/ting_yun/agent/collector/error_collector.rb', line 132

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

#skip_notice_error?(exception) ⇒ Boolean

Returns:

  • (Boolean)


125
126
127
# File 'lib/ting_yun/agent/collector/error_collector.rb', line 125

def skip_notice_error?(exception)
  exception_tagged?(exception)
end