semantic_logger 3.4.1 → 4.0.0.beta1
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.
- checksums.yaml +4 -4
- data/README.md +10 -0
- data/Rakefile +4 -8
- data/lib/semantic_logger.rb +2 -31
- data/lib/semantic_logger/appender.rb +76 -0
- data/lib/semantic_logger/appender/bugsnag.rb +3 -8
- data/lib/semantic_logger/appender/file.rb +1 -1
- data/lib/semantic_logger/appender/honeybadger.rb +1 -1
- data/lib/semantic_logger/appender/http.rb +1 -1
- data/lib/semantic_logger/appender/mongodb.rb +30 -28
- data/lib/semantic_logger/appender/sentry.rb +2 -2
- data/lib/semantic_logger/appender/splunk_http.rb +4 -4
- data/lib/semantic_logger/appender/syslog.rb +2 -2
- data/lib/semantic_logger/appender/tcp.rb +9 -5
- data/lib/semantic_logger/appender/udp.rb +1 -0
- data/lib/semantic_logger/base.rb +73 -140
- data/lib/semantic_logger/core_ext/thread.rb +4 -1
- data/lib/semantic_logger/formatters/color.rb +7 -0
- data/lib/semantic_logger/formatters/default.rb +7 -0
- data/lib/semantic_logger/formatters/syslog.rb +1 -1
- data/lib/semantic_logger/log.rb +115 -12
- data/lib/semantic_logger/logger.rb +6 -215
- data/lib/semantic_logger/metrics/new_relic.rb +1 -1
- data/lib/semantic_logger/metrics/statsd.rb +5 -1
- data/lib/semantic_logger/metrics/udp.rb +80 -0
- data/lib/semantic_logger/processor.rb +235 -0
- data/lib/semantic_logger/semantic_logger.rb +36 -65
- data/lib/semantic_logger/subscriber.rb +2 -2
- data/lib/semantic_logger/version.rb +1 -1
- data/test/appender/bugsnag_test.rb +10 -9
- data/test/appender/elasticsearch_test.rb +3 -2
- data/test/appender/graylog_test.rb +4 -3
- data/test/appender/honeybadger_test.rb +2 -2
- data/test/appender/http_test.rb +3 -2
- data/test/appender/mongodb_test.rb +24 -23
- data/test/appender/new_relic_test.rb +15 -8
- data/test/appender/sentry_test.rb +2 -2
- data/test/appender/splunk_http_test.rb +8 -7
- data/test/appender/splunk_test.rb +6 -5
- data/test/appender/tcp_test.rb +3 -4
- data/test/appender/udp_test.rb +4 -5
- data/test/appender/wrapper_test.rb +37 -38
- data/test/concerns/compatibility_test.rb +2 -2
- data/test/loggable_test.rb +1 -1
- data/test/logger_test.rb +149 -528
- data/test/measure_test.rb +249 -0
- data/test/semantic_logger_test.rb +257 -0
- metadata +24 -16
@@ -0,0 +1,249 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
class MeasureTest < Minitest::Test
|
4
|
+
describe 'Measure' do
|
5
|
+
before do
|
6
|
+
SemanticLogger.default_level = :trace
|
7
|
+
SemanticLogger.backtrace_level = nil
|
8
|
+
@mock_logger = MockLogger.new
|
9
|
+
@appender = SemanticLogger.add_appender(logger: @mock_logger)
|
10
|
+
@logger = SemanticLogger['LoggerTest']
|
11
|
+
@hash = {session_id: 'HSSKLEU@JDK767', tracking_number: 12345}
|
12
|
+
@hash_str = @hash.inspect.sub("{", "\\{").sub("}", "\\}")
|
13
|
+
@thread_name = Thread.current.name
|
14
|
+
@file_name_reg_exp = " #{File.basename(__FILE__)}:\d+"
|
15
|
+
|
16
|
+
# Add mock metric subscriber
|
17
|
+
$last_metric = nil
|
18
|
+
SemanticLogger.on_metric do |log|
|
19
|
+
$last_metric = log.dup
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
after do
|
24
|
+
SemanticLogger.remove_appender(@appender)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Ensure that any log level can be measured and logged
|
28
|
+
SemanticLogger::LEVELS.each do |level|
|
29
|
+
level_char = level.to_s.upcase[0]
|
30
|
+
measure_level = "measure_#{level}".to_sym
|
31
|
+
|
32
|
+
describe "##{measure_level}" do
|
33
|
+
it ':message' do
|
34
|
+
assert_equal 'result', @logger.send(measure_level, 'hello world') { 'result' } # Measure duration of the supplied block
|
35
|
+
SemanticLogger.flush
|
36
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message)
|
37
|
+
end
|
38
|
+
|
39
|
+
it ':payload' do
|
40
|
+
assert_equal 'result', @logger.send(measure_level, 'hello world', payload: @hash) { 'result' } # Measure duration of the supplied block
|
41
|
+
SemanticLogger.flush
|
42
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message)
|
43
|
+
end
|
44
|
+
|
45
|
+
describe ':min_duration' do
|
46
|
+
it 'not log when faster' do
|
47
|
+
assert_equal 'result', @logger.send(measure_level, 'hello world', min_duration: 500) { 'result' } # Measure duration of the supplied block
|
48
|
+
SemanticLogger.flush
|
49
|
+
assert_nil @mock_logger.message
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'log when slower' do
|
53
|
+
assert_equal 'result', @logger.send(measure_level, 'hello world', min_duration: 200, payload: @hash) { sleep 0.5; 'result' } # Measure duration of the supplied block
|
54
|
+
SemanticLogger.flush
|
55
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it ':exception' do
|
60
|
+
assert_raises RuntimeError do
|
61
|
+
@logger.send(measure_level, 'hello world', payload: @hash) { raise RuntimeError.new('Test') } # Measure duration of the supplied block
|
62
|
+
end
|
63
|
+
SemanticLogger.flush
|
64
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- Exception: RuntimeError: Test -- #{@hash_str}/, @mock_logger.message)
|
65
|
+
end
|
66
|
+
|
67
|
+
it ':on_exception_level' do
|
68
|
+
assert_raises RuntimeError do
|
69
|
+
@logger.send(measure_level, 'hello world', payload: @hash, on_exception_level: :fatal) { raise RuntimeError.new('Test') } # Measure duration of the supplied block
|
70
|
+
end
|
71
|
+
SemanticLogger.flush
|
72
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ F \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- Exception: RuntimeError: Test -- #{@hash_str}/, @mock_logger.message)
|
73
|
+
end
|
74
|
+
|
75
|
+
it ':metric' do
|
76
|
+
metric_name = '/my/custom/metric'
|
77
|
+
assert_equal 'result', @logger.send(measure_level, 'hello world', metric: metric_name) { 'result' } # Measure duration of the supplied block
|
78
|
+
SemanticLogger.flush
|
79
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message)
|
80
|
+
assert metric_name, $last_metric.metric
|
81
|
+
end
|
82
|
+
|
83
|
+
it ':backtrace_level' do
|
84
|
+
SemanticLogger.stub(:backtrace_level_index, 0) do
|
85
|
+
assert_equal 'result', @logger.send(measure_level, 'hello world') { 'result' }
|
86
|
+
SemanticLogger.flush
|
87
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}#{@file_name_reg_exp}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#measure(#{level})" do
|
93
|
+
it ':message' do
|
94
|
+
assert_equal 'result', @logger.measure(level, 'hello world') { 'result' } # Measure duration of the supplied block
|
95
|
+
SemanticLogger.flush
|
96
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message)
|
97
|
+
end
|
98
|
+
|
99
|
+
it ':payload' do
|
100
|
+
assert_equal 'result', @logger.measure(level, 'hello world', payload: @hash) { 'result' } # Measure duration of the supplied block
|
101
|
+
SemanticLogger.flush
|
102
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message)
|
103
|
+
end
|
104
|
+
|
105
|
+
describe ':min_duration' do
|
106
|
+
it 'not log when faster' do
|
107
|
+
assert_equal 'result', @logger.measure(level, 'hello world', min_duration: 500) { 'result' } # Measure duration of the supplied block
|
108
|
+
SemanticLogger.flush
|
109
|
+
assert_nil @mock_logger.message
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'log when slower' do
|
113
|
+
assert_equal 'result', @logger.measure(level, 'hello world', min_duration: 200, payload: @hash) { sleep 0.5; 'result' } # Measure duration of the supplied block
|
114
|
+
SemanticLogger.flush
|
115
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
it ':exception' do
|
120
|
+
assert_raises RuntimeError do
|
121
|
+
@logger.measure(level, 'hello world', payload: @hash) { raise RuntimeError.new('Test') } # Measure duration of the supplied block
|
122
|
+
end
|
123
|
+
SemanticLogger.flush
|
124
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- Exception: RuntimeError: Test -- #{@hash_str}/, @mock_logger.message)
|
125
|
+
end
|
126
|
+
|
127
|
+
it ':metric' do
|
128
|
+
metric_name = '/my/custom/metric'
|
129
|
+
assert_equal 'result', @logger.measure(level, 'hello world', metric: metric_name) { 'result' } # Measure duration of the supplied block
|
130
|
+
SemanticLogger.flush
|
131
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message)
|
132
|
+
assert metric_name, $last_metric.metric
|
133
|
+
end
|
134
|
+
|
135
|
+
it "log #{level} info with backtrace" do
|
136
|
+
SemanticLogger.stub(:backtrace_level_index, 0) do
|
137
|
+
assert_equal 'result', @logger.measure(level, 'hello world') { 'result' }
|
138
|
+
SemanticLogger.flush
|
139
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}#{@file_name_reg_exp}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
describe "##{measure_level} named parameters" do
|
145
|
+
it ':message' do
|
146
|
+
assert_equal 'result', @logger.send(measure_level, message: 'hello world') { 'result' } # Measure duration of the supplied block
|
147
|
+
SemanticLogger.flush
|
148
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message)
|
149
|
+
end
|
150
|
+
|
151
|
+
it ':payload' do
|
152
|
+
assert_equal 'result', @logger.send(measure_level, message: 'hello world', payload: @hash) { 'result' } # Measure duration of the supplied block
|
153
|
+
SemanticLogger.flush
|
154
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message)
|
155
|
+
end
|
156
|
+
|
157
|
+
describe ':min_duration' do
|
158
|
+
it 'not log when faster' do
|
159
|
+
assert_equal 'result', @logger.send(measure_level, message: 'hello world', min_duration: 500) { 'result' } # Measure duration of the supplied block
|
160
|
+
SemanticLogger.flush
|
161
|
+
assert_nil @mock_logger.message
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'log when slower' do
|
165
|
+
assert_equal 'result', @logger.send(measure_level, message: 'hello world', min_duration: 200, payload: @hash) { sleep 0.5; 'result' } # Measure duration of the supplied block
|
166
|
+
SemanticLogger.flush
|
167
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
it ':exception' do
|
172
|
+
assert_raises RuntimeError do
|
173
|
+
@logger.send(measure_level, message: 'hello world', payload: @hash) { raise RuntimeError.new('Test') } # Measure duration of the supplied block
|
174
|
+
end
|
175
|
+
SemanticLogger.flush
|
176
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- Exception: RuntimeError: Test -- #{@hash_str}/, @mock_logger.message)
|
177
|
+
end
|
178
|
+
|
179
|
+
it ':on_exception_level' do
|
180
|
+
assert_raises RuntimeError do
|
181
|
+
@logger.send(measure_level, message: 'hello world', payload: @hash, on_exception_level: :fatal) { raise RuntimeError.new('Test') } # Measure duration of the supplied block
|
182
|
+
end
|
183
|
+
SemanticLogger.flush
|
184
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ F \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- Exception: RuntimeError: Test -- #{@hash_str}/, @mock_logger.message)
|
185
|
+
end
|
186
|
+
|
187
|
+
it ':metric' do
|
188
|
+
metric_name = '/my/custom/metric'
|
189
|
+
assert_equal 'result', @logger.send(measure_level, message: 'hello world', metric: metric_name) { 'result' } # Measure duration of the supplied block
|
190
|
+
SemanticLogger.flush
|
191
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message)
|
192
|
+
assert metric_name, $last_metric.metric
|
193
|
+
end
|
194
|
+
|
195
|
+
it ':backtrace_level' do
|
196
|
+
SemanticLogger.stub(:backtrace_level_index, 0) do
|
197
|
+
assert_equal 'result', @logger.send(measure_level, message: 'hello world') { 'result' }
|
198
|
+
SemanticLogger.flush
|
199
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}#{@file_name_reg_exp}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
describe 'return' do
|
207
|
+
it 'log when the block performs a return' do
|
208
|
+
assert_equal 'Good', function_with_return(@logger)
|
209
|
+
SemanticLogger.flush
|
210
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
describe ':silence' do
|
215
|
+
it 'silences messages' do
|
216
|
+
SemanticLogger.default_level = :info
|
217
|
+
@logger.measure_info('hello world', silence: :error) do
|
218
|
+
@logger.warn "don't log me"
|
219
|
+
end
|
220
|
+
SemanticLogger.flush
|
221
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message)
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'does not silence higer level messages' do
|
225
|
+
SemanticLogger.default_level = :info
|
226
|
+
first_message = nil
|
227
|
+
@logger.measure_info('hello world', silence: :trace) do
|
228
|
+
@logger.debug('hello world', @hash) { 'Calculations' }
|
229
|
+
SemanticLogger.flush
|
230
|
+
first_message = @mock_logger.message
|
231
|
+
end
|
232
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] LoggerTest -- hello world -- Calculations -- #{@hash_str}/, first_message)
|
233
|
+
SemanticLogger.flush
|
234
|
+
# Only the last log message is kept in mock logger
|
235
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
# Make sure that measure still logs when a block uses return to return from
|
240
|
+
# a function
|
241
|
+
def function_with_return(logger)
|
242
|
+
logger.measure_info('hello world', payload: @hash) do
|
243
|
+
return 'Good'
|
244
|
+
end
|
245
|
+
'Bad'
|
246
|
+
end
|
247
|
+
|
248
|
+
end
|
249
|
+
end
|
@@ -0,0 +1,257 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
class SemanticLoggerTest < Minitest::Test
|
4
|
+
describe SemanticLogger do
|
5
|
+
describe '.add_appender' do
|
6
|
+
before do
|
7
|
+
@appender = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
after do
|
11
|
+
SemanticLogger.remove_appender(@appender)
|
12
|
+
File.delete('sample.log') if File.exist?('sample.log')
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'adds file appender' do
|
16
|
+
@appender = SemanticLogger.add_appender(file_name: 'sample.log')
|
17
|
+
assert @appender.is_a?(SemanticLogger::Appender::File)
|
18
|
+
assert SemanticLogger.appenders.include?(@appender)
|
19
|
+
assert @appender.formatter.is_a?(SemanticLogger::Formatters::Default)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'adds file appender with json format' do
|
23
|
+
@appender = SemanticLogger.add_appender(file_name: 'sample.log', formatter: :json)
|
24
|
+
assert @appender.is_a?(SemanticLogger::Appender::File)
|
25
|
+
assert SemanticLogger.appenders.include?(@appender)
|
26
|
+
assert @appender.formatter.is_a?(SemanticLogger::Formatters::Json)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'adds stream appender' do
|
30
|
+
@appender = SemanticLogger.add_appender(io: STDOUT)
|
31
|
+
assert @appender.is_a?(SemanticLogger::Appender::File)
|
32
|
+
assert SemanticLogger.appenders.include?(@appender)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'adds symbol appender' do
|
36
|
+
@appender = SemanticLogger.add_appender(appender: :wrapper, logger: Logger.new(STDOUT))
|
37
|
+
assert @appender.is_a?(SemanticLogger::Appender::Wrapper), -> { @appender.ai }
|
38
|
+
assert SemanticLogger.appenders.include?(@appender)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'adds symbol appender with underscores' do
|
42
|
+
@appender = SemanticLogger.add_appender(appender: :new_relic)
|
43
|
+
assert @appender.is_a?(SemanticLogger::Appender::NewRelic), -> { @appender.ai }
|
44
|
+
assert SemanticLogger.appenders.include?(@appender)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'adds logger wrapper appender' do
|
48
|
+
@appender = SemanticLogger.add_appender(logger: ::Logger.new(STDOUT))
|
49
|
+
assert @appender.is_a?(SemanticLogger::Appender::Wrapper)
|
50
|
+
assert @appender.logger.is_a?(::Logger)
|
51
|
+
assert SemanticLogger.appenders.include?(@appender)
|
52
|
+
assert @appender.formatter.is_a?(SemanticLogger::Formatters::Default)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'adds logger wrapper appender with color formatter' do
|
56
|
+
@appender = SemanticLogger.add_appender(logger: ::Logger.new(STDOUT), formatter: :color)
|
57
|
+
assert @appender.is_a?(SemanticLogger::Appender::Wrapper)
|
58
|
+
assert @appender.logger.is_a?(::Logger)
|
59
|
+
assert SemanticLogger.appenders.include?(@appender)
|
60
|
+
assert @appender.formatter.is_a?(SemanticLogger::Formatters::Color)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'adds appender' do
|
64
|
+
@appender = SemanticLogger.add_appender(appender: SemanticLogger::Appender::File.new(io: STDOUT))
|
65
|
+
assert @appender.is_a?(SemanticLogger::Appender::File), @appender.ai
|
66
|
+
assert SemanticLogger.appenders.include?(@appender)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'fails to add invalid logger appender' do
|
70
|
+
assert_raises do
|
71
|
+
SemanticLogger.add_appender(logger: 'blah')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '.add_appender DEPRECATED' do
|
77
|
+
before do
|
78
|
+
@appender = nil
|
79
|
+
end
|
80
|
+
|
81
|
+
after do
|
82
|
+
SemanticLogger.remove_appender(@appender) if @appender
|
83
|
+
File.delete('sample.log') if File.exist?('sample.log')
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'adds file appender' do
|
87
|
+
@appender = SemanticLogger.add_appender('sample.log')
|
88
|
+
assert @appender.is_a?(SemanticLogger::Appender::File)
|
89
|
+
assert SemanticLogger.appenders.include?(@appender)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'adds stream appender' do
|
93
|
+
@appender = SemanticLogger.add_appender(STDOUT)
|
94
|
+
assert @appender.is_a?(SemanticLogger::Appender::File)
|
95
|
+
assert SemanticLogger.appenders.include?(@appender)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'adds appender' do
|
99
|
+
@appender = SemanticLogger.add_appender(SemanticLogger::Appender::File.new(io: STDOUT))
|
100
|
+
assert @appender.is_a?(SemanticLogger::Appender::File), @appender.ai
|
101
|
+
assert SemanticLogger.appenders.include?(@appender)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'adds logger wrapper appender' do
|
105
|
+
@appender = SemanticLogger.add_appender(::Logger.new(STDOUT))
|
106
|
+
assert @appender.is_a?(SemanticLogger::Appender::Wrapper)
|
107
|
+
assert @appender.logger.is_a?(::Logger)
|
108
|
+
assert SemanticLogger.appenders.include?(@appender)
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'fails to add invalid logger appender' do
|
112
|
+
assert_raises do
|
113
|
+
SemanticLogger.add_appender(logger: 'blah')
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe 'mock_logger' do
|
119
|
+
before do
|
120
|
+
# Use a mock logger that just keeps the last logged entry in an instance
|
121
|
+
# variable
|
122
|
+
SemanticLogger.default_level = :trace
|
123
|
+
SemanticLogger.backtrace_level = nil
|
124
|
+
@mock_logger = MockLogger.new
|
125
|
+
@appender = SemanticLogger.add_appender(logger: @mock_logger)
|
126
|
+
|
127
|
+
# Use this test's class name as the application name in the log output
|
128
|
+
@logger = SemanticLogger['LoggerTest']
|
129
|
+
@hash = {session_id: 'HSSKLEU@JDK767', tracking_number: 12345}
|
130
|
+
@hash_str = @hash.inspect.sub("{", "\\{").sub("}", "\\}")
|
131
|
+
@thread_name = Thread.current.name
|
132
|
+
end
|
133
|
+
|
134
|
+
after do
|
135
|
+
SemanticLogger.remove_appender(@appender)
|
136
|
+
end
|
137
|
+
|
138
|
+
describe '.tagged' do
|
139
|
+
it 'add tags to log entries' do
|
140
|
+
SemanticLogger.tagged('12345', 'DJHSFK') do
|
141
|
+
@logger.info('Hello world')
|
142
|
+
SemanticLogger.flush
|
143
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \[12345\] \[DJHSFK\] LoggerTest -- Hello world/, @mock_logger.message)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'add embedded tags to log entries' do
|
148
|
+
SemanticLogger.tagged('First Level', 'tags') do
|
149
|
+
SemanticLogger.tagged('Second Level') do
|
150
|
+
@logger.info('Hello world')
|
151
|
+
SemanticLogger.flush
|
152
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \[First Level\] \[tags\] \[Second Level\] LoggerTest -- Hello world/, @mock_logger.message)
|
153
|
+
end
|
154
|
+
assert_equal 2, SemanticLogger.tags.count, SemanticLogger.tags
|
155
|
+
assert_equal 'First Level', SemanticLogger.tags.first
|
156
|
+
assert_equal 'tags', SemanticLogger.tags.last
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe '.named_tagged' do
|
162
|
+
it 'logs named tags' do
|
163
|
+
SemanticLogger.named_tagged(tracking_number: '123456') do
|
164
|
+
SemanticLogger.named_tagged(even: 2, more: 'data') do
|
165
|
+
@logger.info('Hello world')
|
166
|
+
SemanticLogger.flush
|
167
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \[even: 2\] \[more: data\] \[tracking_number: 123456\] LoggerTest -- Hello world/, @mock_logger.message)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe '.fast_tag' do
|
174
|
+
it 'add string tag to log entries' do
|
175
|
+
@logger.fast_tag('12345') do
|
176
|
+
@logger.info('Hello world')
|
177
|
+
SemanticLogger.flush
|
178
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \[12345\] LoggerTest -- Hello world/, @mock_logger.message)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
describe '.default_level' do
|
184
|
+
before do
|
185
|
+
SemanticLogger.default_level = :debug
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'not log at a level below the global default' do
|
189
|
+
assert_equal :debug, SemanticLogger.default_level
|
190
|
+
assert_equal :debug, @logger.level
|
191
|
+
@logger.trace('hello world', @hash) { 'Calculations' }
|
192
|
+
SemanticLogger.flush
|
193
|
+
assert_nil @mock_logger.message
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'log at the instance level' do
|
197
|
+
assert_equal :debug, SemanticLogger.default_level
|
198
|
+
@logger.level = :trace
|
199
|
+
assert_equal :trace, @logger.level
|
200
|
+
@logger.trace('hello world', @hash) { 'Calculations' }
|
201
|
+
SemanticLogger.flush
|
202
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ T \[\d+:#{@thread_name}\] LoggerTest -- hello world -- Calculations -- #{@hash_str}/, @mock_logger.message)
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'not log at a level below the instance level' do
|
206
|
+
assert_equal :debug, SemanticLogger.default_level
|
207
|
+
@logger.level = :warn
|
208
|
+
assert_equal :warn, @logger.level
|
209
|
+
@logger.debug('hello world', @hash) { 'Calculations' }
|
210
|
+
SemanticLogger.flush
|
211
|
+
assert_nil @mock_logger.message
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe '.silence' do
|
216
|
+
before do
|
217
|
+
SemanticLogger.default_level = :info
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'not log at a level below the silence level' do
|
221
|
+
assert_equal :info, SemanticLogger.default_level
|
222
|
+
assert_equal :info, @logger.level
|
223
|
+
@logger.silence do
|
224
|
+
@logger.warn('hello world', @hash) { 'Calculations' }
|
225
|
+
@logger.info('hello world', @hash) { 'Calculations' }
|
226
|
+
@logger.debug('hello world', @hash) { 'Calculations' }
|
227
|
+
@logger.trace('hello world', @hash) { 'Calculations' }
|
228
|
+
end
|
229
|
+
SemanticLogger.flush
|
230
|
+
assert_nil @mock_logger.message
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'log at the instance level even with the silencer at a higher level' do
|
234
|
+
@logger.level = :trace
|
235
|
+
assert_equal :trace, @logger.level
|
236
|
+
@logger.silence do
|
237
|
+
@logger.trace('hello world', @hash) { 'Calculations' }
|
238
|
+
end
|
239
|
+
SemanticLogger.flush
|
240
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ T \[\d+:#{@thread_name}\] LoggerTest -- hello world -- Calculations -- #{@hash_str}/, @mock_logger.message)
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'log at a silence level below the default level' do
|
244
|
+
assert_equal :info, SemanticLogger.default_level
|
245
|
+
assert_equal :info, @logger.level
|
246
|
+
@logger.silence(:debug) do
|
247
|
+
@logger.debug('hello world', @hash) { 'Calculations' }
|
248
|
+
end
|
249
|
+
SemanticLogger.flush
|
250
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] LoggerTest -- hello world -- Calculations -- #{@hash_str}/, @mock_logger.message)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
end
|
255
|
+
|
256
|
+
end
|
257
|
+
end
|