Class: ErrorLens::Writer

Inherits:
Object
  • Object
show all
Defined in:
lib/error_lens/writer.rb

Class Method Summary collapse

Class Method Details

.extract_app_line(backtrace) ⇒ Object



58
59
60
61
# File 'lib/error_lens/writer.rb', line 58

def self.extract_app_line(backtrace)
  return nil if backtrace.nil? || backtrace.empty?
  backtrace.find { |line| line.start_with?(Rails.root.to_s) } || backtrace.first
end

.generate_fingerprint(exception_class, backtrace) ⇒ Object



63
64
65
66
# File 'lib/error_lens/writer.rb', line 63

def self.generate_fingerprint(exception_class, backtrace)
  app_line = extract_app_line(backtrace) || "unknown"
  Digest::MD5.hexdigest("#{exception_class}-#{app_line}")
end

.write(event) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/error_lens/writer.rb', line 5

def self.write(event)
  fingerprint = generate_fingerprint(event[:exception_class], event[:backtrace])
  app_line = extract_app_line(event[:backtrace])

  group = ErrorLens::ErrorGroup.find_or_create_by!(fingerprint: fingerprint) do |g|
    g.error_class   = event[:exception_class]
    g.message       = event[:exception_message]
    g.first_seen_at = Time.current
    g.last_seen_at  = Time.current
    g.source        = event[:source]
    g.environment   = event[:environment]
    g.location      = app_line
  end

  group.increment!(:occurrences_count)
  group.update_columns(
    last_seen_at: Time.current,
    source:       event[:source],
    location:     app_line
  )

  ErrorLens::ErrorOccurrence.create!(
    error_group:  group,
    message:      event[:exception_message],
    backtrace:    event[:backtrace].to_json,
    source:       event[:source],
    environment:  event[:environment],
    occurred_at:  event[:occurred_at] || Time.current,

    # web
    request_id:   event[:request_id],
    url:          event[:url],
    http_method:  event[:http_method],
    parameters:   (event[:parameters] || {}).to_json,
    user_agent:      event[:user_agent],
    ip_address:      event[:ip_address],
    forwarded_for:   event[:forwarded_for],
    request_headers: (event[:request_headers] || {}).to_json,
    cause_class:     event[:cause_class],
    cause_message:   event[:cause_message],

    # sidekiq
    job_class:    event[:job_class],
    job_args:     (event[:job_args] || []).to_json,
    job_id:       event[:job_id],
    queue:        event[:queue]
  )
rescue => e
  Rails.logger.error "[ErrorLens] Writer failed: #{e.message}" rescue nil
end