semantic_logger 4.0.0 → 4.1.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/README.md +55 -8
- data/lib/semantic_logger.rb +1 -2
- data/lib/semantic_logger/ansi_colors.rb +1 -2
- data/lib/semantic_logger/appender.rb +17 -15
- data/lib/semantic_logger/appender/bugsnag.rb +5 -4
- data/lib/semantic_logger/appender/elasticsearch.rb +102 -16
- data/lib/semantic_logger/appender/elasticsearch_http.rb +76 -0
- data/lib/semantic_logger/appender/file.rb +9 -25
- data/lib/semantic_logger/appender/graylog.rb +43 -38
- data/lib/semantic_logger/appender/honeybadger.rb +3 -5
- data/lib/semantic_logger/appender/http.rb +12 -15
- data/lib/semantic_logger/appender/kafka.rb +183 -0
- data/lib/semantic_logger/appender/mongodb.rb +3 -3
- data/lib/semantic_logger/appender/new_relic.rb +3 -7
- data/lib/semantic_logger/appender/sentry.rb +2 -5
- data/lib/semantic_logger/appender/splunk.rb +7 -10
- data/lib/semantic_logger/appender/splunk_http.rb +16 -16
- data/lib/semantic_logger/appender/syslog.rb +43 -122
- data/lib/semantic_logger/appender/tcp.rb +28 -9
- data/lib/semantic_logger/appender/udp.rb +4 -7
- data/lib/semantic_logger/appender/wrapper.rb +3 -7
- data/lib/semantic_logger/base.rb +47 -7
- data/lib/semantic_logger/formatters/base.rb +29 -10
- data/lib/semantic_logger/formatters/color.rb +75 -45
- data/lib/semantic_logger/formatters/default.rb +53 -28
- data/lib/semantic_logger/formatters/json.rb +7 -8
- data/lib/semantic_logger/formatters/raw.rb +97 -1
- data/lib/semantic_logger/formatters/syslog.rb +46 -80
- data/lib/semantic_logger/formatters/syslog_cee.rb +57 -0
- data/lib/semantic_logger/log.rb +17 -67
- data/lib/semantic_logger/logger.rb +17 -27
- data/lib/semantic_logger/processor.rb +70 -46
- data/lib/semantic_logger/semantic_logger.rb +130 -69
- data/lib/semantic_logger/subscriber.rb +18 -32
- data/lib/semantic_logger/version.rb +1 -1
- data/test/appender/elasticsearch_http_test.rb +75 -0
- data/test/appender/elasticsearch_test.rb +34 -27
- data/test/appender/file_test.rb +2 -2
- data/test/appender/honeybadger_test.rb +1 -1
- data/test/appender/kafka_test.rb +36 -0
- data/test/appender/new_relic_test.rb +1 -1
- data/test/appender/sentry_test.rb +1 -1
- data/test/appender/syslog_test.rb +2 -2
- data/test/appender/wrapper_test.rb +1 -1
- data/test/formatters/color_test.rb +154 -0
- data/test/formatters/default_test.rb +176 -0
- data/test/loggable_test.rb +1 -1
- data/test/logger_test.rb +47 -4
- data/test/measure_test.rb +2 -2
- data/test/semantic_logger_test.rb +34 -6
- data/test/test_helper.rb +8 -0
- metadata +14 -3
@@ -7,7 +7,7 @@ module SemanticLogger
|
|
7
7
|
attr_accessor :formatter
|
8
8
|
attr_writer :application, :host
|
9
9
|
|
10
|
-
# Returns the current log level if set, otherwise it logs everything it receives
|
10
|
+
# Returns the current log level if set, otherwise it logs everything it receives.
|
11
11
|
def level
|
12
12
|
@level || :trace
|
13
13
|
end
|
@@ -22,17 +22,17 @@ module SemanticLogger
|
|
22
22
|
# NOOP
|
23
23
|
end
|
24
24
|
|
25
|
-
# Returns [SemanticLogger::Formatters::Default] formatter
|
25
|
+
# Returns [SemanticLogger::Formatters::Default] default formatter for this subscriber.
|
26
26
|
def default_formatter
|
27
27
|
SemanticLogger::Formatters::Default.new
|
28
28
|
end
|
29
29
|
|
30
|
-
# Allow application name to be set globally or per subscriber
|
30
|
+
# Allow application name to be set globally or on a per subscriber basis.
|
31
31
|
def application
|
32
32
|
@application || SemanticLogger.application
|
33
33
|
end
|
34
34
|
|
35
|
-
# Allow host name to be set globally or per subscriber
|
35
|
+
# Allow host name to be set globally or on a per subscriber basis.
|
36
36
|
def host
|
37
37
|
@host || SemanticLogger.host
|
38
38
|
end
|
@@ -57,37 +57,32 @@ module SemanticLogger
|
|
57
57
|
# Proc: Only include log messages where the supplied Proc returns true
|
58
58
|
# The Proc must return true or false.
|
59
59
|
#
|
60
|
-
# host: [String]
|
61
|
-
# Name of this host to appear in log messages.
|
62
|
-
# Default: SemanticLogger.host
|
63
|
-
#
|
64
60
|
# application: [String]
|
65
61
|
# Name of this application to appear in log messages.
|
66
62
|
# Default: SemanticLogger.application
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
@
|
74
|
-
@
|
75
|
-
@host = options.delete(:host)
|
76
|
-
raise(ArgumentError, "Unknown options: #{options.inspect}") if options.size > 0
|
63
|
+
#
|
64
|
+
# host: [String]
|
65
|
+
# Name of this host to appear in log messages.
|
66
|
+
# Default: SemanticLogger.host
|
67
|
+
def initialize(level: nil, formatter: nil, filter: nil, application: nil, host: nil, &block)
|
68
|
+
@formatter = extract_formatter(formatter, &block)
|
69
|
+
@application = application
|
70
|
+
@host = host
|
77
71
|
|
78
|
-
# Subscribers don't take a class name, so use this class name if
|
79
|
-
# is logged to directly
|
72
|
+
# Subscribers don't take a class name, so use this class name if a subscriber
|
73
|
+
# is logged to directly.
|
80
74
|
super(self.class, level, filter)
|
81
75
|
end
|
82
76
|
|
83
|
-
# Return the level index for fast comparisons
|
77
|
+
# Return the level index for fast comparisons.
|
84
78
|
# Returns the lowest level index if the level has not been explicitly
|
85
|
-
# set for this instance
|
79
|
+
# set for this instance.
|
86
80
|
def level_index
|
87
81
|
@level_index || 0
|
88
82
|
end
|
89
83
|
|
90
|
-
# Return formatter that responds to call
|
84
|
+
# Return formatter that responds to call.
|
85
|
+
#
|
91
86
|
# Supports formatter supplied as:
|
92
87
|
# - Symbol
|
93
88
|
# - Hash ( Symbol => { options })
|
@@ -114,14 +109,5 @@ module SemanticLogger
|
|
114
109
|
end
|
115
110
|
end
|
116
111
|
|
117
|
-
SUBSCRIBER_OPTIONS = [:level, :formatter, :filter, :application, :host].freeze
|
118
|
-
|
119
|
-
# Returns [Hash] the subscriber common options from the supplied Hash
|
120
|
-
def extract_subscriber_options!(options)
|
121
|
-
subscriber_options = {}
|
122
|
-
SUBSCRIBER_OPTIONS.each { |key| subscriber_options[key] = options.delete(key) if options.has_key?(key) }
|
123
|
-
subscriber_options
|
124
|
-
end
|
125
|
-
|
126
112
|
end
|
127
113
|
end
|
@@ -0,0 +1,75 @@
|
|
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 'Reading File', hash['message']
|
51
|
+
assert exception = hash['exception']
|
52
|
+
assert 'NameError', exception['name']
|
53
|
+
assert '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
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -3,36 +3,40 @@ require_relative '../test_helper'
|
|
3
3
|
# Unit Test for SemanticLogger::Appender::Elasticsearch
|
4
4
|
module Appender
|
5
5
|
class ElasticsearchTest < Minitest::Test
|
6
|
-
response_mock = Struct.new(:code, :body)
|
7
|
-
|
8
6
|
describe SemanticLogger::Appender::Elasticsearch do
|
9
7
|
before do
|
10
|
-
|
8
|
+
skip('Concurrent::TimerTask issue is preventing the process from stopping.') if defined? JRuby
|
9
|
+
Elasticsearch::Transport::Client.stub_any_instance(:bulk, true) do
|
11
10
|
@appender = SemanticLogger::Appender::Elasticsearch.new(
|
12
|
-
url: 'http://localhost:9200'
|
11
|
+
url: 'http://localhost:9200',
|
12
|
+
batch_size: 1 # immediate flush
|
13
13
|
)
|
14
14
|
end
|
15
15
|
@message = 'AppenderElasticsearchTest log message'
|
16
16
|
end
|
17
17
|
|
18
|
+
after do
|
19
|
+
@appender.close if @appender
|
20
|
+
end
|
21
|
+
|
18
22
|
it 'logs to daily indexes' do
|
19
23
|
index = nil
|
20
|
-
@appender.stub(:
|
24
|
+
@appender.stub(:enqueue, ->(ind, json){ index = ind['index']['_index'] } ) do
|
21
25
|
@appender.info @message
|
22
26
|
end
|
23
|
-
assert_equal "
|
27
|
+
assert_equal "semantic_logger-#{Time.now.strftime('%Y.%m.%d')}", index
|
24
28
|
end
|
25
29
|
|
26
30
|
SemanticLogger::LEVELS.each do |level|
|
27
31
|
it "send #{level}" do
|
28
32
|
request = nil
|
29
|
-
@appender.
|
33
|
+
@appender.client.stub(:bulk, -> r { request = r; {"status" => 201 } }) do
|
30
34
|
@appender.send(level, @message)
|
31
35
|
end
|
32
|
-
|
33
|
-
|
34
|
-
assert_equal
|
35
|
-
|
36
|
+
|
37
|
+
message = request[:body][1]
|
38
|
+
assert_equal @message, message[:message]
|
39
|
+
assert_equal level, message[:level]
|
36
40
|
end
|
37
41
|
|
38
42
|
it "sends #{level} exceptions" do
|
@@ -43,30 +47,33 @@ module Appender
|
|
43
47
|
exc = e
|
44
48
|
end
|
45
49
|
request = nil
|
46
|
-
@appender.
|
50
|
+
@appender.client.stub(:bulk, -> r { request = r; {"status" => 201 } }) do
|
47
51
|
@appender.send(level, 'Reading File', exc)
|
48
52
|
end
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
assert '
|
53
|
-
assert
|
54
|
-
|
55
|
-
assert
|
53
|
+
|
54
|
+
hash = request[:body][1]
|
55
|
+
|
56
|
+
assert 'Reading File', hash[:message]
|
57
|
+
assert exception = hash[:exception]
|
58
|
+
assert 'NameError', exception[:name]
|
59
|
+
assert 'undefined local variable or method', exception[:message]
|
60
|
+
assert_equal level, hash[:level]
|
61
|
+
assert exception[:stack_trace].first.include?(__FILE__), exception
|
56
62
|
end
|
57
63
|
|
58
64
|
it "sends #{level} custom attributes" do
|
59
65
|
request = nil
|
60
|
-
@appender.
|
66
|
+
@appender.client.stub(:bulk, -> r { request = r; {"status" => 201 } }) do
|
61
67
|
@appender.send(level, @message, {key1: 1, key2: 'a'})
|
62
68
|
end
|
63
|
-
|
64
|
-
|
65
|
-
assert_equal
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
assert_equal
|
69
|
+
|
70
|
+
message = request[:body][1]
|
71
|
+
assert_equal @message, message[:message]
|
72
|
+
assert_equal level, message[:level]
|
73
|
+
refute message[:stack_trace]
|
74
|
+
assert payload = message[:payload], message
|
75
|
+
assert_equal 1, payload[:key1], message
|
76
|
+
assert_equal 'a', payload[:key2], message
|
70
77
|
end
|
71
78
|
end
|
72
79
|
|
data/test/appender/file_test.rb
CHANGED
@@ -10,7 +10,7 @@ module Appender
|
|
10
10
|
SemanticLogger.default_level = :trace
|
11
11
|
@time = Time.new
|
12
12
|
@io = StringIO.new
|
13
|
-
@appender = SemanticLogger::Appender::File.new(@io)
|
13
|
+
@appender = SemanticLogger::Appender::File.new(io: @io)
|
14
14
|
@hash = {session_id: 'HSSKLEU@JDK767', tracking_number: 12345}
|
15
15
|
@hash_str = @hash.inspect.sub("{", "\\{").sub("}", "\\}")
|
16
16
|
@thread_name = Thread.current.name
|
@@ -86,7 +86,7 @@ module Appender
|
|
86
86
|
|
87
87
|
describe 'custom formatter' do
|
88
88
|
before do
|
89
|
-
@appender = SemanticLogger::Appender::File.new(@io) do |log|
|
89
|
+
@appender = SemanticLogger::Appender::File.new(io: @io) do |log|
|
90
90
|
tags = log.tags.collect { |tag| "[#{tag}]" }.join(' ') + ' ' if log.tags && (log.tags.size > 0)
|
91
91
|
|
92
92
|
message = log.message.to_s
|
@@ -5,7 +5,7 @@ module Appender
|
|
5
5
|
class HoneybadgerTest < Minitest::Test
|
6
6
|
describe SemanticLogger::Appender::Honeybadger do
|
7
7
|
before do
|
8
|
-
@appender = SemanticLogger::Appender::Honeybadger.new(:trace)
|
8
|
+
@appender = SemanticLogger::Appender::Honeybadger.new(level: :trace)
|
9
9
|
@message = 'AppenderHoneybadgerTest log message'
|
10
10
|
SemanticLogger.backtrace_level = :error
|
11
11
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
module Appender
|
4
|
+
class KafkaTest < Minitest::Test
|
5
|
+
describe SemanticLogger::Appender::Kafka do
|
6
|
+
before do
|
7
|
+
@appender = SemanticLogger::Appender::Kafka.new(
|
8
|
+
seed_brokers: ['http://localhost:9092']
|
9
|
+
)
|
10
|
+
@message = 'AppenderKafkaTest log message'
|
11
|
+
end
|
12
|
+
|
13
|
+
after do
|
14
|
+
@appender.close if @appender
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'sends log messages in JSON format' do
|
18
|
+
message = nil
|
19
|
+
options = nil
|
20
|
+
::Kafka::Producer.stub_any_instance(:produce, -> value, **opts { message = value; options = opts }) do
|
21
|
+
@appender.info(@message)
|
22
|
+
@appender.flush
|
23
|
+
end
|
24
|
+
|
25
|
+
h = JSON.parse(message)
|
26
|
+
assert_equal 'info', h['level']
|
27
|
+
assert_equal @message, h['message']
|
28
|
+
assert_equal "SemanticLogger::Appender::Kafka", h['name']
|
29
|
+
assert_equal $$, h['pid']
|
30
|
+
|
31
|
+
assert_equal 'log_messages', options[:topic]
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -5,7 +5,7 @@ module Appender
|
|
5
5
|
class SentryTest < Minitest::Test
|
6
6
|
describe SemanticLogger::Appender::Sentry do
|
7
7
|
before do
|
8
|
-
@appender = SemanticLogger::Appender::Sentry.new(:trace)
|
8
|
+
@appender = SemanticLogger::Appender::Sentry.new(level: :trace)
|
9
9
|
@message = 'AppenderRavenTest log message'
|
10
10
|
SemanticLogger.backtrace_level = :error
|
11
11
|
end
|
@@ -22,7 +22,7 @@ module Appender
|
|
22
22
|
message = nil
|
23
23
|
Net::TCPClient.stub_any_instance(:closed?, false) do
|
24
24
|
Net::TCPClient.stub_any_instance(:connect, nil) do
|
25
|
-
syslog_appender = SemanticLogger::Appender::Syslog.new(
|
25
|
+
syslog_appender = SemanticLogger::Appender::Syslog.new(url: 'tcp://localhost:88888', level: :debug)
|
26
26
|
syslog_appender.remote_syslog.stub(:write, Proc.new { |data| message = data }) do
|
27
27
|
syslog_appender.debug 'AppenderSyslogTest log message'
|
28
28
|
end
|
@@ -33,7 +33,7 @@ module Appender
|
|
33
33
|
|
34
34
|
it 'handle remote syslog over UDP' do
|
35
35
|
message = nil
|
36
|
-
syslog_appender = SemanticLogger::Appender::Syslog.new(
|
36
|
+
syslog_appender = SemanticLogger::Appender::Syslog.new(url: 'udp://localhost:88888', level: :debug)
|
37
37
|
UDPSocket.stub_any_instance(:send, -> msg, num, host, port { message = msg }) do
|
38
38
|
syslog_appender.debug 'AppenderSyslogTest log message'
|
39
39
|
end
|
@@ -11,7 +11,7 @@ module Appender
|
|
11
11
|
|
12
12
|
@time = Time.new
|
13
13
|
@mock_logger = MockLogger.new
|
14
|
-
@appender = SemanticLogger::Appender::Wrapper.new(@mock_logger)
|
14
|
+
@appender = SemanticLogger::Appender::Wrapper.new(logger: @mock_logger)
|
15
15
|
@hash = {session_id: 'HSSKLEU@JDK767', tracking_number: 12345}
|
16
16
|
@hash_str = @hash.inspect.sub("{", "\\{").sub("}", "\\}")
|
17
17
|
@thread_name = Thread.current.name
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
module SemanticLogger
|
4
|
+
module Formatters
|
5
|
+
class ColorTest < Minitest::Test
|
6
|
+
describe Color 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
|
+
# :level, :thread_name, :name, :message, :payload, :time, :duration, :tags, :level_index, :exception, :metric, :backtrace, :metric_amount, :named_tags
|
17
|
+
log = SemanticLogger::Log.new('ColorTest', level)
|
18
|
+
log.time = log_time
|
19
|
+
log
|
20
|
+
end
|
21
|
+
|
22
|
+
let(:expected_time) do
|
23
|
+
SemanticLogger::Formatters::Base::PRECISION == 3 ? '2017-01-14 08:32:05.375' : '2017-01-14 08:32:05.375276'
|
24
|
+
end
|
25
|
+
|
26
|
+
let(:set_exception) do
|
27
|
+
begin
|
28
|
+
raise 'Oh no'
|
29
|
+
rescue Exception => exc
|
30
|
+
log.exception = exc
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
let(:backtrace) do
|
35
|
+
[
|
36
|
+
"test/formatters/default_test.rb:35:in `block (2 levels) in <class:DefaultTest>'",
|
37
|
+
"gems/ruby-2.3.3/gems/minitest-5.10.1/lib/minitest/spec.rb:247:in `instance_eval'",
|
38
|
+
"gems/ruby-2.3.3/gems/minitest-5.10.1/lib/minitest/spec.rb:247:in `block (2 levels) in let'",
|
39
|
+
"gems/ruby-2.3.3/gems/minitest-5.10.1/lib/minitest/spec.rb:247:in `fetch'",
|
40
|
+
"ruby-2.3.3/gems/minitest-5.10.1/lib/minitest/spec.rb:247:in `block in let'",
|
41
|
+
"test/formatters/default_test.rb:65:in `block (3 levels) in <class:DefaultTest>'",
|
42
|
+
"ruby-2.3.3/gems/minitest-5.10.1/lib/minitest/test.rb:105:in `block (3 levels) in run'"
|
43
|
+
]
|
44
|
+
end
|
45
|
+
|
46
|
+
let(:bold) do
|
47
|
+
SemanticLogger::AnsiColors::BOLD
|
48
|
+
end
|
49
|
+
|
50
|
+
let(:clear) do
|
51
|
+
SemanticLogger::AnsiColors::CLEAR
|
52
|
+
end
|
53
|
+
|
54
|
+
let(:color) do
|
55
|
+
SemanticLogger::AnsiColors::GREEN
|
56
|
+
end
|
57
|
+
|
58
|
+
let(:formatter) do
|
59
|
+
formatter = SemanticLogger::Formatters::Color.new
|
60
|
+
# Does not use the logger instance for formatting purposes
|
61
|
+
formatter.call(log, nil)
|
62
|
+
formatter
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'level' do
|
66
|
+
it 'logs single character' do
|
67
|
+
assert_equal "#{color}D#{clear}", formatter.level
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'tags' do
|
72
|
+
it 'logs tags' do
|
73
|
+
log.tags = %w(first second third)
|
74
|
+
assert_equal "[#{color}first#{clear}] [#{color}second#{clear}] [#{color}third#{clear}]", formatter.tags
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe 'named_tags' do
|
79
|
+
it 'logs named tags' do
|
80
|
+
log.named_tags = {first: 1, second: 2, third: 3}
|
81
|
+
assert_equal "{#{color}first: 1#{clear}, #{color}second: 2#{clear}, #{color}third: 3#{clear}}", formatter.named_tags
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'duration' do
|
86
|
+
it 'logs long duration' do
|
87
|
+
log.duration = 1_000_000.34567
|
88
|
+
assert_equal "(#{bold}16m 40s#{clear})", formatter.duration
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'logs short duration' do
|
92
|
+
log.duration = 1.34567
|
93
|
+
duration = SemanticLogger::Formatters::Base::PRECISION == 3 ? "(#{bold}1ms#{clear})" : "(#{bold}1.346ms#{clear})"
|
94
|
+
assert_equal duration, formatter.duration
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe 'name' do
|
99
|
+
it 'logs name' do
|
100
|
+
assert_equal "#{color}ColorTest#{clear}", formatter.name
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe 'payload' do
|
105
|
+
it 'logs hash payload' do
|
106
|
+
log.payload = {first: 1, second: 2, third: 3}
|
107
|
+
assert_equal "-- #{log.payload.ai(multiline: false)}", formatter.payload
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'skips nil payload' do
|
111
|
+
refute formatter.payload
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'skips empty payload' do
|
115
|
+
log.payload = {}
|
116
|
+
refute formatter.payload
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe 'exception' do
|
121
|
+
it 'logs exception' do
|
122
|
+
set_exception
|
123
|
+
str = "-- Exception: #{color}RuntimeError: Oh no#{clear}\n"
|
124
|
+
assert_equal str, formatter.exception.lines.first
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'skips nil exception' do
|
128
|
+
refute formatter.exception
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe 'call' do
|
133
|
+
it 'returns minimal elements' do
|
134
|
+
assert_equal "#{expected_time} #{color}D#{clear} [#{$$}:#{Thread.current.name}] #{color}ColorTest#{clear}", formatter.call(log, nil)
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'retuns all elements' do
|
138
|
+
log.tags = %w(first second third)
|
139
|
+
log.named_tags = {first: 1, second: 2, third: 3}
|
140
|
+
log.duration = 1.34567
|
141
|
+
log.message = "Hello World"
|
142
|
+
log.payload = {first: 1, second: 2, third: 3}
|
143
|
+
log.backtrace = backtrace
|
144
|
+
set_exception
|
145
|
+
duration = SemanticLogger::Formatters::Base::PRECISION == 3 ? '1' : '1.346'
|
146
|
+
str = "#{expected_time} #{color}D#{clear} [#{$$}:#{Thread.current.name} default_test.rb:35] [#{color}first#{clear}] [#{color}second#{clear}] [#{color}third#{clear}] {#{color}first: 1#{clear}, #{color}second: 2#{clear}, #{color}third: 3#{clear}} (#{bold}#{duration}ms#{clear}) #{color}ColorTest#{clear} -- Hello World -- #{{:first => 1, :second => 2, :third => 3}.ai(multiline: false)} -- Exception: #{color}RuntimeError: Oh no#{clear}\n"
|
147
|
+
assert_equal str, formatter.call(log, nil).lines.first
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|