Skip to content

Commit 0941b4d

Browse files
committed
feat: Record the time spent instrumentating a function, as opposed to only the time spend executing a function
1 parent 060db30 commit 0941b4d

File tree

5 files changed

+25
-12
lines changed

5 files changed

+25
-12
lines changed

lib/appmap/event.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ def to_h
262262
end
263263

264264
class MethodReturnIgnoreValue < MethodEvent
265-
attr_accessor :parent_id, :elapsed
265+
attr_accessor :parent_id, :elapsed, :elapsed_instrumentation
266266

267267
class << self
268268
def build_from_invocation(parent_id, elapsed: nil, event: MethodReturnIgnoreValue.new)
@@ -279,6 +279,7 @@ def to_h
279279
super.tap do |h|
280280
h[:parent_id] = parent_id
281281
h[:elapsed] = elapsed if elapsed
282+
h[:elapsed_instrumentation] = elapsed_instrumentation if elapsed_instrumentation
282283
end
283284
end
284285
end

lib/appmap/hook/method.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,9 @@ def defined_class
102102
@defined_class ||= Hook.qualify_method_name(hook_method)&.first
103103
end
104104

105-
def after_hook(_receiver, call_event, elapsed, return_value, exception)
105+
def after_hook(_receiver, call_event, elapsed_before, elapsed, after_start_time, return_value, exception)
106106
return_event = handle_return(call_event.id, elapsed, return_value, exception)
107+
return_event.elapsed_instrumentation = elapsed_before + (gettime - after_start_time)
107108
AppMap.tracing.record_event(return_event) if return_event
108109
end
109110

lib/appmap/hook/method/ruby2.rb

+10-5
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,19 @@ class Hook
88
# cf. https://eregon.me/blog/2019/11/10/the-delegation-challenge-of-ruby27.html
99
class Method
1010
ruby2_keywords def call(receiver, *args, &block)
11-
call_event = trace? && with_disabled_hook { before_hook receiver, *args }
11+
call_event = false
12+
if trace?
13+
call_event, elapsed_before = with_disabled_hook { before_hook receiver, *args }
14+
end
1215
# note we can't short-circuit directly to do_call because then the call stack
1316
# depth changes and eval handler doesn't work correctly
14-
trace_call call_event, receiver, *args, &block
17+
trace_call call_event, elapsed_before, receiver, *args, &block
1518
end
1619

1720
protected
1821

1922
def before_hook(receiver, *args)
23+
before_hook_start_time = gettime
2024
call_event = handle_call(receiver, args)
2125
if call_event
2226
AppMap.tracing.record_event \
@@ -25,15 +29,15 @@ def before_hook(receiver, *args)
2529
defined_class: defined_class,
2630
method: hook_method
2731
end
28-
call_event
32+
[call_event, gettime - before_hook_start_time]
2933
end
3034

3135
ruby2_keywords def do_call(receiver, *args, &block)
3236
hook_method.bind(receiver).call(*args, &block)
3337
end
3438

3539
# rubocop:disable Metrics/MethodLength
36-
ruby2_keywords def trace_call(call_event, receiver, *args, &block)
40+
ruby2_keywords def trace_call(call_event, elapsed_before, receiver, *args, &block)
3741
return do_call(receiver, *args, &block) unless call_event
3842

3943
start_time = gettime
@@ -43,7 +47,8 @@ def before_hook(receiver, *args)
4347
exception = $ERROR_INFO
4448
raise
4549
ensure
46-
with_disabled_hook { after_hook receiver, call_event, gettime - start_time, return_value, exception } \
50+
after_start_time = gettime
51+
with_disabled_hook { after_hook receiver, call_event, elapsed_before, after_start_time - start_time, after_start_time, return_value, exception } \
4752
if call_event
4853
end
4954
end

lib/appmap/hook/method/ruby3.rb

+10-5
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,19 @@ class Hook
55
# Delegation methods for Ruby 3.
66
class Method
77
def call(receiver, *args, **kwargs, &block)
8-
call_event = trace? && with_disabled_hook { before_hook receiver, *args, **kwargs }
8+
call_event = false
9+
if trace?
10+
call_event, elapsed_before = with_disabled_hook { before_hook receiver, *args, **kwargs }
11+
end
912
# note we can't short-circuit directly to do_call because then the call stack
1013
# depth changes and eval handler doesn't work correctly
11-
trace_call call_event, receiver, *args, **kwargs, &block
14+
trace_call call_event, elapsed_before, receiver, *args, **kwargs, &block
1215
end
1316

1417
protected
1518

1619
def before_hook(receiver, *args, **kwargs)
20+
before_hook_start_time = gettime
1721
args = [*args, kwargs] if !kwargs.empty? || keyrest?
1822
call_event = handle_call(receiver, args)
1923
if call_event
@@ -23,7 +27,7 @@ def before_hook(receiver, *args, **kwargs)
2327
defined_class: defined_class,
2428
method: hook_method
2529
end
26-
call_event
30+
[call_event, gettime - before_hook_start_time]
2731
end
2832

2933
def keyrest?
@@ -35,7 +39,7 @@ def do_call(receiver, *args, **kwargs, &block)
3539
end
3640

3741
# rubocop:disable Metrics/MethodLength
38-
def trace_call(call_event, receiver, *args, **kwargs, &block)
42+
def trace_call(call_event, elapsed_before, receiver, *args, **kwargs, &block)
3943
return do_call(receiver, *args, **kwargs, &block) unless call_event
4044

4145
start_time = gettime
@@ -45,7 +49,8 @@ def trace_call(call_event, receiver, *args, **kwargs, &block)
4549
exception = $ERROR_INFO
4650
raise
4751
ensure
48-
with_disabled_hook { after_hook receiver, call_event, gettime - start_time, return_value, exception } \
52+
after_start_time = gettime
53+
with_disabled_hook { after_hook receiver, call_event, elapsed_before, after_start_time - start_time, after_start_time, return_value, exception } \
4954
if call_event
5055
end
5156
end

lib/appmap/util.rb

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ def sanitize_paths(h)
8686
def sanitize_event(event, &block)
8787
event.delete(:thread_id)
8888
event.delete(:elapsed)
89+
event.delete(:elapsed_instrumentation)
8990
delete_object_id = ->(obj) { (obj || {}).delete(:object_id) }
9091
delete_object_id.call(event[:receiver])
9192
delete_object_id.call(event[:return_value])

0 commit comments

Comments
 (0)