blob: 477453a693ecc4dc45242db263e2a6077dd4d2b1 (
plain)
1
2
3
4
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
55
56
57
58
59
60
61
62
|
# frozen_string_literal: true
module ErrorTracking
class CollectErrorService < ::BaseService
def execute
# Error is a way to group events based on common data like name or cause
# of exception. We need to keep a sane balance here between taking too little
# and too much data into group logic.
error = project.error_tracking_errors.report_error(
name: exception['type'], # Example: ActionView::MissingTemplate
description: exception['value'], # Example: Missing template posts/show in...
actor: actor, # Example: PostsController#show
platform: event['platform'], # Example: ruby
timestamp: timestamp
)
# The payload field contains all the data on error including stacktrace in jsonb.
# Together with occured_at these are 2 main attributes that we need to save here.
error.events.create!(
environment: event['environment'],
description: exception['value'],
level: event['level'],
occurred_at: timestamp,
payload: event
)
end
private
def event
params[:event]
end
def exception
event['exception']['values'].first
end
def actor
return event['transaction'] if event['transaction']
# Some SDK do not have transaction attribute.
# So we build it by combining function name and module name from
# the last item in stacktrace.
last_line = exception.dig('stacktrace', 'frames').last
"#{last_line['function']}(#{last_line['module']})"
end
def timestamp
return @timestamp if @timestamp
@timestamp = (event['timestamp'] || Time.zone.now)
# Some SDK send timestamp in numeric format like '1630945472.13'.
if @timestamp.to_s =~ /\A\d+(\.\d+)?\z/
@timestamp = Time.zone.at(@timestamp.to_f)
end
@timestamp
end
end
end
|