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