debug_logging 1.0.11 → 1.0.12

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6ea3afaf91b55426d0c4f6674c0515a261dfa77e
4
- data.tar.gz: 537a3865676eda1263d32ed4a63b08644724cca6
3
+ metadata.gz: fd9ac9873cb177a6864e30599bdcfe3093837415
4
+ data.tar.gz: cde61e395a53bf5289ead7d0cd823de06c2925a3
5
5
  SHA512:
6
- metadata.gz: 5185c10484ed70e559c6b97671e2b64b4e4d70a65db62f09f9e6af07b4bda6d288887bfd7675d22b9989c5542a36ebee354d0638b48854daf1096d04b3b6fcd6
7
- data.tar.gz: 500daf82402c0709b67c016f4e03b7d96a605949f9255bdb54269577952b55ff1d691acecc8202a25e1082afe0d0a4bd02438593e3a4d2216606727e686b28e8
6
+ metadata.gz: 31bf8b39f62289b7bf0e8ef845cdca2a8049ba492ce259ba9c19b2cf11fb364a004228d710e1d791ef6c83251e029a8f65c884ff0bcff03d39d901a47a7299c6
7
+ data.tar.gz: f6a1ec5e93ad0c074a3fa91ff50a676db59afaff1406d7b382616cfc383a54690769e763ef1b4b2d9f7bd7342c0446e903b71a633857e1dfd9eaaba9d63bfc29
@@ -1,9 +1,7 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - ruby-2.1.10
5
- - ruby-2.2.7
6
4
  - ruby-2.3.4
7
- - ruby-2.4.1
5
+ - ruby-2.4.2
8
6
  - jruby-9.1.9.0
9
7
  before_install: gem install bundler -v 1.15.4
data/README.md CHANGED
@@ -7,9 +7,11 @@ Unobtrusive, inheritable-overridable-configurable, drop-in debug logging, that w
7
7
  * *colorization by class/method*
8
8
  * *robust argument printer with customizable ellipsis*
9
9
  * *unique invocation identifiers*
10
- * *single line config*
11
- * *separate logger*
12
- * a free pony
10
+ * *single line config, per class/instance/method config*
11
+ * *separate logger, if needed*
12
+ * *log method calls, also when exit scope*
13
+ * *Prevents heavy computation of strings with `logger.debug { 'log me' }` block format.*
14
+ * **so many free ponies** 🎠🐴🎠🐴🎠🐴
13
15
 
14
16
  | Project | DebugLogging |
15
17
  |------------------------ | ----------------- |
@@ -65,7 +67,9 @@ Or install it yourself as:
65
67
 
66
68
  ## Usage
67
69
 
68
- Crack open the specs for usage examples.
70
+ NOTE: Starting with version `1.0.12` this gem utilizes the `logger.debug { "block format" }` to avoid heavy debug processing when the log level threshold is set higher than the level of the statements produced as a result of the configuration of this gem.
71
+
72
+ Crack open the specs for more complex usage examples than the ones below.
69
73
 
70
74
  ### Without Rails
71
75
 
@@ -90,6 +94,7 @@ DebugLogging.configuration.colorized_chain_for_method = false # e.g. ->(colorize
90
94
  DebugLogging.configuration.colorized_chain_for_class = false # e.g. ->(colorized_string) { colorized_string.colorize(:light_blue ).colorize( :background => :red) }
91
95
  DebugLogging.configuration.add_invocation_id = true # identify a method call uniquely in a log, pass a proc for colorization, e.g. ->(colorized_string) { colorized_string.light_black }
92
96
  DebugLogging.configuration.ellipsis = " ✂️ …".freeze
97
+ DebugLogging.configuration.mark_scope_exit = true # Only has an effect if benchmarking is off, since benchmarking always marks the scope exit
93
98
  ```
94
99
 
95
100
  If you prefer to use the block style:
@@ -108,14 +113,18 @@ DebugLogging.configure do |config|
108
113
  config.colorized_chain_for_class = false # e.g. ->(colorized_string) { colorized_string.colorize(:light_blue ).colorize( :background => :red) }
109
114
  config.add_invocation_id = true # identify a method call uniquely in a log, pass a proc for colorization, e.g. ->(colorized_string) { colorized_string.light_black }
110
115
  config.ellipsis = " ✂️ …".freeze
116
+ config.mark_scope_exit = true # Only has an effect if benchmarking is off, since benchmarking always marks the scope exit
111
117
  end
112
118
  ```
