debug_logging 1.0.11 → 1.0.12

Sign up to get free protection for your applications and to get access to all the features.
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.