semantic_logger 4.6.0.beta1 → 4.7.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 +1 -1
- data/Rakefile +7 -7
- data/lib/semantic_logger.rb +23 -22
- data/lib/semantic_logger/appender.rb +32 -33
- data/lib/semantic_logger/appender/async.rb +9 -8
- data/lib/semantic_logger/appender/async_batch.rb +4 -2
- data/lib/semantic_logger/appender/bugsnag.rb +7 -7
- data/lib/semantic_logger/appender/elasticsearch.rb +10 -10
- data/lib/semantic_logger/appender/elasticsearch_http.rb +4 -4
- data/lib/semantic_logger/appender/file.rb +2 -1
- data/lib/semantic_logger/appender/graylog.rb +15 -10
- data/lib/semantic_logger/appender/honeybadger.rb +3 -3
- data/lib/semantic_logger/appender/http.rb +20 -18
- data/lib/semantic_logger/appender/kafka.rb +5 -5
- data/lib/semantic_logger/appender/mongodb.rb +6 -6
- data/lib/semantic_logger/appender/new_relic.rb +2 -2
- data/lib/semantic_logger/appender/rabbitmq.rb +5 -5
- data/lib/semantic_logger/appender/sentry.rb +7 -7
- data/lib/semantic_logger/appender/splunk.rb +5 -5
- data/lib/semantic_logger/appender/splunk_http.rb +3 -4
- data/lib/semantic_logger/appender/syslog.rb +20 -14
- data/lib/semantic_logger/appender/tcp.rb +5 -5
- data/lib/semantic_logger/appender/udp.rb +2 -2
- data/lib/semantic_logger/appenders.rb +11 -11
- data/lib/semantic_logger/base.rb +42 -18
- data/lib/semantic_logger/formatters.rb +11 -11
- data/lib/semantic_logger/formatters/base.rb +8 -3
- data/lib/semantic_logger/formatters/color.rb +10 -6
- data/lib/semantic_logger/formatters/default.rb +18 -5
- data/lib/semantic_logger/formatters/fluentd.rb +3 -3
- data/lib/semantic_logger/formatters/json.rb +1 -1
- data/lib/semantic_logger/formatters/raw.rb +31 -7
- data/lib/semantic_logger/formatters/signalfx.rb +10 -9
- data/lib/semantic_logger/formatters/syslog.rb +7 -6
- data/lib/semantic_logger/formatters/syslog_cee.rb +7 -6
- data/lib/semantic_logger/jruby/garbage_collection_logger.rb +4 -2
- data/lib/semantic_logger/levels.rb +9 -7
- data/lib/semantic_logger/log.rb +52 -60
- data/lib/semantic_logger/logger.rb +6 -8
- data/lib/semantic_logger/metric/new_relic.rb +3 -3
- data/lib/semantic_logger/metric/signalfx.rb +3 -3
- data/lib/semantic_logger/metric/statsd.rb +7 -7
- data/lib/semantic_logger/processor.rb +7 -5
- data/lib/semantic_logger/reporters/minitest.rb +4 -4
- data/lib/semantic_logger/semantic_logger.rb +24 -11
- data/lib/semantic_logger/subscriber.rb +6 -5
- data/lib/semantic_logger/sync.rb +12 -0
- data/lib/semantic_logger/sync_processor.rb +43 -0
- data/lib/semantic_logger/utils.rb +6 -6
- data/lib/semantic_logger/version.rb +1 -1
- metadata +7 -5
data/lib/semantic_logger/base.rb
CHANGED
@@ -126,7 +126,7 @@ module SemanticLogger
|
|
126
126
|
# Log a thread backtrace
|
127
127
|
def backtrace(thread: Thread.current,
|
128
128
|
level: :warn,
|
129
|
-
message:
|
129
|
+
message: "Backtrace:",
|
130
130
|
payload: nil,
|
131
131
|
metric: nil,
|
132
132
|
metric_amount: nil)
|
@@ -190,7 +190,8 @@ module SemanticLogger
|
|
190
190
|
# Allow named tags to be passed into the logger
|
191
191
|
if tags.size == 1
|
192
192
|
tag = tags[0]
|
193
|
-
return yield if tag.nil? || tag ==
|
193
|
+
return yield if tag.nil? || tag == ""
|
194
|
+
|
194
195
|
return tag.is_a?(Hash) ? SemanticLogger.named_tagged(tag, &block) : SemanticLogger.fast_tag(tag.to_s, &block)
|
195
196
|
end
|
196
197
|
|
@@ -240,7 +241,7 @@ module SemanticLogger
|
|
240
241
|
|
241
242
|
# Write log data to underlying data storage
|
242
243
|
def log(_log_)
|
243
|
-
raise NotImplementedError,
|
244
|
+
raise NotImplementedError, "Logging Appender must implement #log(log)"
|
244
245
|
end
|
245
246
|
|
246
247
|
# Whether this log entry meets the criteria to be logged by this appender.
|
@@ -269,7 +270,7 @@ module SemanticLogger
|
|
269
270
|
# The Proc must return true or false
|
270
271
|
def initialize(klass, level = nil, filter = nil)
|
271
272
|
# Support filtering all messages to this logger using a Regular Expression or Proc
|
272
|
-
raise
|
273
|
+
raise ":filter must be a Regexp or Proc" unless filter.nil? || filter.is_a?(Regexp) || filter.is_a?(Proc)
|
273
274
|
|
274
275
|
@filter = filter.is_a?(Regexp) ? filter.freeze : filter
|
275
276
|
@name = klass.is_a?(String) ? klass : klass.name
|
@@ -302,20 +303,42 @@ module SemanticLogger
|
|
302
303
|
end
|
303
304
|
|
304
305
|
# Log message at the specified level
|
305
|
-
def log_internal(level, index, message = nil, payload = nil, exception = nil
|
306
|
-
|
306
|
+
def log_internal(level, index, message = nil, payload = nil, exception = nil)
|
307
|
+
# Handle variable number of arguments by detecting exception object and payload hash.
|
308
|
+
if exception.nil? && payload.nil? && message.respond_to?(:backtrace) && message.respond_to?(:message)
|
309
|
+
exception = message
|
310
|
+
message = nil
|
311
|
+
elsif exception.nil? && payload && payload.respond_to?(:backtrace) && payload.respond_to?(:message)
|
312
|
+
exception = payload
|
313
|
+
payload = nil
|
314
|
+
elsif payload && !payload.is_a?(Hash)
|
315
|
+
message = message.nil? ? payload : "#{message} -- #{payload}"
|
316
|
+
payload = nil
|
317
|
+
end
|
318
|
+
|
319
|
+
log = Log.new(name, level, index)
|
307
320
|
should_log =
|
308
321
|
if payload.nil? && exception.nil? && message.is_a?(Hash)
|
309
|
-
#
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
end
|
322
|
+
# Everything as keyword arguments.
|
323
|
+
log.assign(**log.extract_arguments(message))
|
324
|
+
elsif exception.nil? && message && payload && payload.is_a?(Hash)
|
325
|
+
# Message with keyword arguments as the rest.
|
326
|
+
log.assign(message: message, **log.extract_arguments(payload))
|
315
327
|
else
|
316
|
-
|
328
|
+
# No keyword arguments.
|
329
|
+
log.assign(message: message, payload: payload, exception: exception)
|
317
330
|
end
|
318
331
|
|
332
|
+
# Add result of block to message or payload if not nil
|
333
|
+
if block_given?
|
334
|
+
result = yield(log)
|
335
|
+
if result.is_a?(String)
|
336
|
+
log.message = log.message.nil? ? result : "#{log.message} -- #{result}"
|
337
|
+
elsif result.is_a?(Hash)
|
338
|
+
log.assign_hash(result)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
319
342
|
# Log level may change during assign due to :on_exception_level
|
320
343
|
self.log(log) if should_log && should_log?(log)
|
321
344
|
end
|
@@ -341,8 +364,8 @@ module SemanticLogger
|
|
341
364
|
yield(params)
|
342
365
|
end
|
343
366
|
end
|
344
|
-
rescue Exception =>
|
345
|
-
exception =
|
367
|
+
rescue Exception => e
|
368
|
+
exception = e
|
346
369
|
ensure
|
347
370
|
# Must use ensure block otherwise a `return` in the yield above will skip the log entry
|
348
371
|
log = Log.new(name, level, index)
|
@@ -352,7 +375,7 @@ module SemanticLogger
|
|
352
375
|
if block_given?
|
353
376
|
1_000.0 * (Process.clock_gettime(Process::CLOCK_MONOTONIC) - start)
|
354
377
|
else
|
355
|
-
params[:duration] || raise(
|
378
|
+
params[:duration] || raise("Mandatory block missing when :duration option is not supplied")
|
356
379
|
end
|
357
380
|
|
358
381
|
# Extract options after block completes so that block can modify any of the options
|
@@ -374,6 +397,7 @@ module SemanticLogger
|
|
374
397
|
# Log level may change during assign due to :on_exception_level
|
375
398
|
self.log(log) if should_log && should_log?(log)
|
376
399
|
raise exception if exception
|
400
|
+
|
377
401
|
result
|
378
402
|
end
|
379
403
|
end
|
@@ -392,8 +416,8 @@ module SemanticLogger
|
|
392
416
|
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
393
417
|
begin
|
394
418
|
yield
|
395
|
-
rescue Exception =>
|
396
|
-
exception =
|
419
|
+
rescue Exception => e
|
420
|
+
exception = e
|
397
421
|
ensure
|
398
422
|
log = Log.new(name, level, index)
|
399
423
|
# May return false due to elastic logging
|
@@ -1,15 +1,15 @@
|
|
1
1
|
module SemanticLogger
|
2
2
|
module Formatters
|
3
3
|
# @formatter:off
|
4
|
-
autoload :Base,
|
5
|
-
autoload :Color,
|
6
|
-
autoload :Default,
|
7
|
-
autoload :Json,
|
8
|
-
autoload :Raw,
|
9
|
-
autoload :OneLine,
|
10
|
-
autoload :Signalfx,
|
11
|
-
autoload :Syslog,
|
12
|
-
autoload :Fluentd,
|
4
|
+
autoload :Base, "semantic_logger/formatters/base"
|
5
|
+
autoload :Color, "semantic_logger/formatters/color"
|
6
|
+
autoload :Default, "semantic_logger/formatters/default"
|
7
|
+
autoload :Json, "semantic_logger/formatters/json"
|
8
|
+
autoload :Raw, "semantic_logger/formatters/raw"
|
9
|
+
autoload :OneLine, "semantic_logger/formatters/one_line"
|
10
|
+
autoload :Signalfx, "semantic_logger/formatters/signalfx"
|
11
|
+
autoload :Syslog, "semantic_logger/formatters/syslog"
|
12
|
+
autoload :Fluentd, "semantic_logger/formatters/fluentd"
|
13
13
|
# @formatter:on
|
14
14
|
|
15
15
|
# Return formatter that responds to call.
|
@@ -22,10 +22,10 @@ module SemanticLogger
|
|
22
22
|
# - Any object that responds to :call
|
23
23
|
def self.factory(formatter)
|
24
24
|
if formatter.is_a?(Symbol)
|
25
|
-
SemanticLogger::Utils.constantize_symbol(formatter,
|
25
|
+
SemanticLogger::Utils.constantize_symbol(formatter, "SemanticLogger::Formatters").new
|
26
26
|
elsif formatter.is_a?(Hash) && formatter.size.positive?
|
27
27
|
fmt, options = formatter.first
|
28
|
-
SemanticLogger::Utils.constantize_symbol(fmt.to_sym,
|
28
|
+
SemanticLogger::Utils.constantize_symbol(fmt.to_sym, "SemanticLogger::Formatters").new(**options)
|
29
29
|
elsif formatter.respond_to?(:call)
|
30
30
|
formatter
|
31
31
|
else
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require
|
1
|
+
require "time"
|
2
2
|
module SemanticLogger
|
3
3
|
module Formatters
|
4
4
|
class Base
|
5
|
-
attr_accessor :time_format, :log_host, :log_application, :log_environment, :precision
|
5
|
+
attr_accessor :log, :logger, :time_format, :log_host, :log_application, :log_environment, :precision
|
6
6
|
|
7
7
|
# Time precision varies by Ruby interpreter
|
8
8
|
# JRuby 9.1.8.0 supports microseconds
|
@@ -61,6 +61,11 @@ module SemanticLogger
|
|
61
61
|
format_time(log.time) if time_format
|
62
62
|
end
|
63
63
|
|
64
|
+
# Process ID
|
65
|
+
def pid
|
66
|
+
$$
|
67
|
+
end
|
68
|
+
|
64
69
|
private
|
65
70
|
|
66
71
|
# Return the Time as a formatted string
|
@@ -77,7 +82,7 @@ module SemanticLogger
|
|
77
82
|
when :seconds
|
78
83
|
time.to_f
|
79
84
|
when nil
|
80
|
-
|
85
|
+
""
|
81
86
|
else
|
82
87
|
time.strftime(time_format)
|
83
88
|
end
|
@@ -1,8 +1,12 @@
|
|
1
|
-
# Load
|
1
|
+
# Load Amazing Print, or Awesome Print if available
|
2
2
|
begin
|
3
|
-
require
|
3
|
+
require "amazing_print"
|
4
4
|
rescue LoadError
|
5
|
-
|
5
|
+
begin
|
6
|
+
require "awesome_print"
|
7
|
+
rescue LoadError
|
8
|
+
nil
|
9
|
+
end
|
6
10
|
end
|
7
11
|
|
8
12
|
module SemanticLogger
|
@@ -61,9 +65,9 @@ module SemanticLogger
|
|
61
65
|
#
|
62
66
|
# Parameters:
|
63
67
|
# ap: [Hash]
|
64
|
-
# Any valid
|
68
|
+
# Any valid Amazing Print option for rendering data.
|
65
69
|
# These options can also be changed be creating a `~/.aprc` file.
|
66
|
-
# See: https://github.com/
|
70
|
+
# See: https://github.com/amazing-print/amazing_print
|
67
71
|
#
|
68
72
|
# Note: The option :multiline is set to false if not supplied.
|
69
73
|
# Note: Has no effect if Awesome Print is not installed.
|
@@ -105,7 +109,7 @@ module SemanticLogger
|
|
105
109
|
def payload
|
106
110
|
return unless log.payload?
|
107
111
|
|
108
|
-
if !
|
112
|
+
if !log.payload.respond_to?(:ai)
|
109
113
|
super
|
110
114
|
else
|
111
115
|
begin
|
@@ -2,8 +2,6 @@ module SemanticLogger
|
|
2
2
|
module Formatters
|
3
3
|
# Default non-colored text log output
|
4
4
|
class Default < Base
|
5
|
-
attr_accessor :log, :logger
|
6
|
-
|
7
5
|
# Formatting methods, must return nil, or a string
|
8
6
|
# Nil values are ignored
|
9
7
|
|
@@ -12,9 +10,24 @@ module SemanticLogger
|
|
12
10
|
log.level_to_s
|
13
11
|
end
|
14
12
|
|
15
|
-
#
|
13
|
+
# Name of the thread that logged the message.
|
14
|
+
def thread_name
|
15
|
+
format("%.30s", log.thread_name)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Ruby file name and line number that logged the message.
|
19
|
+
def file_name_and_line
|
20
|
+
file, line = log.file_name_and_line(true)
|
21
|
+
"#{file}:#{line}" if file
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns [String] the available process info
|
25
|
+
# Example:
|
26
|
+
# [18934:thread_name test_logging.rb:51]
|
16
27
|
def process_info
|
17
|
-
"
|
28
|
+
process_id = "#{pid}:" if pid
|
29
|
+
fname = file_name_and_line
|
30
|
+
fname ? "[#{process_id}#{thread_name} #{fname}]" : "[#{process_id}#{thread_name}]"
|
18
31
|
end
|
19
32
|
|
20
33
|
# Tags
|
@@ -67,7 +80,7 @@ module SemanticLogger
|
|
67
80
|
self.log = log
|
68
81
|
self.logger = logger
|
69
82
|
|
70
|
-
[time, level, process_info, tags, named_tags, duration, name, message, payload, exception].compact.join(
|
83
|
+
[time, level, process_info, tags, named_tags, duration, name, message, payload, exception].compact.join(" ")
|
71
84
|
end
|
72
85
|
end
|
73
86
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "json"
|
2
2
|
|
3
3
|
module SemanticLogger
|
4
4
|
module Formatters
|
@@ -13,8 +13,8 @@ module SemanticLogger
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def level
|
16
|
-
hash[
|
17
|
-
hash[
|
16
|
+
hash["severity"] = log.level
|
17
|
+
hash["severity_index"] = log.level_index
|
18
18
|
end
|
19
19
|
|
20
20
|
def process_info
|
@@ -1,9 +1,9 @@
|
|
1
|
-
require
|
1
|
+
require "json"
|
2
2
|
module SemanticLogger
|
3
3
|
module Formatters
|
4
4
|
class Raw < Base
|
5
5
|
# Fields are added by populating this hash.
|
6
|
-
attr_accessor :hash, :
|
6
|
+
attr_accessor :hash, :time_key
|
7
7
|
|
8
8
|
# By default Raw formatter does not reformat the time
|
9
9
|
def initialize(time_format: :none, time_key: :time, **args)
|
@@ -37,11 +37,18 @@ module SemanticLogger
|
|
37
37
|
hash[:level_index] = log.level_index
|
38
38
|
end
|
39
39
|
|
40
|
-
# Process
|
41
|
-
def
|
42
|
-
hash[:pid]
|
40
|
+
# Process ID
|
41
|
+
def pid
|
42
|
+
hash[:pid] = super
|
43
|
+
end
|
44
|
+
|
45
|
+
# Name of the thread that logged the message.
|
46
|
+
def thread_name
|
43
47
|
hash[:thread] = log.thread_name
|
48
|
+
end
|
44
49
|
|
50
|
+
# Ruby file name and line number that logged the message.
|
51
|
+
def file_name_and_line
|
45
52
|
file, line = log.file_name_and_line
|
46
53
|
return unless file
|
47
54
|
|
@@ -85,6 +92,7 @@ module SemanticLogger
|
|
85
92
|
# Exception
|
86
93
|
def exception
|
87
94
|
return unless log.exception
|
95
|
+
|
88
96
|
root = hash
|
89
97
|
log.each_exception do |exception, i|
|
90
98
|
name = i.zero? ? :exception : :cause
|
@@ -93,7 +101,7 @@ module SemanticLogger
|
|
93
101
|
message: exception.message,
|
94
102
|
stack_trace: exception.backtrace
|
95
103
|
}
|
96
|
-
root
|
104
|
+
root = root[name]
|
97
105
|
end
|
98
106
|
end
|
99
107
|
|
@@ -109,7 +117,23 @@ module SemanticLogger
|
|
109
117
|
self.log = log
|
110
118
|
self.logger = logger
|
111
119
|
|
112
|
-
host
|
120
|
+
host
|
121
|
+
application
|
122
|
+
environment
|
123
|
+
time
|
124
|
+
level
|
125
|
+
pid
|
126
|
+
thread_name
|
127
|
+
file_name_and_line
|
128
|
+
duration
|
129
|
+
tags
|
130
|
+
named_tags
|
131
|
+
name
|
132
|
+
message
|
133
|
+
payload
|
134
|
+
exception
|
135
|
+
metric
|
136
|
+
|
113
137
|
hash
|
114
138
|
end
|
115
139
|
end
|
@@ -1,13 +1,13 @@
|
|
1
|
-
require
|
1
|
+
require "json"
|
2
2
|
module SemanticLogger
|
3
3
|
module Formatters
|
4
4
|
class Signalfx < Base
|
5
|
-
attr_accessor :token, :dimensions, :hash, :
|
5
|
+
attr_accessor :token, :dimensions, :hash, :gauge_name, :counter_name
|
6
6
|
|
7
7
|
def initialize(token:,
|
8
8
|
dimensions: nil,
|
9
|
-
gauge_name:
|
10
|
-
counter_name:
|
9
|
+
gauge_name: "Application.average",
|
10
|
+
counter_name: "Application.counter",
|
11
11
|
time_format: :ms,
|
12
12
|
**args)
|
13
13
|
|
@@ -23,19 +23,19 @@ module SemanticLogger
|
|
23
23
|
# Strip leading '/'
|
24
24
|
# Convert remaining '/' to '.'
|
25
25
|
def metric
|
26
|
-
name = log.metric.to_s.sub(
|
26
|
+
name = log.metric.to_s.sub(%r{\A/+}, "")
|
27
27
|
if log.dimensions
|
28
|
-
name.tr!(
|
28
|
+
name.tr!("/", ".")
|
29
29
|
hash[:metric] = name
|
30
30
|
else
|
31
31
|
# Extract class and action from metric name
|
32
|
-
names = name.split(
|
32
|
+
names = name.split("/")
|
33
33
|
h = (hash[:dimensions] ||= {})
|
34
34
|
if names.size > 1
|
35
35
|
h[:action] = names.pop
|
36
|
-
h[:class] = names.join(
|
36
|
+
h[:class] = names.join("::")
|
37
37
|
else
|
38
|
-
h[:class] =
|
38
|
+
h[:class] = "Unknown"
|
39
39
|
h[:action] = names.first || log.metric
|
40
40
|
end
|
41
41
|
|
@@ -67,6 +67,7 @@ module SemanticLogger
|
|
67
67
|
name = name.to_sym
|
68
68
|
value = value.to_s
|
69
69
|
next if value.empty?
|
70
|
+
|
70
71
|
h[name] = value if dimensions&.include?(name)
|
71
72
|
end
|
72
73
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
begin
|
2
|
-
require
|
2
|
+
require "syslog_protocol"
|
3
3
|
rescue LoadError
|
4
|
-
raise 'Gem syslog_protocol is required for remote logging using the Syslog protocol. Please add the gem "syslog_protocol" to your Gemfile.'
|
4
|
+
raise LoadError, 'Gem syslog_protocol is required for remote logging using the Syslog protocol. Please add the gem "syslog_protocol" to your Gemfile.'
|
5
5
|
end
|
6
6
|
|
7
7
|
module SemanticLogger
|
8
8
|
module Formatters
|
9
9
|
class Syslog < Default
|
10
|
-
attr_accessor :level_map, :facility
|
10
|
+
attr_accessor :level_map, :facility, :max_size
|
11
11
|
|
12
12
|
# Default level map for every log level
|
13
13
|
#
|
@@ -50,9 +50,10 @@ module SemanticLogger
|
|
50
50
|
# Example:
|
51
51
|
# # Change the warn level to LOG_NOTICE level instead of a the default of LOG_WARNING.
|
52
52
|
# SemanticLogger.add_appender(appender: :syslog, level_map: {warn: ::Syslog::LOG_NOTICE})
|
53
|
-
def initialize(facility: ::Syslog::LOG_USER, level_map: LevelMap.new)
|
53
|
+
def initialize(facility: ::Syslog::LOG_USER, level_map: LevelMap.new, max_size: Integer)
|
54
54
|
@facility = facility
|
55
55
|
@level_map = level_map.is_a?(LevelMap) ? level_map : LevelMap.new(level_map)
|
56
|
+
@max_size = max_size
|
56
57
|
super()
|
57
58
|
end
|
58
59
|
|
@@ -73,11 +74,11 @@ module SemanticLogger
|
|
73
74
|
packet = SyslogProtocol::Packet.new
|
74
75
|
packet.hostname = logger.host
|
75
76
|
packet.facility = facility
|
76
|
-
packet.tag = logger.application.delete(
|
77
|
+
packet.tag = logger.application.delete(" ")
|
77
78
|
packet.content = message
|
78
79
|
packet.time = log.time
|
79
80
|
packet.severity = level_map[log.level]
|
80
|
-
packet.
|
81
|
+
packet.assemble(@max_size)
|
81
82
|
end
|
82
83
|
end
|
83
84
|
end
|