logging 2.2.1 → 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,11 +20,10 @@ module TestAppenders
20
20
 
21
21
  appender = Logging.appenders.stdout
22
22
  assert_equal 'stdout', appender.name
23
- assert_same STDOUT, appender.instance_variable_get(:@io)
24
23
 
25
- appender.close
26
- assert_equal true, appender.closed?
27
- assert_equal false, STDOUT.closed?
24
+ io = appender.instance_variable_get(:@io)
25
+ assert_same STDOUT, io
26
+ assert_equal STDOUT.fileno, io.fileno
28
27
 
29
28
  appender = Logging.appenders.stdout('foo')
30
29
  assert_equal 'foo', appender.name
@@ -38,7 +37,26 @@ module TestAppenders
38
37
  assert_equal 3, appender.level
39
38
  end
40
39
 
41
- end # class TestStdout
40
+ def test_reopen
41
+ Logging::Repository.instance
42
+
43
+ appender = Logging.appenders.stdout
44
+ io = appender.instance_variable_get(:@io)
45
+
46
+ appender.close
47
+ assert appender.closed?
48
+ refute io.closed?
49
+ refute STDOUT.closed?
50
+
51
+ appender.reopen
52
+ refute appender.closed?
53
+
54
+ new_io = appender.instance_variable_get(:@io)
55
+ assert_same io, new_io
56
+ refute new_io.closed?
57
+ refute io.closed?
58
+ end
59
+ end
42
60
 
43
61
  class TestStderr < Test::Unit::TestCase
44
62
  include LoggingTestCase
@@ -48,11 +66,10 @@ module TestAppenders
48
66
 
49
67
  appender = Logging.appenders.stderr
50
68
  assert_equal 'stderr', appender.name
51
- assert_same STDERR, appender.instance_variable_get(:@io)
52
69
 
53
- appender.close
54
- assert_equal true, appender.closed?
55
- assert_equal false, STDERR.closed?
70
+ io = appender.instance_variable_get(:@io)
71
+ assert_same STDERR, io
72
+ assert_equal STDERR.fileno, io.fileno
56
73
 
57
74
  appender = Logging.appenders.stderr('foo')
58
75
  assert_equal 'foo', appender.name
@@ -66,8 +83,26 @@ module TestAppenders
66
83
  assert_equal 3, appender.level
67
84
  end
68
85
 
69
- end # class TestStderr
86
+ def test_reopen
87
+ Logging::Repository.instance
70
88
 
71
- end # module TestAppenders
72
- end # module TestLogging
89
+ appender = Logging.appenders.stderr
90
+ io = appender.instance_variable_get(:@io)
91
+
92
+ appender.close
93
+ assert appender.closed?
94
+ refute io.closed?
95
+ refute STDERR.closed?
96
+
97
+ appender.reopen
98
+ refute appender.closed?
99
+
100
+ new_io = appender.instance_variable_get(:@io)
101
+ assert_same io, new_io
102
+ refute new_io.closed?
103
+ refute io.closed?
104
+ end
105
+ end
106
+ end
107
+ end
73
108
 
@@ -14,10 +14,10 @@ module TestAppenders
14
14
  super
15
15
  Logging.init
16
16
 
17
- FileUtils.mkdir [File.join(TMP, 'dir'), File.join(TMP, 'uw_dir')]
18
- FileUtils.chmod 0555, File.join(TMP, 'uw_dir')
19
- FileUtils.touch File.join(TMP, 'uw_file')
20
- FileUtils.chmod 0444, File.join(TMP, 'uw_file')
17
+ FileUtils.mkdir [File.join(@tmpdir, 'dir'), File.join(@tmpdir, 'uw_dir')]
18
+ FileUtils.chmod 0555, File.join(@tmpdir, 'uw_dir')
19
+ FileUtils.touch File.join(@tmpdir, 'uw_file')
20
+ FileUtils.chmod 0444, File.join(@tmpdir, 'uw_file')
21
21
  end
