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.
- checksums.yaml +4 -4
- data/lib/semantic_logger.rb +7 -1
- data/lib/semantic_logger/appender.rb +3 -0
- data/lib/semantic_logger/appender/async.rb +29 -10
- data/lib/semantic_logger/appender/rabbitmq.rb +120 -0
- data/lib/semantic_logger/appenders.rb +89 -0
- data/lib/semantic_logger/base.rb +3 -3
- data/lib/semantic_logger/concerns/compatibility.rb +2 -2
- data/lib/semantic_logger/formatters.rb +1 -0
- data/lib/semantic_logger/formatters/base.rb +28 -6
- data/lib/semantic_logger/formatters/color.rb +4 -3
- data/lib/semantic_logger/formatters/fluentd.rb +37 -0
- data/lib/semantic_logger/formatters/json.rb +4 -2
- data/lib/semantic_logger/formatters/raw.rb +2 -2
- data/lib/semantic_logger/formatters/signalfx.rb +4 -3
- data/lib/semantic_logger/levels.rb +38 -0
- data/lib/semantic_logger/log.rb +11 -6
- data/lib/semantic_logger/loggable.rb +1 -1
- data/lib/semantic_logger/logger.rb +43 -1
- data/lib/semantic_logger/processor.rb +10 -130
- data/lib/semantic_logger/reporters/minitest.rb +49 -0
- data/lib/semantic_logger/semantic_logger.rb +40 -75
- data/lib/semantic_logger/version.rb +1 -1
- metadata +9 -81
- data/test/appender/async_batch_test.rb +0 -60
- data/test/appender/async_test.rb +0 -44
- data/test/appender/bugsnag_test.rb +0 -81
- data/test/appender/elasticsearch_http_test.rb +0 -74
- data/test/appender/elasticsearch_test.rb +0 -248
- data/test/appender/file_test.rb +0 -120
- data/test/appender/graylog_test.rb +0 -82
- data/test/appender/honeybadger_test.rb +0 -45
- data/test/appender/http_test.rb +0 -63
- data/test/appender/kafka_test.rb +0 -35
- data/test/appender/mongodb_test.rb +0 -104
- data/test/appender/new_relic_test.rb +0 -80
- data/test/appender/newrelic_rpm.rb +0 -14
- data/test/appender/sentry_test.rb +0 -47
- data/test/appender/splunk_http_test.rb +0 -79
- data/test/appender/splunk_test.rb +0 -83
- data/test/appender/syslog_test.rb +0 -61
- data/test/appender/tcp_test.rb +0 -66
- data/test/appender/udp_test.rb +0 -59
- data/test/appender/wrapper_test.rb +0 -95
- data/test/concerns/compatibility_test.rb +0 -117
- data/test/debug_as_trace_logger_test.rb +0 -81
- data/test/formatters/color_test.rb +0 -153
- data/test/formatters/default_test.rb +0 -175
- data/test/formatters/one_line_test.rb +0 -60
- data/test/formatters/signalfx_test.rb +0 -197
- data/test/formatters_test.rb +0 -36
- data/test/in_memory_appender.rb +0 -8
- data/test/in_memory_appender_helper.rb +0 -43
- data/test/in_memory_batch_appender.rb +0 -8
- data/test/in_memory_metrics_appender.rb +0 -13
- data/test/loggable_test.rb +0 -103
- data/test/logger_test.rb +0 -334
- data/test/measure_test.rb +0 -346
- data/test/metric/new_relic_test.rb +0 -35
- data/test/metric/signalfx_test.rb +0 -77
- data/test/semantic_logger_test.rb +0 -303
- 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
|
data/test/formatters_test.rb
DELETED
@@ -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
|
data/test/in_memory_appender.rb
DELETED
@@ -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,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
|
data/test/loggable_test.rb
DELETED
@@ -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
|