Class: RightScale::ErrorTracker

Inherits:
Object
  • Object
show all
Includes:
RightSupport::Ruby::EasySingleton
Defined in:
lib/right_agent/error_tracker.rb

Overview

Tracker for unexpected errors Logs them with appropriate trace information Accumulates statistics about exceptions Reports exceptions to external Errbit service via Airbrake

Constant Summary collapse

FILTERED_PARAM_VALUE =

Text used for filtered parameter value

"<hidden>"

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#exception_statsObject (readonly)

Container for exception statistics



26
27
28
# File 'lib/right_agent/error_tracker.rb', line 26

def exception_stats
  @exception_stats
end

Instance Method Details

#init(agent, agent_name, options = {}) ⇒ TrueClass

Initialize error tracker

Parameters:

  • agent (Object)

    object using this tracker

  • agent_name (String)

    uniquely identifying agent process on given server

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :shard_id (Integer, NilClass)

    identifying shard of database in use

  • :trace_level (Hash)

    for restricting backtracing and Errbit reporting with exception class as key and :no_trace, :caller, or :trace as value; exceptions with :no_trace are not backtraced when logging nor are they recorded in stats or reported to Errbit

  • :filter_params (Array<Symbol, String>)

    names whose values are to be filtered when notifying

  • :airbrake_endpoint (String)

    URL for Airbrake for reporting exceptions to Errbit

  • :airbrake_api_key (String)

    for using the Airbrake API to access Errbit

Returns:

  • (TrueClass)

    always true



45
46
47
48
49
50
51
# File 'lib/right_agent/error_tracker.rb', line 45

def init(agent, agent_name, options = {})
  @agent = agent
  @trace_level = options[:trace_level] || {}
  notify_init(agent_name, options)
  reset_stats
  true
end

#log(component, description, exception = nil, packet = nil, trace = nil) ⇒ Boolean

Log error and optionally track in stats Errbit notification is left to the callback configured in the stats tracker Logging works even if init was never called

Parameters:

  • component (String, Object)

    reporting error; non-string is snake-cased

  • description (String)

    of failure for use in logging

  • exception (Exception, String) (defaults to: nil)

    to be logged and tracked in stats; string errors are logged but not tracked in stats

  • packet (Packet, Hash, NilClass) (defaults to: nil)

    associated with exception

  • trace (Symbol, NilClass) (defaults to: nil)

    level override unless excluded by configured trace levels

Returns:

  • (Boolean)

    true if successfully logged, otherwise false



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/right_agent/error_tracker.rb', line 66

def log(component, description, exception = nil, packet = nil, trace = nil)
  if exception.nil?
    Log.error(description)
  elsif exception.is_a?(String)
    Log.error(description, exception)
  else
    trace = (@trace_level && @trace_level[exception.class]) || trace || :trace
    Log.error(description, exception, trace)
    track(component, exception, packet) if trace != :no_trace
  end
  true
rescue StandardError => e
  Log.error("Failed to log error", e, :trace) rescue nil
  false
end

#notify(exception, packet = nil, agent = nil, component = nil) ⇒ TrueClass

Notify Errbit of error if notification enabled

Parameters:

  • exception (Exception, String)

    raised

  • packet (Packet, Hash) (defaults to: nil)

    associated with exception

  • agent (Object) (defaults to: nil)

    object reporting error

  • component (String, Object) (defaults to: nil)

    or service area where error occurred

Returns:

  • (TrueClass)

    always true



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/right_agent/error_tracker.rb', line 105

def notify(exception, packet = nil, agent = nil, component = nil)
  if @notify_enabled
    if packet && packet.is_a?(Packet)
      action = packet.type.split("/").last if packet.respond_to?(:type)
      params = packet.respond_to?(:payload) && packet.payload
      uuid = packet.respond_to?(:token) && packet.token
    elsif packet.is_a?(Hash)
      action_path = packet[:path] || packet["path"]
      action = action_path.split("/").last if action_path
      params = packet[:data] || packet["data"]
      uuid = packet[:uuid] || packet["uuid"]
    else
      params = uuid = nil
    end

    component = component.class.name unless component.is_a?(String)

    n = Airbrake.build_notice(
      exception,
      { component: component, action: action },
      :right_agent )

    n[:params] = params.is_a?(Hash) ? filter(params) : {:param => params} if params
    n[:session] = { :uuid => uuid } if uuid

    if agent
      n[:environment] = (@cgi_data || {}).merge(:agent_class => agent.class.name)
    elsif @cgi_data
      n[:environment] = @cgi_data || {}
    end

    Airbrake.notify(n, {}, :right_agent)
  end
  true
rescue Exception => e
  raise if e.class.name =~ /^RSpec/ # keep us from going insane while running tests
  Log.error("Failed to notify Errbit", e, :trace)
end

#notify_callbackProc

Create proc for making callback to notifier

Returns:

  • (Proc)

    notifier callback



147
148
149
150
151
# File 'lib/right_agent/error_tracker.rb', line 147

def notify_callback
  Proc.new do |exception, packet, agent, component|
    notify(exception, packet, agent, component)
  end
end

#stats(reset = false) ⇒ Hash

Get exception statistics

Parameters:

  • reset (Boolean) (defaults to: false)

    Whether to reset the statistics after getting the current ones

Returns:

  • (Hash)

    current statistics



158
159
160
161
162
# File 'lib/right_agent/error_tracker.rb', line 158

def stats(reset = false)
  stats = {"exceptions" => @exception_stats && @exception_stats.all}
  reset_stats if reset
  stats
end

#track(component, exception, packet = nil) ⇒ TrueClass

Track error in stats

Parameters:

  • component (String)

    reporting error

  • exception (Exception)

    to be tracked

  • packet (Packet, Hash, NilClass) (defaults to: nil)

    associated with exception

Returns:

  • (TrueClass)

    always true



89
90
91
92
93
94
95
# File 'lib/right_agent/error_tracker.rb', line 89

def track(component, exception, packet = nil)
  if @exception_stats
    component = component.class.name.split("::").last.snake_case unless component.is_a?(String)
    @exception_stats.track(component, exception, packet)
  end
  true
end