22
22
 
23
23
  def test_factory_method_validates_input
@@ -27,27 +27,27 @@ module TestAppenders
27
27
  end
28
28
 
29
29
  def test_class_assert_valid_logfile
30
- log = File.join(TMP, 'uw_dir', 'file.log')
30
+ log = File.join(@tmpdir, 'uw_dir', 'file.log')
31
31
  assert_raise(ArgumentError) do
32
32
  Logging.appenders.file(log).class.assert_valid_logfile(log)
33
33
  end
34
34
 
35
- log = File.join(TMP, 'dir')
35
+ log = File.join(@tmpdir, 'dir')
36
36
  assert_raise(ArgumentError) do
37
37
  Logging.appenders.file(log).class.assert_valid_logfile(log)
38
38
  end
39
39
 
40
- log = File.join(TMP, 'uw_file')
40
+ log = File.join(@tmpdir, 'uw_file')
41
41
  assert_raise(ArgumentError) do
42
42
  Logging.appenders.file(log).class.assert_valid_logfile(log)
43
43
  end
44
44
 
45
- log = File.join(TMP, 'file.log')
45
+ log = File.join(@tmpdir, 'file.log')
46
46
  assert Logging.appenders.file(log).class.assert_valid_logfile(log)
47
47
  end
48
48
 
49
49
  def test_initialize
50
- log = File.join(TMP, 'file.log')
50
+ log = File.join(@tmpdir, 'file.log')
51
51
  appender = Logging.appenders.file(NAME, :filename => log)
52
52
  assert_equal 'logfile', appender.name
53
53
  assert_equal ::File.expand_path(log), appender.filename
@@ -87,7 +87,7 @@ module TestAppenders
87
87
  end
88
88
 
89
89
  def test_changing_directories
90
- log = File.join(TMP, 'file.log')
90
+ log = File.join(@tmpdir, 'file.log')
91
91
  appender = Logging.appenders.file(NAME, :filename => log)
92
92
 
93
93
  assert_equal 'logfile', appender.name
@@ -95,29 +95,45 @@ module TestAppenders
95
95
 
96
96
  begin
97
97
  pwd = Dir.pwd
98
- Dir.chdir TMP
98
+ Dir.chdir @tmpdir
99
99
  assert_nothing_raised { appender.reopen }
100
100
  ensure
101
101
  Dir.chdir pwd
102
102
  end
103
103
  end
104
104
 
105
- if Object.const_defined? :Encoding
105
+ def test_encoding
106
+ log = File.join(@tmpdir, 'file-encoding.log')
107
+ appender = Logging.appenders.file(NAME, :filename => log, :encoding => 'ASCII')
106
108
 
107
- def test_encoding
108
- log = File.join(TMP, 'file-encoding.log')
109
- appender = Logging.appenders.file(NAME, :filename => log, :encoding => 'ASCII')
109
+ appender << "A normal line of text\n"
110
+ appender << "ümlaut\n"
111
+ appender.close
110
112
 
111
- appender << "A normal line of text\n"
112
- appender << "ümlaut\n"
113
- appender.close
113
+ lines = File.readlines(log, :encoding => 'UTF-8')
114
+ assert_equal "A normal line of text\n", lines[0]
115
+ assert_equal "ümlaut\n", lines[1]
114
116
 
115
- lines = File.readlines(log, :encoding => 'UTF-8')
116
- assert_equal "A normal line of text\n", lines[0]
117
- assert_equal "ümlaut\n", lines[1]
117
+ cleanup
118
+ end
119
+
120
+ def test_reopening_should_not_truncate_the_file
121
+ log = File.join(@tmpdir, 'truncate.log')
122
+ appender = Logging.appenders.file(NAME, filename: log, truncate: true)
123
+
124
+ appender << "This will be the first line\n"
125
+ appender << "This will be the second line\n"
126
+ appender << "This will be the third line\n"
127
+ appender.reopen
118
128
 