113
119
 
114
120
  **All** of the above **config** is **inheritable** and **configurable** at the **per-class** level as well!
115
121
  Just prepend `debug_` to any config value you want to override in a class.
116
122
 
123
+ **All** of the above **config** is **inheritable** and **configurable** at the **per-instance** level as well!
124
+ Just prepend `debug_` to any config value you want to override on an instance of a class.
125
+
117
126
  **All** of the above **config** is **inheritable** and **configurable** at the **per-method** level as well!
118
- Just send along a hash of the config options when you call `logged` or `include DebugLogging::InstanceLogger.new(i_methods: [:drive, :stop])`. See the example class below, and the specs.
127
+ Just send along a hash of the config options when you call `logged` or `include DebugLogging::InstanceLogger.new(i_methods: [:drive, :stop], config: { ellipsis = " ✂️ 2 much" })`. See the example class below, and the specs.
119
128
 
120
129
  **NOTE ON** `Rails.logger` - It will probably be nil in your initializer, so setting the `config.logger` to `Rails.logger` there will result in setting it to `nil`, which means the default will end up being used: `Logger.new(STDOUT)`. Instead just config the logger in your application.rb, or anytime later, but *before your classes get loaded* and start inheriting the config:
121
130
 
@@ -31,4 +31,5 @@ Automatically log selected methods and their arguments as they are called at run
31
31
  spec.add_development_dependency "coveralls", "~> 0.8"
32
32
  spec.add_development_dependency "rake", "~> 10.0"
33
33
  spec.add_development_dependency "rspec", "~> 3.0"
34
+ spec.add_development_dependency "activesupport", "~> 5.1"
34
35
  end
@@ -60,9 +60,15 @@ module DebugLogging
60
60
  end
61
61
 
62
62
  #### API ####
63
- def debug_log(message, config_proxy = nil)
64
- config_proxy ||= self
65
- config_proxy.debug_logger.send(config_proxy.debug_log_level, message) if config_proxy.debug_logger
63
+ # Not used by this gem internally, but provides an external interface for
64
+ # classes to also use this logging tool directly,
65
+ # with configured options like benchmarking, colors, or leg level.
66
+ def debug_log(message = nil, config_proxy = nil, &block)
67
+ # If a, instance-method-level, or class-method-level custom config is not
68
+ # passed in, then fall back to the class' default config, which is a
69
+ # potentially customized copy of the default config for the whole app.
70
+ config_proxy ||= debug_config
71
+ config_proxy.log(message, &block)
66
72
  end
67
73
 
68
74
  # There are times when the class will need access to the configuration object,
@@ -161,6 +167,12 @@ module DebugLogging
161
167
  def debug_add_invocation_id=(add_invocation_id)
162
168
  @debug_logging_configuration.add_invocation_id = add_invocation_id
163
169
  end
170
+ def debug_mark_scope_exit
171
+ @debug_logging_configuration.mark_scope_exit
172
+ end
173
+ def debug_mark_scope_exit=(mark_scope_exit)
174
+ @debug_logging_configuration.mark_scope_exit = mark_scope_exit
175
+ end
164
176
  def debug_ellipsis
165
177
  @debug_logging_configuration.ellipsis
166
178
  end
@@ -1,11 +1,13 @@
1
1
  module DebugLogging
2
2
  module ClassLogger
3
3
  def logged(*methods_to_log)
4
+ # When opts are present it will always be a new configuration instance per method
5
+ # When opts are not present it will reuse the class' configuration object
4
6
  opts = methods_to_log.last.is_a?(Hash) && methods_to_log.pop
5
7
  if methods_to_log.first.is_a?(Array)
6
8
  methods_to_log = methods_to_log.shift
7
9
  else
8
- # logged :meth1, :meth2, :meth3 is valid
10
+ # logged :meth1, :meth2, :meth3 without options is valid too
9
11
  end
10
12
  methods_to_log.each do |method_to_log|
11
13
  # method name must be a symbol
@@ -19,24 +21,35 @@ module DebugLogging
19
21
  proxy = if opts
20
22
  Configuration.new(**(debug_config.to_hash.merge(opts)))
21
23
  else
