class Binnacle::Trap::ExceptionEvent

Attributes

backtrace[R]
component[R]
env[R]
exception[R]
method[R]
module[R]
request[R]

Public Class Methods

new(exception, env) click to toggle source
# File lib/binnacle/trap/exception_event.rb, line 26
def initialize(exception, env)
  @exception = unwrap_exception(exception)
  @env = env

  if env["action_dispatch.request.parameters"] != nil
    @component = env['action_dispatch.request.parameters'][:controller] || nil
    @method = env['action_dispatch.request.parameters'][:action] || nil
    @module = env['action_dispatch.request.parameters'][:module] || nil
  end

  @request = ::Rack::Request.new(env)

  extract_event_name
  extract_session_id
  extract_client_id
  extract_backtrace

  self.log_level = "EXCEPTION"
  self.tags = []
  build_json_payload

  configure(
    Binnacle.configuration.error_channel,
    self.event_name,
    self.client_id,
    self.session_id,
    self.log_level,
    nil,
    self.tags,
    self.json
  )
end

Private Instance Methods

build_json_payload() click to toggle source
# File lib/binnacle/trap/exception_event.rb, line 151
def build_json_payload
  self.json = {
    path: @request.path,
    exception: event_name,
    message: @exception.message,
    component: @component,
    method: @method,
    environment_level: Event.rails_env,
    hostname: extract_hostname,
    user_agent: @request.user_agent,
    ruby_version: extract_ruby_version,
    framework: extract_framework,
    framework_version: extract_framework_version,
    framework_params: extract_framework_params,
    http_params: extract_http_params,
    headers: extract_headers,
    dependencies: extract_libraries_loaded,
    backtrace: @backtrace
  }
end
extract_backtrace() click to toggle source
# File lib/binnacle/trap/exception_event.rb, line 83
def extract_backtrace
  backtrace = Backtrace.parse(@exception.backtrace)
  @backtrace = backtrace.lines.map do |line|
    { number: line.number, file: line.file, method: line.method_name }
  end
end
extract_client_id() click to toggle source
# File lib/binnacle/trap/exception_event.rb, line 141
def extract_client_id
  session = @env["rack.session"] ? @env["rack.session"].to_hash : {}
  warden_info = session.find { |k,v| k.start_with?('warden.') }
  if warden_info
    self.client_id = warden_info.last.first.first
  else
    self.client_id = ""
  end
end
extract_event_name() click to toggle source

The root Exception class name

# File lib/binnacle/trap/exception_event.rb, line 72
def extract_event_name
  self.event_name = @exception.class.to_s
end
extract_framework() click to toggle source
# File lib/binnacle/trap/exception_event.rb, line 104
def extract_framework
  defined?(Rails) ? "Rails" : "unknown"
end
extract_framework_params() click to toggle source
# File lib/binnacle/trap/exception_event.rb, line 112
def extract_framework_params
  {}
end
extract_framework_version() click to toggle source
# File lib/binnacle/trap/exception_event.rb, line 108
def extract_framework_version
  defined?(Rails) ? Rails::VERSION::STRING : "unknown"
end
extract_headers() click to toggle source
# File lib/binnacle/trap/exception_event.rb, line 90
def extract_headers
  http_headers = {}

  http_headers = @env.map.with_object({}) do |(key, value), headers|
    if Binnacle::Trap::HTTP_HEADER_PREFIXES.any? { |prefix| key.to_s.start_with?(prefix) } && !HTTP_HEADER_SKIPS.include?(key.to_s)
      headers[key] = value
    end

    headers
  end

  http_headers
end
extract_hostname() click to toggle source
# File lib/binnacle/trap/exception_event.rb, line 120
def extract_hostname
  require 'socket' unless defined?(Socket)
  Socket.gethostname
rescue
  'UNKNOWN'
end
extract_http_params() click to toggle source
# File lib/binnacle/trap/exception_event.rb, line 137
def extract_http_params
  @request.params rescue {}
end
extract_libraries_loaded() click to toggle source
# File lib/binnacle/trap/exception_event.rb, line 127
def extract_libraries_loaded
  libraries = {}
  begin
    libraries = Hash[*Gem.loaded_specs.map{|name, gem_specification| [name, gem_specification.version.to_s]}.flatten]
  rescue
  end

  libraries
end
extract_ruby_version() click to toggle source
# File lib/binnacle/trap/exception_event.rb, line 116
def extract_ruby_version
  "#{RUBY_VERSION rescue '?.?.?'} p#{RUBY_PATCHLEVEL rescue '???'} #{RUBY_RELEASE_DATE rescue '????-??-??'} #{RUBY_PLATFORM rescue '????'}"
end
extract_session_id() click to toggle source

The affected User or some identifier that can be used to determine who was affected by the exception (Warden, Devise, etc. should be used if available to get this information)

# File lib/binnacle/trap/exception_event.rb, line 79
def extract_session_id
  self.session_id = (@env["rack.session"] ? @env["rack.session"]["session_id"] : nil) || @request.ip
end
unwrap_exception(exception) click to toggle source
# File lib/binnacle/trap/exception_event.rb, line 61
def unwrap_exception(exception)
  if exception.respond_to?(:cause)
    exception.cause
  elsif exception.respond_to?(:original_exception)
    exception.original_exception
  elsif exception.respond_to?(:continued_exception)
    exception.continued_exception
  end || exception
end