ougai 1.4.4 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -0
- data/lib/ougai.rb +1 -1
- data/lib/ougai/child_logger.rb +30 -0
- data/lib/ougai/formatters/bunyan.rb +5 -3
- data/lib/ougai/formatters/readable.rb +6 -2
- data/lib/ougai/logger.rb +18 -0
- data/lib/ougai/logging.rb +31 -6
- data/lib/ougai/version.rb +1 -1
- data/spec/child_logger_spec.rb +83 -0
- data/spec/formatters/bunyan_spec.rb +17 -0
- data/spec/formatters/readable_spec.rb +16 -0
- data/spec/logger_spec.rb +25 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 207074987e412815fd6fbb4acb718da9b4451c95
|
4
|
+
data.tar.gz: 1e0d8320ba60fcd41c87c0dfb575cabc6cd77683
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ebf1a15410b890788c3ff9ea531d05286ec447c479bd348491a08a1735fa46d64783f805c84eedb31e73c074fa02b449c5deb2eb7a78321f493cb181696b092
|
7
|
+
data.tar.gz: 2c3e322ba81f980a55572b31aebbdc753636db5cd394fadbf1a107e160e8c9e6c74a228c64aa3d5820455744f2d37bdbccb1e4decda40daa2e9bb46c44e0b8c9
|
data/README.md
CHANGED
@@ -42,6 +42,14 @@ require 'ougai'
|
|
42
42
|
logger = Ougai::Logger.new(STDOUT)
|
43
43
|
```
|
44
44
|
|
45
|
+
### TRACE level
|
46
|
+
|
47
|
+
The `level` of logger supports **TRACE** level lower than **DEBUG**.
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
logger.level = Ougai::Logger::TRACE # , :trace or 'trace'
|
51
|
+
```
|
52
|
+
|
45
53
|
### log only a message
|
46
54
|
|
47
55
|
```ruby
|
@@ -334,6 +342,7 @@ logger.formatter = Ougai::Formatters::Readable.new
|
|
334
342
|
- [Customize Sidekiq logger](https://github.com/tilfin/ougai/wiki/Customize-Sidekiq-logger)
|
335
343
|
- [Forward logs to Fluentd](https://github.com/tilfin/ougai/wiki/Forward-logs-to-Fluentd)
|
336
344
|
- [Forward logs to Logentries](https://github.com/tilfin/ougai/wiki/Forward-logs-to-Logentries)
|
345
|
+
- [Use as ServerEngine logger](https://github.com/tilfin/ougai/wiki/Use-as-ServerEngine-logger)
|
337
346
|
|
338
347
|
## License
|
339
348
|
|
data/lib/ougai.rb
CHANGED
data/lib/ougai/child_logger.rb
CHANGED
@@ -13,6 +13,36 @@ module Ougai
|
|
13
13
|
@parent.level
|
14
14
|
end
|
15
15
|
|
16
|
+
# Whether the current severity level allows for logging DEBUG.
|
17
|
+
# @return [Boolean] true if allows
|
18
|
+
def debug?
|
19
|
+
@parent.debug?
|
20
|
+
end
|
21
|
+
|
22
|
+
# Whether the current severity level allows for logging INFO.
|
23
|
+
# @return [Boolean] true if allows
|
24
|
+
def info?
|
25
|
+
@parent.info?
|
26
|
+
end
|
27
|
+
|
28
|
+
# Whether the current severity level allows for logging WARN.
|
29
|
+
# @return [Boolean] true if allows
|
30
|
+
def warn?
|
31
|
+
@parent.warn?
|
32
|
+
end
|
33
|
+
|
34
|
+
# Whether the current severity level allows for logging ERROR.
|
35
|
+
# @return [Boolean] true if allows
|
36
|
+
def error?
|
37
|
+
@parent.error?
|
38
|
+
end
|
39
|
+
|
40
|
+
# Whether the current severity level allows for logging FATAL.
|
41
|
+
# @return [Boolean] true if allows
|
42
|
+
def fatal?
|
43
|
+
@parent.fatal?
|
44
|
+
end
|
45
|
+
|
16
46
|
# @private
|
17
47
|
def chain(severity, args, fields, hooks)
|
18
48
|
hooks.push(@before_log) if @before_log
|
@@ -28,6 +28,10 @@ module Ougai
|
|
28
28
|
|
29
29
|
def to_level(severity)
|
30
30
|
case severity
|
31
|
+
when 'TRACE'
|
32
|
+
10
|
33
|
+
when 'DEBUG'
|
34
|
+
20
|
31
35
|
when 'INFO'
|
32
36
|
30
|
33
37
|
when 'WARN'
|
@@ -36,10 +40,8 @@ module Ougai
|
|
36
40
|
50
|
37
41
|
when 'FATAL'
|
38
42
|
60
|
39
|
-
|
43
|
+
else
|
40
44
|
70
|
41
|
-
else # DEBUG
|
42
|
-
20
|
43
45
|
end
|
44
46
|
end
|
45
47
|
|
@@ -33,6 +33,10 @@ module Ougai
|
|
33
33
|
|
34
34
|
def colored_level(severity)
|
35
35
|
case severity
|
36
|
+
when 'TRACE'
|
37
|
+
color = '0;34'
|
38
|
+
when 'DEBUG'
|
39
|
+
color = '0;37'
|
36
40
|
when 'INFO'
|
37
41
|
color = '0;36'
|
38
42
|
when 'WARN'
|
@@ -41,8 +45,8 @@ module Ougai
|
|
41
45
|
color = '0;31'
|
42
46
|
when 'FATAL'
|
43
47
|
color = '0;35'
|
44
|
-
else
|
45
|
-
color = '0;
|
48
|
+
else
|
49
|
+
color = '0;32'
|
46
50
|
end
|
47
51
|
"\e[#{color}m#{severity}\e[0m"
|
48
52
|
end
|
data/lib/ougai/logger.rb
CHANGED
@@ -42,6 +42,20 @@ module Ougai
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
def level=(severity)
|
46
|
+
if severity.is_a?(Integer)
|
47
|
+
@level = severity
|
48
|
+
return
|
49
|
+
end
|
50
|
+
|
51
|
+
if severity.to_s.downcase == 'trace'
|
52
|
+
@level = TRACE
|
53
|
+
return
|
54
|
+
end
|
55
|
+
|
56
|
+
super
|
57
|
+
end
|
58
|
+
|
45
59
|
# @private
|
46
60
|
def chain(severity, args, fields, hooks)
|
47
61
|
hooks.push(@before_log) if @before_log
|
@@ -62,6 +76,10 @@ module Ougai
|
|
62
76
|
|
63
77
|
private
|
64
78
|
|
79
|
+
def format_severity(severity)
|
80
|
+
to_label(severity)
|
81
|
+
end
|
82
|
+
|
65
83
|
def write(severity, args, fields, hooks)
|
66
84
|
data = merge_fields(fields, to_item(args))
|
67
85
|
hooks.each do |hook|
|
data/lib/ougai/logging.rb
CHANGED
@@ -4,6 +4,25 @@ module Ougai
|
|
4
4
|
attr_accessor :with_fields
|
5
5
|
attr_writer :before_log
|
6
6
|
|
7
|
+
module Severity
|
8
|
+
include ::Logger::Severity
|
9
|
+
TRACE = -1
|
10
|
+
|
11
|
+
SEV_LABEL = %w(TRACE DEBUG INFO WARN ERROR FATAL ANY).each(&:freeze).freeze
|
12
|
+
|
13
|
+
def to_label(severity)
|
14
|
+
SEV_LABEL[severity + 1] || 'ANY'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
include Severity
|
18
|
+
|
19
|
+
# Log any one or more of a message, an exception and structured data as TRACE.
|
20
|
+
# @return [Boolean] true
|
21
|
+
# @see Logging#debug
|
22
|
+
def trace(message = nil, ex = nil, data = nil, &block)
|
23
|
+
log(TRACE, message, ex, data, block)
|
24
|
+
end
|
25
|
+
|
7
26
|
# Log any one or more of a message, an exception and structured data as DEBUG.
|
8
27
|
# If the block is given for delay evaluation, it returns them as an array or the one of them as a value.
|
9
28
|
# @param message [String] The message to log. Use default_message if not specified.
|
@@ -12,35 +31,35 @@ module Ougai
|
|
12
31
|
# @yieldreturn [String|Exception|Object|Array] Any one or more of former parameters
|
13
32
|
# @return [Boolean] true
|
14
33
|
def debug(message = nil, ex = nil, data = nil, &block)
|
15
|
-
log(
|
34
|
+
log(DEBUG, message, ex, data, block)
|
16
35
|
end
|
17
36
|
|
18
37
|
# Log any one or more of a message, an exception and structured data as INFO.
|
19
38
|
# @return [Boolean] true
|
20
39
|
# @see Logging#debug
|
21
40
|
def info(message = nil, ex = nil, data = nil, &block)
|
22
|
-
log(
|
41
|
+
log(INFO, message, ex, data, block)
|
23
42
|
end
|
24
43
|
|
25
44
|
# Log any one or more of a message, an exception and structured data as WARN.
|
26
45
|
# @return [Boolean] true
|
27
46
|
# @see Logging#debug
|
28
47
|
def warn(message = nil, ex = nil, data = nil, &block)
|
29
|
-
log(
|
48
|
+
log(WARN, message, ex, data, block)
|
30
49
|
end
|
31
50
|
|
32
51
|
# Log any one or more of a message, an exception and structured data as ERROR.
|
33
52
|
# @return [Boolean] true
|
34
53
|
# @see Logging#debug
|
35
54
|
def error(message = nil, ex = nil, data = nil, &block)
|
36
|
-
log(
|
55
|
+
log(ERROR, message, ex, data, block)
|
37
56
|
end
|
38
57
|
|
39
58
|
# Log any one or more of a message, an exception and structured data as FATAL.
|
40
59
|
# @return [Boolean] true
|
41
60
|
# @see Logging#debug
|
42
61
|
def fatal(message = nil, ex = nil, data = nil, &block)
|
43
|
-
log(
|
62
|
+
log(FATAL, message, ex, data, block)
|
44
63
|
end
|
45
64
|
|
46
65
|
# Log any one or more of a message, an exception and structured data as UNKNOWN.
|
@@ -48,7 +67,13 @@ module Ougai
|
|
48
67
|
# @see Logging#debug
|
49
68
|
def unknown(message = nil, ex = nil, data = nil, &block)
|
50
69
|
args = block ? yield : [message, ex, data]
|
51
|
-
append(
|
70
|
+
append(UNKNOWN, args)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Whether the current severity level allows for logging TRACE.
|
74
|
+
# @return [Boolean] true if allows
|
75
|
+
def trace?
|
76
|
+
level <= TRACE
|
52
77
|
end
|
53
78
|
|
54
79
|
# Creates a child logger and returns it.
|
data/lib/ougai/version.rb
CHANGED
data/spec/child_logger_spec.rb
CHANGED
@@ -32,10 +32,39 @@ describe Ougai::ChildLogger do
|
|
32
32
|
describe '#level propagated from parent one' do
|
33
33
|
let(:logger) { parent_logger.child }
|
34
34
|
|
35
|
+
context 'TRACE' do
|
36
|
+
let(:log_msg) { 'log message' }
|
37
|
+
before { parent_logger.level = Ougai::Logger::TRACE }
|
38
|
+
|
39
|
+
it 'outputs trace message' do
|
40
|
+
logger.trace(log_msg)
|
41
|
+
expect(item).to be_log_message(log_msg, 10)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'outputs debug message' do
|
45
|
+
logger.debug(log_msg)
|
46
|
+
expect(item).to be_log_message(log_msg, 20)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'is consistent with the methods severity allows' do
|
50
|
+
expect(logger.trace?).to be_truthy
|
51
|
+
expect(logger.debug?).to be_truthy
|
52
|
+
expect(logger.info?).to be_truthy
|
53
|
+
expect(logger.warn?).to be_truthy
|
54
|
+
expect(logger.error?).to be_truthy
|
55
|
+
expect(logger.fatal?).to be_truthy
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
35
59
|
context 'DEBUG' do
|
36
60
|
let(:log_msg) { 'log message' }
|
37
61
|
before { parent_logger.level = Logger::DEBUG }
|
38
62
|
|
63
|
+
it 'does not output trace message' do
|
64
|
+
logger.trace(log_msg)
|
65
|
+
expect(item).to be_nil
|
66
|
+
end
|
67
|
+
|
39
68
|
it 'outputs debug message' do
|
40
69
|
logger.debug(log_msg)
|
41
70
|
expect(item).to be_log_message(log_msg, 20)
|
@@ -45,6 +74,15 @@ describe Ougai::ChildLogger do
|
|
45
74
|
logger.info(log_msg)
|
46
75
|
expect(item).to be_log_message(log_msg, 30)
|
47
76
|
end
|
77
|
+
|
78
|
+
it 'is consistent with the methods severity allows' do
|
79
|
+
expect(logger.trace?).to be_falsey
|
80
|
+
expect(logger.debug?).to be_truthy
|
81
|
+
expect(logger.info?).to be_truthy
|
82
|
+
expect(logger.warn?).to be_truthy
|
83
|
+
expect(logger.error?).to be_truthy
|
84
|
+
expect(logger.fatal?).to be_truthy
|
85
|
+
end
|
48
86
|
end
|
49
87
|
|
50
88
|
context 'INFO' do
|
@@ -65,6 +103,15 @@ describe Ougai::ChildLogger do
|
|
65
103
|
logger.warn(log_msg)
|
66
104
|
expect(item).to be_log_message(log_msg, 40)
|
67
105
|
end
|
106
|
+
|
107
|
+
it 'is consistent with the methods severity allows' do
|
108
|
+
expect(logger.trace?).to be_falsey
|
109
|
+
expect(logger.debug?).to be_falsey
|
110
|
+
expect(logger.info?).to be_truthy
|
111
|
+
expect(logger.warn?).to be_truthy
|
112
|
+
expect(logger.error?).to be_truthy
|
113
|
+
expect(logger.fatal?).to be_truthy
|
114
|
+
end
|
68
115
|
end
|
69
116
|
|
70
117
|
context 'WARN' do
|
@@ -85,6 +132,15 @@ describe Ougai::ChildLogger do
|
|
85
132
|
logger.error(log_msg)
|
86
133
|
expect(item).to be_log_message(log_msg, 50)
|
87
134
|
end
|
135
|
+
|
136
|
+
it 'is consistent with the methods severity allows' do
|
137
|
+
expect(logger.trace?).to be_falsey
|
138
|
+
expect(logger.debug?).to be_falsey
|
139
|
+
expect(logger.info?).to be_falsey
|
140
|
+
expect(logger.warn?).to be_truthy
|
141
|
+
expect(logger.error?).to be_truthy
|
142
|
+
expect(logger.fatal?).to be_truthy
|
143
|
+
end
|
88
144
|
end
|
89
145
|
|
90
146
|
context 'ERROR' do
|
@@ -105,6 +161,15 @@ describe Ougai::ChildLogger do
|
|
105
161
|
logger.fatal(log_msg)
|
106
162
|
expect(item).to be_log_message(log_msg, 60)
|
107
163
|
end
|
164
|
+
|
165
|
+
it 'is consistent with the methods severity allows' do
|
166
|
+
expect(logger.trace?).to be_falsey
|
167
|
+
expect(logger.debug?).to be_falsey
|
168
|
+
expect(logger.info?).to be_falsey
|
169
|
+
expect(logger.warn?).to be_falsey
|
170
|
+
expect(logger.error?).to be_truthy
|
171
|
+
expect(logger.fatal?).to be_truthy
|
172
|
+
end
|
108
173
|
end
|
109
174
|
|
110
175
|
context 'FATAL' do
|
@@ -125,6 +190,15 @@ describe Ougai::ChildLogger do
|
|
125
190
|
logger.unknown(log_msg)
|
126
191
|
expect(item).to be_log_message(log_msg, 70)
|
127
192
|
end
|
193
|
+
|
194
|
+
it 'is consistent with the methods severity allows' do
|
195
|
+
expect(logger.trace?).to be_falsey
|
196
|
+
expect(logger.debug?).to be_falsey
|
197
|
+
expect(logger.info?).to be_falsey
|
198
|
+
expect(logger.warn?).to be_falsey
|
199
|
+
expect(logger.error?).to be_falsey
|
200
|
+
expect(logger.fatal?).to be_truthy
|
201
|
+
end
|
128
202
|
end
|
129
203
|
|
130
204
|
context 'UNKNOWN' do
|
@@ -140,6 +214,15 @@ describe Ougai::ChildLogger do
|
|
140
214
|
logger.unknown(log_msg)
|
141
215
|
expect(item).to be_log_message(log_msg, 70)
|
142
216
|
end
|
217
|
+
|
218
|
+
it 'is consistent with the methods severity allows' do
|
219
|
+
expect(logger.trace?).to be_falsey
|
220
|
+
expect(logger.debug?).to be_falsey
|
221
|
+
expect(logger.info?).to be_falsey
|
222
|
+
expect(logger.warn?).to be_falsey
|
223
|
+
expect(logger.error?).to be_falsey
|
224
|
+
expect(logger.fatal?).to be_falsey
|
225
|
+
end
|
143
226
|
end
|
144
227
|
end
|
145
228
|
|
@@ -36,6 +36,15 @@ describe Ougai::Formatters::Bunyan do
|
|
36
36
|
formatter.jsonize = false
|
37
37
|
end
|
38
38
|
|
39
|
+
context 'when severity is TRACE' do
|
40
|
+
subject { formatter.call('TRACE', Time.now, nil, data) }
|
41
|
+
|
42
|
+
it 'includes valid hash' do
|
43
|
+
expect(subject).to include(data.merge(level: 10))
|
44
|
+
expect(subject[:time]).to be_an_instance_of(Time)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
39
48
|
context 'when severity is DEBUG' do
|
40
49
|
subject { formatter.call('DEBUG', Time.now, nil, data) }
|
41
50
|
|
@@ -80,6 +89,14 @@ describe Ougai::Formatters::Bunyan do
|
|
80
89
|
expect(subject[:time]).to be_an_instance_of(Time)
|
81
90
|
end
|
82
91
|
end
|
92
|
+
|
93
|
+
context 'when severity is UNKNOWN' do
|
94
|
+
subject { formatter.call('ANY', Time.now, nil, { msg: 'unknown msg' }) }
|
95
|
+
|
96
|
+
it 'includes valid hash' do
|
97
|
+
expect(subject).to include(level: 70, msg: 'unknown msg')
|
98
|
+
end
|
99
|
+
end
|
83
100
|
end
|
84
101
|
|
85
102
|
context 'with_newline is false' do
|
@@ -18,6 +18,15 @@ describe Ougai::Formatters::Readable do
|
|
18
18
|
}
|
19
19
|
end
|
20
20
|
|
21
|
+
context 'when severity is TRACE' do
|
22
|
+
subject { described_class.new.call('TRACE', Time.now, nil, data) }
|
23
|
+
|
24
|
+
it 'includes valid strings' do
|
25
|
+
expect(subject).to include("\e[0;34mTRACE\e[0m: Log Message!")
|
26
|
+
expect(subject.gsub(/\e\[([;\d]+)?m/, '')).to include(':status => 200')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
21
30
|
context 'when severity is DEBUG' do
|
22
31
|
subject { described_class.new.call('DEBUG', Time.now, nil, data) }
|
23
32
|
|
@@ -62,6 +71,13 @@ describe Ougai::Formatters::Readable do
|
|
62
71
|
end
|
63
72
|
end
|
64
73
|
|
74
|
+
context 'when severity is UNKNOWN' do
|
75
|
+
subject { described_class.new.call('ANY', Time.now, nil, { msg: 'unknown msg' }) }
|
76
|
+
it 'includes valid strings' do
|
77
|
+
expect(subject).to include("\e[0;32mANY\e[0m: unknown msg")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
65
81
|
context 'when logger has excluded_fields' do
|
66
82
|
subject do
|
67
83
|
described_class.new(excluded_fields: [:status, :method]).call('DEBUG', Time.now, nil, data)
|
data/spec/logger_spec.rb
CHANGED
@@ -232,12 +232,36 @@ describe Ougai::Logger do
|
|
232
232
|
end
|
233
233
|
end
|
234
234
|
|
235
|
+
describe '#trace' do
|
236
|
+
let(:log_level) { 10 }
|
237
|
+
let(:log_msg) { 'trace message' }
|
238
|
+
let(:method) { 'trace' }
|
239
|
+
|
240
|
+
before { logger.level = :trace }
|
241
|
+
|
242
|
+
it_behaves_like 'log'
|
243
|
+
|
244
|
+
it 'is consistent with the methods severity allows' do
|
245
|
+
expect(logger.trace?).to be_truthy
|
246
|
+
expect(logger.debug?).to be_truthy
|
247
|
+
expect(logger.info?).to be_truthy
|
248
|
+
expect(logger.warn?).to be_truthy
|
249
|
+
expect(logger.error?).to be_truthy
|
250
|
+
expect(logger.fatal?).to be_truthy
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
235
254
|
describe '#debug' do
|
236
255
|
let(:log_level) { 20 }
|
237
256
|
let(:log_msg) { 'debug message' }
|
238
257
|
let(:method) { 'debug' }
|
239
258
|
|
240
259
|
it_behaves_like 'log'
|
260
|
+
|
261
|
+
it 'is consistent with the methods severity allows' do
|
262
|
+
expect(logger.trace?).to be_falsey
|
263
|
+
expect(logger.debug?).to be_truthy
|
264
|
+
end
|
241
265
|
end
|
242
266
|
|
243
267
|
describe '#info' do
|
@@ -538,7 +562,7 @@ describe Ougai::Logger do
|
|
538
562
|
|
539
563
|
context 'another logger level is the same as original one' do
|
540
564
|
before do
|
541
|
-
logger.level = Logger::INFO # propagate
|
565
|
+
logger.level = Logger::INFO # propagate severity to another one
|
542
566
|
end
|
543
567
|
|
544
568
|
it 'does not output debug log on both loggers' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ougai
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Toshimitsu Takahashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -95,7 +95,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
95
95
|
requirements:
|
96
96
|
- - ">="
|
97
97
|
- !ruby/object:Gem::Version
|
98
|
-
version: 2.1.
|
98
|
+
version: 2.1.2
|
99
99
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - ">="
|
@@ -103,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
103
|
version: '0'
|
104
104
|
requirements: []
|
105
105
|
rubyforge_project:
|
106
|
-
rubygems_version: 2.6.
|
106
|
+
rubygems_version: 2.6.13
|
107
107
|
signing_key:
|
108
108
|
specification_version: 4
|
109
109
|
summary: JSON logger compatible with node-bunyan is capable of handling structured
|