semantic_logger 4.7.3 → 4.8.2
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 +6 -8
- data/lib/semantic_logger/appender.rb +6 -3
- data/lib/semantic_logger/appender/async.rb +1 -1
- data/lib/semantic_logger/appender/elasticsearch.rb +4 -2
- data/lib/semantic_logger/appender/file.rb +12 -3
- data/lib/semantic_logger/appender/kafka.rb +4 -0
- data/lib/semantic_logger/appender/splunk.rb +2 -1
- data/lib/semantic_logger/appender/splunk_http.rb +2 -2
- data/lib/semantic_logger/appender/syslog.rb +5 -3
- data/lib/semantic_logger/appender/wrapper.rb +3 -2
- data/lib/semantic_logger/appenders.rb +31 -27
- data/lib/semantic_logger/base.rb +14 -6
- data/lib/semantic_logger/formatters.rb +10 -11
- data/lib/semantic_logger/formatters/color.rb +3 -3
- data/lib/semantic_logger/formatters/logfmt.rb +54 -0
- data/lib/semantic_logger/formatters/syslog.rb +2 -1
- data/lib/semantic_logger/formatters/syslog_cee.rb +2 -1
- data/lib/semantic_logger/log.rb +2 -4
- data/lib/semantic_logger/loggable.rb +8 -1
- data/lib/semantic_logger/logger.rb +16 -6
- data/lib/semantic_logger/processor.rb +3 -3
- data/lib/semantic_logger/semantic_logger.rb +14 -6
- data/lib/semantic_logger/sync_processor.rb +5 -5
- data/lib/semantic_logger/utils.rb +29 -10
- data/lib/semantic_logger/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d0bd2e2a218bdbf0bfa67ca85da999b352de9b214383890278c0710cd3f84e91
|
|
4
|
+
data.tar.gz: dd3b393e8f0a031ddb25c2ca3cdeaa7d761617586f366006e79d7fcf3de8a9a5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dba969cf8d70cbb63a6542a692b68773f395eda22515267c572630aa5180a3bbfe490f2096e83cc366f06e86bbf06bafc87d2e5800810110107ac5080b7a1046
|
|
7
|
+
data.tar.gz: 35d69548ee2a91fb4d7c0575ea2d1da48648a7352d52304e8f270a6fe095c42e7ad1367594cef0b14941e14fc47906816df2360899c37fc577828b368c71c21a
|
data/README.md
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
# Semantic Logger
|
|
2
|
-
[](https://rubygems.org/gems/semantic_logger) [](https://rubygems.org/gems/semantic_logger) [](https://github.com/reidmorrison/semantic_logger/actions?query=workflow%3Abuild) [](https://rubygems.org/gems/semantic_logger) [](http://opensource.org/licenses/Apache-2.0) 
|
|
3
3
|
|
|
4
4
|
Semantic Logger is a feature rich logging framework, and replacement for existing Ruby & Rails loggers.
|
|
5
5
|
|
|
6
|
-
* https://rocketjob.
|
|
6
|
+
* https://logger.rocketjob.io/
|
|
7
7
|
|
|
8
8
|
## Documentation
|
|
9
9
|
|
|
10
|
-
[Semantic Logger Guide](
|
|
11
|
-
|
|
12
|
-
[Reference Documentation](http://www.rubydoc.info/gems/semantic_logger/)
|
|
10
|
+
[Semantic Logger Guide](https://logger.rocketjob.io/)
|
|
13
11
|
|
|
14
12
|
## Upgrading to Semantic Logger v4.4
|
|
15
13
|
|
|
@@ -50,7 +48,7 @@ handles saving log information to multiple destinations / appenders.
|
|
|
50
48
|
|
|
51
49
|
## Rails
|
|
52
50
|
|
|
53
|
-
When running Rails, use [rails_semantic_logger](http://github.com/
|
|
51
|
+
When running Rails, use [rails_semantic_logger](http://github.com/reidmorrison/rails_semantic_logger)
|
|
54
52
|
instead of Semantic Logger directly since it will automatically replace the Rails default logger with Semantic Logger.
|
|
55
53
|
|
|
56
54
|
## Rocket Job
|
|
@@ -129,13 +127,13 @@ SemanticLogger.default_level = :trace
|
|
|
129
127
|
SemanticLogger.add_appender(file_name: 'development.log', formatter: :color)
|
|
130
128
|
~~~
|
|
131
129
|
|
|
132
|
-
If running rails, see: [Semantic Logger Rails](
|
|
130
|
+
If running rails, see: [Semantic Logger Rails](https://logger.rocketjob.io/rails.html)
|
|
133
131
|
|
|
134
132
|
## Author
|
|
135
133
|
|
|
136
134
|
[Reid Morrison](https://github.com/reidmorrison)
|
|
137
135
|
|
|
138
|
-
[Contributors](https://github.com/
|
|
136
|
+
[Contributors](https://github.com/reidmorrison/semantic_logger/graphs/contributors)
|
|
139
137
|
|
|
140
138
|
## Versioning
|
|
141
139
|
|
|
@@ -66,7 +66,8 @@ module SemanticLogger
|
|
|
66
66
|
elsif appender.is_a?(Subscriber)
|
|
67
67
|
appender
|
|
68
68
|
else
|
|
69
|
-
raise(ArgumentError,
|
|
69
|
+
raise(ArgumentError,
|
|
70
|
+
"Parameter :appender must be either a Symbol or an object derived from SemanticLogger::Subscriber, not: #{appender.inspect}")
|
|
70
71
|
end
|
|
71
72
|
elsif metric
|
|
72
73
|
if metric.is_a?(Symbol)
|
|
@@ -74,10 +75,12 @@ module SemanticLogger
|
|
|
74
75
|
elsif metric.is_a?(Subscriber)
|
|
75
76
|
metric
|
|
76
77
|
else
|
|
77
|
-
raise(ArgumentError,
|
|
78
|
+
raise(ArgumentError,
|
|
79
|
+
"Parameter :metric must be either a Symbol or an object derived from SemanticLogger::Subscriber, not: #{appender.inspect}")
|
|
78
80
|
end
|
|
79
81
|
else
|
|
80
|
-
raise(ArgumentError,
|
|
82
|
+
raise(ArgumentError,
|
|
83
|
+
"To create an appender it must supply one of the following: :io, :file_name, :appender, :metric, or :logger")
|
|
81
84
|
end
|
|
82
85
|
end
|
|
83
86
|
|
|
@@ -53,7 +53,7 @@ module SemanticLogger
|
|
|
53
53
|
# Re-open appender after a fork
|
|
54
54
|
def reopen
|
|
55
55
|
# Workaround CRuby crash on fork by recreating queue on reopen
|
|
56
|
-
# https://github.com/
|
|
56
|
+
# https://github.com/reidmorrison/semantic_logger/issues/103
|
|
57
57
|
@queue&.close
|
|
58
58
|
create_queue
|
|
59
59
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
begin
|
|
2
2
|
require "elasticsearch"
|
|
3
3
|
rescue LoadError
|
|
4
|
-
raise LoadError,
|
|
4
|
+
raise LoadError,
|
|
5
|
+
'Gem elasticsearch is required for logging to Elasticsearch. Please add the gem "elasticsearch" to your Gemfile.'
|
|
5
6
|
end
|
|
6
7
|
|
|
7
8
|
require "date"
|
|
@@ -17,7 +18,8 @@ require "date"
|
|
|
17
18
|
module SemanticLogger
|
|
18
19
|
module Appender
|
|
19
20
|
class Elasticsearch < SemanticLogger::Subscriber
|
|
20
|
-
attr_accessor :url, :index, :date_pattern, :type, :client, :flush_interval, :timeout_interval, :batch_size,
|
|
21
|
+
attr_accessor :url, :index, :date_pattern, :type, :client, :flush_interval, :timeout_interval, :batch_size,
|
|
22
|
+
:elasticsearch_args
|
|
21
23
|
|
|
22
24
|
# Create Elasticsearch appender over persistent HTTP(S)
|
|
23
25
|
#
|
|
@@ -36,7 +36,7 @@ module SemanticLogger
|
|
|
36
36
|
# SemanticLogger.default_level = :info
|
|
37
37
|
#
|
|
38
38
|
# # Log to screen
|
|
39
|
-
# SemanticLogger.add_appender(io:
|
|
39
|
+
# SemanticLogger.add_appender(io: $stdout, formatter: :color)
|
|
40
40
|
#
|
|
41
41
|
# # And log to a file at the same time
|
|
42
42
|
# SemanticLogger.add_appender(file_name: 'application.log', formatter: :color)
|
|
@@ -52,7 +52,7 @@ module SemanticLogger
|
|
|
52
52
|
# SemanticLogger.default_level = :trace
|
|
53
53
|
#
|
|
54
54
|
# # Log to screen but only display :info and above
|
|
55
|
-
# SemanticLogger.add_appender(io:
|
|
55
|
+
# SemanticLogger.add_appender(io: $stdout, level: :info)
|
|
56
56
|
#
|
|
57
57
|
# # And log to a file at the same time, including all :trace level data
|
|
58
58
|
# SemanticLogger.add_appender(file_name: 'application.log')
|
|
@@ -62,9 +62,14 @@ module SemanticLogger
|
|
|
62
62
|
def initialize(io: nil, file_name: nil, **args, &block)
|
|
63
63
|
if io
|
|
64
64
|
@log = io
|
|
65
|
+
unless @log.respond_to?(:write)
|
|
66
|
+
raise(ArgumentError, "SemanticLogging::Appender::File :io is not a valid IO instance: #{io.inspect}")
|
|
67
|
+
end
|
|
65
68
|
else
|
|
66
69
|
@file_name = file_name
|
|
67
|
-
|
|
70
|
+
unless file_name
|
|
71
|
+
raise(ArgumentError, "SemanticLogging::Appender::File missing mandatory parameter :file_name or :io")
|
|
72
|
+
end
|
|
68
73
|
|
|
69
74
|
reopen
|
|
70
75
|
end
|
|
@@ -105,6 +110,10 @@ module SemanticLogger
|
|
|
105
110
|
def flush
|
|
106
111
|
@log.flush if @log.respond_to?(:flush)
|
|
107
112
|
end
|
|
113
|
+
|
|
114
|
+
def console_output?
|
|
115
|
+
[$stderr, $stdout].include?(@log)
|
|
116
|
+
end
|
|
108
117
|
end
|
|
109
118
|
end
|
|
110
119
|
end
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
begin
|
|
2
2
|
require "splunk-sdk-ruby"
|
|
3
3
|
rescue LoadError
|
|
4
|
-
raise LoadError,
|
|
4
|
+
raise LoadError,
|
|
5
|
+
'Gem splunk-sdk-ruby is required for logging to Splunk. Please add the gem "splunk-sdk-ruby" to your Gemfile.'
|
|
5
6
|
end
|
|
6
7
|
|
|
7
8
|
# Splunk log appender.
|
|
@@ -89,9 +89,9 @@ module SemanticLogger
|
|
|
89
89
|
# For splunk format requirements see:
|
|
90
90
|
# https://docs.splunk.com/Documentation/Splunk/latest/Data/FormateventsforHTTPEventCollector
|
|
91
91
|
def call(log, logger)
|
|
92
|
-
h
|
|
92
|
+
h = SemanticLogger::Formatters::Raw.new(time_format: :seconds).call(log, logger)
|
|
93
93
|
h.delete(:host)
|
|
94
|
-
message
|
|
94
|
+
message = {
|
|
95
95
|
source: logger.application,
|
|
96
96
|
host: logger.host,
|
|
97
97
|
time: h.delete(:time),
|
|
@@ -57,7 +57,7 @@ module SemanticLogger
|
|
|
57
57
|
# Only used with the TCP protocol.
|
|
58
58
|
# Specify custom parameters to pass into Net::TCPClient.new
|
|
59
59
|
# For a list of options see the net_tcp_client documentation:
|
|
60
|
-
# https://github.com/
|
|
60
|
+
# https://github.com/reidmorrison/net_tcp_client/blob/master/lib/net/tcp_client/tcp_client.rb
|
|
61
61
|
#
|
|
62
62
|
# level: [:trace | :debug | :info | :warn | :error | :fatal]
|
|
63
63
|
# Override the log level for this appender.
|
|
@@ -151,7 +151,8 @@ module SemanticLogger
|
|
|
151
151
|
begin
|
|
152
152
|
require "syslog_protocol"
|
|
153
153
|
rescue LoadError
|
|
154
|
-
raise LoadError,
|
|
154
|
+
raise LoadError,
|
|
155
|
+
"Missing gem: syslog_protocol. This gem is required when logging over TCP or UDP. To fix this error: gem install syslog_protocol"
|
|
155
156
|
end
|
|
156
157
|
|
|
157
158
|
# The net_tcp_client gem is required when logging over TCP.
|
|
@@ -159,7 +160,8 @@ module SemanticLogger
|
|
|
159
160
|
begin
|
|
160
161
|
require "net/tcp_client"
|
|
161
162
|
rescue LoadError
|
|
162
|
-
raise LoadError,
|
|
163
|
+
raise LoadError,
|
|
164
|
+
"Missing gem: net_tcp_client. This gem is required when logging over TCP. To fix this error: gem install net_tcp_client"
|
|
163
165
|
end
|
|
164
166
|
end
|
|
165
167
|
end
|
|
@@ -32,7 +32,7 @@ module SemanticLogger
|
|
|
32
32
|
# require 'logger'
|
|
33
33
|
# require 'semantic_logger'
|
|
34
34
|
#
|
|
35
|
-
# ruby_logger = Logger.new(
|
|
35
|
+
# ruby_logger = Logger.new($stdout)
|
|
36
36
|
# SemanticLogger.add_appender(logger: ruby_logger)
|
|
37
37
|
#
|
|
38
38
|
# logger = SemanticLogger['test']
|
|
@@ -45,7 +45,8 @@ module SemanticLogger
|
|
|
45
45
|
# Check if the custom appender responds to all the log levels. For example Ruby ::Logger
|
|
46
46
|
does_not_implement = LEVELS[1..-1].find { |i| !@logger.respond_to?(i) }
|
|
47
47
|
if does_not_implement
|
|
48
|
-
raise(ArgumentError,
|
|
48
|
+
raise(ArgumentError,
|
|
49
|
+
"Supplied logger does not implement:#{does_not_implement}. It must implement all of #{LEVELS[1..-1].inspect}")
|
|
49
50
|
end
|
|
50
51
|
|
|
51
52
|
super(**args, &block)
|
|
@@ -10,42 +10,48 @@ module SemanticLogger
|
|
|
10
10
|
|
|
11
11
|
def add(**args, &block)
|
|
12
12
|
appender = SemanticLogger::Appender.factory(**args, &block)
|
|
13
|
+
|
|
14
|
+
if appender.respond_to?(:console_output?) && appender.console_output? && console_output?
|
|
15
|
+
logger.warn "Ignoring attempt to add a second console appender: #{appender.class.name} since it would result in duplicate console output."
|
|
16
|
+
return
|
|
17
|
+
end
|
|
18
|
+
|
|
13
19
|
self << appender
|
|
14
20
|
appender
|
|
15
21
|
end
|
|
16
22
|
|
|
23
|
+
# Whether any of the existing appenders already output to the console?
|
|
24
|
+
# I.e. Writes to stdout or stderr.
|
|
25
|
+
def console_output?
|
|
26
|
+
any? { |appender| appender.respond_to?(:console_output?) && appender.console_output? }
|
|
27
|
+
end
|
|
28
|
+
|
|
17
29
|
def log(log)
|
|
18
30
|
each do |appender|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
logger.error "Failed to log to appender: #{appender.name}", e
|
|
23
|
-
end
|
|
31
|
+
appender.log(log) if appender.should_log?(log)
|
|
32
|
+
rescue Exception => e
|
|
33
|
+
logger.error "Failed to log to appender: #{appender.name}", e
|
|
24
34
|
end
|
|
25
35
|
end
|
|
26
36
|
|
|
27
37
|
def flush
|
|
28
38
|
each do |appender|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
logger.error "Failed to flush appender: #{appender.name}", e
|
|
34
|
-
end
|
|
39
|
+
logger.trace "Flushing appender: #{appender.name}"
|
|
40
|
+
appender.flush
|
|
41
|
+
rescue Exception => e
|
|
42
|
+
logger.error "Failed to flush appender: #{appender.name}", e
|
|
35
43
|
end
|
|
36
44
|
logger.trace "All appenders flushed"
|
|
37
45
|
end
|
|
38
46
|
|
|
39
47
|
def close
|
|
40
|
-
each do |appender|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
logger.error "Failed to close appender: #{appender.name}", e
|
|
48
|
-
end
|
|
48
|
+
to_a.each do |appender|
|
|
49
|
+
logger.trace "Closing appender: #{appender.name}"
|
|
50
|
+
delete(appender)
|
|
51
|
+
appender.flush
|
|
52
|
+
appender.close
|
|
53
|
+
rescue Exception => e
|
|
54
|
+
logger.error "Failed to close appender: #{appender.name}", e
|
|
49
55
|
end
|
|
50
56
|
logger.trace "All appenders closed and removed from appender list"
|
|
51
57
|
end
|
|
@@ -53,14 +59,12 @@ module SemanticLogger
|
|
|
53
59
|
# After a fork the appender thread is not running, start it if it is not running.
|
|
54
60
|
def reopen
|
|
55
61
|
each do |appender|
|
|
56
|
-
|
|
57
|
-
next unless appender.respond_to?(:reopen)
|
|
62
|
+
next unless appender.respond_to?(:reopen)
|
|
58
63
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
end
|
|
64
|
+
logger.trace "Reopening appender: #{appender.name}"
|
|
65
|
+
appender.reopen
|
|
66
|
+
rescue Exception => e
|
|
67
|
+
logger.error "Failed to re-open appender: #{appender.name}", e
|
|
64
68
|
end
|
|
65
69
|
logger.trace "All appenders re-opened"
|
|
66
70
|
end
|
data/lib/semantic_logger/base.rb
CHANGED
|
@@ -63,7 +63,7 @@ module SemanticLogger
|
|
|
63
63
|
# SemanticLogger.default_level = :info
|
|
64
64
|
#
|
|
65
65
|
# # Log to screen
|
|
66
|
-
# SemanticLogger.add_appender(io:
|
|
66
|
+
# SemanticLogger.add_appender(io: $stdout, formatter: :color)
|
|
67
67
|
#
|
|
68
68
|
# # And log to a file at the same time
|
|
69
69
|
# SemanticLogger.add_appender(file_name: 'application.log', formatter: :color)
|
|
@@ -136,7 +136,7 @@ module SemanticLogger
|
|
|
136
136
|
|
|
137
137
|
backtrace =
|
|
138
138
|
if thread == Thread.current
|
|
139
|
-
Utils.extract_backtrace
|
|
139
|
+
Utils.extract_backtrace(caller)
|
|
140
140
|
else
|
|
141
141
|
log.thread_name = thread.name
|
|
142
142
|
log.tags = (thread[:semantic_logger_tags] || []).clone
|
|
@@ -263,14 +263,22 @@ module SemanticLogger
|
|
|
263
263
|
# For example if set to :warn, this appender would only log :warn and :fatal
|
|
264
264
|
# log messages when other appenders could be logging :info and lower
|
|
265
265
|
#
|
|
266
|
-
# filter [Regexp|Proc]
|
|
266
|
+
# filter [Regexp|Proc|Module]
|
|
267
267
|
# RegExp: Only include log messages where the class name matches the supplied
|
|
268
268
|
# regular expression. All other messages will be ignored
|
|
269
269
|
# Proc: Only include log messages where the supplied Proc returns true
|
|
270
270
|
# The Proc must return true or false
|
|
271
|
+
# Module: A module that implements `.call`. For example:
|
|
272
|
+
# module ComplexFilter
|
|
273
|
+
# def self.call(log)
|
|
274
|
+
# (/\AExclude/ =~ log.message).nil?
|
|
275
|
+
# end
|
|
276
|
+
# end
|
|
271
277
|
def initialize(klass, level = nil, filter = nil)
|
|
272
|
-
# Support filtering all messages to this logger
|
|
273
|
-
|
|
278
|
+
# Support filtering all messages to this logger instance.
|
|
279
|
+
unless filter.nil? || filter.is_a?(Regexp) || filter.is_a?(Proc) || filter.respond_to?(:call)
|
|
280
|
+
raise ":filter must be a Regexp, Proc, or implement :call"
|
|
281
|
+
end
|
|
274
282
|
|
|
275
283
|
@filter = filter.is_a?(Regexp) ? filter.freeze : filter
|
|
276
284
|
@name = klass.is_a?(String) ? klass : klass.name
|
|
@@ -368,7 +376,7 @@ module SemanticLogger
|
|
|
368
376
|
exception = e
|
|
369
377
|
ensure
|
|
370
378
|
# Must use ensure block otherwise a `return` in the yield above will skip the log entry
|
|
371
|
-
log
|
|
379
|
+
log = Log.new(name, level, index)
|
|
372
380
|
exception ||= params[:exception]
|
|
373
381
|
message = params[:message] if params[:message]
|
|
374
382
|
duration =
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
module SemanticLogger
|
|
2
2
|
module Formatters
|
|
3
|
-
|
|
4
|
-
autoload :
|
|
5
|
-
autoload :
|
|
6
|
-
autoload :
|
|
7
|
-
autoload :
|
|
8
|
-
autoload :
|
|
9
|
-
autoload :
|
|
10
|
-
autoload :
|
|
11
|
-
autoload :
|
|
12
|
-
autoload :
|
|
13
|
-
# @formatter:on
|
|
3
|
+
autoload :Base, "semantic_logger/formatters/base"
|
|
4
|
+
autoload :Color, "semantic_logger/formatters/color"
|
|
5
|
+
autoload :Default, "semantic_logger/formatters/default"
|
|
6
|
+
autoload :Json, "semantic_logger/formatters/json"
|
|
7
|
+
autoload :Raw, "semantic_logger/formatters/raw"
|
|
8
|
+
autoload :OneLine, "semantic_logger/formatters/one_line"
|
|
9
|
+
autoload :Signalfx, "semantic_logger/formatters/signalfx"
|
|
10
|
+
autoload :Syslog, "semantic_logger/formatters/syslog"
|
|
11
|
+
autoload :Fluentd, "semantic_logger/formatters/fluentd"
|
|
12
|
+
autoload :Logfmt, "semantic_logger/formatters/logfmt"
|
|
14
13
|
|
|
15
14
|
# Return formatter that responds to call.
|
|
16
15
|
#
|
|
@@ -109,14 +109,14 @@ module SemanticLogger
|
|
|
109
109
|
def payload
|
|
110
110
|
return unless log.payload?
|
|
111
111
|
|
|
112
|
-
if
|
|
113
|
-
super
|
|
114
|
-
else
|
|
112
|
+
if log.payload.respond_to?(:ai)
|
|
115
113
|
begin
|
|
116
114
|
"-- #{log.payload.ai(@ai_options)}"
|
|
117
115
|
rescue StandardError
|
|
118
116
|
super
|
|
119
117
|
end
|
|
118
|
+
else
|
|
119
|
+
super
|
|
120
120
|
end
|
|
121
121
|
end
|
|
122
122
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
module SemanticLogger
|
|
4
|
+
module Formatters
|
|
5
|
+
class Logfmt < Raw
|
|
6
|
+
def initialize(time_format: :iso_8601, time_key: :timestamp, **args)
|
|
7
|
+
super(time_format: time_format, time_key: time_key, **args)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def call(log, logger)
|
|
11
|
+
@raw = super(log, logger)
|
|
12
|
+
|
|
13
|
+
raw_to_logfmt
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def raw_to_logfmt
|
|
19
|
+
@parsed = @raw.slice(:timestamp, :level, :name, :message, :duration).merge tag: "success"
|
|
20
|
+
handle_payload
|
|
21
|
+
handle_exception
|
|
22
|
+
|
|
23
|
+
flatten_log
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def handle_payload
|
|
27
|
+
return unless @raw.key? :payload
|
|
28
|
+
|
|
29
|
+
@parsed = @parsed.merge(@raw[:payload])
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def handle_exception
|
|
33
|
+
return unless @raw.key? :exception
|
|
34
|
+
|
|
35
|
+
@parsed[:tag] = "exception"
|
|
36
|
+
@parsed = @parsed.merge(@raw[:exception])
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def flatten_log
|
|
40
|
+
flattened = @parsed.map do |key, value|
|
|
41
|
+
"#{key}=#{parse_value(value)}"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
flattened.join(" ")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def parse_value(value)
|
|
48
|
+
return value.to_json if value.instance_of? String
|
|
49
|
+
|
|
50
|
+
value
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
begin
|
|
2
2
|
require "syslog_protocol"
|
|
3
3
|
rescue LoadError
|
|
4
|
-
raise LoadError,
|
|
4
|
+
raise LoadError,
|
|
5
|
+
'Gem syslog_protocol is required for remote logging using the Syslog protocol. Please add the gem "syslog_protocol" to your Gemfile.'
|
|
5
6
|
end
|
|
6
7
|
|
|
7
8
|
module SemanticLogger
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
begin
|
|
2
2
|
require "syslog_protocol"
|
|
3
3
|
rescue LoadError
|
|
4
|
-
raise LoadError,
|
|
4
|
+
raise LoadError,
|
|
5
|
+
'Gem syslog_protocol is required for remote logging using the Syslog protocol. Please add the gem "syslog_protocol" to your Gemfile.'
|
|
5
6
|
end
|
|
6
7
|
|
|
7
8
|
module SemanticLogger
|
data/lib/semantic_logger/log.rb
CHANGED
|
@@ -114,14 +114,12 @@ module SemanticLogger
|
|
|
114
114
|
|
|
115
115
|
# Elastic logging: Log when :duration exceeds :min_duration
|
|
116
116
|
# Except if there is an exception when it will always be logged
|
|
117
|
-
if duration
|
|
118
|
-
return false if (duration < min_duration) && exception.nil?
|
|
119
|
-
end
|
|
117
|
+
return false if duration && ((duration < min_duration) && exception.nil?)
|
|
120
118
|
|
|
121
119
|
if backtrace
|
|
122
120
|
self.backtrace = Utils.extract_backtrace(backtrace)
|
|
123
121
|
elsif level_index >= SemanticLogger.backtrace_level_index
|
|
124
|
-
self.backtrace = Utils.extract_backtrace
|
|
122
|
+
self.backtrace = Utils.extract_backtrace(caller)
|
|
125
123
|
end
|
|
126
124
|
|
|
127
125
|
true
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
# Example:
|
|
9
9
|
# require 'semantic_logger'
|
|
10
10
|
# SemanticLogger.default_level = :debug
|
|
11
|
-
# SemanticLogger.add_appender(io:
|
|
11
|
+
# SemanticLogger.add_appender(io: $stdout, formatter: :color)
|
|
12
12
|
#
|
|
13
13
|
# class ExternalSupplier
|
|
14
14
|
# # Create class and instance logger methods
|
|
@@ -32,7 +32,14 @@ module SemanticLogger
|
|
|
32
32
|
module Loggable
|
|
33
33
|
def self.included(base)
|
|
34
34
|
base.extend ClassMethods
|
|
35
|
+
base.singleton_class.class_eval do
|
|
36
|
+
undef_method :logger if method_defined?(:logger)
|
|
37
|
+
undef_method :logger= if method_defined?(:logger=)
|
|
38
|
+
end
|
|
35
39
|
base.class_eval do
|
|
40
|
+
undef_method :logger if method_defined?(:logger)
|
|
41
|
+
undef_method :logger= if method_defined?(:logger=)
|
|
42
|
+
|
|
36
43
|
# Returns [SemanticLogger::Logger] class level logger
|
|
37
44
|
def self.logger
|
|
38
45
|
@semantic_logger ||= SemanticLogger[self]
|
|
@@ -21,7 +21,19 @@ module SemanticLogger
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def self.processor
|
|
24
|
-
@processor ||=
|
|
24
|
+
@processor ||= Processor.new
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Switch to the synchronous processor
|
|
28
|
+
def self.sync!
|
|
29
|
+
return if @processor.is_a?(SyncProcessor)
|
|
30
|
+
|
|
31
|
+
@processor = SyncProcessor.new(@processor&.appenders)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Running without the background logging thread?
|
|
35
|
+
def self.sync?
|
|
36
|
+
processor.is_a?(SyncProcessor)
|
|
25
37
|
end
|
|
26
38
|
|
|
27
39
|
# Returns a Logger instance
|
|
@@ -70,11 +82,9 @@ module SemanticLogger
|
|
|
70
82
|
return unless @subscribers
|
|
71
83
|
|
|
72
84
|
@subscribers.each do |subscriber|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
processor.logger.error("Exception calling :on_log subscriber", e)
|
|
77
|
-
end
|
|
85
|
+
subscriber.call(log)
|
|
86
|
+
rescue Exception => e
|
|
87
|
+
processor.logger.error("Exception calling :on_log subscriber", e)
|
|
78
88
|
end
|
|
79
89
|
end
|
|
80
90
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module SemanticLogger
|
|
2
2
|
# Thread that submits and processes log requests
|
|
3
3
|
class Processor < Appender::Async
|
|
4
|
-
# Allow the internal logger to be overridden from its default of
|
|
4
|
+
# Allow the internal logger to be overridden from its default of $stderr
|
|
5
5
|
# Can be replaced with another Ruby logger or Rails logger, but never to
|
|
6
6
|
# SemanticLogger::Logger itself since it is for reporting problems
|
|
7
7
|
# while trying to log to the various appenders
|
|
@@ -11,11 +11,11 @@ module SemanticLogger
|
|
|
11
11
|
|
|
12
12
|
# Internal logger for SemanticLogger
|
|
13
13
|
# For example when an appender is not working etc..
|
|
14
|
-
# By default logs to
|
|
14
|
+
# By default logs to $stderr
|
|
15
15
|
def self.logger
|
|
16
16
|
@logger ||=
|
|
17
17
|
begin
|
|
18
|
-
l = SemanticLogger::Appender::File.new(io:
|
|
18
|
+
l = SemanticLogger::Appender::File.new(io: $stderr, level: :warn)
|
|
19
19
|
l.name = name
|
|
20
20
|
l
|
|
21
21
|
end
|
|
@@ -101,7 +101,7 @@ module SemanticLogger
|
|
|
101
101
|
# Or,
|
|
102
102
|
# io: [IO]
|
|
103
103
|
# An IO Stream to log to.
|
|
104
|
-
# For example
|
|
104
|
+
# For example $stdout, $stderr, etc.
|
|
105
105
|
#
|
|
106
106
|
# Or,
|
|
107
107
|
# appender: [Symbol|SemanticLogger::Subscriber]
|
|
@@ -138,14 +138,14 @@ module SemanticLogger
|
|
|
138
138
|
# Examples:
|
|
139
139
|
#
|
|
140
140
|
# # Send all logging output to Standard Out (Screen)
|
|
141
|
-
# SemanticLogger.add_appender(io:
|
|
141
|
+
# SemanticLogger.add_appender(io: $stdout)
|
|
142
142
|
#
|
|
143
143
|
# # Send all logging output to a file
|
|
144
144
|
# SemanticLogger.add_appender(file_name: 'logfile.log')
|
|
145
145
|
#
|
|
146
146
|
# # Send all logging output to a file and only :info and above to standard output
|
|
147
147
|
# SemanticLogger.add_appender(file_name: 'logfile.log')
|
|
148
|
-
# SemanticLogger.add_appender(io:
|
|
148
|
+
# SemanticLogger.add_appender(io: $stdout, level: :info)
|
|
149
149
|
#
|
|
150
150
|
# Log to log4r, Logger, etc.:
|
|
151
151
|
#
|
|
@@ -154,7 +154,7 @@ module SemanticLogger
|
|
|
154
154
|
# require 'semantic_logger'
|
|
155
155
|
#
|
|
156
156
|
# # Built-in Ruby logger
|
|
157
|
-
# log = Logger.new(
|
|
157
|
+
# log = Logger.new($stdout)
|
|
158
158
|
# log.level = Logger::DEBUG
|
|
159
159
|
#
|
|
160
160
|
# SemanticLogger.default_level = :debug
|
|
@@ -173,7 +173,15 @@ module SemanticLogger
|
|
|
173
173
|
# Remove an existing appender
|
|
174
174
|
# Currently only supports appender instances
|
|
175
175
|
def self.remove_appender(appender)
|
|
176
|
+
return unless appender
|
|
177
|
+
|
|
176
178
|
Logger.processor.appenders.delete(appender)
|
|
179
|
+
appender.close
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Clear out all previously registered appenders
|
|
183
|
+
def self.clear_appenders!
|
|
184
|
+
Logger.processor.close
|
|
177
185
|
end
|
|
178
186
|
|
|
179
187
|
# Returns [SemanticLogger::Subscriber] a copy of the list of active
|
|
@@ -494,12 +502,12 @@ module SemanticLogger
|
|
|
494
502
|
# I.e. Instead of logging messages in a separate thread for better performance,
|
|
495
503
|
# log them using the current thread.
|
|
496
504
|
def self.sync!
|
|
497
|
-
|
|
505
|
+
Logger.sync!
|
|
498
506
|
end
|
|
499
507
|
|
|
500
508
|
# Running in synchronous mode?
|
|
501
509
|
def self.sync?
|
|
502
|
-
|
|
510
|
+
Logger.sync?
|
|
503
511
|
end
|
|
504
512
|
|
|
505
513
|
# Initial default Level for all new instances of SemanticLogger::Logger
|
|
@@ -10,7 +10,7 @@ module SemanticLogger
|
|
|
10
10
|
def_delegator :@appenders, :close
|
|
11
11
|
def_delegator :@appenders, :reopen
|
|
12
12
|
|
|
13
|
-
# Allow the internal logger to be overridden from its default of
|
|
13
|
+
# Allow the internal logger to be overridden from its default of $stderr
|
|
14
14
|
# Can be replaced with another Ruby logger or Rails logger, but never to
|
|
15
15
|
# SemanticLogger::Logger itself since it is for reporting problems
|
|
16
16
|
# while trying to log to the various appenders
|
|
@@ -20,11 +20,11 @@ module SemanticLogger
|
|
|
20
20
|
|
|
21
21
|
# Internal logger for SemanticLogger
|
|
22
22
|
# For example when an appender is not working etc..
|
|
23
|
-
# By default logs to
|
|
23
|
+
# By default logs to $stderr
|
|
24
24
|
def self.logger
|
|
25
25
|
@logger ||=
|
|
26
26
|
begin
|
|
27
|
-
l = SemanticLogger::Appender::File.new(io:
|
|
27
|
+
l = SemanticLogger::Appender::File.new(io: $stderr, level: :warn)
|
|
28
28
|
l.name = name
|
|
29
29
|
l
|
|
30
30
|
end
|
|
@@ -32,8 +32,8 @@ module SemanticLogger
|
|
|
32
32
|
|
|
33
33
|
attr_reader :appenders
|
|
34
34
|
|
|
35
|
-
def initialize
|
|
36
|
-
@appenders = Appenders.new(self.class.logger.dup)
|
|
35
|
+
def initialize(appenders = nil)
|
|
36
|
+
@appenders = appenders || Appenders.new(self.class.logger.dup)
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def start
|
|
@@ -32,29 +32,48 @@ module SemanticLogger
|
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
# Extract the backtrace leaving out the last few Semantic Logger lines.
|
|
35
|
+
# Extract the backtrace stripping off the leading semantic logger entries.
|
|
36
|
+
# Leaves all other system and gem path entries in place.
|
|
38
37
|
def self.extract_backtrace(stack = caller)
|
|
39
|
-
while (first = stack.first) &&
|
|
38
|
+
while (first = stack.first) && extract_path?(first)
|
|
40
39
|
stack.shift
|
|
41
40
|
end
|
|
42
41
|
stack
|
|
43
42
|
end
|
|
44
43
|
|
|
45
|
-
|
|
44
|
+
def self.extract_paths
|
|
45
|
+
@extract_paths ||= %w[lib/semantic_logger lib/rails_semantic_logger]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Whether this path should be excluded from any cleansed backtrace
|
|
49
|
+
def self.extract_path?(path)
|
|
50
|
+
extract_paths.any? { |exclude| path.include?(exclude) }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Try to strip everything off of the supplied backtrace, until the first application stack entry is at the top.
|
|
54
|
+
# For example all leading gem paths and built-in ruby code paths are removed from the top.
|
|
55
|
+
# Once the first application entry is found, the remaining stack is returned.
|
|
46
56
|
def self.strip_backtrace(stack = caller)
|
|
47
|
-
while (first = stack.first) &&
|
|
57
|
+
while (first = stack.first) && (strip_path?(first) || extract_path?(first))
|
|
48
58
|
stack.shift
|
|
49
59
|
end
|
|
50
60
|
stack
|
|
51
61
|
end
|
|
52
62
|
|
|
53
|
-
|
|
63
|
+
# Paths to exclude in the stripped backtrace
|
|
64
|
+
# Includes Gems and built-in Ruby code paths
|
|
65
|
+
def self.strip_paths
|
|
66
|
+
@strip_paths ||=
|
|
67
|
+
begin
|
|
68
|
+
paths = Gem.path | [Gem.default_dir]
|
|
69
|
+
paths << RbConfig::CONFIG["rubylibdir"]
|
|
70
|
+
paths
|
|
71
|
+
end
|
|
72
|
+
end
|
|
54
73
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
74
|
+
# Whether this path should be excluded from any cleansed backtrace
|
|
75
|
+
def self.strip_path?(path)
|
|
76
|
+
strip_paths.any? { |exclude| path.start_with?(exclude) }
|
|
58
77
|
end
|
|
59
78
|
end
|
|
60
79
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: semantic_logger
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.8.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Reid Morrison
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-08-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: concurrent-ruby
|
|
@@ -26,7 +26,6 @@ dependencies:
|
|
|
26
26
|
version: '1.0'
|
|
27
27
|
description:
|
|
28
28
|
email:
|
|
29
|
-
- reidmo@gmail.com
|
|
30
29
|
executables: []
|
|
31
30
|
extensions: []
|
|
32
31
|
extra_rdoc_files: []
|
|
@@ -68,6 +67,7 @@ files:
|
|
|
68
67
|
- lib/semantic_logger/formatters/default.rb
|
|
69
68
|
- lib/semantic_logger/formatters/fluentd.rb
|
|
70
69
|
- lib/semantic_logger/formatters/json.rb
|
|
70
|
+
- lib/semantic_logger/formatters/logfmt.rb
|
|
71
71
|
- lib/semantic_logger/formatters/one_line.rb
|
|
72
72
|
- lib/semantic_logger/formatters/raw.rb
|
|
73
73
|
- lib/semantic_logger/formatters/signalfx.rb
|
|
@@ -89,7 +89,7 @@ files:
|
|
|
89
89
|
- lib/semantic_logger/sync_processor.rb
|
|
90
90
|
- lib/semantic_logger/utils.rb
|
|
91
91
|
- lib/semantic_logger/version.rb
|
|
92
|
-
homepage: https://
|
|
92
|
+
homepage: https://logger.rocketjob.io
|
|
93
93
|
licenses:
|
|
94
94
|
- Apache-2.0
|
|
95
95
|
metadata: {}
|
|
@@ -101,14 +101,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
101
101
|
requirements:
|
|
102
102
|
- - ">="
|
|
103
103
|
- !ruby/object:Gem::Version
|
|
104
|
-
version: '2.
|
|
104
|
+
version: '2.5'
|
|
105
105
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
106
|
requirements:
|
|
107
107
|
- - ">="
|
|
108
108
|
- !ruby/object:Gem::Version
|
|
109
109
|
version: '0'
|
|
110
110
|
requirements: []
|
|
111
|
-
rubygems_version: 3.
|
|
111
|
+
rubygems_version: 3.2.15
|
|
112
112
|
signing_key:
|
|
113
113
|
specification_version: 4
|
|
114
114
|
summary: Feature rich logging framework, and replacement for existing Ruby & Rails
|