appmap 0.102.2 → 0.103.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/.rubocop.yml +6 -0
- data/.standard.yml +1 -0
- data/.travis.yml +2 -2
- data/CHANGELOG.md +17 -0
- data/appmap.gemspec +35 -36
- data/lib/appmap/agent.rb +28 -24
- data/lib/appmap/class_map.rb +36 -31
- data/lib/appmap/config.rb +132 -110
- data/lib/appmap/cucumber.rb +25 -25
- data/lib/appmap/detect_enabled.rb +30 -28
- data/lib/appmap/gem_hooks/activejob.yml +0 -1
- data/lib/appmap/hook/method/ruby2.rb +19 -8
- data/lib/appmap/hook/method/ruby3.rb +20 -13
- data/lib/appmap/hook/method.rb +27 -27
- data/lib/appmap/hook/record_around.rb +77 -0
- data/lib/appmap/hook.rb +74 -44
- data/lib/appmap/metadata.rb +6 -18
- data/lib/appmap/middleware/remote_recording.rb +26 -27
- data/lib/appmap/minitest.rb +27 -27
- data/lib/appmap/rspec.rb +37 -37
- data/lib/appmap/trace.rb +14 -12
- data/lib/appmap/util.rb +71 -61
- data/lib/appmap/version.rb +1 -1
- metadata +5 -16
@@ -1,4 +1,4 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "recording_methods"
|
2
2
|
|
3
3
|
module AppMap
|
4
4
|
# Detects whether AppMap recording should be enabled. This test can be performed generally, or for
|
@@ -9,27 +9,29 @@ module AppMap
|
|
9
9
|
@@detected_for_method = {}
|
10
10
|
|
11
11
|
class << self
|
12
|
+
# rubocop:disable Metrics/MethodLength
|
12
13
|
def discourage_conflicting_recording_methods(recording_method)
|
13
|
-
return if ENV[
|
14
|
+
return if ENV["APPMAP_DISCOURAGE_CONFLICTING_RECORDING_METHODS"] == "false"
|
14
15
|
|
15
16
|
return unless enabled?(recording_method.to_sym) && enabled?(:requests)
|
16
17
|
|
17
18
|
warn Util.color <<~MSG, :yellow
|
18
|
-
AppMap recording is enabled for both 'requests' and '#{recording_method}'. This is not recommended
|
19
|
-
because the recordings will contain duplicitive information, and in some case may conflict with each other.
|
19
|
+
AppMap recording is enabled for both 'requests' and '#{recording_method}'. This is not recommended
|
20
|
+
because the recordings will contain duplicitive information, and in some case may conflict with each other.
|
20
21
|
MSG
|
21
22
|
|
22
|
-
return unless ENV[
|
23
|
+
return unless ENV["APPMAP"] == "true"
|
23
24
|
|
24
25
|
warn Util.color <<~MSG, :yellow
|
25
|
-
The environment contains APPMAP=true, which is not recommended in this application environment because
|
26
|
-
it enables all recording methods. Consider letting AppMap detect the appropriate recording method,
|
27
|
-
or explicitly enabling only the recording methods you want to use using environment variables like
|
28
|
-
APPMAP_RECORD_REQUESTS, APPMAP_RECORD_RSPEC, etc.
|
29
|
-
|
30
|
-
See https://appmap.io/docs/reference/appmap-ruby.html#advanced-runtime-options for more information.
|
26
|
+
The environment contains APPMAP=true, which is not recommended in this application environment because
|
27
|
+
it enables all recording methods. Consider letting AppMap detect the appropriate recording method,
|
28
|
+
or explicitly enabling only the recording methods you want to use using environment variables like
|
29
|
+
APPMAP_RECORD_REQUESTS, APPMAP_RECORD_RSPEC, etc.
|
30
|
+
|
31
|
+
See https://appmap.io/docs/reference/appmap-ruby.html#advanced-runtime-options for more information.
|
31
32
|
MSG
|
32
33
|
end
|
34
|
+
# rubocop:enable Metrics/MethodLength
|
33
35
|
|
34
36
|
def enabled?(recording_method)
|
35
37
|
new(recording_method).enabled?
|
@@ -57,7 +59,7 @@ See https://appmap.io/docs/reference/appmap-ruby.html#advanced-runtime-options f
|
|
57
59
|
|
58
60
|
if @recording_method && (enabled && enabled_by_app_env?)
|
59
61
|
warn AppMap::Util.color(
|
60
|
-
"AppMap #{@recording_method.nil? ?
|
62
|
+
"AppMap #{@recording_method.nil? ? "" : "#{@recording_method} "}recording is enabled because #{message}", :magenta
|
61
63
|
)
|
62
64
|
end
|
63
65
|
|
@@ -77,63 +79,63 @@ See https://appmap.io/docs/reference/appmap-ruby.html#advanced-runtime-options f
|
|
77
79
|
message, enabled = []
|
78
80
|
message, enabled = method(detection_functions.shift).call while enabled.nil? && !detection_functions.empty?
|
79
81
|
|
80
|
-
return [
|
82
|
+
return ["it is not enabled by any configuration or framework", false, false] if enabled.nil?
|
81
83
|
|
82
84
|
_, enabled_by_env = enabled_by_app_env?
|
83
|
-
[
|
85
|
+
[message, enabled, enabled_by_env]
|
84
86
|
end
|
85
87
|
|
86
88
|
def enabled_by_testing?
|
87
89
|
return unless %i[rspec minitest cucumber].member?(@recording_method)
|
88
90
|
|
89
|
-
[
|
91
|
+
["running tests with #{@recording_method}", true]
|
90
92
|
end
|
91
93
|
|
92
94
|
def enabled_by_app_env?
|
93
95
|
env_name, app_env = detect_app_env
|
94
|
-
return [
|
96
|
+
return ["#{env_name} is '#{app_env}'", true] if @recording_method.nil? && %w[test development].member?(app_env)
|
95
97
|
|
96
98
|
return unless %i[remote requests].member?(@recording_method)
|
97
|
-
|
99
|
+
["#{env_name} is '#{app_env}'", true] if app_env == "development"
|
98
100
|
end
|
99
101
|
|
100
102
|
def detect_app_env
|
101
103
|
if rails_env
|
102
|
-
[
|
103
|
-
elsif ENV[
|
104
|
-
[
|
104
|
+
["RAILS_ENV", rails_env]
|
105
|
+
elsif ENV["APP_ENV"]
|
106
|
+
["APP_ENV", ENV["APP_ENV"]]
|
105
107
|
end
|
106
108
|
end
|
107
109
|
|
108
110
|
def globally_enabled?
|
109
111
|
# Don't auto-enable request recording in the 'test' environment, because users probably don't want
|
110
112
|
# AppMaps of both test cases and requests. Requests recording can always be enabled by APPMAP_RECORD_REQUESTS=true.
|
111
|
-
requests_recording_in_test = -> { [
|
112
|
-
[
|
113
|
+
requests_recording_in_test = -> { [:requests].member?(@recording_method) && detect_app_env == "test" }
|
114
|
+
["APPMAP=true", true] if ENV["APPMAP"] == "true" && !requests_recording_in_test.call
|
113
115
|
end
|
114
116
|
|
115
117
|
def globally_disabled?
|
116
|
-
[
|
118
|
+
["APPMAP=false", false] if ENV["APPMAP"] == "false"
|
117
119
|
end
|
118
120
|
|
119
121
|
def recording_method_disabled?
|
120
122
|
return false unless @recording_method
|
121
123
|
|
122
|
-
env_var = [
|
123
|
-
[
|
124
|
+
env_var = ["APPMAP", "RECORD", @recording_method.upcase].join("_")
|
125
|
+
["#{["APPMAP", "RECORD", @recording_method.upcase].join("_")}=false", false] if ENV[env_var] == "false"
|
124
126
|
end
|
125
127
|
|
126
128
|
def recording_method_enabled?
|
127
129
|
return false unless @recording_method
|
128
130
|
|
129
|
-
env_var = [
|
130
|
-
[
|
131
|
+
env_var = ["APPMAP", "RECORD", @recording_method.upcase].join("_")
|
132
|
+
["#{["APPMAP", "RECORD", @recording_method.upcase].join("_")}=true", true] if ENV[env_var] == "true"
|
131
133
|
end
|
132
134
|
|
133
135
|
def rails_env
|
134
136
|
return Rails.env if defined?(::Rails::Railtie)
|
135
137
|
|
136
|
-
ENV.fetch(
|
138
|
+
ENV.fetch("RAILS_ENV", nil)
|
137
139
|
end
|
138
140
|
end
|
139
141
|
end
|
@@ -1,16 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "appmap/util"
|
4
|
+
require_relative "../record_around"
|
4
5
|
|
5
|
-
|
6
|
+
unless respond_to?(:ruby2_keywords, true)
|
7
|
+
def ruby2_keywords(*)
|
8
|
+
end
|
9
|
+
end
|
6
10
|
|
7
11
|
module AppMap
|
8
12
|
class Hook
|
9
13
|
# Delegation methods for Ruby 2.
|
10
14
|
# cf. https://eregon.me/blog/2019/11/10/the-delegation-challenge-of-ruby27.html
|
11
15
|
class Method
|
16
|
+
include RecordAround
|
17
|
+
|
12
18
|
ruby2_keywords def call(receiver, *args, &block)
|
13
19
|
call_event = false
|
20
|
+
record_around_before
|
14
21
|
if trace?
|
15
22
|
call_event, elapsed_before = with_disabled_hook { before_hook receiver, *args }
|
16
23
|
end
|
@@ -22,7 +29,7 @@ module AppMap
|
|
22
29
|
protected
|
23
30
|
|
24
31
|
def before_hook(receiver, *args)
|
25
|
-
before_hook_start_time = AppMap::Util.gettime
|
32
|
+
before_hook_start_time = AppMap::Util.gettime
|
26
33
|
call_event = handle_call(receiver, args)
|
27
34
|
if call_event
|
28
35
|
AppMap.tracing.record_event \
|
@@ -31,10 +38,11 @@ module AppMap
|
|
31
38
|
defined_class: defined_class,
|
32
39
|
method: hook_method
|
33
40
|
end
|
34
|
-
[call_event, AppMap::Util.gettime
|
41
|
+
[call_event, AppMap::Util.gettime - before_hook_start_time]
|
35
42
|
end
|
36
43
|
|
37
44
|
ruby2_keywords def do_call(receiver, *args, &block)
|
45
|
+
# Do not allow this to change to bind_call, it's not defined for Ruby 2.
|
38
46
|
hook_method.bind(receiver).call(*args, &block)
|
39
47
|
end
|
40
48
|
|
@@ -42,16 +50,19 @@ module AppMap
|
|
42
50
|
ruby2_keywords def trace_call(call_event, elapsed_before, receiver, *args, &block)
|
43
51
|
return do_call(receiver, *args, &block) unless call_event
|
44
52
|
|
45
|
-
start_time = AppMap::Util.gettime
|
53
|
+
start_time = AppMap::Util.gettime
|
46
54
|
begin
|
47
55
|
return_value = do_call(receiver, *args, &block)
|
48
56
|
rescue # rubocop:disable Style/RescueStandardError
|
49
57
|
exception = $ERROR_INFO
|
50
58
|
raise
|
51
59
|
ensure
|
52
|
-
after_start_time = AppMap::Util.gettime
|
53
|
-
|
54
|
-
|
60
|
+
after_start_time = AppMap::Util.gettime
|
61
|
+
begin
|
62
|
+
with_disabled_hook { after_hook receiver, call_event, elapsed_before, after_start_time - start_time, after_start_time, return_value, exception }
|
63
|
+
ensure
|
64
|
+
record_around_after
|
65
|
+
end
|
55
66
|
end
|
56
67
|
end
|
57
68
|
# rubocop:enable Metrics/MethodLength
|
@@ -1,17 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "appmap/util"
|
4
|
+
require_relative "../record_around"
|
4
5
|
|
5
6
|
module AppMap
|
6
7
|
class Hook
|
7
8
|
# Delegation methods for Ruby 3.
|
8
9
|
class Method
|
10
|
+
include RecordAround
|
11
|
+
|
9
12
|
def call(receiver, *args, **kwargs, &block)
|
10
13
|
call_event = false
|
14
|
+
record_around_before
|
11
15
|
if trace?
|
12
16
|
call_event, elapsed_before = with_disabled_hook { before_hook receiver, *args, **kwargs }
|
13
17
|
end
|
14
|
-
#
|
18
|
+
# NOTE: we can't short-circuit directly to do_call because then the call stack
|
15
19
|
# depth changes and eval handler doesn't work correctly
|
16
20
|
trace_call call_event, elapsed_before, receiver, *args, **kwargs, &block
|
17
21
|
end
|
@@ -19,7 +23,7 @@ module AppMap
|
|
19
23
|
protected
|
20
24
|
|
21
25
|
def before_hook(receiver, *args, **kwargs)
|
22
|
-
before_hook_start_time = AppMap::Util.gettime
|
26
|
+
before_hook_start_time = AppMap::Util.gettime
|
23
27
|
args = [*args, kwargs] if !kwargs.empty? || keyrest?
|
24
28
|
call_event = handle_call(receiver, args)
|
25
29
|
if call_event
|
@@ -29,31 +33,34 @@ module AppMap
|
|
29
33
|
defined_class: defined_class,
|
30
34
|
method: hook_method
|
31
35
|
end
|
32
|
-
[call_event, AppMap::Util.gettime
|
36
|
+
[call_event, AppMap::Util.gettime - before_hook_start_time]
|
33
37
|
end
|
34
38
|
|
35
39
|
def keyrest?
|
36
40
|
@keyrest ||= parameters.map(&:last).include? :keyrest
|
37
41
|
end
|
38
42
|
|
39
|
-
def do_call(receiver,
|
40
|
-
hook_method.bind_call(receiver,
|
43
|
+
def do_call(receiver, ...)
|
44
|
+
hook_method.bind_call(receiver, ...)
|
41
45
|
end
|
42
46
|
|
43
47
|
# rubocop:disable Metrics/MethodLength
|
44
|
-
def trace_call(call_event, elapsed_before, receiver,
|
45
|
-
return do_call(receiver,
|
48
|
+
def trace_call(call_event, elapsed_before, receiver, ...)
|
49
|
+
return do_call(receiver, ...) unless call_event
|
46
50
|
|
47
|
-
start_time = AppMap::Util.gettime
|
51
|
+
start_time = AppMap::Util.gettime
|
48
52
|
begin
|
49
|
-
return_value = do_call(receiver,
|
53
|
+
return_value = do_call(receiver, ...)
|
50
54
|
rescue # rubocop:disable Style/RescueStandardError
|
51
55
|
exception = $ERROR_INFO
|
52
56
|
raise
|
53
57
|
ensure
|
54
|
-
after_start_time = AppMap::Util.gettime
|
55
|
-
|
56
|
-
|
58
|
+
after_start_time = AppMap::Util.gettime
|
59
|
+
begin
|
60
|
+
with_disabled_hook { after_hook receiver, call_event, elapsed_before, after_start_time - start_time, after_start_time, return_value, exception }
|
61
|
+
ensure
|
62
|
+
record_around_after
|
63
|
+
end
|
57
64
|
end
|
58
65
|
end
|
59
66
|
# rubocop:enable Metrics/MethodLength
|
data/lib/appmap/hook/method.rb
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "appmap/util"
|
4
4
|
|
5
5
|
module AppMap
|
6
6
|
class Hook
|
7
7
|
class << self
|
8
8
|
def method_hash_key(cls, method)
|
9
|
-
[
|
9
|
+
[cls, method.name].hash
|
10
10
|
rescue TypeError => e
|
11
11
|
warn "Error building hash key for #{cls}, #{method}: #{e}"
|
12
12
|
end
|
13
13
|
end
|
14
|
-
|
15
14
|
|
16
15
|
SIGNATURES = {}
|
17
16
|
LOOKUP_SIGNATURE = lambda do |id|
|
@@ -32,19 +31,20 @@ module AppMap
|
|
32
31
|
method
|
33
32
|
end
|
34
33
|
|
35
|
-
RUBY_MAJOR_VERSION, RUBY_MINOR_VERSION, _ = RUBY_VERSION.split(
|
34
|
+
RUBY_MAJOR_VERSION, RUBY_MINOR_VERSION, _ = RUBY_VERSION.split(".").map(&:to_i)
|
36
35
|
|
37
36
|
# Single hooked method.
|
38
37
|
# Call #activate to override the original.
|
39
38
|
class Method
|
40
|
-
attr_reader :hook_package, :hook_class, :hook_method, :parameters, :arity
|
39
|
+
attr_reader :hook_package, :hook_class, :hook_method, :record_around, :parameters, :arity
|
41
40
|
|
42
|
-
HOOK_DISABLE_KEY =
|
41
|
+
HOOK_DISABLE_KEY = "AppMap::Hook.disable"
|
43
42
|
|
44
|
-
def initialize(hook_package, hook_class, hook_method)
|
43
|
+
def initialize(hook_package, hook_class, hook_method, record_around: false)
|
45
44
|
@hook_package = hook_package
|
46
45
|
@hook_class = hook_class
|
47
46
|
@hook_method = hook_method
|
47
|
+
@record_around = record_around
|
48
48
|
@parameters = hook_method.parameters
|
49
49
|
@arity = hook_method.arity
|
50
50
|
end
|
@@ -52,11 +52,11 @@ module AppMap
|
|
52
52
|
def activate
|
53
53
|
if HookLog.enabled?
|
54
54
|
msg = if method_display_name
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
HookLog.log "Hooking #{msg} at line #{(hook_method.source_location || []).join(
|
55
|
+
"#{method_display_name}"
|
56
|
+
else
|
57
|
+
"#{hook_method.name} (class resolution deferred)"
|
58
|
+
end
|
59
|
+
HookLog.log "Hooking #{msg} at line #{(hook_method.source_location || []).join(":")}"
|
60
60
|
end
|
61
61
|
|
62
62
|
hook_method_parameters = hook_method.parameters.dup.freeze
|
@@ -79,13 +79,13 @@ module AppMap
|
|
79
79
|
|
80
80
|
def defining_class(hook_class)
|
81
81
|
cls = if RUBY_MAJOR_VERSION == 2 && RUBY_MINOR_VERSION <= 5
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
82
|
+
hook_class
|
83
|
+
.ancestors
|
84
|
+
.select { |cls| cls.method_defined?(hook_method.name) }
|
85
|
+
.find { |cls| cls.instance_method(hook_method.name).owner == cls }
|
86
|
+
else
|
87
|
+
hook_class.ancestors.find { |cls| cls.method_defined?(hook_method.name, false) }
|
88
|
+
end
|
89
89
|
|
90
90
|
return cls if cls
|
91
91
|
|
@@ -93,7 +93,7 @@ module AppMap
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def trace?
|
96
|
-
return false unless AppMap.tracing_enabled?
|
96
|
+
return false unless AppMap.tracing_enabled?(thread: Thread.current)
|
97
97
|
return false if Thread.current[HOOK_DISABLE_KEY]
|
98
98
|
return false if hook_package&.shallow? && AppMap.tracing.last_package_for_current_thread == hook_package
|
99
99
|
|
@@ -103,7 +103,7 @@ module AppMap
|
|
103
103
|
def method_display_name
|
104
104
|
return @method_display_name if @method_display_name
|
105
105
|
|
106
|
-
return @method_display_name = [defined_class,
|
106
|
+
return @method_display_name = [defined_class, "#", hook_method.name].join if defined_class
|
107
107
|
|
108
108
|
"#{hook_method.name} (class resolution deferred)"
|
109
109
|
end
|
@@ -114,7 +114,7 @@ module AppMap
|
|
114
114
|
|
115
115
|
def after_hook(_receiver, call_event, elapsed_before, elapsed, after_start_time, return_value, exception)
|
116
116
|
return_event = handle_return(call_event.id, elapsed, return_value, exception)
|
117
|
-
return_event.elapsed_instrumentation = elapsed_before + (AppMap::Util.gettime
|
117
|
+
return_event.elapsed_instrumentation = elapsed_before + (AppMap::Util.gettime - after_start_time)
|
118
118
|
AppMap.tracing.record_event(return_event) if return_event
|
119
119
|
end
|
120
120
|
|
@@ -141,20 +141,20 @@ module AppMap
|
|
141
141
|
end
|
142
142
|
end
|
143
143
|
|
144
|
-
unless ENV[
|
144
|
+
unless ENV["APPMAP_NO_PATCH_OBJECT"] == "true"
|
145
145
|
class Object
|
146
146
|
prepend AppMap::ObjectMethods
|
147
147
|
end
|
148
148
|
end
|
149
149
|
|
150
|
-
unless ENV[
|
150
|
+
unless ENV["APPMAP_NO_PATCH_MODULE"] == "true"
|
151
151
|
class Module
|
152
152
|
prepend AppMap::ModuleMethods
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
156
|
-
if RUBY_VERSION <
|
157
|
-
require
|
156
|
+
if RUBY_VERSION < "3"
|
157
|
+
require "appmap/hook/method/ruby2"
|
158
158
|
else
|
159
|
-
require
|
159
|
+
require "appmap/hook/method/ruby3"
|
160
160
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module AppMap
|
2
|
+
class Hook
|
3
|
+
# Start and stop a recording around a Hook::Method.
|
4
|
+
module RecordAround
|
5
|
+
APPMAP_OUTPUT_DIR = File.join(AppMap.output_dir, "requests")
|
6
|
+
|
7
|
+
# Context for a recording.
|
8
|
+
class Context
|
9
|
+
attr_reader :hook_method
|
10
|
+
|
11
|
+
def initialize(hook_method)
|
12
|
+
@hook_method = hook_method
|
13
|
+
@start_time = DateTime.now
|
14
|
+
@tracer = AppMap.tracing.trace(thread: Thread.current)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Finish recording the AppMap by collecting the events and classMap and writing the output file.
|
18
|
+
# rubocop:disable Metrics/MethodLength
|
19
|
+
# rubocop:disable Metrics/AbcSize
|
20
|
+
def finish
|
21
|
+
return unless @tracer
|
22
|
+
|
23
|
+
tracer = @tracer
|
24
|
+
@tracer = nil
|
25
|
+
AppMap.tracing.delete(tracer)
|
26
|
+
|
27
|
+
events = tracer.events.map(&:to_h)
|
28
|
+
|
29
|
+
timestamp = DateTime.now
|
30
|
+
appmap_name = "#{hook_method.name} (#{Thread.current.object_id}) - #{timestamp.strftime("%T.%L")}"
|
31
|
+
appmap_file_name = AppMap::Util.scenario_filename([timestamp.to_f, hook_method.name, Thread.current.object_id].join("_"))
|
32
|
+
|
33
|
+
metadata = AppMap.detect_metadata.tap do |metadata|
|
34
|
+
metadata[:name] = appmap_name
|
35
|
+
metadata[:source_location] = hook_method.source_location
|
36
|
+
metadata[:recorder] = {
|
37
|
+
name: "command",
|
38
|
+
type: "requests"
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
appmap = {
|
43
|
+
version: AppMap::APPMAP_FORMAT_VERSION,
|
44
|
+
classMap: AppMap.class_map(tracer.event_methods),
|
45
|
+
metadata: metadata,
|
46
|
+
events: events
|
47
|
+
}
|
48
|
+
|
49
|
+
AppMap::Util.write_appmap(File.join(APPMAP_OUTPUT_DIR, appmap_file_name), appmap)
|
50
|
+
end
|
51
|
+
# rubocop:enable Metrics/MethodLength
|
52
|
+
# rubocop:enable Metrics/AbcSize
|
53
|
+
end
|
54
|
+
|
55
|
+
# If requests recording is enabled, and we encounter a method which should always be recorded
|
56
|
+
# when requests recording is on, and there is no other recording in progress, then start a
|
57
|
+
# new recording and end it when the method returns.
|
58
|
+
def record_around?
|
59
|
+
(record_around && AppMap.recording_enabled?(:requests) && !AppMap.tracing_enabled?(thread: Thread.current))
|
60
|
+
end
|
61
|
+
|
62
|
+
def record_around_before
|
63
|
+
return unless record_around?
|
64
|
+
|
65
|
+
@record_around_context = Context.new(hook_method)
|
66
|
+
end
|
67
|
+
|
68
|
+
def record_around_after
|
69
|
+
return unless @record_around_context
|
70
|
+
|
71
|
+
context = @record_around_context
|
72
|
+
@record_around_context = nil
|
73
|
+
context.finish
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|