119
- cleanup
129
+ File.open(log, 'r') do |file|
130
+ assert_equal "This will be the first line\n", file.readline
131
+ assert_equal "This will be the second line\n", file.readline
132
+ assert_equal "This will be the third line\n", file.readline
133
+ assert_raise(EOFError) {file.readline}
120
134
  end
135
+
136
+ cleanup
121
137
  end
122
138
 
123
139
  private
@@ -127,7 +143,6 @@ module TestAppenders
127
143
  Logging.appenders[NAME] = nil
128
144
  end
129
145
  end
130
-
131
146
  end # TestFile
132
147
 
133
148
  end # TestAppenders
@@ -13,9 +13,9 @@ module TestAppenders
13
13
  super
14
14
  Logging.init
15
15
 
16
- @fn = File.expand_path('test.log', TMP)
17
- @fn_fmt = File.expand_path('test.%d.log', TMP)
18
- @glob = File.expand_path('*.log', TMP)
16
+ @fn = File.expand_path('test.log', @tmpdir)
17
+ @fn_fmt = File.expand_path('test.%d.log', @tmpdir)
18
+ @glob = File.expand_path('*.log', @tmpdir)
19
19
  end
20
20
 
21
21
  def test_factory_method_validates_input
@@ -93,8 +93,8 @@ module TestAppenders
93
93
  end
94
94
 
95
95
  def test_age
96
- d_glob = File.join(TMP, 'test.*.log')
97
- dt_glob = File.join(TMP, 'test.*-*.log')
96
+ d_glob = File.join(@tmpdir, 'test.*.log')
97
+ dt_glob = File.join(@tmpdir, 'test.*-*.log')
98
98
  age_fn = @fn + '.age'
99
99
 
100
100
  assert_equal [], Dir.glob(@glob)
@@ -205,7 +205,7 @@ module TestAppenders
205
205
 
206
206
  begin
207
207
  pwd = Dir.pwd
208
- Dir.chdir TMP
208
+ Dir.chdir @tmpdir
209
209
 
210
210
  ap << 'X' * 100; ap.flush
211
211
  assert_equal 1, Dir.glob(@glob).length
@@ -249,9 +249,9 @@ module TestAppenders
249
249
  end
250
250
 
251
251
  def test_custom_numberd_filename
252
- fn = File.expand_path('test.log{{.%d}}', TMP)
253
- filename = File.expand_path('test.log', TMP)
254
- glob = File.expand_path('test.log.*', TMP)
252
+ fn = File.expand_path('test.log{{.%d}}', @tmpdir)
253
+ filename = File.expand_path('test.log', @tmpdir)
254
+ glob = File.expand_path('test.log.*', @tmpdir)
255
255
 
256
256
  assert_equal [], Dir.glob(glob)
257
257
  ap = Logging.appenders.rolling_file(NAME, :filename => fn, :size => 100, :keep => 2)
@@ -285,10 +285,10 @@ module TestAppenders
285
285
  end
286
286
 
287
287
  def test_custom_timestamp_filename
288
- fn = File.expand_path('test{{.%S:%M}}.log', TMP)
289
- filename = File.expand_path('test.log', TMP)
288
+ fn = File.expand_path('test{{.%S:%M}}.log', @tmpdir)
289
+ filename = File.expand_path('test.log', @tmpdir)
290
290
  age_file = filename + '.age'
291
- glob = File.expand_path('test.*.log', TMP)
291
+ glob = File.expand_path('test.*.log', @tmpdir)
292
292
 
293
293
  assert_equal [], Dir.glob(glob)
294
294
  ap = Logging.appenders.rolling_file(NAME, :filename => fn, :age => 1, :keep => 2)
@@ -78,7 +78,7 @@ module TestLayouts
78
78
  'log message', false)
79
79
  event.file = 'test_file.rb'
80
80
  event.line = 123
81
- event.method = 'method_name'
81
+ event.method_name = 'method_name'
82
82
 
83
83
  @layout.items = %w[logger]
