semantic_logger 2.16.0 → 2.17.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 +15 -1
- data/lib/semantic_logger/appender/base.rb +22 -6
- data/lib/semantic_logger/appender/bugsnag.rb +22 -9
- data/lib/semantic_logger/appender/mongodb.rb +17 -5
- data/lib/semantic_logger/appender/new_relic.rb +12 -14
- data/lib/semantic_logger/base.rb +38 -6
- data/lib/semantic_logger/semantic_logger.rb +31 -2
- data/lib/semantic_logger/version.rb +1 -1
- data/test/appender/bugsnag_test.rb +65 -0
- data/test/appender/file_test.rb +79 -0
- data/test/appender/mongodb_test.rb +105 -0
- data/test/appender/new_relic_test.rb +64 -0
- data/test/{newrelic_rpm.rb → appender/newrelic_rpm.rb} +0 -0
- data/test/appender/splunk_test.rb +50 -0
- data/test/appender/syslog_test.rb +63 -0
- data/test/{appender_wrapper_test.rb → appender/wrapper_test.rb} +10 -8
- data/test/loggable_test.rb +21 -11
- data/test/logger_test.rb +97 -69
- data/test/test_helper.rb +2 -1
- metadata +18 -18
- data/test/appender_bugsnag_test.rb +0 -60
- data/test/appender_file_test.rb +0 -77
- data/test/appender_mongodb_test.rb +0 -103
- data/test/appender_new_relic_test.rb +0 -83
- data/test/appender_splunk_test.rb +0 -47
- data/test/appender_syslog_test.rb +0 -61
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6d01095b46462b1fc9ea2b2d918a372bda406cd8
|
|
4
|
+
data.tar.gz: d6e2b86770aaaa606727efa5090028ffd0e6bcb5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0ec5d70d0147dba2cb7c63a1981de782a215036adbf469c48d2cb04a1c66a59b055fbf0627214464f0d12199679b69b2ddcd62fc93bf6017311a1cda730e5f90
|
|
7
|
+
data.tar.gz: 84d8f9e36d3ca6d04849e765a6cab837a281bdbcb625d4afebdecbe9d0d30bf86ac0f9153726bb9a726f702d8b22f4551ad782e2c25f285b89ff3bb17b9f0a0b
|
data/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# semantic_logger
|
|
2
|
-
 ](https://rubygems.org/gems/semantic_logger) [](https://travis-ci.org/rocketjob/semantic_logger) [](https://rubygems.org/gems/semantic_logger) [](http://opensource.org/licenses/Apache-2.0)  [-Support-brightgreen.svg)](https://gitter.im/rocketjob/rocketjob)
|
|
3
3
|
|
|
4
4
|
Low latency, high throughput, enterprise-scale logging system for Ruby
|
|
5
5
|
|
|
@@ -56,6 +56,20 @@ and are therefore not automatically included by this gem:
|
|
|
56
56
|
|
|
57
57
|
gem install semantic_logger
|
|
58
58
|
|
|
59
|
+
To configure a stand-alone application for Semantic Logger:
|
|
60
|
+
|
|
61
|
+
```ruby
|
|
62
|
+
require 'semantic_logger'
|
|
63
|
+
|
|
64
|
+
# Set the global default log level
|
|
65
|
+
SemanticLogger.default_level = :trace
|
|
66
|
+
|
|
67
|
+
# Log to a file, and use the colorized formatter
|
|
68
|
+
SemanticLogger.add_appender('development.log', &SemanticLogger::Appender::Base.colorized_formatter)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
If running rails, see: [Semantic Logger Rails](http://rocketjob.github.io/semantic_logger/rails.html)
|
|
72
|
+
|
|
59
73
|
## Author
|
|
60
74
|
|
|
61
75
|
[Reid Morrison](https://github.com/reidmorrison)
|
|
@@ -35,12 +35,20 @@ module SemanticLogger
|
|
|
35
35
|
tags = log.tags.collect { |tag| "[#{tag}]" }.join(' ') + ' ' if log.tags && (log.tags.size > 0)
|
|
36
36
|
|
|
37
37
|
message = log.message.to_s.dup
|
|
38
|
-
message << ' -- ' << log.payload.inspect unless log.payload.nil? || log.payload.empty?
|
|
38
|
+
message << ' -- ' << log.payload.inspect unless log.payload.nil? || (log.payload.respond_to?(:empty?) && log.payload.empty?)
|
|
39
39
|
message << ' -- Exception: ' << "#{log.exception.class}: #{log.exception.message}\n#{(log.exception.backtrace || []).join("\n")}" if log.exception
|
|
40
40
|
|
|
41
41
|
duration_str = log.duration ? "(#{'%.1f' % log.duration}ms) " : ''
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
file_name =
|
|
44
|
+
if log.backtrace || log.exception
|
|
45
|
+
backtrace = log.backtrace || log.exception.backtrace
|
|
46
|
+
location = backtrace[0].split('/').last
|
|
47
|
+
file, line = location.split(':')
|
|
48
|
+
" #{file}:#{line}"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
"#{SemanticLogger::Appender::Base.formatted_time(log.time)} #{log.level.to_s[0..0].upcase} [#{$$}:#{'%.50s' % log.thread_name}#{file_name}] #{tags}#{duration_str}#{log.name} -- #{message}"
|
|
44
52
|
end
|
|
45
53
|
end
|
|
46
54
|
|
|
@@ -55,7 +63,7 @@ module SemanticLogger
|
|
|
55
63
|
tags = log.tags.collect { |tag| "[#{colors::CYAN}#{tag}#{colors::CLEAR}]" }.join(' ') + ' ' if log.tags && (log.tags.size > 0)
|
|
56
64
|
|
|
57
65
|
message = log.message.to_s.dup
|
|
58
|
-
unless log.payload.nil? || log.payload.empty?
|
|
66
|
+
unless log.payload.nil? || (log.payload.respond_to?(:empty?) && log.payload.empty?)
|
|
59
67
|
payload = log.payload
|
|
60
68
|
payload = (defined?(AwesomePrint) && payload.respond_to?(:ai)) ? payload.ai(multiline: false) : payload.inspect
|
|
61
69
|
message << ' -- ' << payload
|
|
@@ -78,7 +86,15 @@ module SemanticLogger
|
|
|
78
86
|
colors::RED
|
|
79
87
|
end
|
|
80
88
|
|
|
81
|
-
|
|
89
|
+
file_name =
|
|
90
|
+
if log.backtrace || log.exception
|
|
91
|
+
backtrace = log.backtrace || log.exception.backtrace
|
|
92
|
+
location = backtrace[0].split('/').last
|
|
93
|
+
file, line = location.split(':')
|
|
94
|
+
" #{level_color}#{file}:#{line}#{colors::CLEAR}"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
"#{SemanticLogger::Appender::Base.formatted_time(log.time)} #{level_color}#{colors::BOLD}#{log.level.to_s[0..0].upcase}#{colors::CLEAR} [#{$$}:#{'%.30s' % log.thread_name}#{file_name}] #{tags}#{duration_str}#{level_color}#{log.name}#{colors::CLEAR} -- #{message}"
|
|
82
98
|
end
|
|
83
99
|
end
|
|
84
100
|
|
|
@@ -128,13 +144,13 @@ module SemanticLogger
|
|
|
128
144
|
# Return the Time as a formatted string
|
|
129
145
|
# JRuby only supports time in ms
|
|
130
146
|
def self.formatted_time(time)
|
|
131
|
-
"#{time.strftime(
|
|
147
|
+
"#{time.strftime('%Y-%m-%d %H:%M:%S')}.#{'%03d' % (time.usec/1000)}"
|
|
132
148
|
end
|
|
133
149
|
else
|
|
134
150
|
# Return the Time as a formatted string
|
|
135
151
|
# Ruby MRI supports micro seconds
|
|
136
152
|
def self.formatted_time(time)
|
|
137
|
-
"#{time.strftime(
|
|
153
|
+
"#{time.strftime('%Y-%m-%d %H:%M:%S')}.#{'%06d' % (time.usec)}"
|
|
138
154
|
end
|
|
139
155
|
end
|
|
140
156
|
|
|
@@ -48,6 +48,8 @@ class SemanticLogger::Appender::Bugsnag < SemanticLogger::Appender::Base
|
|
|
48
48
|
# Default: :error
|
|
49
49
|
# Note: Not recommended to set the log level to :info, :debug, or :trace as that would flood Bugsnag with Error notices
|
|
50
50
|
def initialize(level = :error, &block)
|
|
51
|
+
# Replace the Bugsnag logger so that we can identify its log messages and not forward them to Bugsnag
|
|
52
|
+
Bugsnag.configure { |config| config.logger = SemanticLogger[Bugsnag] }
|
|
51
53
|
super(level, &block)
|
|
52
54
|
end
|
|
53
55
|
|
|
@@ -55,6 +57,7 @@ class SemanticLogger::Appender::Bugsnag < SemanticLogger::Appender::Base
|
|
|
55
57
|
def default_formatter
|
|
56
58
|
proc do |log|
|
|
57
59
|
h = {severity: log_level(log), tags: log.tags, class: log.name}
|
|
60
|
+
h[:message] = log.message if log.exception
|
|
58
61
|
h.merge!(log.payload) if log.payload
|
|
59
62
|
h
|
|
60
63
|
end
|
|
@@ -63,22 +66,32 @@ class SemanticLogger::Appender::Bugsnag < SemanticLogger::Appender::Base
|
|
|
63
66
|
# Send an error notification to Bugsnag
|
|
64
67
|
def log(log)
|
|
65
68
|
# Only log if level is warn, or error.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
return false if (level_index > (log.level_index || 0)) ||
|
|
70
|
+
# We don't want to send fatal as those are already captured by Bugsnag.
|
|
71
|
+
(log.level == :fatal) ||
|
|
72
|
+
# Ignore logs coming from Bugsnag itself
|
|
73
|
+
(log.name == 'Bugsnag') ||
|
|
74
|
+
# Filtered out?
|
|
75
|
+
!include_message?(log)
|
|
76
|
+
|
|
77
|
+
# Send error messages as Runtime exceptions
|
|
78
|
+
exception =
|
|
79
|
+
if log.exception
|
|
80
|
+
log.exception
|
|
81
|
+
else
|
|
82
|
+
error = RuntimeError.new(log.message)
|
|
83
|
+
error.set_backtrace(log.backtrace) if log.backtrace
|
|
84
|
+
error
|
|
85
|
+
end
|
|
72
86
|
# For more documentation on the Bugsnag.notify method see:
|
|
73
87
|
# https://bugsnag.com/docs/notifiers/ruby#sending-handled-exceptions
|
|
74
|
-
Bugsnag.notify(
|
|
88
|
+
Bugsnag.notify(exception, formatter.call(log))
|
|
75
89
|
true
|
|
76
90
|
end
|
|
77
91
|
|
|
78
92
|
private
|
|
79
93
|
|
|
80
94
|
def log_level(log)
|
|
81
|
-
|
|
82
|
-
log.level.to_s
|
|
95
|
+
log.level == :warn ? 'warning' : log.level.to_s
|
|
83
96
|
end
|
|
84
97
|
end
|
|
@@ -28,6 +28,9 @@ module SemanticLogger
|
|
|
28
28
|
# message: 'Invalid value',
|
|
29
29
|
# stack_trace: []
|
|
30
30
|
# }
|
|
31
|
+
# # When a backtrace is captured
|
|
32
|
+
# file_name: 'my_class.rb'
|
|
33
|
+
# line_number: 42
|
|
31
34
|
#
|
|
32
35
|
class MongoDB < SemanticLogger::Appender::Base
|
|
33
36
|
attr_reader :db, :collection_name, :collection
|
|
@@ -155,11 +158,20 @@ module SemanticLogger
|
|
|
155
158
|
document[:duration] = log.duration if log.duration
|
|
156
159
|
document[:tags] = log.tags if log.tags && (log.tags.size > 0)
|
|
157
160
|
document[:payload] = log.payload if log.payload
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
161
|
+
if log.exception
|
|
162
|
+
document[:exception] = {
|
|
163
|
+
name: log.exception.class.name,
|
|
164
|
+
message: log.exception.message,
|
|
165
|
+
stack_trace: log.exception.backtrace
|
|
166
|
+
}
|
|
167
|
+
end
|
|
168
|
+
if log.backtrace || log.exception
|
|
169
|
+
backtrace = log.backtrace || log.exception.backtrace
|
|
170
|
+
location = backtrace[0].split('/').last
|
|
171
|
+
file, line = location.split(':')
|
|
172
|
+
document[:file_name] = file
|
|
173
|
+
document[:line_number] = line.to_i
|
|
174
|
+
end
|
|
163
175
|
document
|
|
164
176
|
end
|
|
165
177
|
end
|
|
@@ -59,34 +59,23 @@ sleep 10
|
|
|
59
59
|
require 'newrelic_rpm'
|
|
60
60
|
|
|
61
61
|
class SemanticLogger::Appender::NewRelic < SemanticLogger::Appender::Base
|
|
62
|
-
|
|
63
62
|
# Allow the level for this appender to be overwritten
|
|
64
63
|
# Default: :error
|
|
65
64
|
# Note: Not recommended to set the log level to :info, :debug, or :trace as that would flood NewRelic with Error notices
|
|
66
65
|
def initialize(level=:error, &block)
|
|
67
|
-
# Pass on the level and custom formatter if supplied
|
|
68
66
|
super(level, &block)
|
|
69
67
|
end
|
|
70
68
|
|
|
71
|
-
# The application may send a multiline string to the appender... use the first non-blank line as a shorter message.
|
|
72
|
-
def self.first_non_empty_line(string)
|
|
73
|
-
string.strip.split("\n").first.to_s
|
|
74
|
-
end
|
|
75
|
-
|
|
76
69
|
# Returns [Hash] of parameters to send to New Relic.
|
|
77
70
|
def default_formatter
|
|
78
71
|
Proc.new do |log|
|
|
79
|
-
short_message = self.class.first_non_empty_line(log.message)
|
|
80
|
-
metric = log.metric || "#{log.name}/#{short_message}"
|
|
81
|
-
|
|
82
72
|
custom_params = {thread_name: log.thread_name}
|
|
83
|
-
# Only show the message under custom attributes if the error message uses an exception or shortened message (first non-empty line).
|
|
84
|
-
custom_params[:message] = log.message if log.message && (log.exception || log.message != short_message)
|
|
85
73
|
custom_params[:duration] = "#{log.duration} ms" if log.duration
|
|
86
74
|
custom_params[:payload] = log.payload if log.payload
|
|
87
75
|
custom_params[:tags] = log.tags if log.tags && (log.tags.size > 0)
|
|
76
|
+
custom_params[:message] = log.message if log.exception
|
|
88
77
|
|
|
89
|
-
{metric: metric, custom_params: custom_params}
|
|
78
|
+
{metric: log.metric, custom_params: custom_params}
|
|
90
79
|
end
|
|
91
80
|
end
|
|
92
81
|
|
|
@@ -95,10 +84,19 @@ class SemanticLogger::Appender::NewRelic < SemanticLogger::Appender::Base
|
|
|
95
84
|
# Ensure minimum log level is met, and check filter
|
|
96
85
|
return false if (level_index > (log.level_index || 0)) || !include_message?(log)
|
|
97
86
|
|
|
87
|
+
# Send error messages as Runtime exceptions
|
|
88
|
+
exception =
|
|
89
|
+
if log.exception
|
|
90
|
+
log.exception
|
|
91
|
+
else
|
|
92
|
+
error = RuntimeError.new(log.message)
|
|
93
|
+
error.set_backtrace(log.backtrace) if log.backtrace
|
|
94
|
+
error
|
|
95
|
+
end
|
|
98
96
|
# For more documentation on the NewRelic::Agent.notice_error method see:
|
|
99
97
|
# http://rubydoc.info/github/newrelic/rpm/NewRelic/Agent#notice_error-instance_method
|
|
100
98
|
# and https://docs.newrelic.com/docs/ruby/ruby-agent-api
|
|
101
|
-
NewRelic::Agent.notice_error(
|
|
99
|
+
NewRelic::Agent.notice_error(exception, formatter.call(log))
|
|
102
100
|
true
|
|
103
101
|
end
|
|
104
102
|
|
data/lib/semantic_logger/base.rb
CHANGED
|
@@ -314,7 +314,10 @@ module SemanticLogger
|
|
|
314
314
|
#
|
|
315
315
|
# metric [Object]
|
|
316
316
|
# Object supplied when benchmark_x was called
|
|
317
|
-
|
|
317
|
+
#
|
|
318
|
+
# backtrace [Array<String>]
|
|
319
|
+
# The backtrace captured at source when the log level >= SemanticLogger.backtrace_level
|
|
320
|
+
Log = Struct.new(:level, :thread_name, :name, :message, :payload, :time, :duration, :tags, :level_index, :exception, :metric, :backtrace)
|
|
318
321
|
|
|
319
322
|
# Whether to log the supplied message based on the current filter if any
|
|
320
323
|
def include_message?(struct)
|
|
@@ -329,14 +332,18 @@ module SemanticLogger
|
|
|
329
332
|
|
|
330
333
|
# Log message at the specified level
|
|
331
334
|
def log_internal(level, index, message=nil, payload=nil, exception=nil, &block)
|
|
335
|
+
# Detect exception being logged
|
|
332
336
|
if exception.nil? && payload.nil? && message.kind_of?(Exception)
|
|
333
337
|
exception = message
|
|
334
338
|
message = exception.inspect
|
|
335
|
-
elsif exception.nil? && payload && payload.
|
|
339
|
+
elsif exception.nil? && payload && payload.respond_to?(:backtrace) && payload.respond_to?(:message)
|
|
340
|
+
# Under JRuby a java exception is not a Ruby Exception
|
|
341
|
+
# Java::JavaLang::ClassCastException.new.is_a?(Exception) => false
|
|
336
342
|
exception = payload
|
|
337
343
|
payload = nil
|
|
338
344
|
end
|
|
339
345
|
|
|
346
|
+
# Add result of block as message or payload if not nil
|
|
340
347
|
if block && (result = block.call)
|
|
341
348
|
if result.is_a?(String)
|
|
342
349
|
message = message.nil? ? result : "#{message} -- #{result}"
|
|
@@ -351,13 +358,24 @@ module SemanticLogger
|
|
|
351
358
|
if self.payload
|
|
352
359
|
payload = payload.nil? ? self.payload : self.payload.merge(payload)
|
|
353
360
|
end
|
|
354
|
-
|
|
361
|
+
|
|
362
|
+
# Add caller stack trace
|
|
363
|
+
backtrace =
|
|
364
|
+
if !exception && (index >= SemanticLogger.backtrace_level_index)
|
|
365
|
+
trace = caller
|
|
366
|
+
# Remove call to this internal method
|
|
367
|
+
trace.shift(1)
|
|
368
|
+
trace
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
struct = Log.new(level, Thread.current.name, name, message, payload, Time.now, nil, tags, index, exception, nil, backtrace)
|
|
355
372
|
log(struct) if include_message?(struct)
|
|
356
373
|
end
|
|
357
374
|
|
|
358
375
|
# Measure the supplied block and log the message
|
|
359
376
|
def benchmark_internal(level, index, message, params, &block)
|
|
360
|
-
start
|
|
377
|
+
start = Time.now
|
|
378
|
+
exception = nil
|
|
361
379
|
begin
|
|
362
380
|
if block
|
|
363
381
|
result =
|
|
@@ -394,6 +412,7 @@ module SemanticLogger
|
|
|
394
412
|
end
|
|
395
413
|
if exception
|
|
396
414
|
logged_exception = exception
|
|
415
|
+
backtrace = nil
|
|
397
416
|
case log_exception
|
|
398
417
|
when :full
|
|
399
418
|
# On exception change the log level
|
|
@@ -409,16 +428,29 @@ module SemanticLogger
|
|
|
409
428
|
end
|
|
410
429
|
message = "#{message} -- Exception: #{exception.class}: #{exception.message}"
|
|
411
430
|
logged_exception = nil
|
|
431
|
+
backtrace = exception.backtrace
|
|
412
432
|
else
|
|
413
433
|
# Log the message with its duration but leave out the exception that was raised
|
|
414
434
|
logged_exception = nil
|
|
435
|
+
backtrace = exception.backtrace
|
|
415
436
|
end
|
|
416
|
-
struct = Log.new(level, Thread.current.name, name, message, payload, end_time, duration, tags, index, logged_exception, metric)
|
|
437
|
+
struct = Log.new(level, Thread.current.name, name, message, payload, end_time, duration, tags, index, logged_exception, metric, backtrace)
|
|
417
438
|
log(struct) if include_message?(struct)
|
|
418
439
|
raise exception
|
|
419
440
|
elsif duration >= min_duration
|
|
420
441
|
# Only log if the block took longer than 'min_duration' to complete
|
|
421
|
-
|
|
442
|
+
# Add caller stack trace
|
|
443
|
+
backtrace =
|
|
444
|
+
if index >= SemanticLogger.backtrace_level_index
|
|
445
|
+
trace = caller
|
|
446
|
+
# Remove call to this internal method
|
|
447
|
+
trace.shift
|
|
448
|
+
# Ruby 1.9 has additional stack entry for parent that calls this method
|
|
449
|
+
trace.shift if RUBY_VERSION.to_f <= 2.0
|
|
450
|
+
trace
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
struct = Log.new(level, Thread.current.name, name, message, payload, end_time, duration, tags, index, nil, metric, backtrace)
|
|
422
454
|
log(struct) if include_message?(struct)
|
|
423
455
|
end
|
|
424
456
|
end
|
|
@@ -20,6 +20,33 @@ module SemanticLogger
|
|
|
20
20
|
@@default_level
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
+
# Sets the level at which backtraces should be captured
|
|
24
|
+
# for every log message.
|
|
25
|
+
#
|
|
26
|
+
# By enabling backtrace capture the filename and line number of where
|
|
27
|
+
# message was logged can be written to the log file. Additionally, the backtrace
|
|
28
|
+
# can be forwarded to error management services such as Bugsnag.
|
|
29
|
+
#
|
|
30
|
+
# Warning:
|
|
31
|
+
# Capturing backtraces is very expensive and should not be done all
|
|
32
|
+
# the time. It is recommended to run it at :error level in production.
|
|
33
|
+
def self.backtrace_level=(level)
|
|
34
|
+
@@backtrace_level = level
|
|
35
|
+
# For performance reasons pre-calculate the level index
|
|
36
|
+
@@backtrace_level_index = level.nil? ? 65535 : level_to_index(level)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Returns the current backtrace level
|
|
40
|
+
def self.backtrace_level
|
|
41
|
+
@@backtrace_level
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Returns the current backtrace level index
|
|
45
|
+
# For internal use only
|
|
46
|
+
def self.backtrace_level_index #:nodoc
|
|
47
|
+
@@backtrace_level_index
|
|
48
|
+
end
|
|
49
|
+
|
|
23
50
|
# Add a new logging appender as a new destination for all log messages
|
|
24
51
|
# emitted from Semantic Logger
|
|
25
52
|
#
|
|
@@ -263,6 +290,8 @@ module SemanticLogger
|
|
|
263
290
|
end
|
|
264
291
|
|
|
265
292
|
# Initial default Level for all new instances of SemanticLogger::Logger
|
|
266
|
-
@@default_level
|
|
267
|
-
@@default_level_index
|
|
293
|
+
@@default_level = :info
|
|
294
|
+
@@default_level_index = level_to_index(@@default_level)
|
|
295
|
+
@@backtrace_level = :error
|
|
296
|
+
@@backtrace_level_index = level_to_index(@@backtrace_level)
|
|
268
297
|
end
|
|
@@ -0,0 +1,65 @@
|
|
|
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(:warn)
|
|
9
|
+
@message = 'AppenderBugsnagTest log message'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
(SemanticLogger::LEVELS - [:warn, :error]).each do |level|
|
|
13
|
+
it "not send :#{level} notifications to Bugsnag" do
|
|
14
|
+
exception = hash = nil
|
|
15
|
+
Bugsnag.stub(:notify, -> exc, h { exception = exc; hash = h }) do
|
|
16
|
+
@appender.send(level, "AppenderBugsnagTest #{level.to_s} message")
|
|
17
|
+
end
|
|
18
|
+
assert_nil exception
|
|
19
|
+
assert_nil hash
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'send error notifications to Bugsnag with severity' do
|
|
24
|
+
exception = hash = nil
|
|
25
|
+
Bugsnag.stub(:notify, -> exc, h { exception = exc; hash = h }) do
|
|
26
|
+
@appender.error @message
|
|
27
|
+
end
|
|
28
|
+
assert_equal 'RuntimeError', exception.class.to_s
|
|
29
|
+
assert_equal @message, exception.message
|
|
30
|
+
assert_equal 'error', hash[:severity]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'send warn notifications to Bugsnag replace warn severity with warning' do
|
|
34
|
+
exception = hash = nil
|
|
35
|
+
Bugsnag.stub(:notify, -> exc, h { exception = exc; hash = h }) do
|
|
36
|
+
@appender.warn @message
|
|
37
|
+
end
|
|
38
|
+
assert_equal 'RuntimeError', exception.class.to_s
|
|
39
|
+
assert_equal @message, exception.message
|
|
40
|
+
assert_equal 'warning', hash[:severity]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'send notification to Bugsnag with custom attributes' do
|
|
44
|
+
exception = hash = nil
|
|
45
|
+
Bugsnag.stub(:notify, -> exc, h { exception = exc; hash = h }) do
|
|
46
|
+
@appender.error @message, {key1: 1, key2: 'a'}
|
|
47
|
+
end
|
|
48
|
+
assert_equal 'RuntimeError', exception.class.to_s
|
|
49
|
+
assert_equal @message, exception.message
|
|
50
|
+
assert_equal(1, hash[:key1], hash)
|
|
51
|
+
assert_equal('a', hash[:key2], hash)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'send notification to Bugsnag with exception' do
|
|
55
|
+
error = RuntimeError.new('Hello World')
|
|
56
|
+
exception = hash = nil
|
|
57
|
+
Bugsnag.stub(:notify, -> exc, h { exception = exc; hash = h }) do
|
|
58
|
+
@appender.error error
|
|
59
|
+
end
|
|
60
|
+
assert_equal error.class.to_s, exception.class.to_s
|
|
61
|
+
assert_equal error.message, exception.message
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|