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,60 +0,0 @@
1
- require_relative '../test_helper'
2
-
3
- module SemanticLogger
4
- module Formatters
5
- class DefaultTest < Minitest::Test
6
- describe Default do
7
- let(:log_time) do
8
- Time.utc(2017, 1, 14, 8, 32, 5.375276)
9
- end
10
-
11
- let(:level) do
12
- :debug
13
- end
14
-
15
- let(:log) do
16
- log = SemanticLogger::Log.new('DefaultTest', level)
17
- log.time = log_time
18
- log
19
- end
20
-
21
- let(:set_exception) do
22
- begin
23
- raise 'Oh no'
24
- rescue Exception => exc
25
- log.exception = exc
26
- end
27
- end
28
-
29
- let(:formatter) do
30
- formatter = SemanticLogger::Formatters::OneLine.new
31
- # Does not use the logger instance for formatting purposes
32
- formatter.call(log, nil)
33
- formatter
34
- end
35
-
36
- describe 'message' do
37
- it 'logs message' do
38
- log.message = "Hello \nWorld\n"
39
- assert_equal '-- Hello World', formatter.message
40
- end
41
-
42
- it 'skips empty message' do
43
- refute formatter.message
44
- end
45
- end
46
-
47
- describe 'exception' do
48
- it 'logs exception' do
49
- set_exception
50
- assert_equal '-- Exception: RuntimeError: Oh no', formatter.exception
51
- end
52
-
53
- it 'skips nil exception' do
54
- refute formatter.exception
55
- end
56
- end
57
- end
58
- end
59
- end
60
- end
@@ -1,197 +0,0 @@
1
- require_relative '../test_helper'
2
- require 'net/http'
3
-
4
- module SemanticLogger
5
- module Formatters
6
- class SignalfxTest < Minitest::Test
7
- describe SemanticLogger::Formatters::Signalfx do
8
- let :average_metric_name do
9
- 'Application.average'
10
- end
11
-
12
- let :counter_metric_name do
13
- 'Application.counter'
14
- end
15
-
16
- let :log do
17
- metric = '/user/login'
18
- log = SemanticLogger::Log.new('User', :debug)
19
- log.metric = metric
20
- log
21
- end
22
-
23
- let :logs do
24
- 3.times.collect do |i|
25
- l = log.dup
26
- l.metric = "/user/login#{i + 1}"
27
- l
28
- end
29
- end
30
-
31
- let :same_logs do
32
- 3.times.collect do |_i|
33
- l = log.dup
34
- l.metric = '/user/login'
35
- l
36
- end
37
- end
38
-
39
- let :dimensions do
40
- {action: 'hit', user: 'jbloggs', state: 'FL'}
41
- end
42
-
43
- let :all_dimensions do
44
- dims = dimensions.merge(
45
- host: SemanticLogger.host,
46
- application: SemanticLogger.application,
47
- environment: 'test'
48
- )
49
- string_keys = {}
50
- dims.each_pair { |k, v| string_keys[k.to_s] = v }
51
- string_keys
52
- end
53
-
54
- let :appender do
55
- Net::HTTP.stub_any_instance(:start, true) do
56
- SemanticLogger::Metric::Signalfx.new(token: 'TEST')
57
- end
58
- end
59
-
60
- let :formatter do
61
- appender.formatter
62
- end
63
-
64
- describe 'format single log' do
65
- let :result do
66
- JSON.parse(formatter.call(log, appender))
67
- end
68
-
69
- it 'send counter metric when there is no duration' do
70
- hash = result
71
- assert counters = hash['counter'], hash
72
- assert counter = counters.first, hash
73
- assert_equal counter_metric_name, counter['metric'], counter
74
- assert_equal 1, counter['value'], counter
75
- assert_equal (log.time.to_i * 1_000).to_i, counter['timestamp'], counter
76
- assert counter.key?('dimensions')
77
- end
78
-
79
- it 'send gauge metric when log includes duration' do
80
- log.duration = 1234
81
- hash = result
82
- assert counters = hash['gauge'], hash
83
- assert counter = counters.first, hash
84
- assert_equal average_metric_name, counter['metric'], counter
85
- assert_equal 1234, counter['value'], counter
86
- assert_equal (log.time.to_i * 1_000).to_i, counter['timestamp'], counter
87
- assert counter.key?('dimensions')
88
- end
89
-
90
- it 'also sends counter metric when gauge metric is sent' do
91
- log.duration = 1234
92
- hash = result
93
- assert counters = hash['counter'], hash
94
- assert counter = counters.first, hash
95
- assert_equal counter_metric_name, counter['metric'], counter
96
- assert_equal 1, counter['value'], counter
97
- assert_equal (log.time.to_i * 1_000).to_i, counter['timestamp'], counter
98
- assert counter.key?('dimensions')
99
- end
100
-
101
- it 'only forwards whitelisted dimensions from named_tags' do
102
- log.named_tags = {user_id: 47, tracking_number: 7474, session_id: 'hsdhngsd'}
103
- formatter.dimensions = %i[user_id application]
104
- hash = result
105
- assert counters = hash['counter'], hash
106
- assert counter = counters.first, hash
107
- assert_equal({'class' => 'user', 'action' => 'login', 'environment' => 'test', 'user_id' => '47', 'host' => SemanticLogger.host, 'application' => SemanticLogger.application}, counter['dimensions'], counter)
108
- end
109
-
110
- it 'raises exception with both a whitelist and blacklist' do
111
- assert_raises ArgumentError do
112
- SemanticLogger::Formatters::Signalfx.new(token: 'TEST', dimensions: [:user_id], exclude_dimensions: [:tracking_number])
113
- end
114
- end
115
-
116
- it 'send custom counter metric when there is no duration' do
117
- log.metric = 'Filter/count'
118
- log.dimensions = dimensions
119
- hash = result
120
-
121
- assert counters = hash['counter'], hash
122
- assert counter = counters.first, hash
123
- assert_equal 'Filter.count', counter['metric'], counter
124
- assert_equal 1, counter['value'], counter
125
- assert_equal (log.time.to_i * 1_000).to_i, counter['timestamp'], counter
126
- assert_equal all_dimensions, counter['dimensions']
127
- end
128
- end
129
-
130
- describe 'format batch logs' do
131
- let :result do
132
- JSON.parse(formatter.batch(logs, appender))
133
- end
134
-
135
- it 'send metrics' do
136
- hash = result
137
-
138
- assert counters = hash['counter'], hash
139
- assert_equal 3, counters.size
140
- assert_equal counter_metric_name, counters[0]['metric']
141
- assert_equal 1, counters[0]['value']
142
- assert_equal counter_metric_name, counters[1]['metric']
143
- assert_equal counter_metric_name, counters[2]['metric']
144
- end
145
-
146
- it 'sends gauge metrics' do
147
- logs.each { |log| log.duration = 3.5 }
148
- hash = result
149
- assert gauges = hash['gauge'], hash
150
- assert_equal 3, gauges.size
151
- assert_equal average_metric_name, gauges[0]['metric']
152
- assert_equal 3.5, gauges[0]['value']
153
- assert_equal average_metric_name, gauges[1]['metric']
154
- assert_equal average_metric_name, gauges[2]['metric']
155
- end
156
-
157
- describe 'send custom' do
158
- let :logs do
159
- 3.times.collect do |_i|
160
- l = log.dup
161
- l.metric = 'Filter/count'
162
- l.dimensions = dimensions
163
- l
164
- end
165
- end
166
-
167
- it 'counter metric when there is no duration' do
168
- hash = result
169
-
170
- assert counters = hash['counter'], hash
171
- assert counter = counters.first, hash
172
- assert_equal 'Filter.count', counter['metric'], counter
173
- assert_equal 3, counter['value'], counter
174
- assert_equal (log.time.to_i * 1_000).to_i, counter['timestamp'], counter
175
- assert_equal all_dimensions, counter['dimensions']
176
- end
177
- end
178
- end
179
-
180
- describe 'format batch logs with aggregation' do
181
- let :result do
182
- JSON.parse(formatter.batch(same_logs, appender))
183
- end
184
-
185
- it 'sends counter metrics' do
186
- hash = result
187
-
188
- assert counters = hash['counter'], hash
189
- assert_equal 1, counters.size
190
- assert_equal counter_metric_name, counters[0]['metric']
191
- assert_equal 3, counters[0]['value']
192
- end
193
- end
194
- end
195
- end
196
- end
197
- end
@@ -1,36 +0,0 @@
1
- require_relative 'test_helper'
2
-
3
- class FormattersTest < Minitest::Test
4
- describe SemanticLogger::Formatters do
5
- describe '.factory' do
6
- let :log do
7
- SemanticLogger::Log.new('Test', :info)
8
- end
9
-
10
- let :appender do
11
- SemanticLogger::Appender::File.new(io: STDOUT)
12
- end
13
-
14
- it 'from a symbol' do
15
- assert formatter = SemanticLogger::Formatters.factory(:raw)
16
- assert formatter.is_a?(SemanticLogger::Formatters::Raw)
17
- assert_equal 'Test', formatter.call(log, appender)[:name]
18
- end
19
-
20
- it 'from a Hash (Symbol with options)' do
21
- assert formatter = SemanticLogger::Formatters.factory(raw: {time_format: '%Y%m%d'})
22
- assert formatter.is_a?(SemanticLogger::Formatters::Raw)
23
- assert result = formatter.call(log, appender)
24
- assert_equal 'Test', result[:name]
25
- assert_equal Time.now.strftime('%Y%m%d'), result[:time]
26
- end
27
-
28
- it 'from block' do
29
- my_formatter = ->(log, _appender) { log.name }
30
- assert formatter = SemanticLogger::Formatters.factory(my_formatter)
31
- assert formatter.is_a?(Proc)
32
- assert_equal 'Test', formatter.call(log, appender)
33
- end
34
- end
35
- end
36
- end
@@ -1,8 +0,0 @@
1
- # Store in memory the last log message received.
2
- class InMemoryAppender < SemanticLogger::Subscriber
3
- attr_accessor :message
4
-
5
- def log(log)
6
- self.message = log
7
- end
8
- end
@@ -1,43 +0,0 @@
1
- require 'minitest/shared_description'
2
-
3
- InMemoryAppenderHelper = shared_description do
4
- let :log_message do
5
- SemanticLogger.flush
6
- appender.message
7
- end
8
-
9
- let :appender do
10
- InMemoryAppender.new
11
- end
12
-
13
- let :thread_name do
14
- Thread.current.name
15
- end
16
-
17
- let :payload do
18
- {session_id: 'HSSKLEU@JDK767', tracking_number: 12_345}
19
- end
20
-
21
- let :logger do
22
- SemanticLogger['TestLogger']
23
- end
24
-
25
- let :appender_options do
26
- {appender: appender}
27
- end
28
-
29
- let :added_appender do
30
- SemanticLogger.add_appender(appender_options)
31
- end
32
-
33
- before do
34
- SemanticLogger.default_level = :trace
35
- SemanticLogger.backtrace_level = :trace
36
- SemanticLogger.flush
37
- added_appender
38
- end
39
-
40
- after do
41
- SemanticLogger.appenders.each { |appender| SemanticLogger.remove_appender(appender) }
42
- end
43
- end
@@ -1,8 +0,0 @@
1
- # Store in memory the last log message received.
2
- class InMemoryBatchAppender < SemanticLogger::Subscriber
3
- attr_accessor :message
4
-
5
- def batch(logs)
6
- self.message = logs
7
- end
8
- end
@@ -1,13 +0,0 @@
1
- # Store in memory the last log message received.
2
- class InMemoryMetricsAppender < SemanticLogger::Subscriber
3
- attr_accessor :message
4
-
5
- def log(log)
6
- self.message = log
7
- end
8
-
9
- # Only forward log entries that contain metrics.
10
- def should_log?(log)
11
- log.metric && meets_log_level?(log) && !filtered?(log)
12
- end
13
- end
@@ -1,103 +0,0 @@
1
- require_relative 'test_helper'
2
- require 'stringio'
3
-
4
- class TestAttribute
5
- include SemanticLogger::Loggable
6
- end
7
-
8
- # Unit Test for SemanticLogger::Appender::File
9
- #
10
- class AppenderFileTest < Minitest::Test
11
- module Perform
12
- def perform
13
- logger.info 'perform'
14
- end
15
- end
16
-
17
- class Base
18
- include SemanticLogger::Loggable
19
- include Perform
20
- end
21
-
22
- module Process
23
- def process
24
- logger.info 'process'
25
- end
26
- end
27
-
28
- class Subclass < Base
29
- include Process
30
- end
31
-
32
- describe SemanticLogger::Loggable do
33
- describe 'inheritance' do
34
- it 'should give child classes their own logger' do
35
- assert_equal Subclass.name, Subclass.logger.name
36
- assert_equal Base.name, Base.logger.name
37
- assert_equal Subclass.name, Subclass.logger.name
38
- child_logger = Subclass.logger
39
- refute_equal child_logger, Base.logger
40
- assert_equal child_logger.object_id, Subclass.logger.object_id
41
- end
42
-
43
- it 'should give child objects their own logger' do
44
- subclass = Subclass.new
45
- base = Base.new
46
- assert_equal subclass.class.name, subclass.logger.name
47
- assert_equal base.class.name, base.logger.name
48
- assert_equal subclass.class.name, subclass.logger.name
49
- child_logger = subclass.logger
50
- refute_equal child_logger, base.logger
51
- assert_equal child_logger.object_id, subclass.logger.object_id
52
- end
53
-
54
- it 'should allow mixins to call parent logger' do
55
- base = Base.new
56
- base.perform
57
- called = false
58
- Base.logger.stub(:info, ->(description) { called = true if description == 'perform' }) do
59
- base.perform
60
- end
61
- assert called, 'Did not call the correct logger'
62
- end
63
-
64
- it 'should allow child mixins to call parent logger' do
65
- subclass = Subclass.new
66
- subclass.process
67
- called = false
68
- Subclass.logger.stub(:info, ->(description) { called = true if description == 'process' }) do
69
- subclass.process
70
- end
71
- assert called, 'Did not call the correct logger'
72
- end
73
- end
74
-
75
- describe 'logger' do
76
- include InMemoryAppenderHelper
77
-
78
- describe 'for each log level' do
79
- # Ensure that any log level can be logged
80
- SemanticLogger::LEVELS.each do |level|
81
- it "logs #{level} information with class attribute" do
82
- TestAttribute.logger.send(level, "hello #{level}", payload)
83
-
84
- assert log = log_message
85
- assert_equal "hello #{level}", log.message
86
- assert_equal level, log.level
87
- assert_equal 'TestAttribute', log.name
88
- assert_equal payload, log.payload
89
- end
90
-
91
- it "log #{level} information with instance attribute" do
92
- TestAttribute.new.logger.send(level, "hello #{level}", payload)
93
- assert log = log_message
94
- assert_equal "hello #{level}", log.message
95
- assert_equal level, log.level
96
- assert_equal 'TestAttribute', log.name
97
- assert_equal payload, log.payload
98
- end
99
- end
100
- end
101
- end
102
- end
103
- end