semantic_logger 3.4.1 → 4.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -85,13 +85,13 @@ class CompatibilityTest < Minitest::Test
|
|
85
85
|
end
|
86
86
|
|
87
87
|
it '#formatter NOOP' do
|
88
|
-
|
88
|
+
assert_nil @logger.formatter
|
89
89
|
@logger.formatter = 'blah'
|
90
90
|
assert_equal 'blah', @logger.formatter
|
91
91
|
end
|
92
92
|
|
93
93
|
it '#datetime_format NOOP' do
|
94
|
-
|
94
|
+
assert_nil @logger.datetime_format
|
95
95
|
@logger.datetime_format = 'blah'
|
96
96
|
assert_equal 'blah', @logger.datetime_format
|
97
97
|
end
|
data/test/loggable_test.rb
CHANGED
@@ -42,7 +42,7 @@ class AppenderFileTest < Minitest::Test
|
|
42
42
|
|
43
43
|
it 'should give child objects their own logger' do
|
44
44
|
subclass = Subclass.new
|
45
|
-
base
|
45
|
+
base = Base.new
|
46
46
|
assert_equal subclass.class.name, subclass.logger.name
|
47
47
|
assert_equal base.class.name, base.logger.name
|
48
48
|
assert_equal subclass.class.name, subclass.logger.name
|
data/test/logger_test.rb
CHANGED
@@ -3,593 +3,214 @@ require_relative 'test_helper'
|
|
3
3
|
# Unit Test for SemanticLogger::Logger
|
4
4
|
class LoggerTest < Minitest::Test
|
5
5
|
describe SemanticLogger::Logger do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
it 'adds file appender with json format' do
|
24
|
-
@appender = SemanticLogger.add_appender(file_name: 'sample.log', formatter: :json)
|
25
|
-
assert @appender.is_a?(SemanticLogger::Appender::File)
|
26
|
-
assert SemanticLogger.appenders.include?(@appender)
|
27
|
-
assert @appender.formatter.is_a?(SemanticLogger::Formatters::Json)
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'adds stream appender' do
|
31
|
-
@appender = SemanticLogger.add_appender(io: STDOUT)
|
32
|
-
assert @appender.is_a?(SemanticLogger::Appender::File)
|
33
|
-
assert SemanticLogger.appenders.include?(@appender)
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'adds symbol appender' do
|
37
|
-
@appender = SemanticLogger.add_appender(appender: :wrapper, logger: Logger.new(STDOUT))
|
38
|
-
assert @appender.is_a?(SemanticLogger::Appender::Wrapper), -> { @appender.ai }
|
39
|
-
assert SemanticLogger.appenders.include?(@appender)
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'adds symbol appender with underscores' do
|
43
|
-
@appender = SemanticLogger.add_appender(appender: :new_relic)
|
44
|
-
assert @appender.is_a?(SemanticLogger::Appender::NewRelic), -> { @appender.ai }
|
45
|
-
assert SemanticLogger.appenders.include?(@appender)
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'adds logger wrapper appender' do
|
49
|
-
@appender = SemanticLogger.add_appender(logger: ::Logger.new(STDOUT))
|
50
|
-
assert @appender.is_a?(SemanticLogger::Appender::Wrapper)
|
51
|
-
assert @appender.logger.is_a?(::Logger)
|
52
|
-
assert SemanticLogger.appenders.include?(@appender)
|
53
|
-
assert @appender.formatter.is_a?(SemanticLogger::Formatters::Default)
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'adds logger wrapper appender with color formatter' do
|
57
|
-
@appender = SemanticLogger.add_appender(logger: ::Logger.new(STDOUT), formatter: :color)
|
58
|
-
assert @appender.is_a?(SemanticLogger::Appender::Wrapper)
|
59
|
-
assert @appender.logger.is_a?(::Logger)
|
60
|
-
assert SemanticLogger.appenders.include?(@appender)
|
61
|
-
assert @appender.formatter.is_a?(SemanticLogger::Formatters::Color)
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'adds appender' do
|
65
|
-
@appender = SemanticLogger.add_appender(appender: SemanticLogger::Appender::File.new(io: STDOUT))
|
66
|
-
assert @appender.is_a?(SemanticLogger::Appender::File), @appender.ai
|
67
|
-
assert SemanticLogger.appenders.include?(@appender)
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'fails to add invalid logger appender' do
|
71
|
-
assert_raises do
|
72
|
-
SemanticLogger.add_appender(logger: 'blah')
|
73
|
-
end
|
74
|
-
end
|
6
|
+
before do
|
7
|
+
# Use a mock logger that just keeps the last logged entry in an instance
|
8
|
+
# variable
|
9
|
+
SemanticLogger.default_level = :trace
|
10
|
+
SemanticLogger.backtrace_level = nil
|
11
|
+
@mock_logger = MockLogger.new
|
12
|
+
@appender = SemanticLogger.add_appender(logger: @mock_logger)
|
13
|
+
|
14
|
+
# Use this test's class name as the application name in the log output
|
15
|
+
@logger = SemanticLogger[LoggerTest]
|
16
|
+
@hash = {session_id: 'HSSKLEU@JDK767', tracking_number: 12345}
|
17
|
+
@hash_str = @hash.inspect.sub("{", "\\{").sub("}", "\\}")
|
18
|
+
@thread_name = Thread.current.name
|
19
|
+
@file_name_reg_exp = ' logger_test.rb:\d+'
|
20
|
+
|
21
|
+
assert_equal [], SemanticLogger.tags
|
22
|
+
assert_equal 65535, SemanticLogger.backtrace_level_index
|
75
23
|
end
|
76
24
|
|
77
|
-
|
78
|
-
|
79
|
-
SemanticLogger.remove_appender(@appender) if @appender
|
80
|
-
File.delete('sample.log') if File.exist?('sample.log')
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'adds file appender' do
|
84
|
-
@appender = SemanticLogger.add_appender('sample.log')
|
85
|
-
assert @appender.is_a?(SemanticLogger::Appender::File)
|
86
|
-
assert SemanticLogger.appenders.include?(@appender)
|
87
|
-
end
|
88
|
-
|
89
|
-
it 'adds stream appender' do
|
90
|
-
@appender = SemanticLogger.add_appender(STDOUT)
|
91
|
-
assert @appender.is_a?(SemanticLogger::Appender::File)
|
92
|
-
assert SemanticLogger.appenders.include?(@appender)
|
93
|
-
end
|
94
|
-
|
95
|
-
it 'adds appender' do
|
96
|
-
@appender = SemanticLogger.add_appender(SemanticLogger::Appender::File.new(io: STDOUT))
|
97
|
-
assert @appender.is_a?(SemanticLogger::Appender::File), @appender.ai
|
98
|
-
assert SemanticLogger.appenders.include?(@appender)
|
99
|
-
end
|
100
|
-
|
101
|
-
it 'adds logger wrapper appender' do
|
102
|
-
@appender = SemanticLogger.add_appender(::Logger.new(STDOUT))
|
103
|
-
assert @appender.is_a?(SemanticLogger::Appender::Wrapper)
|
104
|
-
assert @appender.logger.is_a?(::Logger)
|
105
|
-
assert SemanticLogger.appenders.include?(@appender)
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'fails to add invalid logger appender' do
|
109
|
-
assert_raises do
|
110
|
-
SemanticLogger.add_appender(logger: 'blah')
|
111
|
-
end
|
112
|
-
end
|
25
|
+
after do
|
26
|
+
SemanticLogger.remove_appender(@appender)
|
113
27
|
end
|
114
28
|
|
115
|
-
#
|
116
|
-
|
117
|
-
|
118
|
-
before do
|
119
|
-
# Use a mock logger that just keeps the last logged entry in an instance
|
120
|
-
# variable
|
121
|
-
SemanticLogger.default_level = :trace
|
122
|
-
SemanticLogger.backtrace_level = nil
|
123
|
-
@mock_logger = MockLogger.new
|
124
|
-
@appender = SemanticLogger.add_appender(logger: @mock_logger)
|
125
|
-
@appender.filter = filter
|
126
|
-
|
127
|
-
# Add mock metric subscriber
|
128
|
-
$last_metric = nil
|
129
|
-
SemanticLogger.on_metric do |log|
|
130
|
-
$last_metric = log.dup
|
131
|
-
end
|
132
|
-
|
133
|
-
# Use this test's class name as the application name in the log output
|
134
|
-
@logger = SemanticLogger[LoggerTest]
|
135
|
-
@hash = {session_id: 'HSSKLEU@JDK767', tracking_number: 12345}
|
136
|
-
@hash_str = @hash.inspect.sub("{", "\\{").sub("}", "\\}")
|
137
|
-
@thread_name = Thread.current.name
|
138
|
-
@file_name_reg_exp = ' logger_test.rb:\d+'
|
139
|
-
|
140
|
-
assert_equal [], @logger.tags
|
141
|
-
assert_equal 65535, SemanticLogger.backtrace_level_index
|
142
|
-
end
|
143
|
-
|
144
|
-
after do
|
145
|
-
SemanticLogger.remove_appender(@appender)
|
146
|
-
end
|
147
|
-
|
148
|
-
# Ensure that any log level can be logged
|
149
|
-
SemanticLogger::LEVELS.each do |level|
|
150
|
-
level_char = level.to_s.upcase[0]
|
151
|
-
|
152
|
-
describe level do
|
153
|
-
it 'logs' do
|
154
|
-
@logger.send(level, 'hello world', @hash) { 'Calculations' }
|
155
|
-
SemanticLogger.flush
|
156
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] LoggerTest -- hello world -- Calculations -- #{@hash_str}/, @mock_logger.message)
|
157
|
-
end
|
158
|
-
|
159
|
-
it 'exclude log messages using Proc filter' do
|
160
|
-
if filter.is_a?(Proc)
|
161
|
-
@logger.send(level, 'Exclude this log message', @hash) { 'Calculations' }
|
162
|
-
SemanticLogger.flush
|
163
|
-
assert_nil @mock_logger.message
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
it 'exclude log messages using RegExp filter' do
|
168
|
-
if filter.is_a?(Regexp)
|
169
|
-
logger = SemanticLogger::Logger.new('NotLogger', :trace, filter)
|
170
|
-
logger.send(level, 'Ignore all log messages from this class', @hash) { 'Calculations' }
|
171
|
-
SemanticLogger.flush
|
172
|
-
assert_nil @mock_logger.message
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
it 'logs with backtrace' do
|
177
|
-
SemanticLogger.stub(:backtrace_level_index, 0) do
|
178
|
-
@logger.send(level, 'hello world', @hash) { 'Calculations' }
|
179
|
-
SemanticLogger.flush
|
180
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}#{@file_name_reg_exp}\] LoggerTest -- hello world -- Calculations -- #{@hash_str}/, @mock_logger.message)
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
it 'logs with backtrace and exception' do
|
185
|
-
SemanticLogger.stub(:backtrace_level_index, 0) do
|
186
|
-
exc = RuntimeError.new('Test')
|
187
|
-
@logger.send(level, 'hello world', exc)
|
188
|
-
SemanticLogger.flush
|
189
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}#{@file_name_reg_exp}\] LoggerTest -- hello world -- Exception: RuntimeError: Test/, @mock_logger.message)
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
it 'logs payload' do
|
194
|
-
hash = {tracking_number: '123456', even: 2, more: 'data'}
|
195
|
-
hash_str = hash.inspect.sub('{', '\{').sub('}', '\}')
|
196
|
-
@logger.send(level, 'Hello world', hash)
|
197
|
-
SemanticLogger.flush
|
198
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] LoggerTest -- Hello world -- #{hash_str}/, @mock_logger.message)
|
199
|
-
end
|
200
|
-
|
201
|
-
it 'does not log an empty payload' do
|
202
|
-
hash = {}
|
203
|
-
@logger.send(level, 'Hello world', hash)
|
204
|
-
SemanticLogger.flush
|
205
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] LoggerTest -- Hello world/, @mock_logger.message)
|
206
|
-
end
|
207
|
-
|
208
|
-
describe 'hash only argument' do
|
209
|
-
it 'logs message' do
|
210
|
-
@logger.send(level, message: 'Hello world')
|
211
|
-
SemanticLogger.flush
|
212
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] LoggerTest -- Hello world/, @mock_logger.message)
|
213
|
-
end
|
214
|
-
|
215
|
-
it 'logs payload and message' do
|
216
|
-
@logger.send(level, message: 'Hello world', tracking_number: '123456', even: 2, more: 'data')
|
217
|
-
hash = {tracking_number: '123456', even: 2, more: 'data'}
|
218
|
-
SemanticLogger.flush
|
219
|
-
hash_str = hash.inspect.sub('{', '\{').sub('}', '\}')
|
220
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] LoggerTest -- Hello world -- #{hash_str}/, @mock_logger.message)
|
221
|
-
end
|
222
|
-
|
223
|
-
it 'logs payload and message from block' do
|
224
|
-
@logger.send(level) { {message: 'Hello world', tracking_number: '123456', even: 2, more: 'data'} }
|
225
|
-
hash = {tracking_number: '123456', even: 2, more: 'data'}
|
226
|
-
SemanticLogger.flush
|
227
|
-
hash_str = hash.inspect.sub('{', '\{').sub('}', '\}')
|
228
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] LoggerTest -- Hello world -- #{hash_str}/, @mock_logger.message)
|
229
|
-
end
|
230
|
-
|
231
|
-
it 'logs payload only' do
|
232
|
-
hash = {tracking_number: '123456', even: 2, more: 'data'}
|
233
|
-
@logger.send(level, hash)
|
234
|
-
SemanticLogger.flush
|
235
|
-
hash_str = hash.inspect.sub('{', '\{').sub('}', '\}')
|
236
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] LoggerTest -- #{hash_str}/, @mock_logger.message)
|
237
|
-
end
|
238
|
-
|
239
|
-
it 'logs duration' do
|
240
|
-
@logger.send(level, duration: 123.45, message: 'Hello world', tracking_number: '123456', even: 2, more: 'data')
|
241
|
-
hash = {tracking_number: '123456', even: 2, more: 'data'}
|
242
|
-
SemanticLogger.flush
|
243
|
-
hash_str = hash.inspect.sub('{', '\{').sub('}', '\}')
|
244
|
-
duration_match = defined?(JRuby) ? '\(123ms\)' : '\(123\.5ms\)'
|
245
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] #{duration_match} LoggerTest -- Hello world -- #{hash_str}/, @mock_logger.message)
|
246
|
-
end
|
247
|
-
|
248
|
-
it 'does not log when below min_duration' do
|
249
|
-
@logger.send(level, min_duration: 200, duration: 123.45, message: 'Hello world', tracking_number: '123456', even: 2, more: 'data')
|
250
|
-
SemanticLogger.flush
|
251
|
-
assert_nil @mock_logger.message
|
252
|
-
end
|
253
|
-
|
254
|
-
it 'logs metric' do
|
255
|
-
metric_name = '/my/custom/metric'
|
256
|
-
@logger.send(level, metric: metric_name, duration: 123.45, message: 'Hello world', tracking_number: '123456', even: 2, more: 'data')
|
257
|
-
hash = {tracking_number: '123456', even: 2, more: 'data'}
|
258
|
-
SemanticLogger.flush
|
259
|
-
hash_str = hash.inspect.sub('{', '\{').sub('}', '\}')
|
260
|
-
duration_match = defined?(JRuby) ? '\(123ms\)' : '\(123\.5ms\)'
|
261
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] #{duration_match} LoggerTest -- Hello world -- #{hash_str}/, @mock_logger.message)
|
262
|
-
assert metric_name, $last_metric.metric
|
263
|
-
end
|
264
|
-
|
265
|
-
end
|
29
|
+
# Ensure that any log level can be logged
|
30
|
+
SemanticLogger::LEVELS.each do |level|
|
31
|
+
level_char = level.to_s.upcase[0]
|
266
32
|
|
33
|
+
describe "##{level}" do
|
34
|
+
describe 'positional parameter' do
|
35
|
+
it 'logs message' do
|
36
|
+
@logger.send(level, 'hello world')
|
37
|
+
SemanticLogger.flush
|
38
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] LoggerTest -- hello world/, @mock_logger.message)
|
267
39
|
end
|
268
|
-
end
|
269
40
|
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
SemanticLogger.flush
|
275
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \[12345\] \[DJHSFK\] LoggerTest -- Hello world/, @mock_logger.message)
|
276
|
-
end
|
41
|
+
it 'adds message from block' do
|
42
|
+
@logger.send(level, 'hello world') { 'Calculations' }
|
43
|
+
SemanticLogger.flush
|
44
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] LoggerTest -- hello world -- Calculations/, @mock_logger.message)
|
277
45
|
end
|
278
46
|
|
279
|
-
it '
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
end
|
286
|
-
assert_equal 2, @logger.tags.count, @logger.tags
|
287
|
-
assert_equal 'First Level', @logger.tags.first
|
288
|
-
assert_equal 'tags', @logger.tags.last
|
289
|
-
end
|
47
|
+
it 'logs message and payload' do
|
48
|
+
hash = {tracking_number: '123456', even: 2, more: 'data'}
|
49
|
+
hash_str = hash.inspect.sub('{', '\{').sub('}', '\}')
|
50
|
+
@logger.send(level, 'Hello world', hash)
|
51
|
+
SemanticLogger.flush
|
52
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] LoggerTest -- Hello world -- #{hash_str}/, @mock_logger.message)
|
290
53
|
end
|
291
|
-
end
|
292
54
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
@
|
298
|
-
@logger.with_payload(even: 2, more: 'data') do
|
299
|
-
@logger.info('Hello world')
|
300
|
-
SemanticLogger.flush
|
301
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] LoggerTest -- Hello world -- #{hash_str}/, @mock_logger.message)
|
302
|
-
end
|
303
|
-
end
|
55
|
+
it 'does not log an empty payload' do
|
56
|
+
hash = {}
|
57
|
+
@logger.send(level, 'Hello world', hash)
|
58
|
+
SemanticLogger.flush
|
59
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] LoggerTest -- Hello world/, @mock_logger.message)
|
304
60
|
end
|
305
|
-
end
|
306
61
|
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
@logger.info('Hello world')
|
62
|
+
it 'logs with backtrace' do
|
63
|
+
SemanticLogger.stub(:backtrace_level_index, 0) do
|
64
|
+
@logger.send(level, 'hello world', @hash) { 'Calculations' }
|
311
65
|
SemanticLogger.flush
|
312
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+
|
66
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}#{@file_name_reg_exp}\] LoggerTest -- hello world -- Calculations -- #{@hash_str}/, @mock_logger.message)
|
313
67
|
end
|
314
68
|
end
|
315
|
-
end
|
316
69
|
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
assert_equal Logger::Severity.const_get('ERROR')+1, @logger.send(:level_index)
|
324
|
-
else
|
325
|
-
assert_equal Logger::Severity.const_get(level)+1, @logger.send(:level_index)
|
326
|
-
end
|
70
|
+
it 'logs with backtrace and exception' do
|
71
|
+
SemanticLogger.stub(:backtrace_level_index, 0) do
|
72
|
+
exc = RuntimeError.new('Test')
|
73
|
+
@logger.send(level, 'hello world', exc)
|
74
|
+
SemanticLogger.flush
|
75
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}#{@file_name_reg_exp}\] LoggerTest -- hello world -- Exception: RuntimeError: Test/, @mock_logger.message)
|
327
76
|
end
|
328
77
|
end
|
329
78
|
end
|
330
79
|
|
331
|
-
describe '
|
332
|
-
|
333
|
-
|
334
|
-
level_char = level.to_s.upcase[0]
|
335
|
-
|
336
|
-
describe 'direct method' do
|
337
|
-
it "log #{level} info" do
|
338
|
-
assert_equal 'result', @logger.send("measure_#{level}".to_sym, 'hello world') { 'result' } # Measure duration of the supplied block
|
339
|
-
SemanticLogger.flush
|
340
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message)
|
341
|
-
end
|
342
|
-
|
343
|
-
it "log #{level} info with payload" do
|
344
|
-
assert_equal 'result', @logger.send("measure_#{level}".to_sym, 'hello world', payload: @hash) { 'result' } # Measure duration of the supplied block
|
345
|
-
SemanticLogger.flush
|
346
|
-
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)
|
347
|
-
end
|
348
|
-
|
349
|
-
it "not log #{level} info when block is faster than :min_duration" do
|
350
|
-
assert_equal 'result', @logger.send("measure_#{level}".to_sym, 'hello world', min_duration: 500) { 'result' } # Measure duration of the supplied block
|
351
|
-
SemanticLogger.flush
|
352
|
-
assert_nil @mock_logger.message
|
353
|
-
end
|
354
|
-
|
355
|
-
it "log #{level} info when block duration exceeds :min_duration" do
|
356
|
-
assert_equal 'result', @logger.send("measure_#{level}".to_sym, 'hello world', min_duration: 200, payload: @hash) { sleep 0.5; 'result' } # Measure duration of the supplied block
|
357
|
-
SemanticLogger.flush
|
358
|
-
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)
|
359
|
-
end
|
360
|
-
|
361
|
-
it "log #{level} info with an exception" do
|
362
|
-
assert_raises RuntimeError do
|
363
|
-
@logger.send("measure_#{level}", 'hello world', payload: @hash) { raise RuntimeError.new('Test') } # Measure duration of the supplied block
|
364
|
-
end
|
365
|
-
SemanticLogger.flush
|
366
|
-
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 -- Exception: RuntimeError: Test -- #{@hash_str}/, @mock_logger.message)
|
367
|
-
end
|
368
|
-
|
369
|
-
it "change log #{level} info with an exception" do
|
370
|
-
assert_raises RuntimeError do
|
371
|
-
@logger.send("measure_#{level}", 'hello world', payload: @hash, on_exception_level: :fatal) { raise RuntimeError.new('Test') } # Measure duration of the supplied block
|
372
|
-
end
|
373
|
-
SemanticLogger.flush
|
374
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ F \[\d+:#{@thread_name}#{@file_name_reg_exp}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- Exception: RuntimeError: Test -- #{@hash_str}/, @mock_logger.message)
|
375
|
-
end
|
376
|
-
|
377
|
-
it "log #{level} info with metric" do
|
378
|
-
metric_name = '/my/custom/metric'
|
379
|
-
assert_equal 'result', @logger.send("measure_#{level}".to_sym, 'hello world', metric: metric_name) { 'result' } # Measure duration of the supplied block
|
380
|
-
SemanticLogger.flush
|
381
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message)
|
382
|
-
assert metric_name, $last_metric.metric
|
383
|
-
end
|
384
|
-
|
385
|
-
it "log #{level} info with backtrace" do
|
386
|
-
SemanticLogger.stub(:backtrace_level_index, 0) do
|
387
|
-
assert_equal 'result', @logger.send("measure_#{level}".to_sym, 'hello world') { 'result' }
|
388
|
-
SemanticLogger.flush
|
389
|
-
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)
|
390
|
-
end
|
391
|
-
end
|
392
|
-
end
|
393
|
-
|
394
|
-
describe 'generic method' do
|
395
|
-
it "log #{level} info" do
|
396
|
-
assert_equal 'result', @logger.measure(level, 'hello world') { 'result' } # Measure duration of the supplied block
|
397
|
-
SemanticLogger.flush
|
398
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message)
|
399
|
-
end
|
400
|
-
|
401
|
-
it "log #{level} info with payload" do
|
402
|
-
assert_equal 'result', @logger.measure(level, 'hello world', payload: @hash) { 'result' } # Measure duration of the supplied block
|
403
|
-
SemanticLogger.flush
|
404
|
-
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)
|
405
|
-
end
|
406
|
-
|
407
|
-
it "not log #{level} info when block is faster than :min_duration" do
|
408
|
-
assert_equal 'result', @logger.measure(level, 'hello world', min_duration: 500) { 'result' } # Measure duration of the supplied block
|
409
|
-
SemanticLogger.flush
|
410
|
-
assert_nil @mock_logger.message
|
411
|
-
end
|
412
|
-
|
413
|
-
it "log #{level} info when block duration exceeds :min_duration" do
|
414
|
-
assert_equal 'result', @logger.measure(level, 'hello world', min_duration: 200, payload: @hash) { sleep 0.5; 'result' } # Measure duration of the supplied block
|
415
|
-
SemanticLogger.flush
|
416
|
-
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)
|
417
|
-
end
|
418
|
-
|
419
|
-
it "log #{level} info with an exception" do
|
420
|
-
assert_raises RuntimeError do
|
421
|
-
@logger.measure(level, 'hello world', payload: @hash) { raise RuntimeError.new('Test') } # Measure duration of the supplied block
|
422
|
-
end
|
423
|
-
SemanticLogger.flush
|
424
|
-
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 -- Exception: RuntimeError: Test -- #{@hash_str}/, @mock_logger.message)
|
425
|
-
end
|
426
|
-
|
427
|
-
it "log #{level} info with metric" do
|
428
|
-
metric_name = '/my/custom/metric'
|
429
|
-
assert_equal 'result', @logger.measure(level, 'hello world', metric: metric_name) { 'result' } # Measure duration of the supplied block
|
430
|
-
SemanticLogger.flush
|
431
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message)
|
432
|
-
assert metric_name, $last_metric.metric
|
433
|
-
end
|
434
|
-
|
435
|
-
it "log #{level} info with backtrace" do
|
436
|
-
SemanticLogger.stub(:backtrace_level_index, 0) do
|
437
|
-
assert_equal 'result', @logger.measure(level, 'hello world') { 'result' }
|
438
|
-
SemanticLogger.flush
|
439
|
-
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)
|
440
|
-
end
|
441
|
-
end
|
442
|
-
end
|
443
|
-
end
|
444
|
-
|
445
|
-
it 'log when the block performs a return' do
|
446
|
-
assert_equal 'Good', function_with_return(@logger)
|
80
|
+
describe 'named parameters' do
|
81
|
+
it 'logs message' do
|
82
|
+
@logger.send(level, message: 'Hello world')
|
447
83
|
SemanticLogger.flush
|
448
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+
|
84
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] LoggerTest -- Hello world/, @mock_logger.message)
|
449
85
|
end
|
450
86
|
|
451
|
-
it '
|
452
|
-
|
453
|
-
|
454
|
-
@logger.warn "don't log me"
|
455
|
-
end
|
87
|
+
it 'logs payload and message' do
|
88
|
+
@logger.send(level, message: 'Hello world', payload: {tracking_number: '123456', even: 2, more: 'data'})
|
89
|
+
hash = {tracking_number: '123456', even: 2, more: 'data'}
|
456
90
|
SemanticLogger.flush
|
457
|
-
|
91
|
+
hash_str = hash.inspect.sub('{', '\{').sub('}', '\}')
|
92
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] LoggerTest -- Hello world -- #{hash_str}/, @mock_logger.message)
|
458
93
|
end
|
459
94
|
|
460
|
-
it '
|
461
|
-
|
462
|
-
|
463
|
-
@logger.measure_info('hello world', silence: :trace) do
|
464
|
-
@logger.debug('hello world', @hash) { 'Calculations' }
|
465
|
-
SemanticLogger.flush
|
466
|
-
first_message = @mock_logger.message
|
467
|
-
end
|
468
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] LoggerTest -- hello world -- Calculations -- #{@hash_str}/, first_message)
|
95
|
+
it 'logs payload and message from block' do
|
96
|
+
@logger.send(level) { {message: 'Hello world', payload: {tracking_number: '123456', even: 2, more: 'data'}} }
|
97
|
+
hash = {tracking_number: '123456', even: 2, more: 'data'}
|
469
98
|
SemanticLogger.flush
|
470
|
-
|
471
|
-
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+
|
99
|
+
hash_str = hash.inspect.sub('{', '\{').sub('}', '\}')
|
100
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] LoggerTest -- Hello world -- #{hash_str}/, @mock_logger.message)
|
472
101
|
end
|
473
|
-
end
|
474
102
|
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
end
|
479
|
-
|
480
|
-
it 'not log at a level below the global default' do
|
481
|
-
assert_equal :debug, SemanticLogger.default_level
|
482
|
-
assert_equal :debug, @logger.level
|
483
|
-
@logger.trace('hello world', @hash) { 'Calculations' }
|
103
|
+
it 'logs payload only' do
|
104
|
+
hash = {tracking_number: '123456', even: 2, more: 'data'}
|
105
|
+
@logger.send(level, payload: hash)
|
484
106
|
SemanticLogger.flush
|
485
|
-
|
107
|
+
hash_str = hash.inspect.sub('{', '\{').sub('}', '\}')
|
108
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] LoggerTest -- #{hash_str}/, @mock_logger.message)
|
486
109
|
end
|
487
110
|
|
488
|
-
it '
|
489
|
-
|
490
|
-
|
491
|
-
assert_equal :trace, @logger.level
|
492
|
-
@logger.trace('hello world', @hash) { 'Calculations' }
|
111
|
+
it 'logs duration' do
|
112
|
+
@logger.send(level, duration: 123.45, message: 'Hello world', payload: {tracking_number: '123456', even: 2, more: 'data'})
|
113
|
+
hash = {tracking_number: '123456', even: 2, more: 'data'}
|
493
114
|
SemanticLogger.flush
|
494
|
-
|
115
|
+
hash_str = hash.inspect.sub('{', '\{').sub('}', '\}')
|
116
|
+
duration_match = defined?(JRuby) ? '\(123ms\)' : '\(123\.5ms\)'
|
117
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] #{duration_match} LoggerTest -- Hello world -- #{hash_str}/, @mock_logger.message)
|
495
118
|
end
|
496
119
|
|
497
|
-
it 'not log
|
498
|
-
|
499
|
-
@logger.level = :warn
|
500
|
-
assert_equal :warn, @logger.level
|
501
|
-
@logger.debug('hello world', @hash) { 'Calculations' }
|
120
|
+
it 'does not log when below min_duration' do
|
121
|
+
@logger.send(level, min_duration: 200, duration: 123.45, message: 'Hello world', payload: {tracking_number: '123456', even: 2, more: 'data'})
|
502
122
|
SemanticLogger.flush
|
503
123
|
assert_nil @mock_logger.message
|
504
124
|
end
|
505
|
-
end
|
506
125
|
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
it 'not log at a level below the silence level' do
|
513
|
-
assert_equal :info, SemanticLogger.default_level
|
514
|
-
assert_equal :info, @logger.level
|
515
|
-
@logger.silence do
|
516
|
-
@logger.warn('hello world', @hash) { 'Calculations' }
|
517
|
-
@logger.info('hello world', @hash) { 'Calculations' }
|
518
|
-
@logger.debug('hello world', @hash) { 'Calculations' }
|
519
|
-
@logger.trace('hello world', @hash) { 'Calculations' }
|
126
|
+
it 'logs metric' do
|
127
|
+
# Add mock metric subscriber
|
128
|
+
$last_metric = nil
|
129
|
+
SemanticLogger.on_metric do |log|
|
130
|
+
$last_metric = log.dup
|
520
131
|
end
|
132
|
+
|
133
|
+
metric_name = '/my/custom/metric'
|
134
|
+
@logger.send(level, metric: metric_name, duration: 123.45, message: 'Hello world', payload: {tracking_number: '123456', even: 2, more: 'data'})
|
135
|
+
hash = {tracking_number: '123456', even: 2, more: 'data'}
|
521
136
|
SemanticLogger.flush
|
522
|
-
|
137
|
+
hash_str = hash.inspect.sub('{', '\{').sub('}', '\}')
|
138
|
+
duration_match = defined?(JRuby) ? '\(123ms\)' : '\(123\.5ms\)'
|
139
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] #{duration_match} LoggerTest -- Hello world -- #{hash_str}/, @mock_logger.message)
|
140
|
+
assert metric_name, $last_metric.metric
|
523
141
|
end
|
524
142
|
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
143
|
+
end
|
144
|
+
|
145
|
+
describe '#filter' do
|
146
|
+
it 'Proc' do
|
147
|
+
@appender.filter = Proc.new { |l| (/\AExclude/ =~ l.message).nil? }
|
148
|
+
@logger.send(level, 'Exclude this log message', @hash) { 'Calculations' }
|
531
149
|
SemanticLogger.flush
|
532
|
-
|
150
|
+
assert_nil @mock_logger.message
|
533
151
|
end
|
534
152
|
|
535
|
-
it '
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
end
|
153
|
+
it 'RegExp' do
|
154
|
+
filter = /\ALogger/
|
155
|
+
@appender.filter = filter
|
156
|
+
logger = SemanticLogger::Logger.new('NotLogger', :trace, filter)
|
157
|
+
logger.send(level, 'Ignore all log messages from this class', @hash) { 'Calculations' }
|
541
158
|
SemanticLogger.flush
|
542
|
-
|
159
|
+
assert_nil @mock_logger.message
|
543
160
|
end
|
544
161
|
end
|
162
|
+
end
|
163
|
+
end
|
545
164
|
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
SemanticLogger.default_level = :debug
|
556
|
-
assert_equal :debug, @logger.level, @logger.inspect
|
557
|
-
assert_equal true, @logger.debug?, @logger.inspect
|
558
|
-
assert_equal false, @logger.trace?, @logger.inspect
|
165
|
+
describe 'Compatibility' do
|
166
|
+
# Ensure that any log level can be logged
|
167
|
+
Logger::Severity.constants.each do |level|
|
168
|
+
it "log Ruby logger #{level} info" do
|
169
|
+
@logger.level = Logger::Severity.const_get(level)
|
170
|
+
if level.to_s == 'UNKNOWN'
|
171
|
+
assert_equal Logger::Severity.const_get('ERROR')+1, @logger.send(:level_index)
|
172
|
+
else
|
173
|
+
assert_equal Logger::Severity.const_get(level)+1, @logger.send(:level_index)
|
559
174
|
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
560
178
|
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
179
|
+
describe '#level?' do
|
180
|
+
it 'return true for debug? with :trace level' do
|
181
|
+
SemanticLogger.default_level = :trace
|
182
|
+
assert_equal :trace, @logger.level
|
183
|
+
assert_equal true, @logger.debug?
|
184
|
+
assert_equal true, @logger.trace?
|
185
|
+
end
|
567
186
|
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
187
|
+
it 'return false for debug? with global :debug level' do
|
188
|
+
SemanticLogger.default_level = :debug
|
189
|
+
assert_equal :debug, @logger.level, @logger.inspect
|
190
|
+
assert_equal true, @logger.debug?, @logger.inspect
|
191
|
+
assert_equal false, @logger.trace?, @logger.inspect
|
192
|
+
end
|
574
193
|
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
end
|
194
|
+
it 'return true for debug? with global :info level' do
|
195
|
+
SemanticLogger.default_level = :info
|
196
|
+
assert_equal :info, @logger.level, @logger.inspect
|
197
|
+
assert_equal false, @logger.debug?, @logger.inspect
|
198
|
+
assert_equal false, @logger.trace?, @logger.inspect
|
199
|
+
end
|
582
200
|
|
201
|
+
it 'return false for debug? with instance :debug level' do
|
202
|
+
@logger.level = :debug
|
203
|
+
assert_equal :debug, @logger.level, @logger.inspect
|
204
|
+
assert_equal true, @logger.debug?, @logger.inspect
|
205
|
+
assert_equal false, @logger.trace?, @logger.inspect
|
583
206
|
end
|
584
|
-
end
|
585
207
|
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
208
|
+
it 'return true for debug? with instance :info level' do
|
209
|
+
@logger.level = :info
|
210
|
+
assert_equal :info, @logger.level, @logger.inspect
|
211
|
+
assert_equal false, @logger.debug?, @logger.inspect
|
212
|
+
assert_equal false, @logger.trace?, @logger.inspect
|
591
213
|
end
|
592
|
-
'Bad'
|
593
214
|
end
|
594
215
|
|
595
216
|
end
|