debug_logging 3.1.1 → 3.1.7
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 +8 -0
- data/.rubocop_todo.yml +97 -63
- data/.travis.yml +2 -2
- data/README.md +91 -30
- data/debug_logging.gemspec +6 -3
- data/lib/debug_logging.rb +159 -106
- data/lib/debug_logging/argument_printer.rb +89 -26
- data/lib/debug_logging/class_logger.rb +48 -61
- data/lib/debug_logging/class_notifier.rb +39 -41
- data/lib/debug_logging/configuration.rb +4 -27
- data/lib/debug_logging/constants.rb +33 -0
- data/lib/debug_logging/errors.rb +7 -0
- data/lib/debug_logging/finalize.rb +20 -0
- data/lib/debug_logging/hooks.rb +82 -0
- data/lib/debug_logging/instance_logger.rb +3 -1
- data/lib/debug_logging/instance_logger_modulizer.rb +27 -39
- data/lib/debug_logging/instance_notifier.rb +6 -2
- data/lib/debug_logging/instance_notifier_modulizer.rb +33 -44
- data/lib/debug_logging/util.rb +75 -0
- data/lib/debug_logging/version.rb +1 -1
- metadata +56 -8
@@ -2,52 +2,32 @@
|
|
2
2
|
|
3
3
|
module DebugLogging
|
4
4
|
module InstanceLoggerModulizer
|
5
|
-
def self.to_mod(methods_to_log: nil, config: nil)
|
5
|
+
def self.to_mod(methods_to_log: nil, payload: nil, config: nil)
|
6
6
|
Module.new do
|
7
|
+
methods_to_log, payload, config_opts = DebugLogging::Util.extract_payload_and_config(
|
8
|
+
method_names: Array(methods_to_log),
|
9
|
+
payload: payload,
|
10
|
+
config: config
|
11
|
+
)
|
7
12
|
Array(methods_to_log).each do |method_to_log|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
# method name must be a symbol
|
14
|
-
method_to_log = if method_to_log.is_a?(Array)
|
15
|
-
method_to_log.first&.to_sym
|
16
|
-
else
|
17
|
-
method_to_log.to_sym
|
18
|
-
end
|
13
|
+
method_to_log, method_payload, method_config_opts = DebugLogging::Util.extract_payload_and_config(
|
14
|
+
method_names: method_to_log,
|
15
|
+
payload: payload,
|
16
|
+
config: config_opts
|
17
|
+
)
|
19
18
|
define_method(method_to_log) do |*args, &block|
|
20
19
|
method_return_value = nil
|
21
|
-
config_proxy =
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
elsif !config_opts.empty?
|
28
|
-
Configuration.new(**self.class.debug_config.to_hash.merge(config_opts))
|
29
|
-
else
|
30
|
-
self.class.debug_config
|
31
|
-
end
|
32
|
-
proxy.register(method_to_log)
|
33
|
-
instance_variable_set(DebugLogging::Configuration.config_pointer('ilm', method_to_log),
|
34
|
-
proxy)
|
35
|
-
proxy
|
36
|
-
end
|
20
|
+
config_proxy = DebugLogging::Util.config_proxy_finder(
|
21
|
+
scope: self.class,
|
22
|
+
config_opts: method_config_opts,
|
23
|
+
method_name: method_to_log,
|
24
|
+
proxy_ref: 'ilm'
|
25
|
+
)
|
37
26
|
log_prefix = self.class.debug_invocation_to_s(klass: self.class.to_s, separator: '#',
|
38
27
|
method_to_log: method_to_log, config_proxy: config_proxy)
|
39
28
|
invocation_id = self.class.debug_invocation_id_to_s(args: args, config_proxy: config_proxy)
|
40
29
|
config_proxy.log do
|
41
|
-
paydirt =
|
42
|
-
# TODO: Could make instance variable introspection configurable before or after method execution
|
43
|
-
if payload.key?(:instance_variables)
|
44
|
-
paydirt.merge!(payload.reject { |k| k == :instance_variables })
|
45
|
-
payload[:instance_variables].each do |k|
|
46
|
-
paydirt[k] = instance_variable_get("@#{k}") if instance_variable_defined?("@#{k}")
|
47
|
-
end
|
48
|
-
else
|
49
|
-
paydirt.merge!(payload)
|
50
|
-
end
|
30
|
+
paydirt = DebugLogging::Util.payload_instance_vaiable_hydration(scope: self, payload: method_payload)
|
51
31
|
signature = self.class.debug_signature_to_s(args: args, config_proxy: config_proxy)
|
52
32
|
paymud = debug_payload_to_s(payload: paydirt, config_proxy: config_proxy)
|
53
33
|
"#{log_prefix}#{signature}#{invocation_id} debug: #{paymud}"
|
@@ -60,7 +40,15 @@ module DebugLogging
|
|
60
40
|
"#{log_prefix} #{self.class.debug_benchmark_to_s(tms: tms)}#{invocation_id}"
|
61
41
|
end
|
62
42
|
else
|
63
|
-
|
43
|
+
begin
|
44
|
+
method_return_value = super(*args, &block)
|
45
|
+
rescue => error
|
46
|
+
if config_proxy.error_handler_proc
|
47
|
+
config_proxy.error_handler_proc.call(config_proxy, error, self)
|
48
|
+
else
|
49
|
+
raise error
|
50
|
+
end
|
51
|
+
end
|
64
52
|
if config_proxy.exit_scope_markable? && invocation_id && !invocation_id.empty?
|
65
53
|
config_proxy.log do
|
66
54
|
"#{log_prefix} completed#{invocation_id}"
|
@@ -2,8 +2,10 @@
|
|
2
2
|
|
3
3
|
module DebugLogging
|
4
4
|
class InstanceNotifier < Module
|
5
|
-
def initialize(i_methods: nil)
|
5
|
+
def initialize(i_methods: nil, payload: nil, config: nil)
|
6
6
|
super()
|
7
|
+
@config = config
|
8
|
+
@payload = payload
|
7
9
|
@instance_methods_to_notify = Array(i_methods) if i_methods
|
8
10
|
end
|
9
11
|
|
@@ -11,7 +13,9 @@ module DebugLogging
|
|
11
13
|
return unless @instance_methods_to_notify
|
12
14
|
|
13
15
|
base.send(:include, ArgumentPrinter)
|
14
|
-
instance_method_notifier = DebugLogging::InstanceNotifierModulizer.to_mod(methods_to_notify: @instance_methods_to_notify
|
16
|
+
instance_method_notifier = DebugLogging::InstanceNotifierModulizer.to_mod(methods_to_notify: @instance_methods_to_notify,
|
17
|
+
payload: @payload,
|
18
|
+
config: @config)
|
15
19
|
base.send(:prepend, instance_method_notifier)
|
16
20
|
end
|
17
21
|
end
|
@@ -2,61 +2,50 @@
|
|
2
2
|
|
3
3
|
module DebugLogging
|
4
4
|
module InstanceNotifierModulizer
|
5
|
-
def self.to_mod(methods_to_notify: nil)
|
5
|
+
def self.to_mod(methods_to_notify: nil, payload: nil, config: nil)
|
6
6
|
Module.new do
|
7
|
-
|
8
|
-
|
7
|
+
methods_to_notify, payload, config_opts = DebugLogging::Util.extract_payload_and_config(
|
8
|
+
method_names: Array(methods_to_notify),
|
9
|
+
payload: payload,
|
10
|
+
config: config
|
11
|
+
)
|
9
12
|
Array(methods_to_notify).each do |method_to_notify|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
method_to_notify = if method_to_notify.is_a?(Array)
|
17
|
-
method_to_notify.first&.to_sym
|
18
|
-
else
|
19
|
-
method_to_notify.to_sym
|
20
|
-
end
|
13
|
+
method_to_notify, method_payload, method_config_opts = DebugLogging::Util.extract_payload_and_config(
|
14
|
+
method_names: method_to_notify,
|
15
|
+
payload: payload,
|
16
|
+
config: config_opts
|
17
|
+
)
|
21
18
|
define_method(method_to_notify) do |*args, &block|
|
22
|
-
config_proxy =
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
)
|
35
|
-
proxy
|
36
|
-
end
|
37
|
-
paydirt = {}
|
38
|
-
if payload.key?(:instance_variables)
|
39
|
-
paydirt.merge!(payload.reject { |k| k == :instance_variables })
|
40
|
-
payload[:instance_variables].each do |k|
|
41
|
-
paydirt[k] = instance_variable_get("@#{k}") if instance_variable_defined?("@#{k}")
|
19
|
+
config_proxy = DebugLogging::Util.config_proxy_finder(
|
20
|
+
scope: self.class,
|
21
|
+
config_opts: method_config_opts,
|
22
|
+
method_name: method_to_notify,
|
23
|
+
proxy_ref: 'inm'
|
24
|
+
) do |config_proxy|
|
25
|
+
ActiveSupport::Notifications.subscribe(
|
26
|
+
DebugLogging::ArgumentPrinter.debug_event_name_to_s(method_to_notify: method_to_notify)
|
27
|
+
) do |*args|
|
28
|
+
config_proxy&.log do
|
29
|
+
DebugLogging::LogSubscriber.log_event(ActiveSupport::Notifications::Event.new(*args))
|
30
|
+
end
|
42
31
|
end
|
43
|
-
else
|
44
|
-
paydirt.merge!(payload)
|
45
32
|
end
|
33
|
+
paydirt = DebugLogging::Util.payload_instance_vaiable_hydration(scope: self, payload: method_payload)
|
46
34
|
ActiveSupport::Notifications.instrument(
|
47
35
|
DebugLogging::ArgumentPrinter.debug_event_name_to_s(method_to_notify: method_to_notify),
|
48
36
|
debug_args: args,
|
49
37
|
config_proxy: config_proxy,
|
50
38
|
**paydirt
|
51
39
|
) do
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
40
|
+
begin
|
41
|
+
super(*args, &block)
|
42
|
+
rescue => error
|
43
|
+
if config_proxy.error_handler_proc
|
44
|
+
config_proxy.error_handler_proc.call(config_proxy, error, self)
|
45
|
+
else
|
46
|
+
raise error
|
47
|
+
end
|
48
|
+
end
|
60
49
|
end
|
61
50
|
end
|
62
51
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module DebugLogging
|
2
|
+
module Util
|
3
|
+
module_function
|
4
|
+
|
5
|
+
# methods_to_log may be an array of a single method name, followed by config options and payload,
|
6
|
+
# or it could be an array of method names followed by config options and payload to be shared by the whole set.
|
7
|
+
def extract_payload_and_config(method_names:, payload: nil, config: nil)
|
8
|
+
# When scoped config is present it will always be a new configuration instance per method
|
9
|
+
# When scoped config is not present it will reuse the class' configuration object
|
10
|
+
scoped_payload = (method_names.is_a?(Array) && method_names.last.is_a?(Hash) && method_names.pop.clone(freeze: false)) || {}
|
11
|
+
payload = if payload
|
12
|
+
payload.merge(scoped_payload)
|
13
|
+
else
|
14
|
+
scoped_payload
|
15
|
+
end
|
16
|
+
config_opts = config&.clone(freeze: false) || {}
|
17
|
+
unless payload.empty?
|
18
|
+
DebugLogging::Configuration::CONFIG_KEYS.each { |k| config_opts[k] = payload.delete(k) if payload.key?(k) }
|
19
|
+
end
|
20
|
+
method_names =
|
21
|
+
case method_names
|
22
|
+
when Symbol
|
23
|
+
method_names
|
24
|
+
when String
|
25
|
+
method_names.to_sym
|
26
|
+
when Array
|
27
|
+
if method_names.first.is_a?(Array)
|
28
|
+
# Array of arrays?
|
29
|
+
method_names.shift
|
30
|
+
elsif method_names.size == 1 && method_names.first.is_a?(Symbol)
|
31
|
+
# when set as i_methods: [[:i_with_dsplat_payload, { tags: %w[blue green] }], ...]
|
32
|
+
method_names.shift.to_sym
|
33
|
+
else
|
34
|
+
# Or an array of method name symbols?
|
35
|
+
# logged :meth1, :meth2, :meth3 without options is valid
|
36
|
+
method_names
|
37
|
+
end
|
38
|
+
end
|
39
|
+
[method_names, payload, config_opts]
|
40
|
+
end
|
41
|
+
|
42
|
+
def payload_instance_vaiable_hydration(scope:, payload:)
|
43
|
+
paydirt = {}
|
44
|
+
# TODO: Could make instance variable introspection configurable before or after method execution
|
45
|
+
if payload.key?(:instance_variables)
|
46
|
+
paydirt.merge!(payload.reject { |k| k == :instance_variables })
|
47
|
+
payload[:instance_variables].each do |k|
|
48
|
+
paydirt[k] = scope.send(:instance_variable_get, "@#{k}") if scope.send(:instance_variable_defined?, "@#{k}")
|
49
|
+
end
|
50
|
+
else
|
51
|
+
paydirt.merge!(payload)
|
52
|
+
end
|
53
|
+
paydirt
|
54
|
+
end
|
55
|
+
|
56
|
+
def config_proxy_finder(scope:, method_name:, proxy_ref:, config_opts: {}, &block)
|
57
|
+
if (proxy = scope.send(:instance_variable_get, DebugLogging::Configuration.config_pointer(proxy_ref,
|
58
|
+
method_name)))
|
59
|
+
proxy
|
60
|
+
else
|
61
|
+
base = scope.respond_to?(:debug_config) ? scope.debug_config : DebugLogging.debug_logging_configuration
|
62
|
+
proxy = if config_opts.empty?
|
63
|
+
base
|
64
|
+
else
|
65
|
+
DebugLogging::Configuration.new(**base.to_hash.merge(config_opts))
|
66
|
+
end
|
67
|
+
proxy.register(method_name)
|
68
|
+
scope.send(:instance_variable_set, DebugLogging::Configuration.config_pointer(proxy_ref, method_name),
|
69
|
+
proxy)
|
70
|
+
yield proxy if block
|
71
|
+
proxy
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: debug_logging
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.
|
4
|
+
version: 3.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Boling
|
8
|
+
- guckin
|
8
9
|
autorequire:
|
9
10
|
bindir: exe
|
10
11
|
cert_chain: []
|
11
|
-
date: 2020-12-
|
12
|
+
date: 2020-12-19 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: colorize
|
@@ -116,32 +117,74 @@ dependencies:
|
|
116
117
|
version: '0'
|
117
118
|
- !ruby/object:Gem::Dependency
|
118
119
|
name: rubocop
|
120
|
+
requirement: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.0'
|
125
|
+
type: :development
|
126
|
+
prerelease: false
|
127
|
+
version_requirements: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '1.0'
|
132
|
+
- !ruby/object:Gem::Dependency
|
133
|
+
name: rubocop-md
|
119
134
|
requirement: !ruby/object:Gem::Requirement
|
120
135
|
requirements:
|
121
136
|
- - ">="
|
122
137
|
- !ruby/object:Gem::Version
|
123
|
-
version: '0
|
138
|
+
version: '0'
|
124
139
|
type: :development
|
125
140
|
prerelease: false
|
126
141
|
version_requirements: !ruby/object:Gem::Requirement
|
127
142
|
requirements:
|
128
143
|
- - ">="
|
129
144
|
- !ruby/object:Gem::Version
|
130
|
-
version: '0
|
145
|
+
version: '0'
|
131
146
|
- !ruby/object:Gem::Dependency
|
132
|
-
name: rubocop-
|
147
|
+
name: rubocop-performance
|
133
148
|
requirement: !ruby/object:Gem::Requirement
|
134
149
|
requirements:
|
135
150
|
- - ">="
|
136
151
|
- !ruby/object:Gem::Version
|
137
|
-
version: '
|
152
|
+
version: '0'
|
138
153
|
type: :development
|
139
154
|
prerelease: false
|
140
155
|
version_requirements: !ruby/object:Gem::Requirement
|
141
156
|
requirements:
|
142
157
|
- - ">="
|
143
158
|
- !ruby/object:Gem::Version
|
144
|
-
version: '
|
159
|
+
version: '0'
|
160
|
+
- !ruby/object:Gem::Dependency
|
161
|
+
name: rubocop-rake
|
162
|
+
requirement: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
type: :development
|
168
|
+
prerelease: false
|
169
|
+
version_requirements: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: rubocop-rspec
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '2.0'
|
181
|
+
type: :development
|
182
|
+
prerelease: false
|
183
|
+
version_requirements: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - "~>"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '2.0'
|
145
188
|
- !ruby/object:Gem::Dependency
|
146
189
|
name: silent_stream
|
147
190
|
requirement: !ruby/object:Gem::Requirement
|
@@ -184,11 +227,16 @@ files:
|
|
184
227
|
- lib/debug_logging/class_logger.rb
|
185
228
|
- lib/debug_logging/class_notifier.rb
|
186
229
|
- lib/debug_logging/configuration.rb
|
230
|
+
- lib/debug_logging/constants.rb
|
231
|
+
- lib/debug_logging/errors.rb
|
232
|
+
- lib/debug_logging/finalize.rb
|
233
|
+
- lib/debug_logging/hooks.rb
|
187
234
|
- lib/debug_logging/instance_logger.rb
|
188
235
|
- lib/debug_logging/instance_logger_modulizer.rb
|
189
236
|
- lib/debug_logging/instance_notifier.rb
|
190
237
|
- lib/debug_logging/instance_notifier_modulizer.rb
|
191
238
|
- lib/debug_logging/log_subscriber.rb
|
239
|
+
- lib/debug_logging/util.rb
|
192
240
|
- lib/debug_logging/version.rb
|
193
241
|
- lib/simple_debug_logging.rb
|
194
242
|
homepage: https://github.com/pboling/debug_logging
|
@@ -210,7 +258,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
210
258
|
- !ruby/object:Gem::Version
|
211
259
|
version: '0'
|
212
260
|
requirements: []
|
213
|
-
rubygems_version: 3.1
|
261
|
+
rubygems_version: 3.2.1
|
214
262
|
signing_key:
|
215
263
|
specification_version: 4
|
216
264
|
summary: Drop-in debug logging useful when a call stack gets unruly
|