debug_logging 3.1.9 → 4.0.1
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
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +174 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/LICENSE.txt +1 -1
- data/README.md +89 -47
- data/SECURITY.md +2 -2
- data/lib/debug_logging/active_support_notifications.rb +0 -2
- data/lib/debug_logging/argument_printer.rb +25 -19
- data/lib/debug_logging/class_logger.rb +1 -3
- data/lib/debug_logging/class_notifier.rb +11 -15
- data/lib/debug_logging/configuration.rb +27 -20
- data/lib/debug_logging/constants.rb +11 -9
- data/lib/debug_logging/finalize.rb +0 -2
- data/lib/debug_logging/hooks.rb +12 -16
- data/lib/debug_logging/instance_logger.rb +45 -19
- data/lib/debug_logging/instance_logger_modulizer.rb +55 -51
- data/lib/debug_logging/instance_notifier.rb +18 -18
- data/lib/debug_logging/instance_notifier_modulizer.rb +35 -41
- data/lib/debug_logging/log_subscriber.rb +2 -4
- data/lib/debug_logging/util.rb +17 -0
- data/lib/debug_logging/version.rb +1 -3
- data/lib/debug_logging.rb +45 -22
- data/lib/simple_debug_logging.rb +2 -4
- data.tar.gz.sig +0 -0
- metadata +14 -29
- metadata.gz.sig +0 -0
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
require "date"
|
4
2
|
require "time"
|
5
3
|
|
@@ -9,11 +7,13 @@ module DebugLogging
|
|
9
7
|
"completed in #{format("%f", tms.real)}s (#{format("%f", tms.total)}s CPU)"
|
10
8
|
end
|
11
9
|
|
12
|
-
def debug_invocation_id_to_s(args: nil, config_proxy: nil)
|
13
|
-
return "" unless args && config_proxy
|
10
|
+
def debug_invocation_id_to_s(args: nil, kwargs: nil, start_at: nil, config_proxy: nil)
|
11
|
+
return "" unless (args || kwargs) && config_proxy
|
14
12
|
|
15
13
|
if config_proxy.debug_add_invocation_id
|
16
|
-
|
14
|
+
time = start_at ? Util.debug_time(start_at) : Time.now
|
15
|
+
unique_id = (time.to_f.to_s % "%#-21a")[4..-4]
|
16
|
+
invocation = " ~#{args.object_id}|#{kwargs.object_id}@#{unique_id}~"
|
17
17
|
case config_proxy.debug_add_invocation_id
|
18
18
|
when true
|
19
19
|
invocation
|
@@ -25,21 +25,25 @@ module DebugLogging
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
|
28
|
+
# @return [String]
|
29
|
+
def debug_time_to_s(time_or_monotonic, config_proxy: nil)
|
30
|
+
return "" unless config_proxy&.debug_add_timestamp
|
31
|
+
return config_proxy.debug_time_formatter_proc.call(Time.now) unless time_or_monotonic
|
32
|
+
|
33
|
+
time = Util.debug_time(time_or_monotonic)
|
34
|
+
|
35
|
+
config_proxy.debug_time_formatter_proc.call(time)
|
36
|
+
end
|
37
|
+
|
38
|
+
# A custom time format will never apply here, because ActiveSupport::Notifications have a required time format
|
39
|
+
def debug_event_time_to_s(time_or_monotonic)
|
29
40
|
# Time format must match:
|
30
41
|
# \d{4,}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [-+]\d{4}
|
31
42
|
# YYYY-MM-DD HH:mm:ss +00:00
|
32
43
|
# strftime("%F %T %z")
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
when Time, DateTime
|
37
|
-
time_or_monotonic.strftime("%F %T %z")
|
38
|
-
when String
|
39
|
-
Time.parse(time_or_monotonic).strftime("%F %T %z")
|
40
|
-
else
|
41
|
-
time_or_monotonic
|
42
|
-
end
|
44
|
+
time_or_monotonic = Time.now if time_or_monotonic.nil? || (time_or_monotonic.respond_to?(:empty?) && time_or_monotonic.empty?)
|
45
|
+
time = Util.debug_time(time_or_monotonic)
|
46
|
+
DebugLogging::Constants::EVENT_TIME_FORMATTER.call(time)
|
43
47
|
end
|
44
48
|
|
45
49
|
def debug_invocation_to_s(klass: nil, separator: nil, method_to_log: nil, config_proxy: nil)
|
@@ -58,12 +62,14 @@ module DebugLogging
|
|
58
62
|
"#{klass_string}#{separator}#{method_string}"
|
59
63
|
end
|
60
64
|
|
61
|
-
def debug_signature_to_s(args: nil, config_proxy: nil) # rubocop:disable Metrics/CyclomaticComplexity
|
62
|
-
return "" unless args && config_proxy
|
65
|
+
def debug_signature_to_s(args: nil, kwargs: nil, config_proxy: nil) # rubocop:disable Metrics/CyclomaticComplexity
|
66
|
+
return "" unless (args || kwargs) && config_proxy
|
63
67
|
|
64
68
|
printed_args = ""
|
65
69
|
|
66
70
|
add_args_ellipsis = false
|
71
|
+
args = args.dup
|
72
|
+
args.push(kwargs) if kwargs
|
67
73
|
if config_proxy.debug_last_hash_to_s_proc && args[-1].is_a?(Hash)
|
68
74
|
add_other_args_ellipsis = false
|
69
75
|
if args.length > 1
|
@@ -188,7 +194,7 @@ module DebugLogging
|
|
188
194
|
proc_name: "add_payload",
|
189
195
|
proc: config_proxy.debug_add_payload,
|
190
196
|
args: payload,
|
191
|
-
max_length: config_proxy.
|
197
|
+
max_length: config_proxy.debug_payload_max_length,
|
192
198
|
)
|
193
199
|
printed_payload += printed
|
194
200
|
printed_payload += config_proxy.debug_ellipsis if add_payload_ellipsis
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module DebugLogging
|
4
2
|
module ClassLogger
|
5
3
|
def logged(*methods_to_log)
|
@@ -31,7 +29,7 @@ module DebugLogging
|
|
31
29
|
paydirt = DebugLogging::Util.payload_instance_variable_hydration(scope: self, payload: method_payload)
|
32
30
|
log_prefix = debug_invocation_to_s(
|
33
31
|
klass: to_s,
|
34
|
-
separator: "
|
32
|
+
separator: "::",
|
35
33
|
method_to_log: method_to_log,
|
36
34
|
config_proxy: config_proxy,
|
37
35
|
)
|
@@ -1,8 +1,6 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module DebugLogging
|
4
2
|
module ClassNotifier
|
5
|
-
def
|
3
|
+
def notified(*methods_to_notify)
|
6
4
|
methods_to_notify, payload, config_opts = DebugLogging::Util.extract_payload_and_config(
|
7
5
|
method_names: methods_to_notify,
|
8
6
|
payload: nil,
|
@@ -40,18 +38,16 @@ module DebugLogging
|
|
40
38
|
**paydirt,
|
41
39
|
},
|
42
40
|
) do
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
raise e
|
54
|
-
end
|
41
|
+
if args.size == 1 && (harsh = args[0]) && harsh.is_a?(Hash)
|
42
|
+
original_method.call(**harsh, &block)
|
43
|
+
else
|
44
|
+
original_method.call(*args, &block)
|
45
|
+
end
|
46
|
+
rescue StandardError => e
|
47
|
+
if config_proxy.error_handler_proc
|
48
|
+
config_proxy.error_handler_proc.call(config_proxy, e, self, method_to_notify, args)
|
49
|
+
else
|
50
|
+
raise e
|
55
51
|
end
|
56
52
|
end
|
57
53
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module DebugLogging
|
4
2
|
class Configuration
|
5
3
|
include Constants
|
@@ -11,21 +9,29 @@ module DebugLogging
|
|
11
9
|
# alias the readers to the debug_* prefix so an instance of this class
|
12
10
|
# can have the same API granted by `extend DebugLogging`
|
13
11
|
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
12
|
+
# extend DebugLogging::InstanceLogger
|
13
|
+
# i_logged [:drive, :stop],
|
14
|
+
# {
|
15
|
+
# logger: Logger.new($stdout), # probably want to override to be the Rails.logger
|
16
|
+
# log_level: :debug, # at what level do the messages created by this gem sent at?
|
17
|
+
# multiple_last_hashes: false,
|
18
|
+
# last_hash_to_s_proc: nil, # e.g. ->(hash) { "keys: #{hash.keys}" }
|
19
|
+
# last_hash_max_length: 1_000,
|
20
|
+
# args_to_s_proc: nil, # e.g. ->(*record) { "record id: #{record.first.id}" }
|
21
|
+
# args_max_length: 1_000,
|
22
|
+
# colorized_chain_for_method: false, # e.g. ->(colorized_string) { colorized_string.red.on_blue.underline }
|
23
|
+
# colorized_chain_for_class: false, # e.g. ->(colorized_string) { colorized_string.colorize(:light_blue ).colorize( :background => :red) }
|
24
|
+
# add_invocation_id: true, # allows unique identification of method call; association of entry and exit log lines
|
25
|
+
# ellipsis: " ✂️ …".freeze,
|
26
|
+
# mark_scope_exit: false,
|
27
|
+
# add_payload: true, # Can also be a proc returning a string, which will be called when printing the payload
|
28
|
+
# payload_max_length: 1_000,
|
29
|
+
# error_handler_proc: nil,
|
30
|
+
# time_formatter_proc: DebugLogging::Constants::DEFAULT_TIME_FORMATTER,
|
31
|
+
# add_timestamp: false,
|
32
|
+
# instance_benchmarks: false,
|
33
|
+
# class_benchmarks: false,
|
27
34
|
# }
|
28
|
-
# )
|
29
35
|
#
|
30
36
|
CONFIG_KEYS.each do |key|
|
31
37
|
alias_method :"debug_#{key}", :"#{key}"
|
@@ -39,12 +45,13 @@ module DebugLogging
|
|
39
45
|
"@debug_logging_config_#{type}_#{Digest::MD5.hexdigest(method_to_log.to_s)}".to_sym
|
40
46
|
end
|
41
47
|
end
|
48
|
+
|
42
49
|
def initialize(**options)
|
43
50
|
CONFIG_ATTRS.each do |key|
|
44
|
-
send("#{key}=", get_attr_from_options(options, key))
|
51
|
+
send(:"#{key}=", get_attr_from_options(options, key))
|
45
52
|
end
|
46
53
|
CONFIG_READERS.each do |key|
|
47
|
-
send("#{key}=", get_reader_from_options(options, key))
|
54
|
+
send(:"#{key}=", get_reader_from_options(options, key))
|
48
55
|
end
|
49
56
|
@methods_to_log = []
|
50
57
|
end
|
@@ -63,7 +70,7 @@ module DebugLogging
|
|
63
70
|
def loggable?
|
64
71
|
return @loggable if defined?(@loggable)
|
65
72
|
|
66
|
-
@loggable = logger.send("#{log_level}?")
|
73
|
+
@loggable = logger.send(:"#{log_level}?")
|
67
74
|
end
|
68
75
|
|
69
76
|
def benchmarkable_for?(benchmarks)
|
@@ -95,7 +102,7 @@ module DebugLogging
|
|
95
102
|
|
96
103
|
def to_hash
|
97
104
|
CONFIG_KEYS.each_with_object({}) do |key, hash|
|
98
|
-
hash[key] = instance_variable_get("@#{key}")
|
105
|
+
hash[key] = instance_variable_get(:"@#{key}")
|
99
106
|
end
|
100
107
|
end
|
101
108
|
|
@@ -1,25 +1,27 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module DebugLogging
|
4
2
|
module Constants
|
5
3
|
DEFAULT_ELLIPSIS = " ✂️ …"
|
4
|
+
DEFAULT_TIME_FORMATTER = ->(time) { "[#{time.strftime("%Y%m%d %H:%M:%S")}] " }
|
5
|
+
EVENT_TIME_FORMATTER = ->(time) { time.strftime("%F %T %z") }
|
6
6
|
CONFIG_ATTRS_DEFAULTS = {
|
7
7
|
enabled: true,
|
8
|
-
logger: Logger.new($stdout),
|
9
|
-
log_level: :debug,
|
8
|
+
logger: Logger.new($stdout), # probably want to override to be the Rails.logger
|
9
|
+
log_level: :debug, # at what level do the messages created by this gem sent at?
|
10
10
|
multiple_last_hashes: false,
|
11
|
-
last_hash_to_s_proc: nil,
|
11
|
+
last_hash_to_s_proc: nil, # e.g. ->(hash) { "keys: #{hash.keys}" }
|
12
12
|
last_hash_max_length: 1_000,
|
13
|
-
args_to_s_proc: nil,
|
13
|
+
args_to_s_proc: nil, # e.g. ->(*record) { "record id: #{record.first.id}" }
|
14
14
|
args_max_length: 1_000,
|
15
|
-
colorized_chain_for_method: false,
|
16
|
-
colorized_chain_for_class: false,
|
17
|
-
add_invocation_id: true,
|
15
|
+
colorized_chain_for_method: false, # e.g. ->(colorized_string) { colorized_string.red.on_blue.underline }
|
16
|
+
colorized_chain_for_class: false, # e.g. ->(colorized_string) { colorized_string.colorize(:light_blue ).colorize( :background => :red) }
|
17
|
+
add_invocation_id: true, # allows unique identification of method call; association of entry and exit log lines
|
18
18
|
ellipsis: DEFAULT_ELLIPSIS,
|
19
19
|
mark_scope_exit: false,
|
20
20
|
add_payload: true, # Can also be a proc returning a string, which will be called when printing the payload
|
21
21
|
payload_max_length: 1_000,
|
22
22
|
error_handler_proc: nil,
|
23
|
+
time_formatter_proc: DEFAULT_TIME_FORMATTER,
|
24
|
+
add_timestamp: false,
|
23
25
|
}.freeze
|
24
26
|
CONFIG_ATTRS = CONFIG_ATTRS_DEFAULTS.keys
|
25
27
|
CONFIG_READERS_DEFAULTS = {
|
data/lib/debug_logging/hooks.rb
CHANGED
@@ -16,16 +16,14 @@ module DebugLogging
|
|
16
16
|
names.each do |name|
|
17
17
|
meth = instance_method(name)
|
18
18
|
define_method(name) do |*args, &block|
|
19
|
-
|
20
|
-
|
21
|
-
meth.bind(self).call(*args, &block)
|
22
|
-
end
|
23
|
-
rescue Timeout::Error
|
24
|
-
error_args = [TimeoutError, "execution expired", caller]
|
25
|
-
raise(*error_args) unless blk
|
26
|
-
|
27
|
-
instance_exec(*error_args, &blk)
|
19
|
+
Timeout.timeout(time) do
|
20
|
+
meth.bind_call(self, *args, &block)
|
28
21
|
end
|
22
|
+
rescue Timeout::Error
|
23
|
+
error_args = [TimeoutError, "execution expired", caller]
|
24
|
+
raise(*error_args) unless blk
|
25
|
+
|
26
|
+
instance_exec(*error_args, &blk)
|
29
27
|
end
|
30
28
|
end
|
31
29
|
end
|
@@ -39,11 +37,9 @@ module DebugLogging
|
|
39
37
|
names.each do |name|
|
40
38
|
meth = instance_method(name)
|
41
39
|
define_method(name) do |*args, &block|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
instance_exec(e, &blk)
|
46
|
-
end
|
40
|
+
meth.bind_call(self, *args, &block)
|
41
|
+
rescue StandardError => e
|
42
|
+
instance_exec(e, &blk)
|
47
43
|
end
|
48
44
|
end
|
49
45
|
end
|
@@ -58,7 +54,7 @@ module DebugLogging
|
|
58
54
|
meth = instance_method(name)
|
59
55
|
define_method(name) do |*args, &block|
|
60
56
|
instance_exec(name, *args, block, &blk)
|
61
|
-
meth.
|
57
|
+
meth.bind_call(self, *args, &block)
|
62
58
|
end
|
63
59
|
end
|
64
60
|
end
|
@@ -72,7 +68,7 @@ module DebugLogging
|
|
72
68
|
names.each do |name|
|
73
69
|
meth = instance_method(name)
|
74
70
|
define_method(name) do |*args, &block|
|
75
|
-
result = meth.
|
71
|
+
result = meth.bind_call(self, *args, &block)
|
76
72
|
instance_exec(result, &blk)
|
77
73
|
end
|
78
74
|
end
|
@@ -1,24 +1,50 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module DebugLogging
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
2
|
+
module InstanceLogger
|
3
|
+
# NOTE: These params can be passed in / hidden in a last hash of *args
|
4
|
+
# NOTE: They can also be passed in discretely for each method, by passing *args as an array of arrays
|
5
|
+
# TODO: Refactor to use modern Ruby 3 *args, **kwargs instead
|
6
|
+
# @param logger [Logger] Logger.new($stdout), # probably want to override to be the Rails.logger
|
7
|
+
# @param log_level [Symbol] default: :debug, at what level do the messages created by this gem sent at?
|
8
|
+
# @param multiple_last_hashes [true, false] default: false,
|
9
|
+
# @param last_hash_to_s_proc [nil, Proc] default: nil, e.g. ->(hash) { "keys: #{hash.keys}" }
|
10
|
+
# @param last_hash_max_length [Integer] default: 1_000,
|
11
|
+
# @param args_to_s_proc [nil, Proc] default: nil, e.g. ->(*record) { "record id: #{record.first.id}" }
|
12
|
+
# @param args_max_length [Integer] default: 1_000,
|
13
|
+
# @param colorized_chain_for_method [false, Proc] default: false, e.g. ->(colorized_string) { colorized_string.red.on_blue.underline }
|
14
|
+
# @param colorized_chain_for_class [false, Proc] default: false, e.g. ->(colorized_string) { colorized_string.colorize(:light_blue ).colorize( :background => :red) }
|
15
|
+
# @param add_invocation_id [true, false] default: true, allows unique identification of method call; association of entry and exit log lines
|
16
|
+
# @param ellipsis [String] default: " ✂️ …".freeze,
|
17
|
+
# @param mark_scope_exit [true, false] default: false,
|
18
|
+
# @param add_payload [true, false, Proc] default: true, # Can also be a proc returning a string, which will be called when printing the payload
|
19
|
+
# @param payload_max_length [Integer] default: 1_000,
|
20
|
+
# @param error_handler_proc [nil, Proc] default: nil,
|
21
|
+
# @param time_formatter_proc [nil, Proc] default: DebugLogging::Constants::DEFAULT_TIME_FORMATTER,
|
22
|
+
# @param add_timestamp [true, false] default: false,
|
23
|
+
# @param instance_benchmarks [true, false] default: false,
|
24
|
+
# @param class_benchmarks [true, false] default: false,
|
25
|
+
def i_logged(*methods_to_log)
|
26
|
+
methods_to_log, payload, config_opts = DebugLogging::Util.extract_payload_and_config(
|
27
|
+
method_names: methods_to_log,
|
28
|
+
payload: nil,
|
29
|
+
config: nil,
|
20
30
|
)
|
21
|
-
|
31
|
+
instance_method_modules =
|
32
|
+
Array(methods_to_log).map do |method_to_log|
|
33
|
+
DebugLogging::InstanceLoggerModulizer.to_mod(
|
34
|
+
methods_to_log: Array(method_to_log),
|
35
|
+
payload: payload,
|
36
|
+
config: config_opts,
|
37
|
+
)
|
38
|
+
end
|
39
|
+
wrapped_in_logs = Module.new do
|
40
|
+
singleton_class.send(:define_method, :included) do |host_class|
|
41
|
+
instance_method_modules.each do |mod|
|
42
|
+
host_class.prepend(mod)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
send(:include, wrapped_in_logs)
|
22
48
|
end
|
23
49
|
end
|
24
50
|
end
|
@@ -1,65 +1,69 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module DebugLogging
|
4
2
|
module InstanceLoggerModulizer
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
Array(methods_to_log).each do |method_to_log|
|
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,
|
3
|
+
class << self
|
4
|
+
def to_mod(methods_to_log: nil, payload: nil, config: nil)
|
5
|
+
Module.new do
|
6
|
+
methods_to_log, payload, config_opts = DebugLogging::Util.extract_payload_and_config(
|
7
|
+
method_names: Array(methods_to_log),
|
8
|
+
payload:,
|
9
|
+
config:,
|
17
10
|
)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
method_name: method_to_log,
|
24
|
-
proxy_ref: "ilm",
|
11
|
+
Array(methods_to_log).each do |method_to_log|
|
12
|
+
method_to_log, method_payload, method_config_opts = DebugLogging::Util.extract_payload_and_config(
|
13
|
+
method_names: method_to_log,
|
14
|
+
payload:,
|
15
|
+
config: config_opts,
|
25
16
|
)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
17
|
+
define_method(method_to_log) do |*args, **kwargs, &block|
|
18
|
+
method_return_value = nil
|
19
|
+
config_proxy = DebugLogging::Util.config_proxy_finder(
|
20
|
+
scope: self.class,
|
21
|
+
config_opts: method_config_opts,
|
22
|
+
method_name: method_to_log,
|
23
|
+
proxy_ref: "ilm",
|
24
|
+
)
|
25
|
+
log_prefix = self.class.debug_invocation_to_s(
|
26
|
+
klass: self.class.to_s,
|
27
|
+
separator: "#",
|
28
|
+
method_to_log: method_to_log,
|
29
|
+
config_proxy: config_proxy,
|
30
|
+
)
|
31
|
+
start_at = Time.now
|
32
|
+
start_timestamp = self.class.debug_time_to_s(start_at, config_proxy:)
|
33
|
+
invocation_id = self.class.debug_invocation_id_to_s(args:, kwargs:, start_at:, config_proxy:)
|
43
34
|
config_proxy.log do
|
44
|
-
|
35
|
+
paydirt = DebugLogging::Util.payload_instance_variable_hydration(scope: self, payload: method_payload)
|
36
|
+
signature = self.class.debug_signature_to_s(args:, kwargs:, config_proxy:)
|
37
|
+
paymud = debug_payload_to_s(payload: paydirt, config_proxy:)
|
38
|
+
"#{start_timestamp}#{log_prefix}#{signature}#{invocation_id} debug: #{paymud}"
|
45
39
|
end
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
rescue StandardError => e
|
50
|
-
if config_proxy.error_handler_proc
|
51
|
-
config_proxy.error_handler_proc.call(config_proxy, e, self, method_to_log, args)
|
52
|
-
else
|
53
|
-
raise e
|
40
|
+
if config_proxy.benchmarkable_for?(:debug_instance_benchmarks)
|
41
|
+
tms = Benchmark.measure do
|
42
|
+
method_return_value = super(*args, **kwargs, &block)
|
54
43
|
end
|
55
|
-
|
56
|
-
if config_proxy.exit_scope_markable? && invocation_id && !invocation_id.empty?
|
44
|
+
end_timestamp = self.class.debug_time_to_s(Time.now, config_proxy:)
|
57
45
|
config_proxy.log do
|
58
|
-
"#{log_prefix}
|
46
|
+
"#{end_timestamp}#{log_prefix} #{self.class.debug_benchmark_to_s(tms: tms)}#{invocation_id}"
|
47
|
+
end
|
48
|
+
else
|
49
|
+
begin
|
50
|
+
method_return_value = super(*args, **kwargs, &block)
|
51
|
+
rescue StandardError => e
|
52
|
+
if config_proxy.error_handler_proc
|
53
|
+
config_proxy.error_handler_proc.call(config_proxy, e, self, method_to_log, args, kwargs)
|
54
|
+
else
|
55
|
+
raise e
|
56
|
+
end
|
57
|
+
end
|
58
|
+
if config_proxy.exit_scope_markable? && invocation_id && !invocation_id.empty?
|
59
|
+
end_timestamp = self.class.debug_time_to_s(Time.now, config_proxy:)
|
60
|
+
config_proxy.log do
|
61
|
+
"#{end_timestamp}#{log_prefix} completed#{invocation_id}"
|
62
|
+
end
|
59
63
|
end
|
60
64
|
end
|
65
|
+
method_return_value
|
61
66
|
end
|
62
|
-
method_return_value
|
63
67
|
end
|
64
68
|
end
|
65
69
|
end
|
@@ -1,24 +1,24 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module DebugLogging
|
4
|
-
|
5
|
-
def
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
def included(base)
|
13
|
-
return unless @instance_methods_to_notify
|
14
|
-
|
15
|
-
base.send(:include, ArgumentPrinter)
|
2
|
+
module InstanceNotifier
|
3
|
+
def i_notified(*methods_to_log)
|
4
|
+
method_names, payload, config_opts = DebugLogging::Util.extract_payload_and_config(
|
5
|
+
method_names: methods_to_log,
|
6
|
+
payload: nil,
|
7
|
+
config: nil,
|
8
|
+
)
|
16
9
|
instance_method_notifier = DebugLogging::InstanceNotifierModulizer.to_mod(
|
17
|
-
methods_to_notify:
|
18
|
-
payload:
|
19
|
-
config:
|
10
|
+
methods_to_notify: Array(method_names),
|
11
|
+
payload: payload,
|
12
|
+
config: config_opts,
|
20
13
|
)
|
21
|
-
|
14
|
+
|
15
|
+
wrapped_in_notifier = Module.new do
|
16
|
+
singleton_class.send(:define_method, :included) do |host_class|
|
17
|
+
host_class.prepend(instance_method_notifier)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
send(:include, wrapped_in_notifier)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -1,51 +1,45 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module DebugLogging
|
4
2
|
module InstanceNotifierModulizer
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
Array(methods_to_notify).each do |method_to_notify|
|
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,
|
3
|
+
class << self
|
4
|
+
def to_mod(methods_to_notify: nil, payload: nil, config: nil)
|
5
|
+
Module.new do
|
6
|
+
methods_to_notify, payload, config_opts = DebugLogging::Util.extract_payload_and_config(
|
7
|
+
method_names: Array(methods_to_notify),
|
8
|
+
payload:,
|
9
|
+
config:,
|
17
10
|
)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
) do |
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
11
|
+
Array(methods_to_notify).each do |method_to_notify|
|
12
|
+
method_to_notify, method_payload, method_config_opts = DebugLogging::Util.extract_payload_and_config(
|
13
|
+
method_names: method_to_notify,
|
14
|
+
payload:,
|
15
|
+
config: config_opts,
|
16
|
+
)
|
17
|
+
define_method(method_to_notify) do |*args, **kwargs, &block|
|
18
|
+
config_proxy = DebugLogging::Util.config_proxy_finder(
|
19
|
+
scope: self.class,
|
20
|
+
config_opts: method_config_opts,
|
21
|
+
method_name: method_to_notify,
|
22
|
+
proxy_ref: "inm",
|
23
|
+
) do |config_proxy|
|
24
|
+
ActiveSupport::Notifications.subscribe(
|
25
|
+
DebugLogging::ArgumentPrinter.debug_event_name_to_s(method_to_notify:),
|
26
|
+
) do |*subscribe_args|
|
27
|
+
config_proxy&.log do
|
28
|
+
DebugLogging::LogSubscriber.log_event(ActiveSupport::Notifications::Event.new(*subscribe_args))
|
29
|
+
end
|
30
30
|
end
|
31
31
|
end
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
begin
|
41
|
-
# TODO: I need to split logic based on Ruby version.
|
42
|
-
# TODO: Use VersionGem's minimum Ruby version check
|
43
|
-
# TODO: Switch between positional, and kwargs argument handling
|
44
|
-
# See: https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0/
|
45
|
-
super(*args, &block)
|
32
|
+
paydirt = DebugLogging::Util.payload_instance_variable_hydration(scope: self, payload: method_payload)
|
33
|
+
ActiveSupport::Notifications.instrument(
|
34
|
+
DebugLogging::ArgumentPrinter.debug_event_name_to_s(method_to_notify:),
|
35
|
+
debug_args: kwargs.empty? ? args : args + [kwargs],
|
36
|
+
config_proxy: config_proxy,
|
37
|
+
**paydirt,
|
38
|
+
) do
|
39
|
+
super(*args, **kwargs, &block)
|
46
40
|
rescue StandardError => e
|
47
41
|
if config_proxy.error_handler_proc
|
48
|
-
config_proxy.error_handler_proc.call(config_proxy, e, self, method_to_notify, args)
|
42
|
+
config_proxy.error_handler_proc.call(config_proxy, e, self, method_to_notify, args, kwargs)
|
49
43
|
else
|
50
44
|
raise e
|
51
45
|
end
|