semantic_logger 4.3.1 → 4.4.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.
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