semantic_logger 4.3.1 → 4.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/lib/semantic_logger.rb +7 -1
  3. data/lib/semantic_logger/appender.rb +3 -0
  4. data/lib/semantic_logger/appender/async.rb +29 -10
  5. data/lib/semantic_logger/appender/rabbitmq.rb +120 -0
  6. data/lib/semantic_logger/appenders.rb +89 -0
  7. data/lib/semantic_logger/base.rb +3 -3
  8. data/lib/semantic_logger/concerns/compatibility.rb +2 -2
  9. data/lib/semantic_logger/formatters.rb +1 -0
  10. data/lib/semantic_logger/formatters/base.rb +28 -6
  11. data/lib/semantic_logger/formatters/color.rb +4 -3
  12. data/lib/semantic_logger/formatters/fluentd.rb +37 -0
  13. data/lib/semantic_logger/formatters/json.rb +4 -2
  14. data/lib/semantic_logger/formatters/raw.rb +2 -2
  15. data/lib/semantic_logger/formatters/signalfx.rb +4 -3
  16. data/lib/semantic_logger/levels.rb +38 -0
  17. data/lib/semantic_logger/log.rb +11 -6
  18. data/lib/semantic_logger/loggable.rb +1 -1
  19. data/lib/semantic_logger/logger.rb +43 -1
  20. data/lib/semantic_logger/processor.rb +10 -130
  21. data/lib/semantic_logger/reporters/minitest.rb +49 -0
  22. data/lib/semantic_logger/semantic_logger.rb +40 -75
  23. data/lib/semantic_logger/version.rb +1 -1
  24. metadata +9 -81
  25. data/test/appender/async_batch_test.rb +0 -60
  26. data/test/appender/async_test.rb +0 -44
  27. data/test/appender/bugsnag_test.rb +0 -81
  28. data/test/appender/elasticsearch_http_test.rb +0 -74
  29. data/test/appender/elasticsearch_test.rb +0 -248
  30. data/test/appender/file_test.rb +0 -120
  31. data/test/appender/graylog_test.rb +0 -82
  32. data/test/appender/honeybadger_test.rb +0 -45
  33. data/test/appender/http_test.rb +0 -63
  34. data/test/appender/kafka_test.rb +0 -35
  35. data/test/appender/mongodb_test.rb +0 -104
  36. data/test/appender/new_relic_test.rb +0 -80
  37. data/test/appender/newrelic_rpm.rb +0 -14
  38. data/test/appender/sentry_test.rb +0 -47
  39. data/test/appender/splunk_http_test.rb +0 -79
  40. data/test/appender/splunk_test.rb +0 -83
  41. data/test/appender/syslog_test.rb +0 -61
  42. data/test/appender/tcp_test.rb +0 -66
  43. data/test/appender/udp_test.rb +0 -59
  44. data/test/appender/wrapper_test.rb +0 -95
  45. data/test/concerns/compatibility_test.rb +0 -117
  46. data/test/debug_as_trace_logger_test.rb +0 -81
  47. data/test/formatters/color_test.rb +0 -153
  48. data/test/formatters/default_test.rb +0 -175
  49. data/test/formatters/one_line_test.rb +0 -60
  50. data/test/formatters/signalfx_test.rb +0 -197
  51. data/test/formatters_test.rb +0 -36
  52. data/test/in_memory_appender.rb +0 -8
  53. data/test/in_memory_appender_helper.rb +0 -43
  54. data/test/in_memory_batch_appender.rb +0 -8
  55. data/test/in_memory_metrics_appender.rb +0 -13
  56. data/test/loggable_test.rb +0 -103
  57. data/test/logger_test.rb +0 -334
  58. data/test/measure_test.rb +0 -346
  59. data/test/metric/new_relic_test.rb +0 -35
  60. data/test/metric/signalfx_test.rb +0 -77
  61. data/test/semantic_logger_test.rb +0 -303
  62. data/test/test_helper.rb +0 -31
