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
|
# File 'lib/furia/observer.rb', line 5
def self.wrap(scope)
@root_scope ||= { uid: "root", type: "group", scope: scope, total_queries_num: 0, total_duration_ms: 0, entries: [] }
parent_scope = @current_scope
@current_scope =
if parent_scope
{ uid: SecureRandom.hex(16), type: "group", scope: scope, total_duration_ms: 0, entries: [] }.tap do |new_scope|
parent_scope[:entries] << new_scope
end
else
@root_scope
end
subscriber =
ActiveSupport::Notifications.subscribe("sql.active_record") do |_, started, finished, _, payload|
next if payload[:name] == "SCHEMA"
duration_ms = (finished - started) * 1000
@current_scope[:total_duration_ms] += duration_ms
entry = {
uid: SecureRandom.hex(16),
type: "query",
sql: payload[:sql],
cached: payload[:name] == "CACHE",
duration_ms: duration_ms,
stacktrace: trace_cleaner.clean(caller),
}.freeze
@current_scope[:entries] << entry
@root_scope[:total_queries_num] += 1
end
yield
if parent_scope
parent_scope[:total_duration_ms] += @current_scope[:total_duration_ms]
@current_scope = parent_scope
else
Furia::Sample.create!(data: @root_scope)
end
ensure
ActiveSupport::Notifications.unsubscribe(subscriber)
end
|