debug_logging 3.1.9 → 4.0.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.
@@ -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,20 @@ 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
- # include DebugLogging::InstanceLogger.new(
15
- # i_methods: [:drive, :stop],
16
- # config: {
17
- # logger: Logger.new(STDOUT) # probably want to override to be the Rails.logger
18
- # log_level: :debug # at what level do the messages created by this gem sent at?
19
- # last_hash_to_s_proc: nil # e.g. ->(hash) { "keys: #{hash.keys}" }
20
- # last_hash_max_length: 1_000
21
- # args_to_s_proc: nil # e.g. ->(*record) { "record id: #{record.first.id}" }
22
- # args_max_length: 1_000
23
- # instance_benchmarks: false
24
- # class_benchmarks: false
25
- # add_invocation_id: true # invocation id allows you to identify a method call uniquely in a log
26
- # ellipsis: " ✂️ …".freeze
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
+ # last_hash_to_s_proc: nil # e.g. ->(hash) { "keys: #{hash.keys}" }
18
+ # last_hash_max_length: 1_000
19
+ # args_to_s_proc: nil # e.g. ->(*record) { "record id: #{record.first.id}" }
20
+ # args_max_length: 1_000
21
+ # instance_benchmarks: false
22
+ # class_benchmarks: false
23
+ # add_invocation_id: true # invocation id allows you to identify a method call uniquely in a log
24
+ # ellipsis: " ✂️ …".freeze
27
25
  # }
28
- # )
29
26
  #
30
27
  CONFIG_KEYS.each do |key|
31
28
  alias_method :"debug_#{key}", :"#{key}"
@@ -39,12 +36,13 @@ module DebugLogging
39
36
  "@debug_logging_config_#{type}_#{Digest::MD5.hexdigest(method_to_log.to_s)}".to_sym
40
37
  end
41
38
  end
39
+
42
40
  def initialize(**options)
43
41
  CONFIG_ATTRS.each do |key|
44
- send("#{key}=", get_attr_from_options(options, key))
42
+ send(:"#{key}=", get_attr_from_options(options, key))
45
43
  end
46
44
  CONFIG_READERS.each do |key|
47
- send("#{key}=", get_reader_from_options(options, key))
45
+ send(:"#{key}=", get_reader_from_options(options, key))
48
46
  end
49
47
  @methods_to_log = []
50
48
  end
@@ -63,7 +61,7 @@ module DebugLogging
63
61
  def loggable?
64
62
  return @loggable if defined?(@loggable)
65
63
 
66
- @loggable = logger.send("#{log_level}?")
64
+ @loggable = logger.send(:"#{log_level}?")
67
65
  end
68
66
 
69
67
  def benchmarkable_for?(benchmarks)
@@ -95,7 +93,7 @@ module DebugLogging
95
93
 
96
94
  def to_hash
97
95
  CONFIG_KEYS.each_with_object({}) do |key, hash|
98
- hash[key] = instance_variable_get("@#{key}")
96
+ hash[key] = instance_variable_get(:"@#{key}")
99
97
  end
100
98
  end
101
99
 
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module DebugLogging
4
2
  module Constants
5
3
  DEFAULT_ELLIPSIS = " ✂️ …"
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  # From: https://stackoverflow.com/a/34559282
4
2
  # License: https://creativecommons.org/licenses/by-sa/4.0/
5
3
  module DebugLogging
@@ -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
- begin
20
- Timeout.timeout(time) do
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
- begin
43
- meth.bind(self).call(*args, &block)
44
- rescue StandardError => e
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.bind(self).call(*args, &block)
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.bind(self).call(*args, &block)
71
+ result = meth.bind_call(self, *args, &block)
76
72
  instance_exec(result, &blk)
77
73
  end
78
74
  end
@@ -1,24 +1,28 @@
1
- # frozen_string_literal: true
2
-
3
1
  module DebugLogging
