semantic_logger 4.1.1 → 4.2.0
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/lib/semantic_logger.rb +6 -13
- data/lib/semantic_logger/ansi_colors.rb +10 -10
- data/lib/semantic_logger/appender.rb +42 -26
- data/lib/semantic_logger/appender/async.rb +179 -0
- data/lib/semantic_logger/appender/async_batch.rb +95 -0
- data/lib/semantic_logger/appender/bugsnag.rb +2 -1
- data/lib/semantic_logger/appender/elasticsearch.rb +113 -81
- data/lib/semantic_logger/appender/elasticsearch_http.rb +1 -3
- data/lib/semantic_logger/appender/file.rb +1 -3
- data/lib/semantic_logger/appender/graylog.rb +6 -5
- data/lib/semantic_logger/appender/honeybadger.rb +0 -2
- data/lib/semantic_logger/appender/http.rb +25 -10
- data/lib/semantic_logger/appender/kafka.rb +1 -3
- data/lib/semantic_logger/appender/mongodb.rb +1 -3
- data/lib/semantic_logger/appender/new_relic.rb +7 -3
- data/lib/semantic_logger/appender/sentry.rb +6 -7
- data/lib/semantic_logger/appender/splunk.rb +1 -2
- data/lib/semantic_logger/appender/splunk_http.rb +3 -4
- data/lib/semantic_logger/appender/syslog.rb +1 -3
- data/lib/semantic_logger/appender/tcp.rb +7 -9
- data/lib/semantic_logger/appender/udp.rb +0 -2
- data/lib/semantic_logger/appender/wrapper.rb +0 -2
- data/lib/semantic_logger/base.rb +76 -19
- data/lib/semantic_logger/formatters.rb +37 -0
- data/lib/semantic_logger/formatters/base.rb +10 -3
- data/lib/semantic_logger/formatters/json.rb +2 -6
- data/lib/semantic_logger/formatters/one_line.rb +18 -0
- data/lib/semantic_logger/formatters/raw.rb +8 -2
- data/lib/semantic_logger/formatters/signalfx.rb +169 -0
- data/lib/semantic_logger/log.rb +23 -14
- data/lib/semantic_logger/loggable.rb +88 -15
- data/lib/semantic_logger/logger.rb +0 -20
- data/lib/semantic_logger/metric/new_relic.rb +75 -0
- data/lib/semantic_logger/metric/signalfx.rb +123 -0
- data/lib/semantic_logger/{metrics → metric}/statsd.rb +20 -8
- data/lib/semantic_logger/processor.rb +67 -169
- data/lib/semantic_logger/semantic_logger.rb +7 -31
- data/lib/semantic_logger/subscriber.rb +32 -36
- data/lib/semantic_logger/utils.rb +47 -0
- data/lib/semantic_logger/version.rb +1 -1
- data/test/appender/async_batch_test.rb +61 -0
- data/test/appender/async_test.rb +45 -0
- data/test/appender/elasticsearch_http_test.rb +3 -3
- data/test/appender/elasticsearch_test.rb +211 -49
- data/test/appender/file_test.rb +9 -8
- data/test/appender/mongodb_test.rb +3 -3
- data/test/appender/newrelic_rpm.rb +6 -0
- data/test/appender/sentry_test.rb +3 -1
- data/test/appender/wrapper_test.rb +29 -0
- data/test/concerns/compatibility_test.rb +64 -60
- data/test/debug_as_trace_logger_test.rb +62 -77
- data/test/formatters/one_line_test.rb +61 -0
- data/test/formatters/signalfx_test.rb +200 -0
- data/test/formatters_test.rb +36 -0
- data/test/in_memory_appender.rb +9 -0
- data/test/in_memory_appender_helper.rb +43 -0
- data/test/in_memory_batch_appender.rb +9 -0
- data/test/in_memory_metrics_appender.rb +14 -0
- data/test/loggable_test.rb +15 -30
- data/test/logger_test.rb +181 -135
- data/test/measure_test.rb +212 -113
- data/test/metric/new_relic_test.rb +36 -0
- data/test/metric/signalfx_test.rb +78 -0
- data/test/semantic_logger_test.rb +58 -65
- data/test/test_helper.rb +19 -2
- metadata +33 -7
- data/lib/semantic_logger/metrics/new_relic.rb +0 -30
- data/lib/semantic_logger/metrics/udp.rb +0 -80
- data/test/mock_logger.rb +0 -29
data/test/measure_test.rb
CHANGED
@@ -2,201 +2,297 @@ require_relative 'test_helper'
|
|
2
2
|
|
3
3
|
class MeasureTest < Minitest::Test
|
4
4
|
describe 'Measure' do
|
5
|
-
|
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
|
5
|
+
include InMemoryAppenderHelper
|
26
6
|
|
27
7
|
# Ensure that any log level can be measured and logged
|
28
8
|
SemanticLogger::LEVELS.each do |level|
|
29
|
-
level_char = level.to_s.upcase[0]
|
30
9
|
measure_level = "measure_#{level}".to_sym
|
31
10
|
|
32
11
|
describe "##{measure_level}" do
|
33
12
|
it ':message' do
|
34
|
-
assert_equal 'result',
|
35
|
-
|
36
|
-
|
13
|
+
assert_equal 'result', logger.send(measure_level, 'hello world') { 'result' }
|
14
|
+
|
15
|
+
assert log = log_message
|
16
|
+
assert_equal 'hello world', log.message
|
17
|
+
end
|
18
|
+
|
19
|
+
it ':level' do
|
20
|
+
assert_equal 'result', logger.send(measure_level, 'hello world') { 'result' }
|
21
|
+
|
22
|
+
assert log = log_message
|
23
|
+
assert_equal level, log.level
|
37
24
|
end
|
38
25
|
|
39
26
|
it ':payload' do
|
40
|
-
assert_equal 'result',
|
41
|
-
|
42
|
-
|
27
|
+
assert_equal 'result', logger.send(measure_level, 'hello world', payload: payload) { 'result' }
|
28
|
+
|
29
|
+
assert log = log_message
|
30
|
+
assert_equal payload, log.payload
|
43
31
|
end
|
44
32
|
|
45
33
|
describe ':min_duration' do
|
46
34
|
it 'not log when faster' do
|
47
|
-
assert_equal 'result',
|
48
|
-
|
49
|
-
assert_nil @mock_logger.message
|
35
|
+
assert_equal 'result', logger.send(measure_level, 'hello world', min_duration: 2000) { 'result' }
|
36
|
+
refute log_message
|
50
37
|
end
|
51
38
|
|
52
39
|
it 'log when slower' do
|
53
|
-
assert_equal 'result',
|
54
|
-
|
55
|
-
|
40
|
+
assert_equal 'result', logger.send(measure_level, 'hello world', min_duration: 200, payload: payload) { sleep 0.5; 'result' }
|
41
|
+
|
42
|
+
assert log = log_message
|
43
|
+
assert_equal 'hello world', log.message
|
56
44
|
end
|
57
45
|
end
|
58
46
|
|
59
47
|
it ':exception' do
|
60
48
|
assert_raises RuntimeError do
|
61
|
-
|
49
|
+
logger.send(measure_level, 'hello world', payload: payload) { raise RuntimeError.new('Test') }
|
62
50
|
end
|
63
|
-
|
64
|
-
|
51
|
+
|
52
|
+
assert log = log_message
|
53
|
+
refute log.exception
|
54
|
+
assert_equal 'hello world -- Exception: RuntimeError: Test', log.message
|
55
|
+
assert_equal level, log.level
|
65
56
|
end
|
66
57
|
|
67
58
|
it ':on_exception_level' do
|
68
59
|
assert_raises RuntimeError do
|
69
|
-
|
60
|
+
logger.measure(level, 'hello world', payload: payload, on_exception_level: :fatal) { raise RuntimeError.new('Test') }
|
61
|
+
end
|
62
|
+
|
63
|
+
assert log = log_message
|
64
|
+
refute log.exception
|
65
|
+
assert_equal 'hello world -- Exception: RuntimeError: Test', log.message
|
66
|
+
assert_equal :fatal, log.level
|
67
|
+
end
|
68
|
+
|
69
|
+
describe 'log_exception' do
|
70
|
+
it 'default' do
|
71
|
+
assert_raises RuntimeError do
|
72
|
+
logger.send(measure_level, 'hello world') { raise RuntimeError.new('Test') }
|
73
|
+
end
|
74
|
+
|
75
|
+
assert log = log_message
|
76
|
+
refute log.exception
|
77
|
+
assert_equal 'hello world -- Exception: RuntimeError: Test', log.message
|
78
|
+
end
|
79
|
+
|
80
|
+
it ':full' do
|
81
|
+
assert_raises RuntimeError do
|
82
|
+
logger.send(measure_level, 'hello world', log_exception: :full) { raise RuntimeError.new('Test') }
|
83
|
+
end
|
84
|
+
|
85
|
+
assert log = log_message
|
86
|
+
assert log.exception.is_a?(RuntimeError)
|
87
|
+
assert log.exception.backtrace
|
88
|
+
assert_equal level, log.level
|
89
|
+
assert_equal 'hello world', log.message
|
90
|
+
end
|
91
|
+
|
92
|
+
it ':partial' do
|
93
|
+
assert_raises RuntimeError do
|
94
|
+
logger.send(measure_level, 'hello world', log_exception: :partial) { raise RuntimeError.new('Test') }
|
95
|
+
end
|
96
|
+
|
97
|
+
assert log = log_message
|
98
|
+
refute log.exception
|
99
|
+
assert_equal 'hello world -- Exception: RuntimeError: Test', log.message
|
100
|
+
end
|
101
|
+
|
102
|
+
it ':none' do
|
103
|
+
assert_raises RuntimeError do
|
104
|
+
logger.send(measure_level, 'hello world', log_exception: :none) { raise RuntimeError.new('Test') }
|
105
|
+
end
|
106
|
+
|
107
|
+
assert log = log_message
|
108
|
+
refute log.exception
|
109
|
+
assert_equal 'hello world', log.message
|
70
110
|
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
111
|
end
|
74
112
|
|
75
113
|
it ':metric' do
|
76
114
|
metric_name = '/my/custom/metric'
|
77
|
-
assert_equal 'result',
|
78
|
-
|
79
|
-
|
80
|
-
|
115
|
+
assert_equal 'result', logger.send(measure_level, 'hello world', metric: metric_name) { 'result' }
|
116
|
+
|
117
|
+
assert log = log_message
|
118
|
+
assert_equal metric_name, log.metric
|
81
119
|
end
|
82
120
|
|
83
121
|
it ':backtrace_level' do
|
84
122
|
SemanticLogger.stub(:backtrace_level_index, 0) do
|
85
|
-
assert_equal 'result',
|
86
|
-
|
87
|
-
|
123
|
+
assert_equal 'result', logger.send(measure_level, 'hello world') { 'result' }
|
124
|
+
|
125
|
+
assert log = log_message
|
126
|
+
assert log.backtrace
|
127
|
+
assert log.backtrace.size > 0
|
128
|
+
|
129
|
+
# Extract file name and line number from backtrace
|
130
|
+
h = log.to_h
|
131
|
+
assert_match /measure_test.rb/, h[:file], h
|
132
|
+
assert h[:line].is_a?(Integer)
|
88
133
|
end
|
89
134
|
end
|
90
135
|
end
|
91
136
|
|
92
137
|
describe "#measure(#{level})" do
|
93
138
|
it ':message' do
|
94
|
-
assert_equal 'result',
|
95
|
-
|
96
|
-
|
139
|
+
assert_equal 'result', logger.measure(level, 'hello world') { 'result' }
|
140
|
+
|
141
|
+
assert log = log_message
|
142
|
+
assert_equal 'hello world', log.message
|
143
|
+
end
|
144
|
+
|
145
|
+
it ':level' do
|
146
|
+
assert_equal 'result', logger.measure(level, 'hello world') { 'result' }
|
147
|
+
|
148
|
+
assert log = log_message
|
149
|
+
assert_equal level, log.level
|
97
150
|
end
|
98
151
|
|
99
152
|
it ':payload' do
|
100
|
-
assert_equal 'result',
|
101
|
-
|
102
|
-
|
153
|
+
assert_equal 'result', logger.measure(level, 'hello world', payload: payload) { 'result' }
|
154
|
+
|
155
|
+
assert log = log_message
|
156
|
+
assert_equal payload, log.payload
|
103
157
|
end
|
104
158
|
|
105
159
|
describe ':min_duration' do
|
106
160
|
it 'not log when faster' do
|
107
|
-
assert_equal 'result',
|
108
|
-
|
109
|
-
assert_nil @mock_logger.message
|
161
|
+
assert_equal 'result', logger.measure(level, 'hello world', min_duration: 2000) { 'result' }
|
162
|
+
refute log_message
|
110
163
|
end
|
111
164
|
|
112
165
|
it 'log when slower' do
|
113
|
-
assert_equal 'result',
|
114
|
-
|
115
|
-
|
166
|
+
assert_equal 'result', logger.measure(level, 'hello world', min_duration: 200, payload: payload) { sleep 0.5; 'result' }
|
167
|
+
assert log = log_message
|
168
|
+
assert_equal 'hello world', log.message
|
116
169
|
end
|
117
170
|
end
|
118
171
|
|
119
172
|
it ':exception' do
|
120
173
|
assert_raises RuntimeError do
|
121
|
-
|
174
|
+
logger.measure(level, 'hello world', payload: payload) { raise RuntimeError.new('Test') }
|
122
175
|
end
|
123
|
-
|
124
|
-
|
176
|
+
|
177
|
+
assert log = log_message
|
178
|
+
refute log.exception
|
179
|
+
assert_equal 'hello world -- Exception: RuntimeError: Test', log.message
|
180
|
+
assert_equal level, log.level
|
181
|
+
end
|
182
|
+
|
183
|
+
it ':on_exception_level' do
|
184
|
+
assert_raises RuntimeError do
|
185
|
+
logger.measure(level, 'hello world', payload: payload, on_exception_level: :fatal) { raise RuntimeError.new('Test') }
|
186
|
+
end
|
187
|
+
|
188
|
+
assert log = log_message
|
189
|
+
refute log.exception
|
190
|
+
assert_equal 'hello world -- Exception: RuntimeError: Test', log.message
|
191
|
+
assert_equal :fatal, log.level
|
125
192
|
end
|
126
193
|
|
127
194
|
it ':metric' do
|
128
195
|
metric_name = '/my/custom/metric'
|
129
|
-
assert_equal 'result',
|
130
|
-
|
131
|
-
|
132
|
-
|
196
|
+
assert_equal 'result', logger.measure(level, 'hello world', metric: metric_name) { 'result' }
|
197
|
+
|
198
|
+
assert log = log_message
|
199
|
+
assert_equal metric_name, log.metric
|
133
200
|
end
|
134
201
|
|
135
|
-
it
|
202
|
+
it ':backtrace_level' do
|
136
203
|
SemanticLogger.stub(:backtrace_level_index, 0) do
|
137
|
-
assert_equal 'result',
|
138
|
-
|
139
|
-
|
204
|
+
assert_equal 'result', logger.measure(level, 'hello world') { 'result' }
|
205
|
+
|
206
|
+
assert log = log_message
|
207
|
+
assert log.backtrace
|
208
|
+
assert log.backtrace.size > 0
|
209
|
+
|
210
|
+
# Extract file name and line number from backtrace
|
211
|
+
h = log.to_h
|
212
|
+
assert_match /measure_test.rb/, h[:file], h
|
213
|
+
assert h[:line].is_a?(Integer)
|
140
214
|
end
|
141
215
|
end
|
142
216
|
end
|
143
217
|
|
144
|
-
describe "##{measure_level}
|
218
|
+
describe "##{measure_level} keyword arguments" do
|
145
219
|
it ':message' do
|
146
|
-
assert_equal 'result',
|
147
|
-
|
148
|
-
|
220
|
+
assert_equal 'result', logger.send(measure_level, message: 'hello world') { 'result' }
|
221
|
+
|
222
|
+
assert log = log_message
|
223
|
+
assert_equal 'hello world', log.message
|
224
|
+
end
|
225
|
+
|
226
|
+
it ':level' do
|
227
|
+
assert_equal 'result', logger.send(measure_level, message: 'hello world') { 'result' }
|
228
|
+
|
229
|
+
assert log = log_message
|
230
|
+
assert_equal level, log.level
|
149
231
|
end
|
150
232
|
|
151
233
|
it ':payload' do
|
152
|
-
assert_equal 'result',
|
153
|
-
|
154
|
-
|
234
|
+
assert_equal 'result', logger.send(measure_level, message: 'hello world', payload: payload) { 'result' }
|
235
|
+
|
236
|
+
assert log = log_message
|
237
|
+
assert_equal payload, log.payload
|
155
238
|
end
|
156
239
|
|
157
240
|
describe ':min_duration' do
|
158
241
|
it 'not log when faster' do
|
159
|
-
assert_equal 'result',
|
160
|
-
|
161
|
-
assert_nil @mock_logger.message
|
242
|
+
assert_equal 'result', logger.send(measure_level, message: 'hello world', min_duration: 2000) { 'result' }
|
243
|
+
refute log_message
|
162
244
|
end
|
163
245
|
|
164
246
|
it 'log when slower' do
|
165
|
-
assert_equal 'result',
|
166
|
-
|
167
|
-
|
247
|
+
assert_equal 'result', logger.send(measure_level, message: 'hello world', min_duration: 200, payload: payload) { sleep 0.5; 'result' }
|
248
|
+
|
249
|
+
assert log = log_message
|
250
|
+
assert_equal 'hello world', log.message
|
168
251
|
end
|
169
252
|
end
|
170
253
|
|
171
254
|
it ':exception' do
|
172
255
|
assert_raises RuntimeError do
|
173
|
-
|
256
|
+
logger.send(measure_level, message: 'hello world', payload: payload) { raise RuntimeError.new('Test') }
|
174
257
|
end
|
175
|
-
|
176
|
-
|
258
|
+
|
259
|
+
assert log = log_message
|
260
|
+
refute log.exception
|
261
|
+
assert_equal 'hello world -- Exception: RuntimeError: Test', log.message
|
262
|
+
assert_equal level, log.level
|
177
263
|
end
|
178
264
|
|
179
265
|
it ':on_exception_level' do
|
180
266
|
assert_raises RuntimeError do
|
181
|
-
|
267
|
+
logger.send(measure_level, message: 'hello world', payload: payload, on_exception_level: :fatal) { raise RuntimeError.new('Test') }
|
182
268
|
end
|
183
|
-
|
184
|
-
|
269
|
+
|
270
|
+
assert log = log_message
|
271
|
+
refute log.exception
|
272
|
+
assert_equal 'hello world -- Exception: RuntimeError: Test', log.message
|
273
|
+
assert_equal :fatal, log.level
|
185
274
|
end
|
186
275
|
|
187
276
|
it ':metric' do
|
188
277
|
metric_name = '/my/custom/metric'
|
189
|
-
assert_equal 'result',
|
190
|
-
|
191
|
-
|
192
|
-
|
278
|
+
assert_equal 'result', logger.send(measure_level, message: 'hello world', metric: metric_name) { 'result' }
|
279
|
+
|
280
|
+
assert log = log_message
|
281
|
+
assert_equal metric_name, log.metric
|
193
282
|
end
|
194
283
|
|
195
284
|
it ':backtrace_level' do
|
196
285
|
SemanticLogger.stub(:backtrace_level_index, 0) do
|
197
|
-
assert_equal 'result',
|
198
|
-
|
199
|
-
|
286
|
+
assert_equal 'result', logger.send(measure_level, message: 'hello world') { 'result' }
|
287
|
+
|
288
|
+
assert log = log_message
|
289
|
+
assert log.backtrace
|
290
|
+
assert log.backtrace.size > 0
|
291
|
+
|
292
|
+
# Extract file name and line number from backtrace
|
293
|
+
h = log.to_h
|
294
|
+
assert_match /measure_test.rb/, h[:file], h
|
295
|
+
assert h[:line].is_a?(Integer)
|
200
296
|
end
|
201
297
|
end
|
202
298
|
end
|
@@ -205,41 +301,44 @@ class MeasureTest < Minitest::Test
|
|
205
301
|
|
206
302
|
describe 'return' do
|
207
303
|
it 'log when the block performs a return' do
|
208
|
-
assert_equal 'Good', function_with_return(
|
209
|
-
|
210
|
-
|
304
|
+
assert_equal 'Good', function_with_return(logger)
|
305
|
+
|
306
|
+
assert log = log_message
|
307
|
+
assert_equal 'hello world', log.message
|
211
308
|
end
|
212
309
|
end
|
213
310
|
|
214
311
|
describe ':silence' do
|
215
312
|
it 'silences messages' do
|
216
313
|
SemanticLogger.default_level = :info
|
217
|
-
|
218
|
-
|
314
|
+
logger.measure_info('hello world', silence: :error) do
|
315
|
+
logger.warn "don't log me"
|
219
316
|
end
|
220
|
-
|
221
|
-
|
317
|
+
|
318
|
+
assert log = log_message
|
319
|
+
assert_equal 'hello world', log.message
|
222
320
|
end
|
223
321
|
|
224
|
-
it 'does not silence
|
322
|
+
it 'does not silence higher level messages' do
|
225
323
|
SemanticLogger.default_level = :info
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
first_message = @mock_logger.message
|
324
|
+
first = nil
|
325
|
+
logger.measure_info('hello world', silence: :trace) do
|
326
|
+
logger.debug('hello world', payload) { 'Calculations' }
|
327
|
+
first = log_message
|
231
328
|
end
|
232
|
-
|
329
|
+
assert_equal 'hello world -- Calculations', first.message
|
330
|
+
assert_equal payload, first.payload
|
331
|
+
|
233
332
|
SemanticLogger.flush
|
234
|
-
|
235
|
-
|
333
|
+
assert log = appender.message
|
334
|
+
assert_equal 'hello world', log.message
|
236
335
|
end
|
237
336
|
end
|
238
337
|
|
239
338
|
# Make sure that measure still logs when a block uses return to return from
|
240
339
|
# a function
|
241
340
|
def function_with_return(logger)
|
242
|
-
logger.measure_info('hello world', payload:
|
341
|
+
logger.measure_info('hello world', payload: payload) do
|
243
342
|
return 'Good'
|
244
343
|
end
|
245
344
|
'Bad'
|