ougai 1.7.1-java

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.
@@ -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