4
- class InstanceLogger < Module
5
- def initialize(i_methods: nil, payload: nil, config: nil)
6
- super()
7
- @config = config
8
- @payload = payload
9
- @instance_methods_to_log = Array(i_methods) if i_methods
10
- end
11
-
12
- def included(base)
13
- return unless @instance_methods_to_log
14
-
15
- base.send(:include, ArgumentPrinter)
16
- instance_method_logger = DebugLogging::InstanceLoggerModulizer.to_mod(
17
- methods_to_log: @instance_methods_to_log,
18
- payload: @payload,
19
- config: @config,
2
+ module InstanceLogger
3
+ def i_logged(*methods_to_log)
4
+ methods_to_log, payload, config_opts = DebugLogging::Util.extract_payload_and_config(
5
+ method_names: methods_to_log,
6
+ payload: nil,
7
+ config: nil,
20
8
  )
21
- base.send(:prepend, instance_method_logger)
9
+ instance_method_modules =
10
+ Array(methods_to_log).map do |method_to_log|
11
+ DebugLogging::InstanceLoggerModulizer.to_mod(
12
+ methods_to_log: Array(method_to_log),
13
+ payload: payload,
14
+ config: config_opts,
15
+ )
16
+ end
17
+ wrapped_in_logs = Module.new do
18
+ singleton_class.send(:define_method, :included) do |host_class|
19
+ instance_method_modules.each do |mod|
20
+ host_class.prepend(mod)
21
+ end
22
+ end
23
+ end
24
+
25
+ send(:include, wrapped_in_logs)
22
26
  end
23
27
  end
24
28
  end
@@ -1,65 +1,65 @@
1
- # frozen_string_literal: true
2
-
3
1
  module DebugLogging
4
2
  module InstanceLoggerModulizer
5
- def self.to_mod(methods_to_log: nil, payload: nil, config: nil)
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
- )
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
- define_method(method_to_log) do |*args, &block|
19
- method_return_value = nil
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",
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
- log_prefix = self.class.debug_invocation_to_s(
27
- klass: self.class.to_s,
28
- separator: "#",
29
- method_to_log: method_to_log,
30
- config_proxy: config_proxy,
31
- )
32
- invocation_id = self.class.debug_invocation_id_to_s(args: args, config_proxy: config_proxy)
33
- config_proxy.log do
34
- paydirt = DebugLogging::Util.payload_instance_variable_hydration(scope: self, payload: method_payload)
35
- signature = self.class.debug_signature_to_s(args: args, config_proxy: config_proxy)
36
- paymud = debug_payload_to_s(payload: paydirt, config_proxy: config_proxy)
37
- "#{log_prefix}#{signature}#{invocation_id} debug: #{paymud}"
38
- end
39
- if config_proxy.benchmarkable_for?(:debug_instance_benchmarks)
40
- tms = Benchmark.measure do
41
- method_return_value = super(*args, &block)
42
- end
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
+ invocation_id = self.class.debug_invocation_id_to_s(args:, kwargs:, config_proxy:)
43
32
  config_proxy.log do
44
- "#{log_prefix} #{self.class.debug_benchmark_to_s(tms: tms)}#{invocation_id}"
33
+ paydirt = DebugLogging::Util.payload_instance_variable_hydration(scope: self, payload: method_payload)
34
+ signature = self.class.debug_signature_to_s(args:, kwargs:, config_proxy:)
35
+ paymud = debug_payload_to_s(payload: paydirt, config_proxy:)
36
+ "#{log_prefix}#{signature}#{invocation_id} debug: #{paymud}"
45
37
  end
46
- else
47
- begin
48
- method_return_value = super(*args, &block)
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
38
+ if config_proxy.benchmarkable_for?(:debug_instance_benchmarks)
39
+ tms = Benchmark.measure do
40
+ method_return_value = super(*args, **kwargs, &block)
54
41
  end
55
- end
56
- if config_proxy.exit_scope_markable? && invocation_id && !invocation_id.empty?
57
42
  config_proxy.log do
58
- "#{log_prefix} completed#{invocation_id}"
43
+ "#{log_prefix} #{self.class.debug_benchmark_to_s(tms: tms)}#{invocation_id}"
44
+ end
45
+ else
46
+ begin
47
+ method_return_value = super(*args, **kwargs, &block)
48
+ rescue StandardError => e
49
+ if config_proxy.error_handler_proc
50
+ config_proxy.error_handler_proc.call(config_proxy, e, self, method_to_log, args, kwargs)
51
+ else
52
+ raise e
53
+ end
54
+ end
55
+ if config_proxy.exit_scope_markable? && invocation_id && !invocation_id.empty?
56
+ config_proxy.log do
57
+ "#{log_prefix} completed#{invocation_id}"
58
+ end
59
59
  end
60
60
  end
61
+ method_return_value
61
62
  end
62
- method_return_value
63
63
  end
64
64
  end
65
65
  end
@@ -1,24 +1,24 @@
1
- # frozen_string_literal: true
2
-
3
1
  module DebugLogging
4
- class InstanceNotifier < Module
5
- def initialize(i_methods: nil, payload: nil, config: nil)
6
- super()
7
- @config = config
8
- @payload = payload
9
- @instance_methods_to_notify = Array(i_methods) if i_methods
10
- end
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: @instance_methods_to_notify,
18
- payload: @payload,
19
- config: @config,
10
+ methods_to_notify: Array(method_names),
11
+ payload: payload,
12
+ config: config_opts,
20
13
  )
21
- base.send(:prepend, instance_method_notifier)
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
- def self.to_mod(methods_to_notify: nil, payload: nil, config: nil)
6
- Module.new do
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
- )
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
- define_method(method_to_notify) do |*args, &block|
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))
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
- end
33
- paydirt = DebugLogging::Util.payload_instance_variable_hydration(scope: self, payload: method_payload)
34
- ActiveSupport::Notifications.instrument(
35
- DebugLogging::ArgumentPrinter.debug_event_name_to_s(method_to_notify: method_to_notify),
36
- debug_args: args,
37
- config_proxy: config_proxy,
38
- **paydirt,
39
- ) do
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
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  require "active_support"
4
2
  require "active_support/log_subscriber"
5
3
 
@@ -14,6 +14,7 @@ module DebugLogging
14
14
  scoped_payload
15
15
  end
