appmap 0.92.0 → 0.93.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +1 -1
- data/CHANGELOG.md +17 -0
- data/lib/appmap/event.rb +2 -1
- data/lib/appmap/handler/rails/request_handler.rb +10 -1
- data/lib/appmap/handler/rails/sql_handler.rb +8 -2
- data/lib/appmap/hook/method/ruby2.rb +13 -6
- data/lib/appmap/hook/method/ruby3.rb +13 -6
- data/lib/appmap/hook/method.rb +4 -5
- data/lib/appmap/util.rb +5 -0
- data/lib/appmap/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 837bc5a036d3217c12b40f46ed7e21406ef298b3ca5c8b712b8ce1f15707434e
|
4
|
+
data.tar.gz: 763d5c9abd0f8583035117a54c8a6bb0d841089c902ab2e1805ff0795f3acff1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7812c770c07f1e00dc93e0ce4c79598c26daff3fe1d737804dcfc012d29cdefe0754cd3ff06f2810feebe1952cb2038cee2f078d486067188875ec7eb71842de
|
7
|
+
data.tar.gz: 73db38443e22f4a57bf8575035b4735f7fe044f57dd78f6213ac2694434487732778cb0feacb3733c0565080dd859b22dfcf651ec129b70f028a1500a9ff63ea
|
data/.github/workflows/main.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
# [0.93.0](https://github.com/getappmap/appmap-ruby/compare/v0.92.1...v0.93.0) (2022-09-22)
|
2
|
+
|
3
|
+
|
4
|
+
### Features
|
5
|
+
|
6
|
+
* Record the time spent instrumentating a function, as opposed to only the time spend executing a function ([0941b4d](https://github.com/getappmap/appmap-ruby/commit/0941b4d343b1ea2964268d3a47d8f762de00deea))
|
7
|
+
* save elapsed_instrumentation for HTTP requests ([a32fb52](https://github.com/getappmap/appmap-ruby/commit/a32fb526a6f7b47ddc859e86a68b53b50b052061))
|
8
|
+
* save elapsed_instrumentation for RequestListener ([5a081cc](https://github.com/getappmap/appmap-ruby/commit/5a081ccf558a4591035acc81b1717b2ccef880ee))
|
9
|
+
* Save elapsed_instrumentation for sql_query ([40a851e](https://github.com/getappmap/appmap-ruby/commit/40a851e5d40cc5ada36ea52e32d5222da4c67d10))
|
10
|
+
|
11
|
+
## [0.92.1](https://github.com/getappmap/appmap-ruby/compare/v0.92.0...v0.92.1) (2022-09-21)
|
12
|
+
|
13
|
+
|
14
|
+
### Bug Fixes
|
15
|
+
|
16
|
+
* Drop database server version ([e52f210](https://github.com/getappmap/appmap-ruby/commit/e52f210baa26be49232003c224e4ffee19be823d))
|
17
|
+
|
1
18
|
# [0.92.0](https://github.com/applandinc/appmap-ruby/compare/v0.91.0...v0.92.0) (2022-09-19)
|
2
19
|
|
3
20
|
|
data/lib/appmap/event.rb
CHANGED
@@ -262,7 +262,7 @@ module AppMap
|
|
262
262
|
end
|
263
263
|
|
264
264
|
class MethodReturnIgnoreValue < MethodEvent
|
265
|
-
attr_accessor :parent_id, :elapsed
|
265
|
+
attr_accessor :parent_id, :elapsed, :elapsed_instrumentation
|
266
266
|
|
267
267
|
class << self
|
268
268
|
def build_from_invocation(parent_id, elapsed: nil, event: MethodReturnIgnoreValue.new)
|
@@ -279,6 +279,7 @@ module AppMap
|
|
279
279
|
super.tap do |h|
|
280
280
|
h[:parent_id] = parent_id
|
281
281
|
h[:elapsed] = elapsed if elapsed
|
282
|
+
h[:elapsed_instrumentation] = elapsed_instrumentation if elapsed_instrumentation
|
282
283
|
end
|
283
284
|
end
|
284
285
|
end
|
@@ -10,7 +10,7 @@ module AppMap
|
|
10
10
|
|
11
11
|
module RequestHandler
|
12
12
|
class HTTPServerRequest < AppMap::Event::MethodEvent
|
13
|
-
attr_accessor :normalized_path_info, :request_method, :path_info, :params, :headers
|
13
|
+
attr_accessor :normalized_path_info, :request_method, :path_info, :params, :headers, :call_elapsed_instrumentation
|
14
14
|
|
15
15
|
def initialize(request)
|
16
16
|
super AppMap::Event.next_id_counter, :call, Thread.current.object_id
|
@@ -101,16 +101,21 @@ module AppMap
|
|
101
101
|
protected
|
102
102
|
|
103
103
|
def before_hook(receiver, *)
|
104
|
+
before_hook_start_time = AppMap::Util.gettime()
|
104
105
|
call_event = HTTPServerRequest.new(receiver.request)
|
106
|
+
call_event.call_elapsed_instrumentation = (AppMap::Util.gettime() - before_hook_start_time)
|
105
107
|
# http_server_request events are i/o and do not require a package name.
|
106
108
|
AppMap.tracing.record_event call_event, defined_class: defined_class, method: hook_method
|
107
109
|
call_event
|
108
110
|
end
|
109
111
|
|
110
112
|
def after_hook(receiver, call_event, elapsed, *)
|
113
|
+
after_hook_start_time = AppMap::Util.gettime()
|
111
114
|
return_value = Thread.current[TEMPLATE_RENDER_VALUE]
|
112
115
|
Thread.current[TEMPLATE_RENDER_VALUE] = nil
|
113
116
|
return_event = HTTPServerResponse.build_from_invocation call_event.id, return_value, elapsed, receiver.response
|
117
|
+
return_event.elapsed_instrumentation = (AppMap::Util.gettime() - after_hook_start_time) + call_event.call_elapsed_instrumentation
|
118
|
+
call_event.call_elapsed_instrumentation = nil # to stay consistent with elapsed_instrumentation only being stored in return
|
114
119
|
AppMap.tracing.record_event return_event
|
115
120
|
end
|
116
121
|
end
|
@@ -134,13 +139,16 @@ module AppMap
|
|
134
139
|
end
|
135
140
|
|
136
141
|
def before_hook(payload)
|
142
|
+
before_hook_start_time = AppMap::Util.gettime()
|
137
143
|
@call_event = HTTPServerRequest.new payload[:request]
|
144
|
+
@call_event.call_elapsed_instrumentation = (AppMap::Util.gettime() - before_hook_start_time)
|
138
145
|
AppMap.tracing.record_event @call_event
|
139
146
|
end
|
140
147
|
|
141
148
|
def after_hook(_name, started, finished, _unique_id, payload)
|
142
149
|
return unless @request_id == payload[:request].request_id
|
143
150
|
|
151
|
+
after_hook_start_time = AppMap::Util.gettime()
|
144
152
|
return_value = Thread.current[TEMPLATE_RENDER_VALUE]
|
145
153
|
Thread.current[TEMPLATE_RENDER_VALUE] = nil
|
146
154
|
return_event = HTTPServerResponse.build_from_invocation(
|
@@ -149,6 +157,7 @@ module AppMap
|
|
149
157
|
finished - started,
|
150
158
|
payload[:response] || payload
|
151
159
|
)
|
160
|
+
return_event.elapsed_instrumentation = (AppMap::Util.gettime() - after_hook_start_time) + @call_event.call_elapsed_instrumentation
|
152
161
|
|
153
162
|
AppMap.tracing.record_event return_event
|
154
163
|
ActiveSupport::Notifications.unsubscribe(@subscriber)
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'appmap/event'
|
4
4
|
require 'appmap/hook/method'
|
5
|
+
require 'appmap/util'
|
5
6
|
|
6
7
|
module AppMap
|
7
8
|
module Handler
|
@@ -75,7 +76,6 @@ module AppMap
|
|
75
76
|
end
|
76
77
|
end
|
77
78
|
|
78
|
-
payload[:server_version] = examiner.server_version
|
79
79
|
payload[:database_type] = examiner.database_type.to_s
|
80
80
|
end
|
81
81
|
|
@@ -92,6 +92,8 @@ module AppMap
|
|
92
92
|
|
93
93
|
class SequelExaminer
|
94
94
|
def server_version
|
95
|
+
# Queries the database, therefore this is pretty unsafe to do inside of a hook.
|
96
|
+
# As a result, this is not being used at the moment.
|
95
97
|
Sequel::Model.db.server_version
|
96
98
|
end
|
97
99
|
|
@@ -147,6 +149,8 @@ module AppMap
|
|
147
149
|
reentry_key = "#{self.class.name}#call"
|
148
150
|
return if Thread.current[reentry_key] == true
|
149
151
|
|
152
|
+
after_start_time = AppMap::Util.gettime()
|
153
|
+
|
150
154
|
Thread.current[reentry_key] = true
|
151
155
|
begin
|
152
156
|
sql = payload[:sql].strip
|
@@ -155,7 +159,9 @@ module AppMap
|
|
155
159
|
|
156
160
|
call = SQLCall.new(payload)
|
157
161
|
AppMap.tracing.record_event(call)
|
158
|
-
|
162
|
+
sql_return_event = SQLReturn.new(call.id, finished - started)
|
163
|
+
sql_return_event.elapsed_instrumentation = AppMap::Util.gettime() - after_start_time
|
164
|
+
AppMap.tracing.record_event(sql_return_event)
|
159
165
|
ensure
|
160
166
|
Thread.current[reentry_key] = nil
|
161
167
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'appmap/util'
|
4
|
+
|
3
5
|
def ruby2_keywords(*); end unless respond_to?(:ruby2_keywords, true)
|
4
6
|
|
5
7
|
module AppMap
|
@@ -8,15 +10,19 @@ module AppMap
|
|
8
10
|
# cf. https://eregon.me/blog/2019/11/10/the-delegation-challenge-of-ruby27.html
|
9
11
|
class Method
|
10
12
|
ruby2_keywords def call(receiver, *args, &block)
|
11
|
-
call_event =
|
13
|
+
call_event = false
|
14
|
+
if trace?
|
15
|
+
call_event, elapsed_before = with_disabled_hook { before_hook receiver, *args }
|
16
|
+
end
|
12
17
|
# note we can't short-circuit directly to do_call because then the call stack
|
13
18
|
# depth changes and eval handler doesn't work correctly
|
14
|
-
trace_call call_event, receiver, *args, &block
|
19
|
+
trace_call call_event, elapsed_before, receiver, *args, &block
|
15
20
|
end
|
16
21
|
|
17
22
|
protected
|
18
23
|
|
19
24
|
def before_hook(receiver, *args)
|
25
|
+
before_hook_start_time = AppMap::Util.gettime()
|
20
26
|
call_event = handle_call(receiver, args)
|
21
27
|
if call_event
|
22
28
|
AppMap.tracing.record_event \
|
@@ -25,7 +31,7 @@ module AppMap
|
|
25
31
|
defined_class: defined_class,
|
26
32
|
method: hook_method
|
27
33
|
end
|
28
|
-
call_event
|
34
|
+
[call_event, AppMap::Util.gettime() - before_hook_start_time]
|
29
35
|
end
|
30
36
|
|
31
37
|
ruby2_keywords def do_call(receiver, *args, &block)
|
@@ -33,17 +39,18 @@ module AppMap
|
|
33
39
|
end
|
34
40
|
|
35
41
|
# rubocop:disable Metrics/MethodLength
|
36
|
-
ruby2_keywords def trace_call(call_event, receiver, *args, &block)
|
42
|
+
ruby2_keywords def trace_call(call_event, elapsed_before, receiver, *args, &block)
|
37
43
|
return do_call(receiver, *args, &block) unless call_event
|
38
44
|
|
39
|
-
start_time = gettime
|
45
|
+
start_time = AppMap::Util.gettime()
|
40
46
|
begin
|
41
47
|
return_value = do_call(receiver, *args, &block)
|
42
48
|
rescue # rubocop:disable Style/RescueStandardError
|
43
49
|
exception = $ERROR_INFO
|
44
50
|
raise
|
45
51
|
ensure
|
46
|
-
|
52
|
+
after_start_time = AppMap::Util.gettime()
|
53
|
+
with_disabled_hook { after_hook receiver, call_event, elapsed_before, after_start_time - start_time, after_start_time, return_value, exception } \
|
47
54
|
if call_event
|
48
55
|
end
|
49
56
|
end
|
@@ -1,19 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'appmap/util'
|
4
|
+
|
3
5
|
module AppMap
|
4
6
|
class Hook
|
5
7
|
# Delegation methods for Ruby 3.
|
6
8
|
class Method
|
7
9
|
def call(receiver, *args, **kwargs, &block)
|
8
|
-
call_event =
|
10
|
+
call_event = false
|
11
|
+
if trace?
|
12
|
+
call_event, elapsed_before = with_disabled_hook { before_hook receiver, *args, **kwargs }
|
13
|
+
end
|
9
14
|
# note we can't short-circuit directly to do_call because then the call stack
|
10
15
|
# depth changes and eval handler doesn't work correctly
|
11
|
-
trace_call call_event, receiver, *args, **kwargs, &block
|
16
|
+
trace_call call_event, elapsed_before, receiver, *args, **kwargs, &block
|
12
17
|
end
|
13
18
|
|
14
19
|
protected
|
15
20
|
|
16
21
|
def before_hook(receiver, *args, **kwargs)
|
22
|
+
before_hook_start_time = AppMap::Util.gettime()
|
17
23
|
args = [*args, kwargs] if !kwargs.empty? || keyrest?
|
18
24
|
call_event = handle_call(receiver, args)
|
19
25
|
if call_event
|
@@ -23,7 +29,7 @@ module AppMap
|
|
23
29
|
defined_class: defined_class,
|
24
30
|
method: hook_method
|
25
31
|
end
|
26
|
-
call_event
|
32
|
+
[call_event, AppMap::Util.gettime() - before_hook_start_time]
|
27
33
|
end
|
28
34
|
|
29
35
|
def keyrest?
|
@@ -35,17 +41,18 @@ module AppMap
|
|
35
41
|
end
|
36
42
|
|
37
43
|
# rubocop:disable Metrics/MethodLength
|
38
|
-
def trace_call(call_event, receiver, *args, **kwargs, &block)
|
44
|
+
def trace_call(call_event, elapsed_before, receiver, *args, **kwargs, &block)
|
39
45
|
return do_call(receiver, *args, **kwargs, &block) unless call_event
|
40
46
|
|
41
|
-
start_time = gettime
|
47
|
+
start_time = AppMap::Util.gettime()
|
42
48
|
begin
|
43
49
|
return_value = do_call(receiver, *args, **kwargs, &block)
|
44
50
|
rescue # rubocop:disable Style/RescueStandardError
|
45
51
|
exception = $ERROR_INFO
|
46
52
|
raise
|
47
53
|
ensure
|
48
|
-
|
54
|
+
after_start_time = AppMap::Util.gettime()
|
55
|
+
with_disabled_hook { after_hook receiver, call_event, elapsed_before, after_start_time - start_time, after_start_time, return_value, exception } \
|
49
56
|
if call_event
|
50
57
|
end
|
51
58
|
end
|
data/lib/appmap/hook/method.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'appmap/util'
|
4
|
+
|
3
5
|
module AppMap
|
4
6
|
class Hook
|
5
7
|
SIGNATURES = {}
|
@@ -78,10 +80,6 @@ module AppMap
|
|
78
80
|
warn "#{hook_method.name} not found on #{hook_class}" if Hook::LOG
|
79
81
|
end
|
80
82
|
|
81
|
-
def gettime
|
82
|
-
Process.clock_gettime Process::CLOCK_MONOTONIC
|
83
|
-
end
|
84
|
-
|
85
83
|
def trace?
|
86
84
|
return false unless AppMap.tracing_enabled?
|
87
85
|
return false if Thread.current[HOOK_DISABLE_KEY]
|
@@ -102,8 +100,9 @@ module AppMap
|
|
102
100
|
@defined_class ||= Hook.qualify_method_name(hook_method)&.first
|
103
101
|
end
|
104
102
|
|
105
|
-
def after_hook(_receiver, call_event, elapsed, return_value, exception)
|
103
|
+
def after_hook(_receiver, call_event, elapsed_before, elapsed, after_start_time, return_value, exception)
|
106
104
|
return_event = handle_return(call_event.id, elapsed, return_value, exception)
|
105
|
+
return_event.elapsed_instrumentation = elapsed_before + (AppMap::Util.gettime() - after_start_time)
|
107
106
|
AppMap.tracing.record_event(return_event) if return_event
|
108
107
|
end
|
109
108
|
|
data/lib/appmap/util.rb
CHANGED
@@ -86,6 +86,7 @@ module AppMap
|
|
86
86
|
def sanitize_event(event, &block)
|
87
87
|
event.delete(:thread_id)
|
88
88
|
event.delete(:elapsed)
|
89
|
+
event.delete(:elapsed_instrumentation)
|
89
90
|
delete_object_id = ->(obj) { (obj || {}).delete(:object_id) }
|
90
91
|
delete_object_id.call(event[:receiver])
|
91
92
|
delete_object_id.call(event[:return_value])
|
@@ -231,6 +232,10 @@ module AppMap
|
|
231
232
|
def ruby_minor_version
|
232
233
|
@ruby_minor_version ||= RUBY_VERSION.split('.')[0..1].join('.').to_f
|
233
234
|
end
|
235
|
+
|
236
|
+
def gettime
|
237
|
+
Process.clock_gettime Process::CLOCK_MONOTONIC
|
238
|
+
end
|
234
239
|
end
|
235
240
|
end
|
236
241
|
end
|
data/lib/appmap/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appmap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.93.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Gilpin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-09-
|
11
|
+
date: 2022-09-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: method_source
|
@@ -455,7 +455,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
455
455
|
- !ruby/object:Gem::Version
|
456
456
|
version: '0'
|
457
457
|
requirements: []
|
458
|
-
rubygems_version: 3.
|
458
|
+
rubygems_version: 3.1.6
|
459
459
|
signing_key:
|
460
460
|
specification_version: 4
|
461
461
|
summary: Record the operation of a Ruby program, using the AppLand 'AppMap' format.
|