semantic_logger 3.2.1 → 3.3.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 +1 -1
- data/lib/semantic_logger.rb +22 -2
- data/lib/semantic_logger/appender/bugsnag.rb +2 -2
- data/lib/semantic_logger/appender/elasticsearch.rb +9 -1
- data/lib/semantic_logger/appender/file.rb +1 -1
- data/lib/semantic_logger/appender/graylog.rb +18 -21
- data/lib/semantic_logger/appender/honeybadger.rb +27 -12
- data/lib/semantic_logger/appender/http.rb +19 -11
- data/lib/semantic_logger/appender/mongodb.rb +23 -30
- data/lib/semantic_logger/appender/new_relic.rb +2 -2
- data/lib/semantic_logger/appender/splunk.rb +32 -21
- data/lib/semantic_logger/appender/splunk_http.rb +1 -3
- data/lib/semantic_logger/appender/syslog.rb +25 -10
- data/lib/semantic_logger/appender/tcp.rb +231 -0
- data/lib/semantic_logger/appender/udp.rb +106 -0
- data/lib/semantic_logger/appender/wrapper.rb +1 -1
- data/lib/semantic_logger/base.rb +9 -3
- data/lib/semantic_logger/formatters/base.rb +36 -0
- data/lib/semantic_logger/formatters/color.rb +13 -10
- data/lib/semantic_logger/formatters/default.rb +8 -5
- data/lib/semantic_logger/formatters/json.rb +10 -3
- data/lib/semantic_logger/formatters/raw.rb +13 -0
- data/lib/semantic_logger/formatters/syslog.rb +119 -0
- data/lib/semantic_logger/log.rb +7 -5
- data/lib/semantic_logger/loggable.rb +5 -0
- data/lib/semantic_logger/logger.rb +45 -10
- data/lib/semantic_logger/metrics/new_relic.rb +1 -1
- data/lib/semantic_logger/metrics/statsd.rb +5 -1
- data/lib/semantic_logger/metrics/udp.rb +80 -0
- data/lib/semantic_logger/semantic_logger.rb +23 -27
- data/lib/semantic_logger/subscriber.rb +127 -0
- data/lib/semantic_logger/version.rb +1 -1
- data/test/appender/elasticsearch_test.rb +6 -4
- data/test/appender/file_test.rb +12 -12
- data/test/appender/honeybadger_test.rb +7 -1
- data/test/appender/http_test.rb +4 -2
- data/test/appender/mongodb_test.rb +1 -2
- data/test/appender/splunk_http_test.rb +8 -6
- data/test/appender/splunk_test.rb +48 -45
- data/test/appender/syslog_test.rb +3 -3
- data/test/appender/tcp_test.rb +68 -0
- data/test/appender/udp_test.rb +61 -0
- data/test/appender/wrapper_test.rb +5 -5
- data/test/concerns/compatibility_test.rb +6 -6
- data/test/debug_as_trace_logger_test.rb +2 -2
- data/test/loggable_test.rb +2 -2
- data/test/logger_test.rb +48 -45
- metadata +13 -3
- data/lib/semantic_logger/appender/base.rb +0 -101
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'socket'
|
2
|
+
module SemanticLogger
|
3
|
+
module Metrics
|
4
|
+
class Udp < Subscriber
|
5
|
+
attr_accessor :server, :separator, :udp_flags
|
6
|
+
attr_reader :socket
|
7
|
+
|
8
|
+
# Write metrics to in JSON format to Udp
|
9
|
+
#
|
10
|
+
# Parameters:
|
11
|
+
# server: [String]
|
12
|
+
# Host name and port to write UDP messages to
|
13
|
+
# Example:
|
14
|
+
# localhost:8125
|
15
|
+
#
|
16
|
+
# udp_flags: [Integer]
|
17
|
+
# Should be a bitwise OR of Socket::MSG_* constants.
|
18
|
+
# Default: 0
|
19
|
+
#
|
20
|
+
# Limitations:
|
21
|
+
# * UDP packet size is limited by the connected network and any routers etc
|
22
|
+
# that the message has to traverse. See https://en.wikipedia.org/wiki/Maximum_transmission_unit
|
23
|
+
#
|
24
|
+
# Example:
|
25
|
+
# subscriber = SemanticLogger::Metrics::Udp.new(server: 'localhost:8125')
|
26
|
+
# SemanticLogger.on_metric(subscriber)
|
27
|
+
def initialize(options = {}, &block)
|
28
|
+
options = options.dup
|
29
|
+
@server = options.delete(:server)
|
30
|
+
@udp_flags = options.delete(:udp_flags) || 0
|
31
|
+
raise(ArgumentError, 'Missing mandatory argument: :server') unless @server
|
32
|
+
|
33
|
+
super(options, &block)
|
34
|
+
reopen
|
35
|
+
end
|
36
|
+
|
37
|
+
# After forking an active process call #reopen to re-open
|
38
|
+
# open the handles to resources
|
39
|
+
def reopen
|
40
|
+
close
|
41
|
+
@socket = UDPSocket.new
|
42
|
+
host, port = server.split(':')
|
43
|
+
@socket.connect(host, port)
|
44
|
+
end
|
45
|
+
|
46
|
+
def call(log)
|
47
|
+
metric = log.metric
|
48
|
+
if duration = log.duration
|
49
|
+
@statsd.timing(metric, duration)
|
50
|
+
else
|
51
|
+
amount = (log.metric_amount || 1).round
|
52
|
+
if amount < 0
|
53
|
+
amount.times { @statsd.decrement(metric) }
|
54
|
+
else
|
55
|
+
amount.times { @statsd.increment(metric) }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
@socket.send(data, udp_flags)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Flush is called by the semantic_logger during shutdown.
|
62
|
+
def flush
|
63
|
+
@socket.flush if @socket
|
64
|
+
end
|
65
|
+
|
66
|
+
# Close is called during shutdown, or with reopen
|
67
|
+
def close
|
68
|
+
@socket.close if @socket
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
# Returns [SemanticLogger::Formatters::Default] formatter default for this Appender
|
74
|
+
def default_formatter
|
75
|
+
SemanticLogger::Formatters::Json.new
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -63,7 +63,7 @@ module SemanticLogger
|
|
63
63
|
# Returns [String] name of this application for logging purposes
|
64
64
|
# Note: Not all appenders use `application`
|
65
65
|
def self.application
|
66
|
-
@@application
|
66
|
+
@@application
|
67
67
|
end
|
68
68
|
|
69
69
|
# Override the default application
|
@@ -71,6 +71,8 @@ module SemanticLogger
|
|
71
71
|
@@application = application
|
72
72
|
end
|
73
73
|
|
74
|
+
@@application = 'Semantic Logger'
|
75
|
+
|
74
76
|
# Add a new logging appender as a new destination for all log messages
|
75
77
|
# emitted from Semantic Logger
|
76
78
|
#
|
@@ -90,12 +92,12 @@ module SemanticLogger
|
|
90
92
|
# For example STDOUT, STDERR, etc.
|
91
93
|
#
|
92
94
|
# Or,
|
93
|
-
# appender: [Symbol|SemanticLogger::
|
95
|
+
# appender: [Symbol|SemanticLogger::Subscriber]
|
94
96
|
# A symbol identifying the appender to create.
|
95
97
|
# For example:
|
96
98
|
# :bugsnag, :elasticsearch, :graylog, :http, :mongodb, :new_relic, :splunk_http, :syslog, :wrapper
|
97
99
|
# Or,
|
98
|
-
# An instance of an appender derived from SemanticLogger::
|
100
|
+
# An instance of an appender derived from SemanticLogger::Subscriber
|
99
101
|
# For example:
|
100
102
|
# SemanticLogger::Appender::Http.new(url: 'http://localhost:8088/path')
|
101
103
|
#
|
@@ -165,7 +167,7 @@ module SemanticLogger
|
|
165
167
|
@@appenders.delete(appender)
|
166
168
|
end
|
167
169
|
|
168
|
-
# Returns [SemanticLogger::
|
170
|
+
# Returns [SemanticLogger::Subscriber] a copy of the list of active
|
169
171
|
# appenders for debugging etc.
|
170
172
|
# Use SemanticLogger.add_appender and SemanticLogger.remove_appender
|
171
173
|
# to manipulate the active appenders list
|
@@ -179,6 +181,11 @@ module SemanticLogger
|
|
179
181
|
SemanticLogger::Logger.flush
|
180
182
|
end
|
181
183
|
|
184
|
+
# Close and flush all appenders
|
185
|
+
def self.close
|
186
|
+
SemanticLogger::Logger.close
|
187
|
+
end
|
188
|
+
|
182
189
|
# After forking an active process call SemanticLogger.reopen to re-open
|
183
190
|
# any open file handles etc to resources
|
184
191
|
#
|
@@ -429,51 +436,40 @@ module SemanticLogger
|
|
429
436
|
options[:file_name] = appender
|
430
437
|
elsif appender.is_a?(IO)
|
431
438
|
options[:io] = appender
|
432
|
-
elsif appender.is_a?(Symbol) || appender.is_a?(
|
439
|
+
elsif appender.is_a?(Symbol) || appender.is_a?(Subscriber)
|
433
440
|
options[:appender] = appender
|
434
441
|
else
|
435
442
|
options[:logger] = appender
|
436
443
|
end
|
437
|
-
warn "[DEPRECATED] SemanticLogger.add_appender parameters have changed. Please use: #{options.inspect}"
|
444
|
+
warn "[DEPRECATED] SemanticLogger.add_appender parameters have changed. Please use: #{options.inspect}" if $VERBOSE
|
438
445
|
options
|
439
446
|
end
|
440
447
|
|
441
|
-
# Returns [SemanticLogger::
|
448
|
+
# Returns [SemanticLogger::Subscriber] appender for the supplied options
|
442
449
|
def self.appender_from_options(options, &block)
|
443
450
|
if options[:io] || options[:file_name]
|
444
451
|
SemanticLogger::Appender::File.new(options, &block)
|
445
452
|
elsif appender = options.delete(:appender)
|
446
453
|
if appender.is_a?(Symbol)
|
447
|
-
|
448
|
-
elsif appender.is_a?(
|
454
|
+
constantize_symbol(appender).new(options)
|
455
|
+
elsif appender.is_a?(Subscriber)
|
449
456
|
appender
|
450
457
|
else
|
451
|
-
raise(ArgumentError, "Parameter :appender must be either a Symbol or an object derived from SemanticLogger::
|
458
|
+
raise(ArgumentError, "Parameter :appender must be either a Symbol or an object derived from SemanticLogger::Subscriber, not: #{appender.inspect}")
|
452
459
|
end
|
453
460
|
elsif options[:logger]
|
454
461
|
SemanticLogger::Appender::Wrapper.new(options, &block)
|
455
462
|
end
|
456
463
|
end
|
457
464
|
|
458
|
-
def self.
|
459
|
-
|
460
|
-
klass
|
461
|
-
klass
|
465
|
+
def self.constantize_symbol(symbol, namespace = 'SemanticLogger::Appender')
|
466
|
+
symbol = symbol.to_s
|
467
|
+
klass = symbol.respond_to?(:camelize) ? symbol.camelize : camelize(symbol)
|
468
|
+
klass = "#{namespace}::#{klass}"
|
462
469
|
begin
|
463
|
-
|
470
|
+
symbol.respond_to?(:constantize) ? klass.constantize : eval(klass)
|
464
471
|
rescue NameError
|
465
|
-
raise(ArgumentError, "Could not
|
466
|
-
end
|
467
|
-
end
|
468
|
-
|
469
|
-
def self.named_formatter(formatter)
|
470
|
-
formatter = formatter.to_s
|
471
|
-
klass = formatter.respond_to?(:camelize) ? formatter.camelize : camelize(formatter)
|
472
|
-
klass = "SemanticLogger::Formatters::#{klass}"
|
473
|
-
begin
|
474
|
-
formatter.respond_to?(:constantize) ? klass.constantize : eval(klass)
|
475
|
-
rescue NameError => exc
|
476
|
-
raise(ArgumentError, "Could not find formatter class: #{klass} for #{appender}")
|
472
|
+
raise(ArgumentError, "Could not convert symbol: #{symbol} to a class in: #{namespace}. Looking for: #{klass}")
|
477
473
|
end
|
478
474
|
end
|
479
475
|
|
@@ -0,0 +1,127 @@
|
|
1
|
+
# Abstract Subscriber
|
2
|
+
#
|
3
|
+
# Abstract base class for appender and metrics subscribers.
|
4
|
+
module SemanticLogger
|
5
|
+
class Subscriber < SemanticLogger::Base
|
6
|
+
# Every logger has its own formatter
|
7
|
+
attr_accessor :formatter
|
8
|
+
attr_writer :application, :host
|
9
|
+
|
10
|
+
# Returns the current log level if set, otherwise it logs everything it receives
|
11
|
+
def level
|
12
|
+
@level || :trace
|
13
|
+
end
|
14
|
+
|
15
|
+
# A subscriber should implement flush if it can.
|
16
|
+
def flush
|
17
|
+
# NOOP
|
18
|
+
end
|
19
|
+
|
20
|
+
# A subscriber should implement close if it can.
|
21
|
+
def close
|
22
|
+
# NOOP
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns [SemanticLogger::Formatters::Default] formatter default for this subscriber
|
26
|
+
def default_formatter
|
27
|
+
SemanticLogger::Formatters::Default.new
|
28
|
+
end
|
29
|
+
|
30
|
+
# Allow application name to be set globally or per subscriber
|
31
|
+
def application
|
32
|
+
@application || SemanticLogger.application
|
33
|
+
end
|
34
|
+
|
35
|
+
# Allow host name to be set globally or per subscriber
|
36
|
+
def host
|
37
|
+
@host || SemanticLogger.host
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# Initializer for Abstract Class SemanticLogger::Subscriber
|
43
|
+
#
|
44
|
+
# Parameters
|
45
|
+
# level: [:trace | :debug | :info | :warn | :error | :fatal]
|
46
|
+
# Override the log level for this subscriber.
|
47
|
+
# Default: :error
|
48
|
+
#
|
49
|
+
# formatter: [Object|Proc]
|
50
|
+
# An instance of a class that implements #call, or a Proc to be used to format
|
51
|
+
# the output from this subscriber
|
52
|
+
# Default: Use the built-in formatter (See: #call)
|
53
|
+
#
|
54
|
+
# filter: [Regexp|Proc]
|
55
|
+
# RegExp: Only include log messages where the class name matches the supplied.
|
56
|
+
# regular expression. All other messages will be ignored.
|
57
|
+
# Proc: Only include log messages where the supplied Proc returns true
|
58
|
+
# The Proc must return true or false.
|
59
|
+
#
|
60
|
+
# host: [String]
|
61
|
+
# Name of this host to appear in log messages.
|
62
|
+
# Default: SemanticLogger.host
|
63
|
+
#
|
64
|
+
# application: [String]
|
65
|
+
# Name of this application to appear in log messages.
|
66
|
+
# Default: SemanticLogger.application
|
67
|
+
def initialize(options={}, &block)
|
68
|
+
# Backward compatibility
|
69
|
+
options = {level: options} unless options.is_a?(Hash)
|
70
|
+
options = options.dup
|
71
|
+
level = options.delete(:level)
|
72
|
+
filter = options.delete(:filter)
|
73
|
+
@formatter = extract_formatter(options.delete(:formatter), &block)
|
74
|
+
@application = options.delete(:application)
|
75
|
+
@host = options.delete(:host)
|
76
|
+
raise(ArgumentError, "Unknown options: #{options.inspect}") if options.size > 0
|
77
|
+
|
78
|
+
# Subscribers don't take a class name, so use this class name if an subscriber
|
79
|
+
# is logged to directly
|
80
|
+
super(self.class, level, filter)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Return the level index for fast comparisons
|
84
|
+
# Returns the lowest level index if the level has not been explicitly
|
85
|
+
# set for this instance
|
86
|
+
def level_index
|
87
|
+
@level_index || 0
|
88
|
+
end
|
89
|
+
|
90
|
+
# Return formatter that responds to call
|
91
|
+
# Supports formatter supplied as:
|
92
|
+
# - Symbol
|
93
|
+
# - Hash ( Symbol => { options })
|
94
|
+
# - Instance of any of SemanticLogger::Formatters
|
95
|
+
# - Proc
|
96
|
+
# - Any object that responds to :call
|
97
|
+
# - If none of the above apply, then the supplied block is returned as the formatter.
|
98
|
+
# - Otherwise an instance of the default formatter is returned.
|
99
|
+
def extract_formatter(formatter, &block)
|
100
|
+
case
|
101
|
+
when formatter.is_a?(Symbol)
|
102
|
+
SemanticLogger.constantize_symbol(formatter, 'SemanticLogger::Formatters').new
|
103
|
+
when formatter.is_a?(Hash) && formatter.size > 0
|
104
|
+
fmt, options = formatter.first
|
105
|
+
SemanticLogger.constantize_symbol(fmt.to_sym, 'SemanticLogger::Formatters').new(options)
|
106
|
+
when formatter.respond_to?(:call)
|
107
|
+
formatter
|
108
|
+
when block
|
109
|
+
block
|
110
|
+
when respond_to?(:call)
|
111
|
+
self
|
112
|
+
else
|
113
|
+
default_formatter
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
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
|
+
end
|
127
|
+
end
|
@@ -7,10 +7,12 @@ module Appender
|
|
7
7
|
|
8
8
|
describe SemanticLogger::Appender::Elasticsearch do
|
9
9
|
before do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
Net::HTTP.stub_any_instance(:start, true) do
|
11
|
+
@appender = SemanticLogger::Appender::Elasticsearch.new(
|
12
|
+
url: 'http://localhost:9200'
|
13
|
+
)
|
14
|
+
end
|
15
|
+
@message = 'AppenderElasticsearchTest log message'
|
14
16
|
end
|
15
17
|
|
16
18
|
it 'logs to daily indexes' do
|
data/test/appender/file_test.rb
CHANGED
@@ -20,48 +20,48 @@ module Appender
|
|
20
20
|
describe 'format logs into text form' do
|
21
21
|
it 'handle no message or payload' do
|
22
22
|
@appender.debug
|
23
|
-
assert_match
|
23
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File\n/, @io.string)
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'handle message' do
|
27
27
|
@appender.debug 'hello world'
|
28
|
-
assert_match
|
28
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- hello world\n/, @io.string)
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'handle message and payload' do
|
32
32
|
@appender.debug 'hello world', @hash
|
33
|
-
assert_match
|
33
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- hello world -- #{@hash_str}\n/, @io.string)
|
34
34
|
end
|
35
35
|
|
36
36
|
it 'handle message, payload, and exception' do
|
37
37
|
@appender.debug 'hello world', @hash, StandardError.new('StandardError')
|
38
|
-
assert_match
|
38
|
+
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)
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'logs exception with nil backtrace' do
|
42
42
|
@appender.debug StandardError.new('StandardError')
|
43
|
-
assert_match
|
43
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- Exception: StandardError: StandardError\n\n/, @io.string)
|
44
44
|
end
|
45
45
|
|
46
46
|
it 'handle nested exception' do
|
47
47
|
begin
|
48
48
|
raise StandardError, 'FirstError'
|
49
|
-
rescue Exception
|
49
|
+
rescue Exception
|
50
50
|
begin
|
51
51
|
raise StandardError, 'SecondError'
|
52
52
|
rescue Exception => e2
|
53
53
|
@appender.debug e2
|
54
54
|
end
|
55
55
|
end
|
56
|
-
assert_match
|
57
|
-
assert_match
|
56
|
+
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)
|
57
|
+
assert_match(/^Cause: StandardError: FirstError\n/, @io.string) if Exception.instance_methods.include?(:cause)
|
58
58
|
end
|
59
59
|
|
60
60
|
it 'logs exception with empty backtrace' do
|
61
61
|
exc = StandardError.new('StandardError')
|
62
62
|
exc.set_backtrace([])
|
63
63
|
@appender.debug exc
|
64
|
-
assert_match
|
64
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- Exception: StandardError: StandardError\n\n/, @io.string)
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
@@ -71,14 +71,14 @@ module Appender
|
|
71
71
|
it "log #{level} with file_name" do
|
72
72
|
SemanticLogger.stub(:backtrace_level_index, 0) do
|
73
73
|
@appender.send(level, 'hello world', @hash)
|
74
|
-
assert_match
|
74
|
+
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)
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
78
|
it "log #{level} without file_name" do
|
79
79
|
SemanticLogger.stub(:backtrace_level_index, 100) do
|
80
80
|
@appender.send(level, 'hello world', @hash)
|
81
|
-
assert_match
|
81
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- hello world -- #{@hash_str}\n/, @io.string)
|
82
82
|
end
|
83
83
|
end
|
84
84
|
end
|
@@ -101,7 +101,7 @@ module Appender
|
|
101
101
|
|
102
102
|
it 'format using formatter' do
|
103
103
|
@appender.debug
|
104
|
-
assert_match
|
104
|
+
assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ DEBUG \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- \n/, @io.string)
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
@@ -7,6 +7,7 @@ module Appender
|
|
7
7
|
before do
|
8
8
|
@appender = SemanticLogger::Appender::Honeybadger.new(:trace)
|
9
9
|
@message = 'AppenderHoneybadgerTest log message'
|
10
|
+
SemanticLogger.backtrace_level = :error
|
10
11
|
end
|
11
12
|
|
12
13
|
SemanticLogger::LEVELS.each do |level|
|
@@ -17,7 +18,12 @@ module Appender
|
|
17
18
|
end
|
18
19
|
assert_equal @message, hash[:error_message]
|
19
20
|
assert_equal 'SemanticLogger::Appender::Honeybadger', hash[:error_class]
|
20
|
-
|
21
|
+
|
22
|
+
if [:error, :fatal].include?(level)
|
23
|
+
assert hash.has_key?(:backtrace)
|
24
|
+
else
|
25
|
+
refute hash.has_key?(:backtrace)
|
26
|
+
end
|
21
27
|
assert_equal true, hash.has_key?(:context)
|
22
28
|
assert_equal level, hash[:context][:level]
|
23
29
|
end
|