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 HydraulicBrake

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) (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
# File 'lib/right_agent/error_tracker.rb', line 105

def notify(exception, packet = nil, agent = nil, component = nil)
  if @notify_enabled
    data = {
      :error_message => exception.respond_to?(:message) ? exception.message : exception.to_s,
      :backtrace => exception.respond_to?(:backtrace) ? exception.backtrace : caller,
      :environment_name => ENV["RAILS_ENV"],
    }
    if agent
      data[:cgi_data] = (@cgi_data || {}).merge(:agent_class => agent.class.name)
    elsif @cgi_data
      data[:cgi_data] = @cgi_data
    end
    data[:error_class] = exception.class.name if exception.is_a?(Exception)
    data[:component] = component if component
    if packet && packet.is_a?(Packet)
      data[: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 = packet[:path] || packet["path"]
      data[:action] = action.split("/").last if action
      params = packet[:data] || packet["data"]
      uuid = packet[:uuid] || packet["uuid"]
    else
      params = uuid = nil
    end
    data[:parameters] = params.is_a?(Hash) ? filter(params) : {:param => params} if params
    data[:session_data] = {:uuid => uuid} if uuid
    HydraulicBrake.notify(data)
  end
  true
rescue Exception => e
  Log.error("Failed to notify Errbit", e, :trace)
end

#notify_callbackProc

Create proc for making callback to notifier

Returns:

  • (Proc)

    notifier callback



143
144
145
146
147
# File 'lib/right_agent/error_tracker.rb', line 143

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



154
155
156
157
158
# File 'lib/right_agent/error_tracker.rb', line 154

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