22
- self
24
+ debug_config
23
25
  end
26
+ proxy.register(method_to_log)
24
27
  instance_variable_set("@debug_config_proxy_for_k_#{method_to_log}".to_sym, proxy)
25
28
  proxy
26
29
  end
27
30
  method_return_value = nil
28
- # TODO: Put all the logic into a logger block, so it will never be computed at runtime if the log level is too high
29
- log_prefix = debug_invocation_to_s(klass: self.to_s, separator: ".", method_to_log: method_to_log, config_proxy: config_proxy)
30
- signature = debug_signature_to_s(args: args, config_proxy: config_proxy)
31
- invocation_id = debug_invocation_id_to_s(args: args, config_proxy: config_proxy)
32
- debug_log("#{log_prefix}#{signature}#{invocation_id}", config_proxy)
33
- if config_proxy.debug_class_benchmarks
31
+ log_prefix = nil
32
+ invocation_id = nil
33
+ config_proxy.log do
34
+ log_prefix = debug_invocation_to_s(klass: to_s, separator: ".", method_to_log: method_to_log, config_proxy: config_proxy)
35
+ invocation_id = debug_invocation_id_to_s(args: args, config_proxy: config_proxy)
36
+ signature = debug_signature_to_s(args: args, config_proxy: config_proxy)
37
+ "#{log_prefix}#{signature}#{invocation_id}"
38
+ end
39
+ if config_proxy.benchmarkable_for?(:debug_class_benchmarks)
34
40
  tms = Benchmark.measure do
35
41
  method_return_value = original_method.call(*args, &block)
36
42
  end
37
- debug_log("#{log_prefix} #{debug_benchmark_to_s(tms: tms)}#{invocation_id}", config_proxy)
43
+ config_proxy.log do
44
+ "#{log_prefix} #{debug_benchmark_to_s(tms: tms)}#{invocation_id}"
45
+ end
38
46
  else
39
47
  method_return_value = original_method.call(*args, &block)
48
+ if config_proxy.exit_scope_markable? && invocation_id && !invocation_id.empty?
49
+ config_proxy.log do
50
+ "#{log_prefix} completed#{invocation_id}"
51
+ end
52
+ end
40
53
  end
41
54
  method_return_value
42
55
  end
@@ -1,6 +1,7 @@
1
1
  module DebugLogging
2
2
  class Configuration
3
3
  DEFAULT_ELLIPSIS = " ✂️ …".freeze
4
+ # LEVELS = { 0 => :debug, 1 => :info, 2 => :warn, 3 => :error, 4 => :fatal, 5 => :unknown }
4
5
  attr_accessor :logger
5
6
  attr_accessor :log_level
6
7
  attr_accessor :multiple_last_hashes
@@ -13,6 +14,8 @@ module DebugLogging
13
14
  attr_accessor :colorized_chain_for_class
14
15
  attr_accessor :add_invocation_id
15
16
  attr_accessor :ellipsis
17
+ attr_accessor :mark_scope_exit
18
+ attr_reader :methods_to_log
16
19
  # alias the readers to the debug_* prefix so an instance of this class
17
20
  # can have the same API granted by `extend DebugLogging`
18
21
  #
@@ -43,6 +46,7 @@ module DebugLogging
43
46
  alias :debug_colorized_chain_for_class :colorized_chain_for_class
44
47
  alias :debug_add_invocation_id :add_invocation_id
45
48
  alias :debug_ellipsis :ellipsis
49
+ alias :debug_mark_scope_exit :mark_scope_exit
46
50
  def initialize(**options)
47
51
  @logger = options.key?(:logger) ? options[:logger] : Logger.new(STDOUT)
48
52
  @log_level = options.key?(:log_level) ? options[:log_level] : :debug
@@ -56,6 +60,28 @@ module DebugLogging
56
60
  @colorized_chain_for_class = options.key?(:colorized_chain_for_class) ? options[:colorized_chain_for_class] : false
57
61
  @add_invocation_id = options.key?(:add_invocation_id) ? options[:add_invocation_id] : true
58
62
  @ellipsis = options.key?(:ellipsis) ? options[:ellipsis] : DEFAULT_ELLIPSIS
