ougai 1.7.1-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ougai
4
+ # Common Logging features
5
+ module Logging
6
+ attr_accessor :with_fields
7
+ attr_writer :before_log
8
+
9
+ module Severity
10
+ include ::Logger::Severity
11
+ TRACE = -1
12
+
13
+ SEV_LABEL = %w(TRACE DEBUG INFO WARN ERROR FATAL ANY)
14
+
15
+ def to_label(severity)
16
+ SEV_LABEL[severity + 1] || 'ANY'
17
+ end
18
+ end
19
+ include Severity
20
+
21
+ # Log any one or more of a message, an exception and structured data as TRACE.
22
+ # @return [Boolean] true
23
+ # @see Logging#debug
24
+ def trace(message = nil, ex = nil, data = nil, &block)
25
+ log(TRACE, message, ex, data, block)
26
+ end
27
+
28
+ # Log any one or more of a message, an exception and structured data as DEBUG.
29
+ # If the block is given for delay evaluation, it returns them as an array or the one of them as a value.
30
+ # @param message [String] The message to log. Use default_message if not specified.
31
+ # @param ex [Exception] The exception or the error
32
+ # @param data [Object] Any structured data
33
+ # @yieldreturn [String|Exception|Object|Array] Any one or more of former parameters
34
+ # @return [Boolean] true
35
+ def debug(message = nil, ex = nil, data = nil, &block)
36
+ log(DEBUG, message, ex, data, block)
37
+ end
38
+
39
+ # Log any one or more of a message, an exception and structured data as INFO.
40
+ # @return [Boolean] true
41
+ # @see Logging#debug
42
+ def info(message = nil, ex = nil, data = nil, &block)
43
+ log(INFO, message, ex, data, block)
44
+ end
45
+
46
+ # Log any one or more of a message, an exception and structured data as WARN.
47
+ # @return [Boolean] true
48
+ # @see Logging#debug
49
+ def warn(message = nil, ex = nil, data = nil, &block)
50
+ log(WARN, message, ex, data, block)
51
+ end
52
+
53
+ # Log any one or more of a message, an exception and structured data as ERROR.
54
+ # @return [Boolean] true
55
+ # @see Logging#debug
56
+ def error(message = nil, ex = nil, data = nil, &block)
57
+ log(ERROR, message, ex, data, block)
58
+ end
59
+
60
+ # Log any one or more of a message, an exception and structured data as FATAL.
61
+ # @return [Boolean] true
62
+ # @see Logging#debug
63
+ def fatal(message = nil, ex = nil, data = nil, &block)
64
+ log(FATAL, message, ex, data, block)
65
+ end
66
+
67
+ # Log any one or more of a message, an exception and structured data as UNKNOWN.
68
+ # @return [Boolean] true
69
+ # @see Logging#debug
70
+ def unknown(message = nil, ex = nil, data = nil, &block)
71
+ args = block ? yield : [message, ex, data]
72
+ append(UNKNOWN, args)
73
+ end
74
+
75
+ # Whether the current severity level allows for logging TRACE.
76
+ # @return [Boolean] true if allows
77
+ def trace?
78
+ level <= TRACE
79
+ end
80
+
81
+ # Creates a child logger and returns it.
82
+ # @param fields [Hash] The fields appending to all logs
83
+ # @return [ChildLogger] A created child logger
84
+ def child(fields = {})
85
+ ch = ChildLogger.new(self, fields)
86
+
87
+ if !block_given?
88
+ ch
89
+ else
90
+ yield ch
91
+ end
92
+ end
93
+
94
+ # @private
95
+ def chain(_severity, _args, _fields, _hooks)
96
+ raise NotImplementedError
97
+ end
98
+
99
+ protected
100
+
101
+ # @private
102
+ def append(severity, args)
103
+ raise NotImplementedError
104
+ end
105
+
106
+ # @private
107
+ def weak_merge!(base_data, inferior_data)
108
+ base_data.merge!(inferior_data) do |_, base_v, inferior_v|
109
+ if base_v.is_a?(Array) and inferior_v.is_a?(Array)
110
+ (inferior_v + base_v).uniq
111
+ else
112
+ base_v
113
+ end
114
+ end
115
+ end
116
+
117
+ private
118
+
119
+ def log(severity, message, ex, data, block)
120
+ return true if level > severity
121
+ args = block ? block.call : [message, ex, data]
122
+ append(severity, args)
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ougai
4
+ class Serializer
5
+ def self.for_json
6
+ if RUBY_PLATFORM =~ /java/
7
+ require 'ougai/serializers/json_jr_jackson'
8
+ Serializers::JsonJrJackson.new
9
+ else
10
+ require 'ougai/serializers/json_oj'
11
+ Serializers::JsonOj.new
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jrjackson'
4
+
5
+ module Ougai::Serializers
6
+ class JsonJrJackson < Ougai::Serializer
7
+ def serialize(data)
8
+ JrJackson::Json.dump(data)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'oj'
4
+
5
+ module Ougai::Serializers
6
+ class JsonOj < Ougai::Serializer
7
+ OJ_OPTIONS = { mode: :custom, time_format: :xmlschema,
8
+ use_as_json: true, use_to_hash: true, use_to_json: true }
9
+
10
+ def serialize(data)
11
+ Oj.dump(data, OJ_OPTIONS)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ougai
4
+ VERSION = '1.7.1'
5
+ end
@@ -0,0 +1,439 @@
1
+ require 'spec_helper'
2
+ require 'stringio'
3
+ require 'json'
4
+
5
+ describe Ougai::ChildLogger do
6
+ let(:pid) { Process.pid }
7
+
8
+ matcher :be_log_message do |message, level|
9
+ match do |actual|
10
+ actual[:name] == 'rspec' \
11
+ && actual[:msg] == message \
12
+ && actual[:level] == level \
13
+ && actual[:pid] == pid \
14
+ && actual[:v] == 0
15
+ end
16
+ end
17
+
18
+ let(:io) { StringIO.new }
19
+ let(:parent_logger) { Ougai::Logger.new(io) }
20
+
21
+ let(:items) do
22
+ io.rewind
23
+ io.readlines.map do |line|
24
+ JSON.parse(line.chomp, symbolize_names: true)
25
+ end
26
+ end
27
+
28
+ let(:item) {
29
+ items[0]
30
+ }
31
+
32
+ describe '#level propagated from parent one' do
33
+ let(:logger) { parent_logger.child }
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
+
59
+ context 'DEBUG' do
60
+ let(:log_msg) { 'log message' }
61
+ before { parent_logger.level = Logger::DEBUG }
62
+
63
+ it 'does not output trace message' do
64
+ logger.trace(log_msg)
65
+ expect(item).to be_nil
66
+ end
67
+
68
+ it 'outputs debug message' do
69
+ logger.debug(log_msg)
70
+ expect(item).to be_log_message(log_msg, 20)
71
+ end
72
+
73
+ it 'outputs info message' do
74
+ logger.info(log_msg)
75
+ expect(item).to be_log_message(log_msg, 30)
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
86
+ end
87
+
88
+ context 'INFO' do
89
+ let(:log_msg) { 'log message' }
90
+ before { parent_logger.level = Logger::INFO }
91
+
92
+ it 'does not output debug message' do
93
+ logger.debug(log_msg)
94
+ expect(item).to be_nil
95
+ end
96
+
97
+ it 'outputs info message' do
98
+ logger.info(log_msg)
99
+ expect(item).to be_log_message(log_msg, 30)
100
+ end
101
+
102
+ it 'outputs warning message' do
103
+ logger.warn(log_msg)
104
+ expect(item).to be_log_message(log_msg, 40)
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
115
+ end
116
+
117
+ context 'WARN' do
118
+ let(:log_msg) { 'log message' }
119
+ before { parent_logger.level = Logger::WARN }
120
+
121
+ it 'does not output info message' do
122
+ logger.info(log_msg)
123
+ expect(item).to be_nil
124
+ end
125
+
126
+ it 'outputs warning message' do
127
+ logger.warn(log_msg)
128
+ expect(item).to be_log_message(log_msg, 40)
129
+ end
130
+
131
+ it 'outputs error message' do
132
+ logger.error(log_msg)
133
+ expect(item).to be_log_message(log_msg, 50)
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
144
+ end
145
+
146
+ context 'ERROR' do
147
+ let(:log_msg) { 'log message' }
148
+ before { parent_logger.level = Logger::ERROR }
149
+
150
+ it 'does not output warning message' do
151
+ logger.warn(log_msg)
152
+ expect(item).to be_nil
153
+ end
154
+
155
+ it 'outputs error message' do
156
+ logger.error(log_msg)
157
+ expect(item).to be_log_message(log_msg, 50)
158
+ end
159
+
160
+ it 'outputs fatal message' do
161
+ logger.fatal(log_msg)
162
+ expect(item).to be_log_message(log_msg, 60)
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
173
+ end
174
+
175
+ context 'FATAL' do
176
+ let(:log_msg) { 'log message' }
177
+ before { parent_logger.level = Logger::FATAL }
178
+
179
+ it 'does not output error message' do
180
+ logger.error(log_msg)
181
+ expect(item).to be_nil
182
+ end
183
+
184
+ it 'outputs fatal message' do
185
+ logger.fatal(log_msg)
186
+ expect(item).to be_log_message(log_msg, 60)
187
+ end
188
+
189
+ it 'outputs unknown message' do
190
+ logger.unknown(log_msg)
191
+ expect(item).to be_log_message(log_msg, 70)
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
202
+ end
203
+
204
+ context 'UNKNOWN' do
205
+ let(:log_msg) { 'log message' }
206
+ before { parent_logger.level = Logger::UNKNOWN }
207
+
208
+ it 'does not output fatal message' do
209
+ logger.fatal(log_msg)
210
+ expect(item).to be_nil
211
+ end
212
+
213
+ it 'outputs unknown message' do
214
+ logger.unknown(log_msg)
215
+ expect(item).to be_log_message(log_msg, 70)
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
226
+ end
227
+ end
228
+
229
+ describe '#chain' do
230
+ let(:log_level) { 30 }
231
+ let(:log_msg) { 'log message' }
232
+ let(:parent_log_msg) { 'parent log message' }
233
+
234
+ context 'parent with fields, child with fields' do
235
+ before do
236
+ parent_logger.with_fields = { foo: 1, pos: 'parent' }
237
+ end
238
+
239
+ let(:logger) { parent_logger.child(bar: '1', pos: 'child') }
240
+
241
+ it 'outputs with merged parent and child fields' do
242
+ logger.info(log_msg)
243
+ parent_logger.info(parent_log_msg)
244
+
245
+ expect(items[0]).to be_log_message(log_msg, log_level)
246
+ expect(items[0]).to include(foo: 1, bar: '1', pos: 'child')
247
+ expect(items[1]).to be_log_message(parent_log_msg, log_level)
248
+ expect(items[1]).to include(foo: 1, pos: 'parent')
249
+ expect(items[1]).not_to include(:bar)
250
+ end
251
+
252
+ context 'after updating with_fieldses of parent and child' do
253
+ before do
254
+ parent_logger.with_fields = { foo: 11 }
255
+ logger.with_fields = { bar: '11' }
256
+ end
257
+
258
+ it 'outputs with child fields' do
259
+ logger.info(log_msg)
260
+ parent_logger.info(parent_log_msg)
261
+
262
+ expect(items[0]).to be_log_message(log_msg, log_level)
263
+ expect(items[0]).to include(foo: 11, bar: '11')
264
+ expect(items[0]).not_to include(:pos)
265
+ expect(items[1]).to be_log_message(parent_log_msg, log_level)
266
+ expect(items[1]).to include(foo: 11)
267
+ expect(items[1]).not_to include(:bar, :pos)
268
+ end
269
+ end
270
+ end
271
+
272
+ context 'parent with fields, child without fields' do
273
+ before do
274
+ parent_logger.with_fields = { foo: 2, pos: 'parent' }
275
+ end
276
+
277
+ let(:logger) { parent_logger.child }
278
+
279
+ it 'output valid' do
280
+ logger.info(log_msg)
281
+ parent_logger.info(parent_log_msg)
282
+
283
+ expect(items[0]).to be_log_message(log_msg, log_level)
284
+ expect(items[0]).to include(foo: 2, pos: 'parent')
285
+ expect(items[1]).to be_log_message(parent_log_msg, log_level)
286
+ expect(items[1]).to include(foo: 2, pos: 'parent')
287
+ end
288
+
289
+ context 'after updating parent logger with_fields' do
290
+ before do
291
+ parent_logger.with_fields = { foo: 22 }
292
+ end
293
+
294
+ it 'output with new parent fields' do
295
+ logger.info(log_msg)
296
+ parent_logger.info(parent_log_msg)
297
+
298
+ expect(items[0]).to be_log_message(log_msg, log_level)
299
+ expect(items[0]).to include(foo: 22)
300
+ expect(items[0]).not_to include(:pos)
301
+ expect(items[1]).to be_log_message(parent_log_msg, log_level)
302
+ expect(items[1]).to include(foo: 22)
303
+ expect(items[1]).not_to include(:pos)
304
+ end
305
+ end
306
+ end
307
+
308
+ context 'parent without fields, child with fields' do
309
+ before do
310
+ parent_logger.with_fields = {}
311
+ end
312
+
313
+ let(:logger) { parent_logger.child(bar: '3', pos: 'child') }
314
+
315
+ it 'output valid' do
316
+ logger.info(log_msg)
317
+ parent_logger.info(parent_log_msg)
318
+
319
+ expect(items[0]).to be_log_message(log_msg, log_level)
320
+ expect(items[0]).to include(bar: '3', pos: 'child')
321
+ expect(items[1]).to be_log_message(parent_log_msg, log_level)
322
+ expect(items[1]).not_to include(:bar, :pos)
323
+ end
324
+
325
+ context 'after updating child logger with_fields' do
326
+ before do
327
+ logger.with_fields = { bar: '33' }
328
+ end
329
+
330
+ it 'output valid' do
331
+ logger.info(log_msg)
332
+ parent_logger.info(parent_log_msg)
333
+
334
+ expect(items[0]).to be_log_message(log_msg, log_level)
335
+ expect(items[0]).to include(bar: '33')
336
+ expect(items[0]).not_to include(:pos)
337
+ expect(items[1]).to be_log_message(parent_log_msg, log_level)
338
+ expect(items[1]).not_to include(:bar, :pos)
339
+ end
340
+ end
341
+ end
342
+
343
+ context 'grandchild logger' do
344
+ before do
345
+ parent_logger.with_fields = { tag: 'parent', tags: ['parent'] }
346
+ end
347
+
348
+ let(:logger) { parent_logger.child(tag: 'child', tags: ['child']) }
349
+ let(:grand_logger) { logger.child(tag: 'grandchild', tags: ['grandchild']) }
350
+
351
+ it 'outputs with all merged fields' do
352
+ grand_logger.info('Hi', foo: 3)
353
+ logger.info(log_msg, foo: 2)
354
+ parent_logger.info(parent_log_msg, foo: 10)
355
+ parent_logger.info('Good evening!', foo: 11)
356
+
357
+ expect(items[0]).to be_log_message('Hi', log_level)
358
+ expect(items[0]).to include(tag: 'grandchild', tags: ['parent', 'child', 'grandchild'], foo: 3)
359
+
360
+ expect(items[1]).to be_log_message(log_msg, log_level)
361
+ expect(items[1]).to include(tag: 'child', tags: ['parent', 'child'], foo: 2)
362
+
363
+ expect(items[2]).to be_log_message(parent_log_msg, log_level)
364
+ expect(items[2]).to include(tag: 'parent', tags: ['parent'], foo: 10)
365
+ expect(items[3]).to be_log_message('Good evening!', log_level)
366
+ expect(items[3]).to include(tag: 'parent', tags: ['parent'], foo: 11)
367
+ end
368
+
369
+ context 'after updating child logger with_fields' do
370
+ before do
371
+ logger.with_fields = { bar: '33' }
372
+ end
373
+
374
+ it 'outputs with child fields' do
375
+ logger.info(log_msg)
376
+ expect(items[0]).to be_log_message(log_msg, log_level)
377
+ expect(items[0]).to include(bar: '33')
378
+ expect(items[0]).not_to include(:pos)
379
+ end
380
+ end
381
+ end
382
+ end
383
+
384
+ describe '#before_log' do
385
+ let(:logger) { parent_logger.child }
386
+ let(:log_msg) { 'before_log test' }
387
+
388
+ before do
389
+ parent_logger.level = Logger::INFO
390
+ end
391
+
392
+ context 'child logger to be set before_log' do
393
+ before do
394
+ logger.before_log = lambda do |data|
395
+ data[:context_id] = 123
396
+ end
397
+ end
398
+
399
+ it 'outputs the field to be added in before_log' do
400
+ logger.info(log_msg)
401
+ expect(item).to be_log_message(log_msg, 30)
402
+ expect(item).to include(context_id: 123)
403
+ end
404
+ end
405
+
406
+ context 'parent logger to be set before_log' do
407
+ before do
408
+ parent_logger.before_log = lambda do |data|
409
+ data[:context_id] = 12345
410
+ end
411
+ end
412
+
413
+ it 'outputs the field to be added in before_log' do
414
+ logger.info(log_msg)
415
+ expect(item).to be_log_message(log_msg, 30)
416
+ expect(item).to include(context_id: 12345)
417
+ end
418
+ end
419
+
420
+ context 'both child logger and parent logger to be set before_log' do
421
+ before do
422
+ logger.before_log = lambda do |data|
423
+ data[:context_id] = 67890
424
+ data[:context_name] = 'sub'
425
+ end
426
+ parent_logger.before_log = lambda do |data|
427
+ data[:context_id] = 12345
428
+ end
429
+ end
430
+
431
+ it 'outputs the fields to be added in each before_log' do
432
+ logger.info(log_msg)
433
+ expect(item).to be_log_message(log_msg, 30)
434
+ expect(item).to include(context_id: 12345) # parent
435
+ expect(item).to include(context_name: 'sub') # child
436
+ end
437
+ end
438
+ end
439
+ end