16
16
  config_opts = config&.clone(freeze: false) || {}
17
+ # puts "[EPAC] config: #{config}, scoped_payload: #{scoped_payload}, payload: #{payload}, config_opts: #{config_opts}"
17
18
  unless payload.empty?
18
19
  DebugLogging::Configuration::CONFIG_KEYS.each { |k| config_opts[k] = payload.delete(k) if payload.key?(k) }
19
20
  end
@@ -1,7 +1,5 @@
1
- # frozen_string_literal: true
2
-
3
1
  module DebugLogging
4
2
  module Version
5
- VERSION = "3.1.9"
3
+ VERSION = "4.0.0"
6
4
  end
7
5
  end
data/lib/debug_logging.rb CHANGED
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  # Std Lib
4
2
  require "logger"
5
3
  require "digest"
@@ -44,7 +42,8 @@ require "debug_logging/class_logger"
44
42
  #
45
43
  # # For instance methods:
46
44
  # # Option 1: specify the exact method(s) to add logging to
47
- # include DebugLogging::InstanceLogger.new(i_methods: [:drive, :stop])
45
+ # extend DebugLogging::InstanceLogger
46
+ # i_logged [:drive, :stop]
48
47
  #
49
48
  # # Provides the `logged` method decorator
50
49
  # extend DebugLogging::ClassLogger
@@ -59,7 +58,8 @@ require "debug_logging/class_logger"
59
58
  #
60
59
  # # For instance methods:
61
60
  # # Option 2: add logging to all instance methods defined above (but *not* defined below)
62
- # include DebugLogging::InstanceLogger.new(i_methods: self.instance_methods(false))
61
+ # extend DebugLogging::InstanceLogger
62
+ # i_logged instance_methods(false)
63
63
  #
64
64
  # def will_not_be_logged; false; end
65
65
  #
@@ -68,29 +68,36 @@ require "debug_logging/class_logger"
68
68
  ####################
69
69
 
70
70
  module DebugLogging
71
- def self.extended(base)
72
- base.send(:extend, ArgumentPrinter)
73
- base.send(:extend, ApiClassMethods)
74
- base.send(:extend, ConfigClassMethods)
75
- base.debug_config_reset(Configuration.new(**debug_logging_configuration.to_hash))
76
- base.class_eval do
77
- def base.inherited(subclass)
78
- subclass.debug_config_reset(Configuration.new(**debug_config.to_hash))
71
+ # We can't compare with nil to check for no arguments passed as a configuration value,
72
+ # because nil can be an argument passed, hence:
73
+ ACTUAL_NOTHING = Object.new
74
+
75
+ class << self
76
+ def extended(base)
77
+ base.send(:extend, ArgumentPrinter)
78
+ base.send(:include, ArgumentPrinter)
79
+ base.send(:extend, ApiClassMethods)
80
+ base.send(:extend, ConfigClassMethods)
81
+ base.debug_config_reset(Configuration.new(**debug_logging_configuration.to_hash))
82
+ base.class_eval do
83
+ def base.inherited(subclass)
84
+ subclass.debug_config_reset(Configuration.new(**debug_config.to_hash))
85
+ end
79
86
  end
80
87
  end
81
- end
82
88
 
83
- #### API ####
89
+ #### API ####
84
90
 
85
- # For single statement global config in an initializer
86
- # e.g. DebugLogging.configuration.ellipsis = "..."
87
- def self.configuration
88
- self.debug_logging_configuration ||= Configuration.new
89
- end
91
+ # For single statement global config in an initializer
92
+ # e.g. DebugLogging.configuration.ellipsis = "..."
93
+ def configuration
94
+ self.debug_logging_configuration ||= Configuration.new
95
+ end
90
96
 
91
- # For global config in an initializer with a block
92
- def self.configure
93
- yield(configuration)
97
+ # For global config in an initializer with a block
98
+ def configure
99
+ yield(configuration)
100
+ end
94
101
  end
95
102
 
96
103
  module ApiClassMethods
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  # Simpler version of what the sibling DebugLogging library does. Included as a bauble.
4
2
  #
5
3
  ############# THIS IS A BAUBLE
@@ -57,11 +55,11 @@ class SimpleDebugLogging < Module
57
55
  define_method(method_to_log.to_sym) do |*args|
58
56
  method_return_value = nil
59
57
  invocation_id = " ~#{args.object_id}@#{Time.now.to_i}~" if args
60
- puts "#{self}.#{method_to_log}(#{args.map(&:inspect).join(", ")})#{invocation_id}"
58
+ puts "#{self}::#{method_to_log}(#{args.map(&:inspect).join(", ")})#{invocation_id}"
61
59
  elapsed = Benchmark.realtime do
62
60
  method_return_value = original_method.call(*args)
63
61
  end
64
- puts "#{self}.#{method_to_log} ~#{args.hash}~ complete in #{elapsed}s#{invocation_id}"
62
+ puts "#{self}::#{method_to_log} ~#{args.hash}~ complete in #{elapsed}s#{invocation_id}"
65
63
  method_return_value
66
64
  end
67
65
  end
data.tar.gz.sig CHANGED
Binary file