84
84
  assert_equal %Q[{"logger":"TestLogger"}\n], @layout.format(event)
@@ -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
- raise StandardError, 'nested exception'
12
- rescue
13
- raise Exception, 'root exception'
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
- rescue Exception => e
20
+
16
21
  layout = Logging.layouts.basic({})
17
- log = layout.format_obj(e)
18
- assert_not_nil log.index('<Exception> root exception')
22
+ log = layout.format_obj(err)
23
+ assert_not_nil log.index('<StandardError> root exception')
19
24
 
20
- if defined? e.cause
21
- assert_not_nil log.index('<StandardError> nested exception')
22
- assert_operator log.index('<Exception> root exception'), :<, log.index('<StandardError> nested exception')
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(err)
49
+ assert_not_nil log.index('<StandardError> root exception')
50
+
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
- raise StandardError, 'nested exception'
29
- rescue
30
- raise Exception, 'root exception'
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
- rescue Exception => e
69
+
33
70
  layout = Logging.layouts.parseable.new
34
- log = layout.format_obj(e)
35
- assert_equal Exception.name, log[:class]
71
+ log = layout.format_obj(err)
72
+ assert_equal 'StandardError', log[:class]
36
73
  assert_equal 'root exception', log[:message]
37
- assert_operator log[:backtrace].size, :>, 0
74
+ assert log[:backtrace].size > 0
38
75
 
39
- if defined? e.cause
76
+ if err.respond_to?(:cause)
40
77
  assert_not_nil log[:cause]
41
78
 
42
79
  log = log[:cause]
43
- assert_equal StandardError.name, log[:class]
80
+ assert_equal 'ArgumentError', log[:class]
44
81
  assert_equal 'nested exception', log[:message]
45
82
  assert_nil log[:cause]
46
- assert_operator log[:backtrace].size, :>, 0
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(err)
105
+
106
+ assert_equal 'StandardError', log[:class]
107
+ assert_equal 'root exception', log[:message]
108
+ assert log[:backtrace].size > 0
109
+
110
+ if err.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'
@@ -105,7 +105,7 @@ module TestLayouts
105
105
  'log message', false)
106
106
  event.file = 'test_file.rb'
107
107
  event.line = '123'
108
- event.method = 'method_name'
108
+ event.method_name = 'method_name'
109
109
 
110
110
  @layout.pattern = '%c'
111
111
  assert_equal 'TestLogger', @layout.format(event)
@@ -68,7 +68,7 @@ module TestLayouts
68
68
  'log message', false)
69
69
  event.file = 'test_file.rb'
70
70
  event.line = 123
71
- event.method = 'method_name'
71
+ event.method_name = 'method_name'
72
72
 
73
73
  @layout.items = %w[logger]
74
74
  assert_match %r/\A--- ?\nlogger: TestLogger\n/, @layout.format(event)
data/test/setup.rb CHANGED
@@ -5,6 +5,12 @@ LOGGING_TEST_SETUP = true
5
5
 
6
6
  require "rubygems"
7
7
  require "test/unit"
8
+ require "tmpdir"
9
+
10
+ LOGGING_TEST_TMPDIR = Dir.mktmpdir("logging")
11
+ Test::Unit.at_exit do
12
+ FileUtils.remove_entry(LOGGING_TEST_TMPDIR)
13
+ end
8
14
 
9
15
  if Test::Unit::TestCase.respond_to? :test_order=
10
16
  Test::Unit::TestCase.test_order = :random
@@ -15,18 +21,16 @@ require File.expand_path("../../lib/logging", __FILE__)
15
21
  module TestLogging
16
22
  module LoggingTestCase
17
23
 
18
- TMP = 'tmp'
19
-
20
24
  def setup
21
25
  super
22
26
  Logging.reset
23
- FileUtils.rm_rf TMP
24
- FileUtils.mkdir TMP
27
+ @tmpdir = LOGGING_TEST_TMPDIR
28
+ FileUtils.rm_rf(Dir.glob(File.join(@tmpdir, "*")))
25
29
  end