63
+ @mark_scope_exit = options.key?(:mark_scope_exit) ? options[:mark_scope_exit] : false
64
+ @methods_to_log = []
65
+ end
66
+ def log(message = nil, &block)
67
+ return unless logger
68
+ if block_given?
69
+ logger.send(log_level, &block)
70
+ else
71
+ logger.send(log_level, message)
72
+ end
73
+ end
74
+ def loggable?
75
+ return @loggable if defined?(@loggable)
76
+ @loggable = logger.send("#{log_level}?")
77
+ end
78
+ def benchmarkable_for?(benchmarks)
79
+ return @benchmarkable if defined?(@benchmarkable)
80
+ @benchmarkable = loggable? && self.send(benchmarks)
81
+ end
82
+ def exit_scope_markable?
83
+ return @exit_scope_markable if defined?(@exit_scope_markable)
84
+ @exit_scope_markable = loggable? && mark_scope_exit
59
85
  end
60
86
  def instance_benchmarks=(instance_benchmarks)
61
87
  require "benchmark" if instance_benchmarks
@@ -81,5 +107,8 @@ module DebugLogging
81
107
  ellipsis: ellipsis
82
108
  }
83
109
  end
110
+ def register(method_lo_log)
111
+ @methods_to_log << method_lo_log
112
+ end
84
113
  end
85
114
  end
@@ -4,7 +4,6 @@ module DebugLogging
4
4
  Module.new do
5
5
  Array(methods_to_log).each do |method_to_log|
6
6
  # method name must be a symbol
7
-
8
7
  define_method(method_to_log.to_sym) do |*args, &block|
9
8
  method_return_value = nil
10
9
  config_proxy = if (proxy = instance_variable_get("@debug_config_proxy_for_#{method_to_log}".to_sym))
@@ -13,23 +12,32 @@ module DebugLogging
13
12
  proxy = if config
14
13
  Configuration.new(**(self.class.debug_config.to_hash.merge(config)))
15
14
  else
16
- self.class
15
+ self.class.debug_config
17
16
  end
17
+ proxy.register(method_to_log)
18
18
  instance_variable_set("@debug_config_proxy_for_#{method_to_log}".to_sym, proxy)
19
19
  proxy
20
20
  end
21
- # TODO: Put all the logic into a logger block, so it will never be computed at runtime if the log level is too high
22
21
  log_prefix = self.class.debug_invocation_to_s(klass: self.class.to_s, separator: "#", method_to_log: method_to_log, config_proxy: config_proxy)
23
- signature = self.class.debug_signature_to_s(args: args, config_proxy: config_proxy)
24
22
  invocation_id = self.class.debug_invocation_id_to_s(args: args, config_proxy: config_proxy)
25
- self.class.debug_log("#{log_prefix}#{signature}#{invocation_id}", config_proxy)
26
- if config_proxy.debug_instance_benchmarks
23
+ config_proxy.log do
24
+ signature = self.class.debug_signature_to_s(args: args, config_proxy: config_proxy)
25
+ "#{log_prefix}#{signature}#{invocation_id}"
26
+ end
27
+ if config_proxy.benchmarkable_for?(:debug_instance_benchmarks)
27
28
  tms = Benchmark.measure do
28
29
  method_return_value = super(*args, &block)
29
30
  end
30
- self.class.debug_log("#{log_prefix} #{self.class.debug_benchmark_to_s(tms: tms)}#{invocation_id}", config_proxy)
31
+ config_proxy.log do
32
+ "#{log_prefix} #{self.class.debug_benchmark_to_s(tms: tms)}#{invocation_id}"
33
+ end
31
34
  else
32
35
  method_return_value = super(*args, &block)
36
+ if config_proxy.exit_scope_markable? && invocation_id && !invocation_id.empty?
37
+ config_proxy.log do
38
+ "#{log_prefix} completed#{invocation_id}"
39
+ end
40
+ end
33
41
  end
34
42
  method_return_value
35
43
  end
@@ -1,3 +1,3 @@
1
1
  module DebugLogging
2
- VERSION = "1.0.11"
2
+ VERSION = "1.0.12"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: debug_logging
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.11
4
+ version: 1.0.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Boling
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-10-06 00:00:00.000000000 Z
11
+ date: 2017-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: activesupport
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '5.1'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '5.1'
97
111
  description: |2
98
112
 
99
113
  Unobtrusive debug logging for Ruby. NO LITTERING.