debug_logging 3.1.1 → 3.1.7
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
- data/.rubocop.yml +8 -0
- data/.rubocop_todo.yml +97 -63
- data/.travis.yml +2 -2
- data/README.md +91 -30
- data/debug_logging.gemspec +6 -3
- data/lib/debug_logging.rb +159 -106
- data/lib/debug_logging/argument_printer.rb +89 -26
- data/lib/debug_logging/class_logger.rb +48 -61
- data/lib/debug_logging/class_notifier.rb +39 -41
- data/lib/debug_logging/configuration.rb +4 -27
- data/lib/debug_logging/constants.rb +33 -0
- data/lib/debug_logging/errors.rb +7 -0
- data/lib/debug_logging/finalize.rb +20 -0
- data/lib/debug_logging/hooks.rb +82 -0
- data/lib/debug_logging/instance_logger.rb +3 -1
- data/lib/debug_logging/instance_logger_modulizer.rb +27 -39
- data/lib/debug_logging/instance_notifier.rb +6 -2
- data/lib/debug_logging/instance_notifier_modulizer.rb +33 -44
- data/lib/debug_logging/util.rb +75 -0
- data/lib/debug_logging/version.rb +1 -1
- metadata +56 -8
data/debug_logging.gemspec
CHANGED
@@ -7,7 +7,7 @@ require 'debug_logging/version'
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
8
|
spec.name = 'debug_logging'
|
9
9
|
spec.version = DebugLogging::VERSION
|
10
|
-
spec.authors = ['Peter Boling']
|
10
|
+
spec.authors = ['Peter Boling', 'guckin']
|
11
11
|
spec.email = ['peter.boling@gmail.com']
|
12
12
|
|
13
13
|
spec.summary = 'Drop-in debug logging useful when a call stack gets unruly'
|
@@ -33,7 +33,10 @@ Automatically log selected methods and their arguments as they are called at run
|
|
33
33
|
spec.add_development_dependency 'rake', '>= 13'
|
34
34
|
spec.add_development_dependency 'rspec', '>= 3'
|
35
35
|
spec.add_development_dependency 'rspec-pending_for', '>= 0'
|
36
|
-
spec.add_development_dependency 'rubocop', '
|
37
|
-
spec.add_development_dependency 'rubocop-
|
36
|
+
spec.add_development_dependency 'rubocop', '~> 1.0'
|
37
|
+
spec.add_development_dependency 'rubocop-md'
|
38
|
+
spec.add_development_dependency 'rubocop-performance'
|
39
|
+
spec.add_development_dependency 'rubocop-rake'
|
40
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 2.0'
|
38
41
|
spec.add_development_dependency 'silent_stream', '>= 1'
|
39
42
|
end
|
data/lib/debug_logging.rb
CHANGED
@@ -4,9 +4,14 @@ require 'logger'
|
|
4
4
|
require 'colorized_string'
|
5
5
|
require 'digest'
|
6
6
|
|
7
|
+
require 'debug_logging/constants'
|
7
8
|
require 'debug_logging/version'
|
9
|
+
require 'debug_logging/errors'
|
8
10
|
require 'debug_logging/configuration'
|
11
|
+
require 'debug_logging/util'
|
12
|
+
require 'debug_logging/finalize'
|
9
13
|
require 'debug_logging/argument_printer'
|
14
|
+
require 'debug_logging/hooks'
|
10
15
|
require 'debug_logging/instance_logger_modulizer'
|
11
16
|
require 'debug_logging/instance_logger'
|
12
17
|
require 'debug_logging/class_logger'
|
@@ -60,26 +65,17 @@ require 'debug_logging/class_logger'
|
|
60
65
|
module DebugLogging
|
61
66
|
def self.extended(base)
|
62
67
|
base.send(:extend, ArgumentPrinter)
|
68
|
+
base.send(:extend, ApiClassMethods)
|
69
|
+
base.send(:extend, ConfigClassMethods)
|
63
70
|
base.debug_config_reset(Configuration.new(**debug_logging_configuration.to_hash))
|
71
|
+
base.class_eval do
|
72
|
+
def base.inherited(subclass)
|
73
|
+
subclass.debug_config_reset(Configuration.new(**debug_config.to_hash))
|
74
|
+
end
|
75
|
+
end
|
64
76
|
end
|
65
77
|
|
66
78
|
#### API ####
|
67
|
-
# Not used by this gem internally, but provides an external interface for
|
68
|
-
# classes to also use this logging tool directly,
|
69
|
-
# with configured options like benchmarking, colors, or leg level.
|
70
|
-
def debug_log(message = nil, config_proxy = nil, &block)
|
71
|
-
# If a, instance-method-level, or class-method-level custom config is not
|
72
|
-
# passed in, then fall back to the class' default config, which is a
|
73
|
-
# potentially customized copy of the default config for the whole app.
|
74
|
-
config_proxy ||= debug_config
|
75
|
-
config_proxy.log(message, &block)
|
76
|
-
end
|
77
|
-
|
78
|
-
# There are times when the class will need access to the configuration object,
|
79
|
-
# such as to override it per instance method
|
80
|
-
def debug_config
|
81
|
-
@debug_logging_configuration
|
82
|
-
end
|
83
79
|
|
84
80
|
# For single statement global config in an initializer
|
85
81
|
# e.g. DebugLogging.configuration.ellipsis = "..."
|
@@ -92,130 +88,187 @@ module DebugLogging
|
|
92
88
|
yield(configuration)
|
93
89
|
end
|
94
90
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
91
|
+
module ApiClassMethods
|
92
|
+
# Not used by this gem internally, but provides an external interface for
|
93
|
+
# classes to also use this logging tool directly,
|
94
|
+
# with configured options like benchmarking, colors, or leg level.
|
95
|
+
def debug_log(message = nil, config_proxy = nil, &block)
|
96
|
+
# If a, instance-method-level, or class-method-level custom config is not
|
97
|
+
# passed in, then fall back to the class' default config, which is a
|
98
|
+
# potentially customized copy of the default config for the whole app.
|
99
|
+
config_proxy ||= debug_config
|
100
|
+
config_proxy.log(message, &block)
|
101
|
+
end
|
102
|
+
|
103
|
+
# There are times when the class will need access to the configuration object,
|
104
|
+
# such as to override it per instance method
|
105
|
+
def debug_config
|
106
|
+
@debug_logging_configuration
|
107
|
+
end
|
99
108
|
end
|
100
109
|
|
101
110
|
#### CONFIG ####
|
102
111
|
class << self
|
103
112
|
attr_accessor :debug_logging_configuration
|
104
113
|
end
|
105
|
-
def debug_config_reset(config = Configuration.new)
|
106
|
-
@debug_logging_configuration = config
|
107
|
-
end
|
108
114
|
|
109
|
-
|
110
|
-
|
111
|
-
end
|
115
|
+
module ConfigClassMethods
|
116
|
+
include Constants
|
112
117
|
|
113
|
-
|
114
|
-
|
115
|
-
|
118
|
+
# For per-class config with a block
|
119
|
+
def debug_logging_configure
|
120
|
+
@debug_logging_configuration ||= Configuration.new
|
121
|
+
yield(@debug_logging_configuration)
|
122
|
+
end
|
116
123
|
|
117
|
-
|
118
|
-
|
119
|
-
|
124
|
+
def debug_config_reset(config = Configuration.new)
|
125
|
+
@debug_logging_configuration = config
|
126
|
+
end
|
120
127
|
|
121
|
-
|
122
|
-
|
123
|
-
|
128
|
+
def debug_enabled
|
129
|
+
@debug_logging_configuration.enabled
|
130
|
+
end
|
124
131
|
|
125
|
-
|
126
|
-
|
127
|
-
|
132
|
+
def debug_enabled=(value)
|
133
|
+
@debug_logging_configuration.enabled = value
|
134
|
+
end
|
128
135
|
|
129
|
-
|
130
|
-
|
131
|
-
|
136
|
+
def debug_logger
|
137
|
+
@debug_logging_configuration.logger
|
138
|
+
end
|
132
139
|
|
133
|
-
|
134
|
-
|
135
|
-
|
140
|
+
def debug_logger=(logger)
|
141
|
+
@debug_logging_configuration.logger = logger
|
142
|
+
end
|
136
143
|
|
137
|
-
|
138
|
-
|
139
|
-
|
144
|
+
def debug_log_level
|
145
|
+
@debug_logging_configuration.log_level
|
146
|
+
end
|
140
147
|
|
141
|
-
|
142
|
-
|
143
|
-
|
148
|
+
def debug_log_level=(log_level)
|
149
|
+
@debug_logging_configuration.log_level = log_level
|
150
|
+
end
|
144
151
|
|
145
|
-
|
146
|
-
|
147
|
-
|
152
|
+
def debug_multiple_last_hashes
|
153
|
+
@debug_logging_configuration.multiple_last_hashes
|
154
|
+
end
|
148
155
|
|
149
|
-
|
150
|
-
|
151
|
-
|
156
|
+
def debug_multiple_last_hashes=(multiple_last_hashes)
|
157
|
+
@debug_logging_configuration.multiple_last_hashes = multiple_last_hashes
|
158
|
+
end
|
152
159
|
|
153
|
-
|
154
|
-
|
155
|
-
|
160
|
+
def debug_last_hash_to_s_proc
|
161
|
+
@debug_logging_configuration.last_hash_to_s_proc
|
162
|
+
end
|
156
163
|
|
157
|
-
|
158
|
-
|
159
|
-
|
164
|
+
def debug_last_hash_to_s_proc=(last_hash_to_s_proc)
|
165
|
+
@debug_logging_configuration.last_hash_to_s_proc = last_hash_to_s_proc
|
166
|
+
end
|
160
167
|
|
161
|
-
|
162
|
-
|
163
|
-
|
168
|
+
def debug_last_hash_max_length
|
169
|
+
@debug_logging_configuration.last_hash_max_length
|
170
|
+
end
|
164
171
|
|
165
|
-
|
166
|
-
|
167
|
-
|
172
|
+
def debug_last_hash_max_length=(last_hash_max_length)
|
173
|
+
@debug_logging_configuration.last_hash_max_length = last_hash_max_length
|
174
|
+
end
|
168
175
|
|
169
|
-
|
170
|
-
|
171
|
-
|
176
|
+
def debug_args_to_s_proc
|
177
|
+
@debug_logging_configuration.args_to_s_proc
|
178
|
+
end
|
172
179
|
|
173
|
-
|
174
|
-
|
175
|
-
|
180
|
+
def debug_args_to_s_proc=(args_to_s_proc)
|
181
|
+
@debug_logging_configuration.args_to_s_proc = args_to_s_proc
|
182
|
+
end
|
176
183
|
|
177
|
-
|
178
|
-
|
179
|
-
|
184
|
+
def debug_args_max_length
|
185
|
+
@debug_logging_configuration.args_max_length
|
186
|
+
end
|
180
187
|
|
181
|
-
|
182
|
-
|
183
|
-
|
188
|
+
def debug_args_max_length=(args_max_length)
|
189
|
+
@debug_logging_configuration.args_max_length = args_max_length
|
190
|
+
end
|
184
191
|
|
185
|
-
|
186
|
-
|
187
|
-
|
192
|
+
def debug_instance_benchmarks
|
193
|
+
@debug_logging_configuration.instance_benchmarks
|
194
|
+
end
|
188
195
|
|
189
|
-
|
190
|
-
|
191
|
-
|
196
|
+
def debug_instance_benchmarks=(instance_benchmarks)
|
197
|
+
@debug_logging_configuration.instance_benchmarks = instance_benchmarks
|
198
|
+
end
|
192
199
|
|
193
|
-
|
194
|
-
|
195
|
-
|
200
|
+
def debug_class_benchmarks
|
201
|
+
@debug_logging_configuration.class_benchmarks
|
202
|
+
end
|
196
203
|
|
197
|
-
|
198
|
-
|
199
|
-
|
204
|
+
def debug_class_benchmarks=(class_benchmarks)
|
205
|
+
@debug_logging_configuration.class_benchmarks = class_benchmarks
|
206
|
+
end
|
200
207
|
|
201
|
-
|
202
|
-
|
203
|
-
|
208
|
+
def debug_colorized_chain_for_method
|
209
|
+
@debug_logging_configuration.colorized_chain_for_method
|
210
|
+
end
|
204
211
|
|
205
|
-
|
206
|
-
|
207
|
-
|
212
|
+
def debug_colorized_chain_for_method=(colorized_chain_for_method)
|
213
|
+
@debug_logging_configuration.colorized_chain_for_method = colorized_chain_for_method
|
214
|
+
end
|
208
215
|
|
209
|
-
|
210
|
-
|
211
|
-
|
216
|
+
def debug_colorized_chain_for_class
|
217
|
+
@debug_logging_configuration.colorized_chain_for_class
|
218
|
+
end
|
212
219
|
|
213
|
-
|
214
|
-
|
215
|
-
|
220
|
+
def debug_colorized_chain_for_class=(colorized_chain_for_class)
|
221
|
+
@debug_logging_configuration.colorized_chain_for_class = colorized_chain_for_class
|
222
|
+
end
|
223
|
+
|
224
|
+
def debug_add_invocation_id
|
225
|
+
@debug_logging_configuration.add_invocation_id
|
226
|
+
end
|
216
227
|
|
217
|
-
|
218
|
-
|
228
|
+
def debug_add_invocation_id=(add_invocation_id)
|
229
|
+
@debug_logging_configuration.add_invocation_id = add_invocation_id
|
230
|
+
end
|
231
|
+
|
232
|
+
def debug_ellipsis
|
233
|
+
@debug_logging_configuration.ellipsis
|
234
|
+
end
|
235
|
+
|
236
|
+
def debug_ellipsis=(ellipsis)
|
237
|
+
@debug_logging_configuration.ellipsis = ellipsis
|
238
|
+
end
|
239
|
+
|
240
|
+
def debug_mark_scope_exit
|
241
|
+
@debug_logging_configuration.mark_scope_exit
|
242
|
+
end
|
243
|
+
|
244
|
+
def debug_mark_scope_exit=(mark_scope_exit)
|
245
|
+
@debug_logging_configuration.mark_scope_exit = mark_scope_exit
|
246
|
+
end
|
247
|
+
|
248
|
+
def debug_add_payload
|
249
|
+
@debug_logging_configuration.add_payload
|
250
|
+
end
|
251
|
+
|
252
|
+
def debug_add_payload=(add_payload)
|
253
|
+
@debug_logging_configuration.add_payload = add_payload
|
254
|
+
end
|
255
|
+
|
256
|
+
def debug_payload_max_length
|
257
|
+
@debug_logging_configuration.payload_max_length
|
258
|
+
end
|
259
|
+
|
260
|
+
def debug_payload_max_length=(payload_max_length)
|
261
|
+
@debug_logging_configuration.payload_max_length = payload_max_length
|
262
|
+
end
|
263
|
+
|
264
|
+
def debug_error_handler_proc
|
265
|
+
@debug_logging_configuration.error_handler_proc
|
266
|
+
end
|
267
|
+
|
268
|
+
def debug_error_handler_proc=(error_handler_proc)
|
269
|
+
@debug_logging_configuration.error_handler_proc = error_handler_proc
|
270
|
+
end
|
219
271
|
end
|
272
|
+
|
220
273
|
self.debug_logging_configuration = Configuration.new # setup defaults
|
221
274
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module DebugLogging
|
4
4
|
module ArgumentPrinter
|
5
|
-
def debug_benchmark_to_s(tms:
|
5
|
+
def debug_benchmark_to_s(tms:)
|
6
6
|
"completed in #{format('%f', tms.real)}s (#{format('%f', tms.total)}s CPU)"
|
7
7
|
end
|
8
8
|
|
@@ -38,56 +38,97 @@ module DebugLogging
|
|
38
38
|
"#{klass_string}#{separator}#{method_string}"
|
39
39
|
end
|
40
40
|
|
41
|
-
def debug_signature_to_s(args: nil, config_proxy: nil) # rubocop:disable Metrics/CyclomaticComplexity
|
41
|
+
def debug_signature_to_s(args: nil, config_proxy: nil) # rubocop:disable Metrics/CyclomaticComplexity
|
42
42
|
return '' unless args && config_proxy
|
43
43
|
|
44
44
|
printed_args = ''
|
45
45
|
|
46
46
|
add_args_ellipsis = false
|
47
47
|
if config_proxy.debug_last_hash_to_s_proc && args[-1].is_a?(Hash)
|
48
|
-
|
48
|
+
add_other_args_ellipsis = false
|
49
49
|
if args.length > 1
|
50
50
|
if config_proxy.debug_multiple_last_hashes
|
51
51
|
last_hash_args, other_args = args.partition do |arg|
|
52
52
|
arg.is_a?(Hash)
|
53
53
|
end
|
54
|
-
other_args_string =
|
54
|
+
other_args_string = if config_proxy.debug_args_to_s_proc
|
55
|
+
printed, add_other_args_ellipsis = debug_safe_proc(
|
56
|
+
proc_name:'args_to_s_proc',
|
57
|
+
proc: config_proxy.debug_args_to_s_proc,
|
58
|
+
args: other_args,
|
59
|
+
max_length: config_proxy.debug_args_max_length
|
60
|
+
)
|
61
|
+
printed
|
62
|
+
else
|
63
|
+
other_args.map(&:inspect).join(', ').tap do |x|
|
64
|
+
add_other_args_ellipsis = x.length > config_proxy.debug_args_max_length
|
65
|
+
end[0..(config_proxy.debug_args_max_length)]
|
66
|
+
end
|
67
|
+
other_args_string += config_proxy.debug_ellipsis if add_other_args_ellipsis
|
55
68
|
# On the debug_multiple_last_hashes truthy branch we don't print the ellipsis after regular args
|
56
|
-
# because it will go instead after the last
|
69
|
+
# because it will go instead after each of the last hashes (if needed)
|
57
70
|
# ...join(", ").tap {|x| _add_args_ellipsis = x.length > config_proxy.debug_args_max_length}
|
58
71
|
last_hash_args_string = last_hash_args.map do |arg|
|
59
72
|
arr = []
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
73
|
+
printed, add_last_hash_ellipsis = debug_safe_proc(
|
74
|
+
proc_name:'last_hash_to_s_proc',
|
75
|
+
proc: config_proxy.debug_last_hash_to_s_proc,
|
76
|
+
args: arg,
|
77
|
+
max_length: config_proxy.debug_last_hash_max_length
|
78
|
+
)
|
79
|
+
printed += config_proxy.debug_ellipsis if add_last_hash_ellipsis
|
80
|
+
arr << printed
|
68
81
|
arr
|
69
82
|
end.flatten.join(', ')
|
70
83
|
printed_args += other_args_string if other_args_string
|
71
84
|
printed_args += ', ' if !other_args_string.empty? && !last_hash_args_string.empty?
|
72
85
|
printed_args += last_hash_args_string if last_hash_args_string && !last_hash_args_string.empty?
|
73
86
|
else
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
87
|
+
other_args = args[0..-2]
|
88
|
+
other_args_string = if config_proxy.debug_args_to_s_proc
|
89
|
+
printed, add_other_args_ellipsis = debug_safe_proc(
|
90
|
+
proc_name:'args_to_s_proc',
|
91
|
+
proc: config_proxy.debug_args_to_s_proc,
|
92
|
+
args: other_args,
|
93
|
+
max_length: config_proxy.debug_args_max_length
|
94
|
+
)
|
95
|
+
printed
|
96
|
+
else
|
97
|
+
other_args.map(&:inspect).join(', ').tap do |x|
|
98
|
+
add_other_args_ellipsis = x.length > config_proxy.debug_args_max_length
|
99
|
+
end[0..(config_proxy.debug_args_max_length)]
|
100
|
+
end
|
101
|
+
other_args_string += config_proxy.debug_ellipsis if add_other_args_ellipsis
|
102
|
+
printed_args += other_args_string
|
103
|
+
printed, add_last_hash_ellipsis = debug_safe_proc(
|
104
|
+
proc_name:'last_hash_to_s_proc',
|
105
|
+
proc: config_proxy.debug_last_hash_to_s_proc,
|
106
|
+
args: args[-1],
|
107
|
+
max_length: config_proxy.debug_last_hash_max_length
|
108
|
+
)
|
109
|
+
printed_args += ", #{printed}"
|
81
110
|
printed_args += config_proxy.debug_ellipsis if add_last_hash_ellipsis
|
82
111
|
end
|
83
112
|
else
|
84
|
-
|
85
|
-
|
86
|
-
|
113
|
+
printed, add_last_hash_ellipsis = debug_safe_proc(
|
114
|
+
proc_name:'last_hash_to_s_proc',
|
115
|
+
proc: config_proxy.debug_last_hash_to_s_proc,
|
116
|
+
args: args[0],
|
117
|
+
max_length: config_proxy.debug_last_hash_max_length
|
118
|
+
)
|
119
|
+
printed_args += printed
|
87
120
|
printed_args += config_proxy.debug_ellipsis if add_last_hash_ellipsis
|
88
121
|
end
|
89
122
|
else
|
90
|
-
printed_args += if
|
123
|
+
printed_args += if config_proxy.debug_args_to_s_proc
|
124
|
+
printed, add_args_ellipsis = debug_safe_proc(
|
125
|
+
proc_name:'args_to_s_proc',
|
126
|
+
proc: config_proxy.debug_args_to_s_proc,
|
127
|
+
args: args,
|
128
|
+
max_length: config_proxy.debug_args_max_length
|
129
|
+
)
|
130
|
+
printed
|
131
|
+
elsif args.length == 1 && args[0].is_a?(Hash)
|
91
132
|
# handle double splat
|
92
133
|
("**#{args.map(&:inspect).join(', ').tap do |x|
|
93
134
|
add_args_ellipsis = x.length > config_proxy.debug_args_max_length
|
@@ -95,13 +136,26 @@ module DebugLogging
|
|
95
136
|
else
|
96
137
|
args.map(&:inspect).join(', ').tap do |x|
|
97
138
|
add_args_ellipsis = x.length > config_proxy.debug_args_max_length
|
98
|
-
end
|
139
|
+
end[0..(config_proxy.debug_args_max_length)]
|
99
140
|
end
|
100
141
|
printed_args += config_proxy.debug_ellipsis if add_args_ellipsis
|
101
142
|
end
|
102
143
|
"(#{printed_args})"
|
103
144
|
end
|
104
145
|
|
146
|
+
def debug_safe_proc(proc_name:, proc:, args:, max_length:)
|
147
|
+
max_length ||= 1000 # can't be nil
|
148
|
+
begin
|
149
|
+
add_ellipsis = false
|
150
|
+
printed = String(proc.call(args)).tap do |x|
|
151
|
+
add_ellipsis = x.length > max_length
|
152
|
+
end[0..(max_length)]
|
153
|
+
return printed, add_ellipsis
|
154
|
+
rescue => e
|
155
|
+
return "#{e.class}: #{e.message}\nPlease check that your #{proc_name} is able to handle #{args}", false
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
105
159
|
def debug_payload_to_s(payload: nil, config_proxy: nil)
|
106
160
|
return '' unless payload && config_proxy
|
107
161
|
|
@@ -110,7 +164,16 @@ module DebugLogging
|
|
110
164
|
when true
|
111
165
|
payload.inspect
|
112
166
|
else
|
113
|
-
|
167
|
+
printed_payload = ""
|
168
|
+
printed, add_payload_ellipsis = debug_safe_proc(
|
169
|
+
proc_name: "add_payload",
|
170
|
+
proc: config_proxy.debug_add_payload,
|
171
|
+
args: payload,
|
172
|
+
max_length: config_proxy.payload_max_length
|
173
|
+
)
|
174
|
+
printed_payload += printed
|
175
|
+
printed_payload += config_proxy.debug_ellipsis if add_payload_ellipsis
|
176
|
+
printed_payload
|
114
177
|
end
|
115
178
|
else
|
116
179
|
''
|