26
30
 
27
31
  def teardown
28
32
  super
29
- FileUtils.rm_rf TMP
33
+ FileUtils.rm_rf(Dir.glob(File.join(@tmpdir, "*")))
30
34
  end
31
35
  end
32
36
  end
@@ -68,12 +68,12 @@ module TestLogging
68
68
  assert_equal 'MyLogger', @event.logger
69
69
  end
70
70
 
71
- def test_method
71
+ def test_method_name
72
72
  assert_equal '', @event.file
73
73
 
74
74
  @logger.caller_tracing = true
75
75
  @logger.debug 'debug message'
76
- assert_equal 'test_method', @appender.event.method
76
+ assert_equal 'test_method_name', @appender.event.method_name
77
77
  end
78
78
 
79
79
  end # class TestLogEvent
data/test/test_logging.rb CHANGED
@@ -11,8 +11,8 @@ module TestLogging
11
11
  @levels = ::Logging::LEVELS
12
12
  @lnames = ::Logging::LNAMES
13
13
 
14
- @fn = File.join(TMP, 'test.log')
15
- @glob = File.join(TMP, '*.log')
14
+ @fn = File.join(@tmpdir, 'test.log')
15
+ @glob = File.join(@tmpdir, '*.log')
16
16
  end
17
17
 
18
18
  def test_backtrace
@@ -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
 
@@ -235,6 +253,31 @@ module TestLogging
235
253
  assert_match %r/\d+\.\d+\.\d+/, ::Logging.version
236
254
  end
237
255
 
238
- end # class TestLogging
239
- end # module TestLogging
256
+ class Failer
257
+ class WriteError < StandardError ; end
258
+ def self.write(*args)
259
+ raise WriteError.new("Oh noooooo")
260
+ end
261
+ end
240
262
 
263
+ def test_error_handling
264
+ logger = ::Logging.logger Failer, 2, 100
265
+ logger.appenders.first.level = :debug
266
+
267
+ # No errors are raised by default
268
+ logger.fatal 'this is a debug message'
269
+ # Always reset the level; we disable appenders that raise by setting them
270
+ # to :off
271
+ logger.appenders.first.level = :debug
272
+
273
+ begin
274
+ Logging.raise_errors = true
275
+ assert_raises Failer::WriteError do
276
+ logger.fatal 'this fails because the file descriptor is closed'
277
+ end
278
+ ensure
279
+ Logging.raise_errors = false
280
+ end
281
+ end
282
+ end
283
+ end
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.1
4
+ version: 2.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Pease
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-10 00:00:00.000000000 Z
11
+ date: 2022-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: little-plugger
@@ -30,28 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.10'
33
+ version: '1.14'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.10'
40
+ version: '1.14'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: test-unit
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '3.1'
47
+ version: '3.3'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '3.1'
54
+ version: '3.3'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bones-git
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: 3.8.4
75
+ version: 3.8.5
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: 3.8.4
82
+ version: 3.8.5
83
83
  description: |-
84
84
  **Logging** is a flexible logging library for use in Ruby programs based on the
85
85
  design of Java's log4j library. It features a hierarchical logging system,
@@ -179,7 +179,7 @@ files:
179
179
  homepage: http://rubygems.org/gems/logging
180
180
  licenses: []
181
181
  metadata: {}
182
- post_install_message:
182
+ post_install_message:
183
183
  rdoc_options:
184
184
  - "--main"
185
185
  - README.md
@@ -196,9 +196,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
196
196
  - !ruby/object:Gem::Version
197
197
  version: '0'
198
198
  requirements: []
199
- rubyforge_project: logging
200
- rubygems_version: 2.6.11
201
- signing_key:
199
+ rubygems_version: 3.3.7
200
+ signing_key:
202
201
  specification_version: 4
203
202
  summary: A flexible and extendable logging library for Ruby
204
203
  test_files: