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,98 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ougai::Formatters::Base do
4
+ subject { described_class.new(app_name, hostname) }
5
+
6
+ context 'default' do
7
+ let!(:app_name) { nil }
8
+ let!(:hostname) { nil }
9
+
10
+ it 'has datetime format default ISO8601' do
11
+ expect(subject.datetime_format).to match(/^\%FT\%T\.\%3N(Z|\%\:z)$/)
12
+ end
13
+
14
+ it 'has datetime_format accessor' do
15
+ subject.datetime_format = '%I:%M:%S %p'
16
+ expect(subject.datetime_format).to eq('%I:%M:%S %p')
17
+
18
+ # revert default format by to set nil
19
+ subject.datetime_format = nil
20
+ expect(subject.datetime_format).to match(/^\%FT\%T\.\%3N(Z|\%\:z)$/)
21
+ end
22
+ end
23
+
24
+ context 'without arguments and hostname contains a UTF-8 char' do
25
+ let!(:app_name) { nil }
26
+ let!(:hostname) { nil }
27
+
28
+ it 'has default app_name and default hostname' do
29
+ myhostname = "Taro\xE2\x80\x99s-MacBook".force_encoding('ASCII-8BIT')
30
+ allow(Socket).to receive(:gethostname).and_return(myhostname)
31
+ expect(subject.app_name).to eq('rspec')
32
+ expect(subject.hostname).to eq("Taro’s-MacBook")
33
+ end
34
+ end
35
+
36
+ context 'with app_name' do
37
+ let!(:app_name) { 'myapp' }
38
+ let!(:hostname) { nil }
39
+
40
+ it 'has specified app_name and default hostname' do
41
+ myhostname = "Hanako's PC".encode('ASCII-8BIT')
42
+ allow(Socket).to receive(:gethostname).and_return(myhostname)
43
+ expect(subject.app_name).to eq('myapp')
44
+ expect(subject.hostname).to eq("Hanako's PC")
45
+ end
46
+ end
47
+
48
+ context 'with hostname' do
49
+ let!(:app_name) { nil }
50
+ let!(:hostname) { 'myhost' }
51
+
52
+ it 'has default app_name and specified hostname' do
53
+ expect(subject.app_name).to eq('rspec')
54
+ expect(subject.hostname).to eq('myhost')
55
+ end
56
+ end
57
+
58
+ context 'with app_name and hostname' do
59
+ let!(:app_name) { 'myapp' }
60
+ let!(:hostname) { 'myhost' }
61
+
62
+ it 'has specified app_name and specified hostname' do
63
+ expect(subject.app_name).to eq('myapp')
64
+ expect(subject.hostname).to eq('myhost')
65
+ end
66
+ end
67
+
68
+ describe '#serialize_exc' do
69
+ let!(:app_name) { 'myapp' }
70
+ let!(:hostname) { 'myhost' }
71
+ let!(:errmsg) { 'dummy error' }
72
+
73
+ it 'returning data with stack as String' do
74
+ begin
75
+ raise errmsg
76
+ rescue => e
77
+ result = subject.serialize_exc(e)
78
+ end
79
+ expect(result[:message]).to eq(errmsg)
80
+ expect(result[:stack]).to be_instance_of(String)
81
+ end
82
+
83
+ context 'not serialize backtrace' do
84
+ it 'returning data with stack as Array' do
85
+ subject.serialize_backtrace = false
86
+ subject.trace_max_lines = 6
87
+ begin
88
+ raise errmsg
89
+ rescue => e
90
+ result = subject.serialize_exc(e)
91
+ end
92
+ expect(result[:message]).to eq(errmsg)
93
+ expect(result[:stack]).to be_instance_of(Array)
94
+ expect(result[:stack].size).to eq(6)
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,157 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ougai::Formatters::Bunyan do
4
+ let(:data) do
5
+ {
6
+ msg: 'Log Message!',
7
+ status: 200,
8
+ method: 'GET',
9
+ path: '/'
10
+ }
11
+ end
12
+
13
+ let(:stack) { "error1.rb\n error2.rb" }
14
+
15
+ let(:err) do
16
+ {
17
+ name: 'DummyError',
18
+ message: 'it is dummy.',
19
+ stack: stack
20
+ }
21
+ end
22
+
23
+ let(:formatter) { described_class.new }
24
+
25
+ include_examples 'formatter#initialize',
26
+ default_opts: {
27
+ trace_indent: 2,
28
+ trace_max_lines: 100,
29
+ serialize_backtrace: true,
30
+ jsonize: true,
31
+ with_newline: true
32
+ },
33
+ options: {
34
+ jsonize: false,
35
+ with_newline: false
36
+ }
37
+
38
+ describe '#call' do
39
+ subject { formatter.call(severity, Time.now, nil, data) }
40
+
41
+ context 'jsonize is true and with_newline is true' do
42
+ let!(:severity) { 'DEBUG' }
43
+
44
+ it 'includes valid strings' do
45
+ expect(subject).to end_with("\n")
46
+ result = JSON.parse(subject.chomp, symbolize_names: true)
47
+ expect(result).to include(data.merge(pid: $$, level: 20, v: 0))
48
+ expect(result[:time]).to match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/)
49
+ end
50
+ end
51
+
52
+ context 'jsonize is false' do
53
+ before do
54
+ formatter.jsonize = false
55
+ end
56
+
57
+ context 'when severity is TRACE' do
58
+ let!(:severity) { 'TRACE' }
59
+
60
+ it 'includes valid hash' do
61
+ expect(subject).to include(data.merge(pid: $$, level: 10, v: 0))
62
+ expect(subject[:time]).to be_an_instance_of(Time)
63
+ end
64
+ end
65
+
66
+ context 'when severity is DEBUG' do
67
+ let!(:severity) { 'DEBUG' }
68
+
69
+ it 'includes valid hash' do
70
+ expect(subject).to include(data.merge(pid: $$, level: 20, v: 0))
71
+ expect(subject[:time]).to be_an_instance_of(Time)
72
+ end
73
+ end
74
+
75
+ context 'when severity is INFO' do
76
+ let!(:severity) { 'INFO' }
77
+
78
+ it 'includes valid hash' do
79
+ expect(subject).to include(data.merge(pid: $$, level: 30, v: 0))
80
+ expect(subject[:time]).to be_an_instance_of(Time)
81
+ end
82
+ end
83
+
84
+ context 'when severity is WARN' do
85
+ let!(:severity) { 'WARN' }
86
+
87
+ it 'includes valid hash' do
88
+ expect(subject).to include(data.merge(pid: $$, level: 40, v: 0))
89
+ expect(subject[:time]).to be_an_instance_of(Time)
90
+ end
91
+ end
92
+
93
+ context 'when severity is ERROR' do
94
+ let!(:severity) { 'ERROR' }
95
+
96
+ before { data.merge!({ err: err }) }
97
+
98
+ it 'includes valid hash' do
99
+ expect(subject).to include(pid: $$, level: 50, v: 0, err: err)
100
+ expect(subject[:time]).to be_an_instance_of(Time)
101
+ end
102
+ end
103
+
104
+ context 'when severity is FATAL' do
105
+ let!(:severity) { 'FATAL' }
106
+ let!(:data) do
107
+ { msg: 'TheEnd', err: err }
108
+ end
109
+
110
+ it 'includes valid hash' do
111
+ expect(subject).to include(pid: $$, level: 60, v: 0, err: err)
112
+ expect(subject[:time]).to be_an_instance_of(Time)
113
+ end
114
+ end
115
+
116
+ context 'when severity is UNKNOWN' do
117
+ let!(:severity) { 'ANY' }
118
+ let!(:data) do
119
+ { msg: 'unknown msg' }
120
+ end
121
+
122
+ it 'includes valid hash' do
123
+ expect(subject).to include(pid: $$, level: 70, msg: 'unknown msg', v: 0)
124
+ end
125
+ end
126
+ end
127
+
128
+ context 'with_newline is false' do
129
+ let!(:severity) { 'INFO' }
130
+
131
+ before do
132
+ formatter.with_newline = false
133
+ end
134
+
135
+ it 'includes valid strings' do
136
+ expect(subject).not_to end_with("\n")
137
+ result = JSON.parse(subject, symbolize_names: true)
138
+ expect(result).to include(data.merge(pid: $$, level: 30, v: 0))
139
+ expect(result[:time]).to match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/)
140
+ end
141
+ end
142
+ end
143
+
144
+ describe '#datetime_format' do
145
+ context 'is time AM/PM format' do
146
+ before do
147
+ formatter.datetime_format = '%I:%M:%S %p'
148
+ end
149
+
150
+ it 'applys output' do
151
+ subject = formatter.call('DEBUG', Time.now, nil, data)
152
+ result = JSON.parse(subject, symbolize_names: true)
153
+ expect(result[:time]).to match(/^\d{2}:\d{2}:\d{2} [AP]M$/)
154
+ end
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,168 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ougai::Formatters::Pino do
4
+ let(:data) do
5
+ {
6
+ msg: 'Log Message!',
7
+ status: 200,
8
+ method: 'GET',
9
+ path: '/'
10
+ }
11
+ end
12
+
13
+ let(:stack) { "error1.rb\n error2.rb" }
14
+
15
+ let(:err) do
16
+ {
17
+ name: 'DummyError',
18
+ message: 'it is dummy.',
19
+ stack: stack
20
+ }
21
+ end
22
+
23
+ let(:formatter) { described_class.new }
24
+
25
+ include_examples 'formatter#initialize',
26
+ default_opts: {
27
+ trace_indent: 4,
28
+ trace_max_lines: 100,
29
+ serialize_backtrace: true,
30
+ jsonize: true,
31
+ with_newline: true
32
+ },
33
+ options: {
34
+ jsonize: false,
35
+ with_newline: false
36
+ }
37
+
38
+ describe '#call' do
39
+ let!(:time_epoc_msec) { 1518710101026 }
40
+
41
+ before { Timecop.freeze(Time.at(time_epoc_msec / 1000.0)) }
42
+ after { Timecop.return }
43
+
44
+ subject { formatter.call(severity, Time.now, nil, data) }
45
+
46
+ context 'jsonize is true and with_newline is true' do
47
+ let!(:severity) { 'DEBUG' }
48
+
49
+ it 'includes valid strings' do
50
+ expect(subject).to end_with("\n")
51
+ result = JSON.parse(subject.chomp, symbolize_names: true)
52
+ expect(result).to include(data.merge(pid: $$, level: 20, time: time_epoc_msec, v: 1))
53
+ end
54
+ end
55
+
56
+ context 'jsonize is false' do
57
+ let!(:time) { Time.at(time_epoc_msec / 1000.0) }
58
+
59
+ before do
60
+ formatter.jsonize = false
61
+ end
62
+
63
+ context 'when severity is TRACE' do
64
+ let!(:severity) { 'TRACE' }
65
+
66
+ it 'includes valid hash' do
67
+ expect(subject).to include(data.merge(pid: $$, level: 10, time: time, v: 1))
68
+ end
69
+ end
70
+
71
+ context 'when severity is DEBUG' do
72
+ let!(:severity) { 'DEBUG' }
73
+
74
+ it 'includes valid hash' do
75
+ expect(subject).to include(data.merge(pid: $$, level: 20, time: time, v: 1))
76
+ end
77
+ end
78
+
79
+ context 'when severity is INFO' do
80
+ let!(:severity) { 'INFO' }
81
+
82
+ it 'includes valid hash' do
83
+ expect(subject).to include(data.merge(pid: $$, level: 30, time: time, v: 1))
84
+ end
85
+ end
86
+
87
+ context 'when severity is WARN' do
88
+ let!(:severity) { 'WARN' }
89
+
90
+ it 'includes valid hash' do
91
+ expect(subject).to include(data.merge(pid: $$, level: 40, time: time, v: 1))
92
+ end
93
+ end
94
+
95
+ context 'when severity is ERROR' do
96
+ let!(:severity) { 'ERROR' }
97
+
98
+ before do
99
+ data.delete(:msg)
100
+ data.merge!({ err: err })
101
+ end
102
+
103
+ it 'includes valid hash' do
104
+ expect(subject).to include({
105
+ pid: $$, level: 50, time: time, v: 1,
106
+ type: 'Error',
107
+ msg: 'it is dummy.',
108
+ stack: "DummyError: it is dummy.\n #{stack}"
109
+ })
110
+ end
111
+ end
112
+
113
+ context 'when severity is FATAL and trace_indent = 2' do
114
+ let!(:severity) { 'FATAL' }
115
+
116
+ let!(:data) do
117
+ { msg: 'TheEnd', err: err }
118
+ end
119
+
120
+ before do
121
+ formatter.trace_indent = 2
122
+ stack.gsub!(/ /, ' ')
123
+ end
124
+
125
+ it 'includes valid hash' do
126
+ expect(subject).to include({
127
+ pid: $$, level: 60, time: time, v: 1,
128
+ type: 'Error',
129
+ msg: 'TheEnd',
130
+ stack: "DummyError: it is dummy.\n #{stack}",
131
+ })
132
+ end
133
+ end
134
+
135
+ context 'when severity is UNKNOWN' do
136
+ let!(:severity) { 'ANY' }
137
+
138
+ let!(:data) do
139
+ { msg: 'unknown msg' }
140
+ end
141
+
142
+ it 'includes valid hash' do
143
+ expect(subject).to include(pid: $$, level: 70, time: time, msg: 'unknown msg')
144
+ end
145
+ end
146
+ end
147
+
148
+ context 'with_newline is false' do
149
+ let!(:severity) { 'INFO' }
150
+
151
+ before do
152
+ formatter.with_newline = false
153
+ end
154
+
155
+ it 'includes valid strings' do
156
+ expect(subject).not_to end_with("\n")
157
+ result = JSON.parse(subject, symbolize_names: true)
158
+ expect(result).to include(data.merge(level: 30, time: time_epoc_msec))
159
+ end
160
+ end
161
+ end
162
+
163
+ describe '#datetime_format' do
164
+ it 'is not supported' do
165
+ expect{ formatter.datetime_format = '%I:%M:%S %p' }.to raise_error(NotImplementedError)
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,142 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ougai::Formatters::Readable do
4
+ let!(:re_start_with_datetime) { /^\[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}(Z|[\+\-\:0-9]{4,6})\]/ }
5
+
6
+ let(:data) do
7
+ {
8
+ msg: 'Log Message!',
9
+ status: 200,
10
+ method: 'GET',
11
+ path: '/'
12
+ }
13
+ end
14
+
15
+ let(:err) do
16
+ {
17
+ name: 'DummyError',
18
+ message: 'it is dummy.',
19
+ stack: "error1.rb\n error2.rb"
20
+ }
21
+ end
22
+
23
+ let(:formatter) { described_class.new }
24
+
25
+ include_examples 'formatter#initialize',
26
+ default_opts: {
27
+ trace_indent: 4,
28
+ trace_max_lines: 100,
29
+ serialize_backtrace: true,
30
+ plain: false,
31
+ excluded_fields: []
32
+ },
33
+ options: {
34
+ plain: true,
35
+ excluded_fields: [:card_number]
36
+ }
37
+
38
+ context 'when severity is TRACE' do
39
+ subject { formatter.call('TRACE', Time.now, nil, data) }
40
+
41
+ it 'includes valid strings' do
42
+ expect(subject).to match(re_start_with_datetime)
43
+ expect(subject).to include("\e[0;34mTRACE\e[0m: Log Message!")
44
+ expect(subject.gsub(/\e\[([;\d]+)?m/, '')).to include(':status => 200')
45
+ end
46
+ end
47
+
48
+ context 'when severity is DEBUG' do
49
+ subject { formatter.call('DEBUG', Time.now, nil, data) }
50
+
51
+ it 'includes valid strings' do
52
+ expect(subject).to match(re_start_with_datetime)
53
+ expect(subject).to include("\e[0;37mDEBUG\e[0m: Log Message!")
54
+ expect(subject.gsub(/\e\[([;\d]+)?m/, '')).to include(':status => 200')
55
+ end
56
+ end
57
+
58
+ context 'when severity is INFO' do
59
+ subject { formatter.call('INFO', Time.now, nil, data) }
60
+
61
+ it 'includes valid strings' do
62
+ expect(subject).to match(re_start_with_datetime)
63
+ expect(subject).to include("\e[0;36mINFO\e[0m: Log Message!")
64
+ expect(subject.gsub(/\e\[([;\d]+)?m/, '')).to include(':method => "GET"')
65
+ end
66
+ end
67
+
68
+ context 'when severity is WARN' do
69
+ subject { formatter.call('WARN', Time.now, nil, data) }
70
+
71
+ it 'includes valid strings' do
72
+ expect(subject).to match(re_start_with_datetime)
73
+ expect(subject).to include("\e[0;33mWARN\e[0m: Log Message!")
74
+ expect(subject.gsub(/\e\[([;\d]+)?m/, '')).to include(':path => "/"')
75
+ end
76
+ end
77
+
78
+ context 'when severity is ERROR' do
79
+ subject { formatter.call('ERROR', Time.now, nil, data.merge({ err: err })) }
80
+
81
+ it 'includes valid strings' do
82
+ expect(subject).to match(re_start_with_datetime)
83
+ expect(subject).to include("\e[0;31mERROR\e[0m: Log Message!")
84
+ expect(subject.gsub(/\e\[([;\d]+)?m/, '')).to include('DummyError (it is dummy.):')
85
+ end
86
+ end
87
+
88
+ context 'when severity is FATAL' do
89
+ subject { formatter.call('FATAL', Time.now, nil, { msg: 'TheEnd', err: err }) }
90
+
91
+ it 'includes valid strings' do
92
+ expect(subject).to match(re_start_with_datetime)
93
+ expect(subject).to include("\e[0;35mFATAL\e[0m: TheEnd")
94
+ expect(subject.gsub(/\e\[([;\d]+)?m/, '')).to include("error1.rb\n error2.rb")
95
+ end
96
+ end
97
+
98
+ context 'when severity is UNKNOWN' do
99
+ subject { formatter.call('ANY', Time.now, nil, { msg: 'unknown msg' }) }
100
+
101
+ it 'includes valid strings' do
102
+ expect(subject).to match(re_start_with_datetime)
103
+ expect(subject).to include("\e[0;32mANY\e[0m: unknown msg")
104
+ end
105
+ end
106
+
107
+ context 'when logger has excluded_fields' do
108
+ subject do
109
+ described_class.new(excluded_fields: [:status, :method]).call('DEBUG', Time.now, nil, data)
110
+ end
111
+
112
+ it 'includes valid strings' do
113
+ expect(subject).to include("\e[0;37mDEBUG\e[0m: Log Message!")
114
+ plain_subject = subject.gsub(/\e\[([;\d]+)?m/, '')
115
+ expect(plain_subject).to include(':path => "/"')
116
+ expect(plain_subject).not_to include(':status => 200')
117
+ expect(plain_subject).not_to include(':method => "GET"')
118
+ end
119
+ end
120
+
121
+ describe '#datetime_format' do
122
+ subject do
123
+ formatter.call('DEBUG', Time.now, nil, data)
124
+ end
125
+
126
+ context 'is time AM/PM format' do
127
+ before do
128
+ formatter.datetime_format = '%I:%M:%S %p'
129
+ end
130
+
131
+ it 'applys output' do
132
+ expect(subject).to match(/^\[\d{2}:\d{2}:\d{2} [AP]M\]/)
133
+ end
134
+ end
135
+ end
136
+
137
+ describe '#serialize_backtrace' do
138
+ it 'is not supported' do
139
+ expect{ formatter.serialize_backtrace = false }.to raise_error(NotImplementedError)
140
+ end
141
+ end
142
+ end