Class: ExceptionDog::Handler

Inherits:
Object
  • Object
show all
Defined in:
lib/exception_dog/handler.rb

Constant Summary collapse

MAX_LINE_LENGTH =
80
MAX_TITLE_LENGTH =
100
MAX_TEXT_LEGNTH =
4000
BACKTRACE_LINES =
2

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(configuration) ⇒ Handler

Returns a new instance of Handler.



10
11
12
13
14
# File 'lib/exception_dog/handler.rb', line 10

def initialize(configuration)
  @configuration = configuration
  @logger = @configuration.logger
  @notifier = Object.const_get(@configuration.notifier).new(configuration)
end

Instance Attribute Details

#configurationObject (readonly)

Returns the value of attribute configuration.



7
8
9
# File 'lib/exception_dog/handler.rb', line 7

def configuration
  @configuration
end

#loggerObject (readonly)

Returns the value of attribute logger.



8
9
10
# File 'lib/exception_dog/handler.rb', line 8

def logger
  @logger
end

Class Method Details

.current_trace_idObject



59
60
61
62
# File 'lib/exception_dog/handler.rb', line 59

def self.current_trace_id
  context = Thread.current[:datadog_context]
  context&.trace_id
end

.dd_trace_enabledObject



64
65
66
# File 'lib/exception_dog/handler.rb', line 64

def self.dd_trace_enabled
  @dd_trace_enabled ||= Object.const_get('Datadog::Context') rescue false
end

Instance Method Details

#aggregation_key(exception) ⇒ Object



39
40
41
# File 'lib/exception_dog/handler.rb', line 39

def aggregation_key(exception)
  "#{exception.class.name}-#{exception.message}-#{exception.backtrace&.first}".hash.to_s
end

#attach_dd_trace_id(data) ⇒ Object



43
44
45
# File 'lib/exception_dog/handler.rb', line 43

def attach_dd_trace_id(data)
  data[:trace_id] = "https://app.datadoghq.com/apm/trace/#{self.class.current_trace_id}" if self.class.current_trace_id
end

#exception_text(exception, data) ⇒ Object



31
32
33
34
35
36
37
# File 'lib/exception_dog/handler.rb', line 31

def exception_text(exception, data)
  detail = [exception.class.name[0..MAX_LINE_LENGTH], exception.message[0..MAX_LINE_LENGTH]]
  data.each do |key, val|
    detail << "#{key}: #{val && val.to_s[0..MAX_LINE_LENGTH]}"
  end
  (detail + format_backtrace(exception.backtrace)).compact.join("\n")
end

#format_backtrace(backtrace) ⇒ Object

remove backticks, single quotes, n and ensure each line is reasonably small



52
53
54
55
56
57
# File 'lib/exception_dog/handler.rb', line 52

def format_backtrace(backtrace)
  backtrace ||= []
  backtrace[0..BACKTRACE_LINES].collect do |line|
    "#{line.gsub(/\n|\`|\'/, '')}".split(//).last(MAX_LINE_LENGTH).join
  end
end

#ignored(exception) ⇒ Object



47
48
49
# File 'lib/exception_dog/handler.rb', line 47

def ignored(exception)
  configuration.ignore_exceptions&.include?(exception.class.name)
end

#notify(exception, data) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/exception_dog/handler.rb', line 17

def notify(exception, data)
  return if ignored(exception)
  attach_dd_trace_id(data) if self.class.dd_trace_enabled
  title = exception.message[0..MAX_TITLE_LENGTH]
  text = exception_text(exception, data)[0..MAX_TEXT_LEGNTH]
  opts = {}
  opts[:priority] ||= 'normal'
  opts[:tags] = ["environment:#{configuration.environment}", "service:#{configuration.service_name}"] + configuration.tags
  opts[:aggregation_key] = aggregation_key(exception)
  opts[:source_type_name] = configuration.source_type_name
  opts[:alert_type] = 'error'
  @notifier.notify(title, text, opts)
end