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 +4 -4
- data/.travis.yml +1 -3
- data/README.md +14 -5
- data/debug_logging.gemspec +1 -0
- data/lib/debug_logging.rb +15 -3
- data/lib/debug_logging/class_logger.rb +22 -9
- data/lib/debug_logging/configuration.rb +29 -0
- data/lib/debug_logging/instance_logger_modulizer.rb +15 -7
- data/lib/debug_logging/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd9ac9873cb177a6864e30599bdcfe3093837415
|
4
|
+
data.tar.gz: cde61e395a53bf5289ead7d0cd823de06c2925a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 31bf8b39f62289b7bf0e8ef845cdca2a8049ba492ce259ba9c19b2cf11fb364a004228d710e1d791ef6c83251e029a8f65c884ff0bcff03d39d901a47a7299c6
|
7
|
+
data.tar.gz: f6a1ec5e93ad0c074a3fa91ff50a676db59afaff1406d7b382616cfc383a54690769e763ef1b4b2d9f7bd7342c0446e903b71a633857e1dfd9eaaba9d63bfc29
|
data/.travis.yml
CHANGED
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
|
-
*
|
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
|
-
|
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
|
|
data/debug_logging.gemspec
CHANGED
@@ -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
|
data/lib/debug_logging.rb
CHANGED
@@ -60,9 +60,15 @@ module DebugLogging
|
|
60
60
|
end
|
61
61
|
|
62
62
|
#### API ####
|
63
|
-
|
64
|
-
|
65
|
-
|
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
|
-
|
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
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
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
|
-
|
26
|
-
|
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
|
-
|
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
|
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.
|
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-
|
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.
|