@@ -1,81 +0,0 @@
1
- require_relative '../test_helper'
2
-
3
- # Unit Test for SemanticLogger::Appender::Bugsnag
4
- module Appender
5
- class BugsnagTest < Minitest::Test
6
- describe SemanticLogger::Appender::Bugsnag do
7
- before do
8
- @appender = SemanticLogger::Appender::Bugsnag.new(level: :info)
9
- @message = 'AppenderBugsnagTest log message'
10
- end
11
-
12
- SemanticLogger::LEVELS.each do |level|
13
- it "sends #{level} message" do
14
- bugsnag_level =
15
- case level
16
- when :warn
17
- 'warning'
18
- when :fatal
19
- 'error'
20
- else
21
- level.to_s
22
- end
23
- exception = hash = nil
24
- Bugsnag.stub(:notify, ->(exc, h) { exception = exc; hash = h }) do
25
- @appender.send(level, @message)
26
- end
27
- if %i[trace debug].include?(level)
28
- assert_nil exception
29
- assert_nil hash
30
- else
31
- assert_equal 'RuntimeError', exception.class.to_s
32
- assert_equal @message, exception.message
33
- assert_equal bugsnag_level.to_s, hash[:severity]
34
- end
35
- end
36
-
37
- it "sends #{level} custom attributes" do
38
- exception = hash = nil
39
- Bugsnag.stub(:notify, ->(exc, h) { exception = exc; hash = h }) do
40
- @appender.send(level, @message, key1: 1, key2: 'a')
41
- end
42
- if %i[trace debug].include?(level)
43
- assert_nil exception
44
- assert_nil hash
45
- else
46
- assert_equal 'RuntimeError', exception.class.to_s
47
- assert_equal @message, exception.message
48
- assert payload = hash[:payload], hash
49
- assert_equal 1, payload[:key1], payload
50
- assert_equal 'a', payload[:key2], payload
51
- end
52
- end
53
-
54
- it "sends #{level} exceptions" do
55
- error = RuntimeError.new('Hello World')
56
- exception = hash = nil
57
- Bugsnag.stub(:notify, ->(exc, h) { exception = exc; hash = h }) do
58
- @appender.send(level, @message, error)
59
- end
60
- if %i[trace debug].include?(level)
61
- assert_nil exception
62
- assert_nil hash
63
- else
64
- assert_equal error.class.to_s, exception.class.to_s
65
- assert_equal error.message, exception.message
66
- assert_equal @message, hash[:message], hash
67
- end
68
- end
69
-
70
- it 'does not send metric only notifications' do
71
- exception = hash = nil
72
- Bugsnag.stub(:notify, ->(exc, h) { exception = exc; hash = h }) do
73
- @appender.debug metric: 'my/custom/metric', payload: {hello: :world}
74
- end
75
- assert_nil exception
76
- assert_nil hash
77
- end
78
- end
79
- end
80
- end
81
- end
@@ -1,74 +0,0 @@
1
- require_relative '../test_helper'
2
-
3
- # Unit Test for SemanticLogger::Appender::Elasticsearch
4
- module Appender
5
- class ElasticsearchHttpTest < Minitest::Test
6
- response_mock = Struct.new(:code, :body)
7
-
8
- describe SemanticLogger::Appender::ElasticsearchHttp do
9
- before do
10
- Net::HTTP.stub_any_instance(:start, true) do
11
- @appender = SemanticLogger::Appender::ElasticsearchHttp.new(
12
- url: 'http://localhost:9200'
13
- )
14
- end
15
- @message = 'AppenderElasticsearchTest log message'
16
- end
17
-
18
- it 'logs to daily indexes' do
19
- index = nil
20
- @appender.stub(:post, ->(_json, ind) { index = ind }) do
21
- @appender.info @message
22
- end
23
- assert_equal "/semantic_logger-#{Time.now.utc.strftime('%Y.%m.%d')}/log", index
24
- end
25
-
26
- SemanticLogger::LEVELS.each do |level|
27
- it "send #{level}" do
28
- request = nil
29
- @appender.http.stub(:request, ->(r) { request = r; response_mock.new('200', 'ok') }) do
30
- @appender.send(level, @message)
31
- end
32
- message = JSON.parse(request.body)
33
- assert_equal @message, message['message']
34
- assert_equal level.to_s, message['level']
35
- refute message['exception']
36
- end
37
-
38
- it "sends #{level} exceptions" do
39
- exc = nil
40
- begin
41
- Uh oh
42
- rescue Exception => e
43
- exc = e
44
- end
45
- request = nil
46
- @appender.http.stub(:request, ->(r) { request = r; response_mock.new('200', 'ok') }) do
47
- @appender.send(level, 'Reading File', exc)
48
- end
49
- hash = JSON.parse(request.body)
50
- assert_equal 'Reading File', hash['message'], hash
51
- assert exception = hash['exception']
52
- assert_equal 'NameError', exception['name']
53
- assert_match 'undefined local variable or method', exception['message']
54
- assert_equal level.to_s, hash['level']
55
- assert exception['stack_trace'].first.include?(__FILE__), exception
56
- end
57
-
58
- it "sends #{level} custom attributes" do
59
- request = nil
60
- @appender.http.stub(:request, ->(r) { request = r; response_mock.new('200', 'ok') }) do
61
- @appender.send(level, @message, key1: 1, key2: 'a')
62
- end
63
- message = JSON.parse(request.body)
64
- assert_equal @message, message['message']
65
- assert_equal level.to_s, message['level']
66
- refute message['stack_trace']
67
- assert payload = message['payload'], message
68
- assert_equal 1, payload['key1'], message
69
- assert_equal 'a', payload['key2'], message
70
- end
71
- end
72
- end
73
- end
74
- end
@@ -1,248 +0,0 @@
1
- require_relative '../test_helper'
2
-
3
- # Unit Test for SemanticLogger::Appender::Elasticsearch
4
- module Appender
5
- class ElasticsearchTest < Minitest::Test
6
- describe SemanticLogger::Appender::Elasticsearch do
7
- describe 'providing a url' do
8
- let :appender do
9
- if ENV['ELASTICSEARCH']
10
- SemanticLogger::Appender::Elasticsearch.new(url: 'http://localhost:9200')
11
- else
12
- Elasticsearch::Transport::Client.stub_any_instance(:bulk, true) do
13
- SemanticLogger::Appender::Elasticsearch.new(url: 'http://localhost:9200')
14
- end
15
- end
16
- end
17
-
18
- let :log_message do
19
- 'AppenderElasticsearchTest log message'
20
- end
21
-
22
- let :log do
23
- log = SemanticLogger::Log.new('User', :info)
24
- log.message = log_message
25
- log
26
- end
27
-
28
- let :exception do
29
- exc = nil
30
- begin
31
- Uh oh
32
- rescue Exception => e
33
- exc = e
34
- end
35
- exc
36
- end
37
-
38
- after do
39
- appender.close
40
- end
41
-
42
- describe 'synchronous' do
43
- it 'logs to daily indexes' do
44
- bulk_index = nil
45
- appender.stub(:write_to_elasticsearch, ->(messages) { bulk_index = messages.first }) do
46
- appender.info log_message
47
- end
48
- index = bulk_index['index']['_index']
49
- assert_equal "semantic_logger-#{Time.now.strftime('%Y.%m.%d')}", index
50
- end
51
-
52
- it 'logs message' do
53
- request = stub_client { appender.log(log) }
54
-
55
- assert hash = request[:body][1]
56
- assert_equal log_message, hash[:message]
57
- end
58
-
59
- it 'logs level' do
60
- request = stub_client { appender.log(log) }
61
-
62
- assert hash = request[:body][1]
63
- assert_equal :info, hash[:level]
64
- end
65
-
66
- it 'logs exception' do
67
- log.exception = exception
68
- request = stub_client { appender.log(log) }
69
-
70
- assert hash = request[:body][1]
71
- assert exception = hash[:exception]
72
- assert_equal 'NameError', exception[:name]
73
- assert_match 'undefined local variable or method', exception[:message]
74
- assert exception[:stack_trace].first.include?(__FILE__), exception
75
- end
76
-
77
- it 'logs payload' do
78
- h = {key1: 1, key2: 'a'}
79
- log.payload = h
80
- request = stub_client { appender.log(log) }
81
-
82
- assert hash = request[:body][1]
83
- refute hash[:stack_trace]
84
- assert_equal h, hash[:payload], hash
85
- end
86
- end
87
-
88
- describe 'async batch' do
89
- it 'logs message' do
90
- request = stub_client { appender.batch([log]) }
91
-
92
- assert hash = request[:body][1]
93
- assert_equal log_message, hash[:message]
94
- assert_equal :info, hash[:level]
95
- end
96
-
97
- let :logs do
98
- Array.new(3) do |i|
99
- l = log.dup
100
- l.message = "hello world#{i + 1}"
101
- l
102
- end
103
- end
104
-
105
- it 'logs multiple messages' do
106
- request = stub_client { appender.batch(logs) }
107
-
108
- assert body = request[:body]
109
- assert_equal 6, body.size, body
110
-
111
- index = "semantic_logger-#{Time.now.strftime('%Y.%m.%d')}"
112
- assert_equal index, body[0]['index']['_index']
113
- assert_equal 'hello world1', body[1][:message]
114
- assert_equal index, body[2]['index']['_index']
115
- assert_equal 'hello world2', body[3][:message]
116
- assert_equal index, body[4]['index']['_index']
117
- assert_equal 'hello world3', body[5][:message]
118
- end
119
- end
120
-
121
- def stub_client(&block)
122
- request = nil
123
- appender.client.stub(:bulk, ->(r) { request = r; {'status' => 201} }, &block)
124
- request
125
- end
126
- end
127
-
128
- describe 'elasticsearch parameters' do
129
- let :appender do
130
- Elasticsearch::Transport::Client.stub_any_instance(:bulk, true) do
131
- SemanticLogger::Appender::Elasticsearch.new(
132
- hosts: [{host: 'localhost', port: 9200}]
133
- )
134
- end
135
- end
136
-
137
- let :log_message do
138
- 'AppenderElasticsearchTest log message'
139
- end
140
-
141
- let :log do
142
- log = SemanticLogger::Log.new('User', :info)
143
- log.message = log_message
144
- log
145
- end
146
-
147
- let :exception do
148
- exc = nil
149
- begin
150
- Uh oh
151
- rescue Exception => e
152
- exc = e
153
- end
154
- exc
155
- end
156
-
157
- after do
158
- appender.close
159
- end
160
-
161
- describe 'synchronous' do
162
- it 'logs to daily indexes' do
163
- bulk_index = nil
164
- appender.stub(:write_to_elasticsearch, ->(messages) { bulk_index = messages.first }) do
165
- appender.info log_message
166
- end
167
- index = bulk_index['index']['_index']
168
- assert_equal "semantic_logger-#{Time.now.strftime('%Y.%m.%d')}", index
169
- end
170
-
171
- it 'logs message' do
172
- request = stub_client { appender.log(log) }
173
-
174
- assert hash = request[:body][1]
175
- assert_equal log_message, hash[:message]
176
- end
177
-
178
- it 'logs level' do
179
- request = stub_client { appender.log(log) }
180
-
181
- assert hash = request[:body][1]
182
- assert_equal :info, hash[:level]
183
- end
184
-
185
- it 'logs exception' do
186
- log.exception = exception
187
- request = stub_client { appender.log(log) }
188
-
189
- assert hash = request[:body][1]
190
- assert exception = hash[:exception]
191
- assert_equal 'NameError', exception[:name]
192
- assert_match 'undefined local variable or method', exception[:message]
193
- assert exception[:stack_trace].first.include?(__FILE__), exception
194
- end
195
-
196
- it 'logs payload' do
197
- h = {key1: 1, key2: 'a'}
198
- log.payload = h
199
- request = stub_client { appender.log(log) }
200
-
201
- assert hash = request[:body][1]
202
- refute hash[:stack_trace]
203
- assert_equal h, hash[:payload], hash
204
- end
205
- end
206
-
207
- describe 'async batch' do
208
- it 'logs message' do
209
- request = stub_client { appender.batch([log]) }
210
-
211
- assert hash = request[:body][1]
212
- assert_equal log_message, hash[:message]
213
- assert_equal :info, hash[:level]
214
- end
215
-
216
- let :logs do
217
- Array.new(3) do |i|
218
- l = log.dup
219
- l.message = "hello world#{i + 1}"
220
- l
221
- end
222
- end
223
-
224
- it 'logs multiple messages' do
225
- request = stub_client { appender.batch(logs) }
226
-
227
- assert body = request[:body]
228
- assert_equal 6, body.size, body
229
-
230
- index = "semantic_logger-#{Time.now.strftime('%Y.%m.%d')}"
231
- assert_equal index, body[0]['index']['_index']
232
- assert_equal 'hello world1', body[1][:message]
233
- assert_equal index, body[2]['index']['_index']
234
- assert_equal 'hello world2', body[3][:message]
235
- assert_equal index, body[4]['index']['_index']
236
- assert_equal 'hello world3', body[5][:message]
237
- end
238
- end
239
-
240
- def stub_client(&block)
241
- request = nil
242
- appender.client.stub(:bulk, ->(r) { request = r; {'status' => 201} }, &block)
243
- request
244
- end
245
- end
246
- end
247
- end
248
- end
@@ -1,120 +0,0 @@
1
- require_relative '../test_helper'
2
- require 'stringio'
3
-
4
- # Unit Test for SemanticLogger::Appender::File
5
- #
6
- module Appender
7
- class FileTest < Minitest::Test
8
- describe SemanticLogger::Appender::File do
9
- before do
10
- SemanticLogger.default_level = :trace
11
- SemanticLogger.backtrace_level = :error
12
- @time = Time.new
13
- @io = StringIO.new
14
- @appender = SemanticLogger::Appender::File.new(io: @io)
15
- @hash = {session_id: 'HSSKLEU@JDK767', tracking_number: 12_345}
16
- @hash_str = @hash.inspect.sub('{', '\\{').sub('}', '\\}')
17
- @thread_name = Thread.current.name
18
- @file_name_reg_exp = RUBY_VERSION.to_f <= 2.0 ? ' (mock|file_test).rb:\d+' : ' file_test.rb:\d+'
19
- end
20
-
21
- describe 'format logs into text form' do
22
- it 'handle no message or payload' do
23
- @appender.debug
24
- assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File\n/, @io.string)
25
- end
26
-
27
- it 'handle message' do
28
- @appender.debug 'hello world'
29
- assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- hello world\n/, @io.string)
30
- end
31
-
32
- it 'handle message and payload' do
33
- @appender.debug 'hello world', @hash
34
- assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- hello world -- #{@hash_str}\n/, @io.string)
35
- end
36
-
37
- it 'handle message, payload, and exception' do
38
- @appender.debug 'hello world', @hash, StandardError.new('StandardError')
39
- assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- hello world -- #{@hash_str} -- Exception: StandardError: StandardError\n\n/, @io.string)
40
- end
41
-
42
- it 'logs exception with nil backtrace' do
43
- @appender.debug StandardError.new('StandardError')
44
- assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- Exception: StandardError: StandardError\n\n/, @io.string)
45
- end
46
-
47
- it 'handle nested exception' do
48
- begin
49
- raise StandardError, 'FirstError'
50
- rescue Exception
51
- begin
52
- raise StandardError, 'SecondError'
53
- rescue Exception => e2
54
- @appender.debug e2
55
- end
56
- end
57
- assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name} file_test.rb:\d+\] SemanticLogger::Appender::File -- Exception: StandardError: SecondError\n/, @io.string)
58
- assert_match(/^Cause: StandardError: FirstError\n/, @io.string) if Exception.instance_methods.include?(:cause)
59
- end
60
-
61
- it 'logs exception with empty backtrace' do
62
- exc = StandardError.new('StandardError')
63
- exc.set_backtrace([])
64
- @appender.debug exc
65
- assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- Exception: StandardError: StandardError\n\n/, @io.string)
66
- end
67
-
68
- it 'ignores metric only messages' do
69
- @appender.debug metric: 'my/custom/metric'
70
- assert_equal '', @io.string
71
- end
72
-
73
- it 'ignores metric only messages with payload' do
74
- @appender.debug metric: 'my/custom/metric', payload: {hello: :world}
75
- assert_equal '', @io.string
76
- end
77
- end
78
-
79
- describe 'for each log level' do
80
- # Ensure that any log level can be logged
81
- SemanticLogger::LEVELS.each do |level|
82
- it "log #{level} with file_name" do
83
- SemanticLogger.stub(:backtrace_level_index, 0) do
84
- @appender.send(level, 'hello world', @hash)
85
- assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:#{@thread_name}#{@file_name_reg_exp}\] SemanticLogger::Appender::File -- hello world -- #{@hash_str}\n/, @io.string)
86
- end
87
- end
88
-
89
- it "log #{level} without file_name" do
90
- SemanticLogger.stub(:backtrace_level_index, 100) do
91
- @appender.send(level, 'hello world', @hash)
92
- assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- hello world -- #{@hash_str}\n/, @io.string)
93
- end
94
- end
95
- end
96
- end
97
-
98
- describe 'custom formatter' do
99
- before do
100
- @appender = SemanticLogger::Appender::File.new(io: @io) do |log|
101
- tags = log.tags.collect { |tag| "[#{tag}]" }.join(' ') + ' ' if log.tags&.size&.positive?
102
-
103
- message = log.message.to_s
104
- message << ' -- ' << log.payload.inspect if log.payload
105
- message << ' -- ' << "#{log.exception.class}: #{log.exception.message}\n#{(log.exception.backtrace || []).join("\n")}" if log.exception
106
-
107
- duration_str = log.duration ? " (#{format('%.1f', log.duration)}ms)" : ''
108
-
109
- "#{log.formatted_time} #{log.level.to_s.upcase} [#{$$}:#{log.thread_name}] #{tags}#{log.name} -- #{message}#{duration_str}"
110
- end
111
- end
112
-
113
- it 'format using formatter' do
114
- @appender.debug
115
- assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ DEBUG \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- \n/, @io.string)
116
- end
117
- end
118
- end
119
- end
120
- end