logging 2.2.1 → 2.2.2
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/History.txt +5 -0
- data/lib/logging.rb +27 -1
- data/lib/logging/layout.rb +81 -15
- data/lib/logging/layouts/parseable.rb +42 -8
- data/lib/logging/version.rb +1 -1
- data/test/layouts/test_nested_exceptions.rb +89 -17
- data/test/test_logging.rb +18 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb433e2db44c13bc4956095561ad2ad34cd4fabf
|
4
|
+
data.tar.gz: 6d6a401267834a2b1dad3c5992bb4c4c28ea05a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44ad1070f56d8618f9e6c118876364f70442723424d055716928e422a6699a40e744c68a86619227ed8fd5eea26e6c1fd6850f50877c74769a5160d6133b5140
|
7
|
+
data.tar.gz: bf24fb750a15937f18d75b2acc738e323a8ea718661bb9877ea64b0d23eea12def864c3175e71cd1f9b7ccff69c44d661455ff3526e5c192cc0f67c026a77a7f
|
data/History.txt
CHANGED
data/lib/logging.rb
CHANGED
@@ -23,6 +23,8 @@ module Logging
|
|
23
23
|
PATH = ::File.expand_path('../..', __FILE__) + ::File::SEPARATOR
|
24
24
|
LEVELS = {}
|
25
25
|
LNAMES = []
|
26
|
+
DEFAULT_CAUSE_DEPTH = 8
|
27
|
+
|
26
28
|
module Plugins; end
|
27
29
|
# :startdoc:
|
28
30
|
|
@@ -255,6 +257,8 @@ module Logging
|
|
255
257
|
longest = 'off' if longest.length < 3
|
256
258
|
module_eval "MAX_LEVEL_LENGTH = #{longest.length}", __FILE__, __LINE__
|
257
259
|
|
260
|
+
self.cause_depth = nil unless defined? @cause_depth
|
261
|
+
|
258
262
|
initialize_plugins
|
259
263
|
levels.keys
|
260
264
|
end
|
@@ -336,6 +340,27 @@ module Logging
|
|
336
340
|
|
337
341
|
attr_reader :utc_offset
|
338
342
|
|
343
|
+
# Set the default Exception#cause depth used when formatting Exceptions.
|
344
|
+
# This sets the maximum number of nested errors that will be formatted by
|
345
|
+
# the layouts before giving up. This is used to avoid extremely large
|
346
|
+
# outputs.
|
347
|
+
#
|
348
|
+
# Logging.cause_depth = nil # set to the DEFAULT_CAUSE_DEPTH
|
349
|
+
# Logging.cause_depth = 0 # do not show any exception causes
|
350
|
+
# Logging.cause_depth = 1024 # show up to 1024 causes
|
351
|
+
# Logging.cause_depth = -1 # results in the DEFAULT_CAUSE_DEPTH
|
352
|
+
#
|
353
|
+
def cause_depth=( value )
|
354
|
+
if value.nil?
|
355
|
+
@cause_depth = DEFAULT_CAUSE_DEPTH
|
356
|
+
else
|
357
|
+
value = Integer(value)
|
358
|
+
@cause_depth = value < 0 ? DEFAULT_CAUSE_DEPTH : value
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
attr_reader :cause_depth
|
363
|
+
|
339
364
|
# Used to define a `basepath` that will be removed from filenames when
|
340
365
|
# reporting tracing information for log events. Normally you would set this
|
341
366
|
# to the root of your project:
|
@@ -516,7 +541,8 @@ module Logging
|
|
516
541
|
remove_instance_variable :@basepath if defined? @basepath
|
517
542
|
remove_const :MAX_LEVEL_LENGTH if const_defined? :MAX_LEVEL_LENGTH
|
518
543
|
remove_const :OBJ_FORMAT if const_defined? :OBJ_FORMAT
|
519
|
-
self.utc_offset
|
544
|
+
self.utc_offset = nil
|
545
|
+
self.cause_depth = nil
|
520
546
|
self
|
521
547
|
end
|
522
548
|
|
data/lib/logging/layout.rb
CHANGED
@@ -41,8 +41,9 @@ class Layout
|
|
41
41
|
when :inspect, :yaml, :json; f
|
42
42
|
else :string end
|
43
43
|
|
44
|
-
self.backtrace
|
45
|
-
self.utc_offset
|
44
|
+
self.backtrace = opts.fetch(:backtrace, ::Logging.backtrace)
|
45
|
+
self.utc_offset = opts.fetch(:utc_offset, ::Logging.utc_offset)
|
46
|
+
self.cause_depth = opts.fetch(:cause_depth, ::Logging.cause_depth)
|
46
47
|
end
|
47
48
|
|
48
49
|
# call-seq:
|
@@ -89,6 +90,20 @@ class Layout
|
|
89
90
|
# Returns the UTC offset.
|
90
91
|
attr_reader :utc_offset
|
91
92
|
|
93
|
+
#
|
94
|
+
#
|
95
|
+
def cause_depth=( value )
|
96
|
+
if value.nil?
|
97
|
+
@cause_depth = ::Logging::DEFAULT_CAUSE_DEPTH
|
98
|
+
else
|
99
|
+
value = Integer(value)
|
100
|
+
@cause_depth = value < 0 ? ::Logging::DEFAULT_CAUSE_DEPTH : value
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Returns the exception cause depth formatting limit.
|
105
|
+
attr_reader :cause_depth
|
106
|
+
|
92
107
|
# Internal: Helper method that applies the UTC offset to the given `time`
|
93
108
|
# instance. A new Time is returned that is equivalent to the original `time`
|
94
109
|
# but pinned to the timezone given by the UTC offset.
|
@@ -142,15 +157,10 @@ class Layout
|
|
142
157
|
case obj
|
143
158
|
when String; obj
|
144
159
|
when Exception
|
145
|
-
|
146
|
-
if backtrace? &&
|
147
|
-
|
148
|
-
|
149
|
-
if defined?(obj.cause) && !obj.cause.nil?
|
150
|
-
ary << "--- Caused by ---"
|
151
|
-
ary << format_obj(obj.cause)
|
152
|
-
end
|
153
|
-
ary.join("\n\t")
|
160
|
+
lines = ["<#{obj.class.name}> #{obj.message}"]
|
161
|
+
lines.concat(obj.backtrace) if backtrace? && obj.backtrace
|
162
|
+
format_cause(obj, lines)
|
163
|
+
lines.join("\n\t")
|
154
164
|
when nil; "<#{obj.class.name}> nil"
|
155
165
|
else
|
156
166
|
str = "<#{obj.class.name}> "
|
@@ -163,6 +173,64 @@ class Layout
|
|
163
173
|
end
|
164
174
|
end
|
165
175
|
|
176
|
+
# Internal: Format any nested exceptions found in the given exception `e`
|
177
|
+
# while respecting the maximum `cause_depth`. The lines array is used to
|
178
|
+
# capture all the output lines form the nested exceptions; the array is later
|
179
|
+
# joined by the `format_obj` method.
|
180
|
+
#
|
181
|
+
# e - Exception to format
|
182
|
+
# lines - Array of output lines
|
183
|
+
#
|
184
|
+
# Returns the input `lines` Array
|
185
|
+
def format_cause(e, lines)
|
186
|
+
return lines if cause_depth == 0
|
187
|
+
|
188
|
+
cause_depth.times do
|
189
|
+
break unless e.respond_to?(:cause) && e.cause
|
190
|
+
|
191
|
+
cause = e.cause
|
192
|
+
lines << "--- Caused by ---"
|
193
|
+
lines << "<#{cause.class.name}> #{cause.message}"
|
194
|
+
lines.concat(format_cause_backtrace(e, cause)) if backtrace? && cause.backtrace
|
195
|
+
|
196
|
+
e = cause
|
197
|
+
end
|
198
|
+
|
199
|
+
if e.respond_to?(:cause) && e.cause
|
200
|
+
lines << "--- Further #cause backtraces were omitted ---"
|
201
|
+
end
|
202
|
+
|
203
|
+
lines
|
204
|
+
end
|
205
|
+
|
206
|
+
# Internal: Format the backtrace of the nested `cause` but remove the common
|
207
|
+
# exception lines from the parent exception. This helps keep the backtraces a
|
208
|
+
# wee bit shorter and more comprehensible.
|
209
|
+
#
|
210
|
+
# e - parent exception
|
211
|
+
# cause - the nested exception generating the returned backtrace
|
212
|
+
#
|
213
|
+
# Returns an Array of backtracke lines.
|
214
|
+
def format_cause_backtrace(e, cause)
|
215
|
+
# Find where the cause's backtrace differs from the parent exception's.
|
216
|
+
backtrace = Array(e.backtrace)
|
217
|
+
cause_backtrace = Array(cause.backtrace)
|
218
|
+
index = -1
|
219
|
+
min_index = [backtrace.size, cause_backtrace.size].min * -1
|
220
|
+
just_in_case = -5000
|
221
|
+
|
222
|
+
while index > min_index && backtrace[index] == cause_backtrace[index] && index >= just_in_case
|
223
|
+
index -= 1
|
224
|
+
end
|
225
|
+
|
226
|
+
# Add on a few common frames to make it clear where the backtraces line up.
|
227
|
+
index += 3
|
228
|
+
index = -1 if index >= 0
|
229
|
+
|
230
|
+
cause_backtrace[0..index]
|
231
|
+
end
|
232
|
+
|
233
|
+
|
166
234
|
# Attempt to format the _obj_ using yaml, but fall back to inspect style
|
167
235
|
# formatting if yaml fails.
|
168
236
|
#
|
@@ -188,7 +256,5 @@ class Layout
|
|
188
256
|
rescue StandardError
|
189
257
|
obj.inspect
|
190
258
|
end
|
191
|
-
|
192
|
-
end
|
193
|
-
end # module Logging
|
194
|
-
|
259
|
+
end
|
260
|
+
end
|
@@ -219,11 +219,15 @@ module Logging::Layouts
|
|
219
219
|
def format_obj( obj )
|
220
220
|
case obj
|
221
221
|
when Exception
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
222
|
+
hash = {
|
223
|
+
:class => obj.class.name,
|
224
|
+
:message => obj.message
|
225
|
+
}
|
226
|
+
hash[:backtrace] = obj.backtrace if backtrace? && obj.backtrace
|
227
|
+
|
228
|
+
cause = format_cause(obj)
|
229
|
+
hash[:cause] = cause unless cause.empty?
|
230
|
+
hash
|
227
231
|
when Time
|
228
232
|
iso8601_format(obj)
|
229
233
|
else
|
@@ -231,6 +235,37 @@ module Logging::Layouts
|
|
231
235
|
end
|
232
236
|
end
|
233
237
|
|
238
|
+
# Internal: Format any nested exceptions found in the given exception `e`
|
239
|
+
# while respecting the maximum `cause_depth`.
|
240
|
+
#
|
241
|
+
# e - Exception to format
|
242
|
+
#
|
243
|
+
# Returns the cause formatted as a Hash
|
244
|
+
def format_cause(e)
|
245
|
+
rv = curr = {}
|
246
|
+
prev = nil
|
247
|
+
|
248
|
+
cause_depth.times do
|
249
|
+
break unless e.respond_to?(:cause) && e.cause
|
250
|
+
|
251
|
+
cause = e.cause
|
252
|
+
curr[:class] = cause.class.name
|
253
|
+
curr[:message] = cause.message
|
254
|
+
curr[:backtrace] = format_cause_backtrace(e, cause) if backtrace? && cause.backtrace
|
255
|
+
|
256
|
+
prev[:cause] = curr unless prev.nil?
|
257
|
+
prev, curr = curr, {}
|
258
|
+
|
259
|
+
e = cause
|
260
|
+
end
|
261
|
+
|
262
|
+
if e.respond_to?(:cause) && e.cause
|
263
|
+
prev[:cause] = {message: "Further #cause backtraces were omitted"}
|
264
|
+
end
|
265
|
+
|
266
|
+
rv
|
267
|
+
end
|
268
|
+
|
234
269
|
private
|
235
270
|
|
236
271
|
# Call the appropriate class level create format method based on the
|
@@ -258,6 +293,5 @@ module Logging::Layouts
|
|
258
293
|
return str << (value.gmt_offset < 0 ? '-' : '+') << offset
|
259
294
|
end
|
260
295
|
|
261
|
-
end
|
262
|
-
end
|
263
|
-
|
296
|
+
end
|
297
|
+
end
|
data/lib/logging/version.rb
CHANGED
@@ -7,46 +7,118 @@ module TestLogging
|
|
7
7
|
include LoggingTestCase
|
8
8
|
|
9
9
|
def test_basic_format_obj
|
10
|
+
err = nil
|
10
11
|
begin
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
begin
|
13
|
+
raise ArgumentError, 'nested exception'
|
14
|
+
rescue
|
15
|
+
raise StandardError, 'root exception'
|
16
|
+
end
|
17
|
+
rescue => e
|
18
|
+
err = e
|
14
19
|
end
|
15
|
-
|
20
|
+
|
16
21
|
layout = Logging.layouts.basic({})
|
17
22
|
log = layout.format_obj(e)
|
18
|
-
assert_not_nil log.index('<
|
23
|
+
assert_not_nil log.index('<StandardError> root exception')
|
24
|
+
|
25
|
+
if err.respond_to?(:cause)
|
26
|
+
assert_not_nil log.index('<ArgumentError> nested exception')
|
27
|
+
assert(log.index('<StandardError> root exception') < log.index('<ArgumentError> nested exception'))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_cause_depth_limiting
|
32
|
+
err = nil
|
33
|
+
begin
|
34
|
+
begin
|
35
|
+
begin
|
36
|
+
raise TypeError, 'nested exception 2'
|
37
|
+
rescue
|
38
|
+
raise ArgumentError, 'nested exception 1'
|
39
|
+
end
|
40
|
+
rescue
|
41
|
+
raise StandardError, 'root exception'
|
42
|
+
end
|
43
|
+
rescue => e
|
44
|
+
err = e
|
45
|
+
end
|
46
|
+
|
47
|
+
layout = Logging.layouts.basic(cause_depth: 1)
|
48
|
+
log = layout.format_obj(e)
|
49
|
+
assert_not_nil log.index('<StandardError> root exception')
|
19
50
|
|
20
|
-
if
|
21
|
-
assert_not_nil log.index('<
|
22
|
-
|
51
|
+
if err.respond_to?(:cause)
|
52
|
+
assert_not_nil log.index('<ArgumentError> nested exception 1')
|
53
|
+
assert_nil log.index('<TypeError> nested exception 2')
|
54
|
+
assert_equal '--- Further #cause backtraces were omitted ---', log.split("\n\t").last
|
23
55
|
end
|
24
56
|
end
|
25
57
|
|
26
58
|
def test_parseable_format_obj
|
59
|
+
err = nil
|
27
60
|
begin
|
28
|
-
|
29
|
-
|
30
|
-
|
61
|
+
begin
|
62
|
+
raise ArgumentError, 'nested exception'
|
63
|
+
rescue
|
64
|
+
raise StandardError, 'root exception'
|
65
|
+
end
|
66
|
+
rescue => e
|
67
|
+
err = e
|
31
68
|
end
|
32
|
-
|
69
|
+
|
33
70
|
layout = Logging.layouts.parseable.new
|
34
71
|
log = layout.format_obj(e)
|
35
|
-
assert_equal
|
72
|
+
assert_equal 'StandardError', log[:class]
|
36
73
|
assert_equal 'root exception', log[:message]
|
37
|
-
|
74
|
+
assert log[:backtrace].size > 0
|
38
75
|
|
39
|
-
if
|
76
|
+
if e.respond_to?(:cause)
|
40
77
|
assert_not_nil log[:cause]
|
41
78
|
|
42
79
|
log = log[:cause]
|
43
|
-
assert_equal
|
80
|
+
assert_equal 'ArgumentError', log[:class]
|
44
81
|
assert_equal 'nested exception', log[:message]
|
45
82
|
assert_nil log[:cause]
|
46
|
-
|
83
|
+
assert log[:backtrace].size > 0
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_parseable_cause_depth_limiting
|
88
|
+
err = nil
|
89
|
+
begin
|
90
|
+
begin
|
91
|
+
begin
|
92
|
+
raise TypeError, 'nested exception 2'
|
93
|
+
rescue
|
94
|
+
raise ArgumentError, 'nested exception 1'
|
95
|
+
end
|
96
|
+
rescue
|
97
|
+
raise StandardError, 'root exception'
|
98
|
+
end
|
99
|
+
rescue => e
|
100
|
+
err = e
|
101
|
+
end
|
102
|
+
|
103
|
+
layout = Logging.layouts.parseable.new(cause_depth: 1)
|
104
|
+
log = layout.format_obj(e)
|
105
|
+
|
106
|
+
assert_equal 'StandardError', log[:class]
|
107
|
+
assert_equal 'root exception', log[:message]
|
108
|
+
assert log[:backtrace].size > 0
|
109
|
+
|
110
|
+
if e.respond_to?(:cause)
|
111
|
+
assert_not_nil log[:cause]
|
112
|
+
|
113
|
+
log = log[:cause]
|
114
|
+
assert_equal 'ArgumentError', log[:class]
|
115
|
+
assert_equal 'nested exception 1', log[:message]
|
116
|
+
assert_equal({message: "Further #cause backtraces were omitted"}, log[:cause])
|
117
|
+
assert log[:backtrace].size > 0
|
47
118
|
end
|
48
119
|
end
|
49
120
|
end
|
50
121
|
end
|
51
122
|
end
|
52
123
|
|
124
|
+
require 'pp'
|
data/test/test_logging.rb
CHANGED
@@ -54,6 +54,24 @@ module TestLogging
|
|
54
54
|
assert_raise(ArgumentError) {::Logging.utc_offset = "06:00"}
|
55
55
|
end
|
56
56
|
|
57
|
+
def test_cause_depth
|
58
|
+
assert_equal ::Logging::DEFAULT_CAUSE_DEPTH, ::Logging.cause_depth
|
59
|
+
|
60
|
+
::Logging.cause_depth = 0
|
61
|
+
assert_equal 0, ::Logging.cause_depth
|
62
|
+
|
63
|
+
::Logging.cause_depth = nil
|
64
|
+
assert_equal ::Logging::DEFAULT_CAUSE_DEPTH, ::Logging.cause_depth
|
65
|
+
|
66
|
+
::Logging.cause_depth = "1024"
|
67
|
+
assert_equal 1024, ::Logging.cause_depth
|
68
|
+
|
69
|
+
::Logging.cause_depth = -1
|
70
|
+
assert_equal ::Logging::DEFAULT_CAUSE_DEPTH, ::Logging.cause_depth
|
71
|
+
|
72
|
+
assert_raise(ArgumentError) {::Logging.cause_depth = "foo"}
|
73
|
+
end
|
74
|
+
|
57
75
|
def test_basepath
|
58
76
|
assert_nil ::Logging.basepath
|
59
77
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logging
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Pease
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: little-plugger
|