semantic_logger 4.3.1 → 4.4.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/lib/semantic_logger.rb +7 -1
- data/lib/semantic_logger/appender.rb +3 -0
- data/lib/semantic_logger/appender/async.rb +29 -10
- data/lib/semantic_logger/appender/rabbitmq.rb +120 -0
- data/lib/semantic_logger/appenders.rb +89 -0
- data/lib/semantic_logger/base.rb +3 -3
- data/lib/semantic_logger/concerns/compatibility.rb +2 -2
- data/lib/semantic_logger/formatters.rb +1 -0
- data/lib/semantic_logger/formatters/base.rb +28 -6
- data/lib/semantic_logger/formatters/color.rb +4 -3
- data/lib/semantic_logger/formatters/fluentd.rb +37 -0
- data/lib/semantic_logger/formatters/json.rb +4 -2
- data/lib/semantic_logger/formatters/raw.rb +2 -2
- data/lib/semantic_logger/formatters/signalfx.rb +4 -3
- data/lib/semantic_logger/levels.rb +38 -0
- data/lib/semantic_logger/log.rb +11 -6
- data/lib/semantic_logger/loggable.rb +1 -1
- data/lib/semantic_logger/logger.rb +43 -1
- data/lib/semantic_logger/processor.rb +10 -130
- data/lib/semantic_logger/reporters/minitest.rb +49 -0
- data/lib/semantic_logger/semantic_logger.rb +40 -75
- data/lib/semantic_logger/version.rb +1 -1
- metadata +9 -81
- data/test/appender/async_batch_test.rb +0 -60
- data/test/appender/async_test.rb +0 -44
- data/test/appender/bugsnag_test.rb +0 -81
- data/test/appender/elasticsearch_http_test.rb +0 -74
- data/test/appender/elasticsearch_test.rb +0 -248
- data/test/appender/file_test.rb +0 -120
- data/test/appender/graylog_test.rb +0 -82
- data/test/appender/honeybadger_test.rb +0 -45
- data/test/appender/http_test.rb +0 -63
- data/test/appender/kafka_test.rb +0 -35
- data/test/appender/mongodb_test.rb +0 -104
- data/test/appender/new_relic_test.rb +0 -80
- data/test/appender/newrelic_rpm.rb +0 -14
- data/test/appender/sentry_test.rb +0 -47
- data/test/appender/splunk_http_test.rb +0 -79
- data/test/appender/splunk_test.rb +0 -83
- data/test/appender/syslog_test.rb +0 -61
- data/test/appender/tcp_test.rb +0 -66
- data/test/appender/udp_test.rb +0 -59
- data/test/appender/wrapper_test.rb +0 -95
- data/test/concerns/compatibility_test.rb +0 -117
- data/test/debug_as_trace_logger_test.rb +0 -81
- data/test/formatters/color_test.rb +0 -153
- data/test/formatters/default_test.rb +0 -175
- data/test/formatters/one_line_test.rb +0 -60
- data/test/formatters/signalfx_test.rb +0 -197
- data/test/formatters_test.rb +0 -36
- data/test/in_memory_appender.rb +0 -8
- data/test/in_memory_appender_helper.rb +0 -43
- data/test/in_memory_batch_appender.rb +0 -8
- data/test/in_memory_metrics_appender.rb +0 -13
- data/test/loggable_test.rb +0 -103
- data/test/logger_test.rb +0 -334
- data/test/measure_test.rb +0 -346
- data/test/metric/new_relic_test.rb +0 -35
- data/test/metric/signalfx_test.rb +0 -77
- data/test/semantic_logger_test.rb +0 -303
- data/test/test_helper.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88a1f36f6ef4d857e13b696e283f6bbd643329a0ca7f3fd9ac4c9ef1e670aaae
|
4
|
+
data.tar.gz: 01a175a96d750f9692bb28512d914434e442336c68eadd9f7b9f409a4d2f4a2b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e06dd57a7ee95bfc5aea5d4b2948101a1fbdb00dd76ac1b9ac0b68a4a3f666670b227d559451d4137e510d1c63b9ec9bd8f99326bfe765f9a610294221c2259f
|
7
|
+
data.tar.gz: 0e2b66a5da5f5e2d21c185555f3502e7982d8d197ec9bade63092acae1750dcf1d8191de71dc8fbe0598d844b2c5f85931c407030a599260f41ad35470802a14
|
data/lib/semantic_logger.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
require 'semantic_logger/core_ext/thread'
|
2
2
|
require 'semantic_logger/version'
|
3
|
-
require 'semantic_logger/semantic_logger'
|
4
3
|
|
5
4
|
# @formatter:off
|
6
5
|
module SemanticLogger
|
7
6
|
autoload :AnsiColors, 'semantic_logger/ansi_colors'
|
8
7
|
autoload :Appender, 'semantic_logger/appender'
|
8
|
+
autoload :Appenders, 'semantic_logger/appenders'
|
9
9
|
autoload :Base, 'semantic_logger/base'
|
10
10
|
autoload :DebugAsTraceLogger, 'semantic_logger/debug_as_trace_logger'
|
11
11
|
autoload :Formatters, 'semantic_logger/formatters'
|
12
|
+
autoload :Levels, 'semantic_logger/levels'
|
12
13
|
autoload :Log, 'semantic_logger/log'
|
13
14
|
autoload :Logger, 'semantic_logger/logger'
|
14
15
|
autoload :Loggable, 'semantic_logger/loggable'
|
@@ -26,12 +27,17 @@ module SemanticLogger
|
|
26
27
|
autoload :Statsd, 'semantic_logger/metric/statsd'
|
27
28
|
end
|
28
29
|
|
30
|
+
module Reporters
|
31
|
+
autoload :Minitest, 'semantic_logger/reporters/minitest'
|
32
|
+
end
|
33
|
+
|
29
34
|
if defined?(JRuby)
|
30
35
|
module JRuby
|
31
36
|
autoload :GarbageCollectionLogger, 'semantic_logger/jruby/garbage_collection_logger'
|
32
37
|
end
|
33
38
|
end
|
34
39
|
end
|
40
|
+
require 'semantic_logger/semantic_logger'
|
35
41
|
# @formatter:on
|
36
42
|
|
37
43
|
# Flush all appenders at exit, waiting for outstanding messages on the queue
|
@@ -14,6 +14,7 @@ module SemanticLogger
|
|
14
14
|
autoload :Http, 'semantic_logger/appender/http'
|
15
15
|
autoload :MongoDB, 'semantic_logger/appender/mongodb'
|
16
16
|
autoload :NewRelic, 'semantic_logger/appender/new_relic'
|
17
|
+
autoload :Rabbitmq, 'semantic_logger/appender/rabbitmq'
|
17
18
|
autoload :Splunk, 'semantic_logger/appender/splunk'
|
18
19
|
autoload :SplunkHttp, 'semantic_logger/appender/splunk_http'
|
19
20
|
autoload :Syslog, 'semantic_logger/appender/syslog'
|
@@ -56,6 +57,8 @@ module SemanticLogger
|
|
56
57
|
elsif async == true
|
57
58
|
proxy_options[:appender] = appender
|
58
59
|
Appender::Async.new(proxy_options)
|
60
|
+
|
61
|
+
|
59
62
|
else
|
60
63
|
appender
|
61
64
|
end
|
@@ -6,8 +6,8 @@ module SemanticLogger
|
|
6
6
|
class Async
|
7
7
|
extend Forwardable
|
8
8
|
|
9
|
-
attr_accessor :
|
10
|
-
attr_reader :queue, :appender
|
9
|
+
attr_accessor :lag_check_interval, :lag_threshold_s
|
10
|
+
attr_reader :queue, :appender, :max_queue_size
|
11
11
|
|
12
12
|
# Forward methods that can be called directly
|
13
13
|
def_delegator :@appender, :name
|
@@ -18,6 +18,7 @@ module SemanticLogger
|
|
18
18
|
def_delegator :@appender, :level
|
19
19
|
def_delegator :@appender, :level=
|
20
20
|
def_delegator :@appender, :logger
|
21
|
+
def_delegator :@appender, :logger=
|
21
22
|
|
22
23
|
# Appender proxy to allow an existing appender to run asynchronously in a separate thread.
|
23
24
|
#
|
@@ -43,17 +44,24 @@ module SemanticLogger
|
|
43
44
|
@lag_check_interval = lag_check_interval
|
44
45
|
@lag_threshold_s = lag_threshold_s
|
45
46
|
@thread = nil
|
46
|
-
|
47
|
-
|
48
|
-
@queue = Queue.new
|
49
|
-
@capped = false
|
50
|
-
else
|
51
|
-
@queue = SizedQueue.new(max_queue_size)
|
52
|
-
@capped = true
|
53
|
-
end
|
47
|
+
@max_queue_size = max_queue_size
|
48
|
+
create_queue
|
54
49
|
thread
|
55
50
|
end
|
56
51
|
|
52
|
+
# Re-open appender after a fork
|
53
|
+
def reopen
|
54
|
+
# Workaround CRuby crash on fork by recreating queue on reopen
|
55
|
+
# https://github.com/rocketjob/semantic_logger/issues/103
|
56
|
+
@queue&.close
|
57
|
+
create_queue
|
58
|
+
|
59
|
+
appender.reopen if appender.respond_to?(:reopen)
|
60
|
+
|
61
|
+
@thread.kill if @thread&.alive?
|
62
|
+
@thread = Thread.new { process }
|
63
|
+
end
|
64
|
+
|
57
65
|
# Returns [true|false] if the queue has a capped size.
|
58
66
|
def capped?
|
59
67
|
@capped
|
@@ -91,6 +99,16 @@ module SemanticLogger
|
|
91
99
|
|
92
100
|
private
|
93
101
|
|
102
|
+
def create_queue
|
103
|
+
if max_queue_size == -1
|
104
|
+
@queue = Queue.new
|
105
|
+
@capped = false
|
106
|
+
else
|
107
|
+
@queue = SizedQueue.new(max_queue_size)
|
108
|
+
@capped = true
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
94
112
|
# Separate thread for batching up log messages before writing.
|
95
113
|
def process
|
96
114
|
# This thread is designed to never go down unless the main thread terminates
|
@@ -140,6 +158,7 @@ module SemanticLogger
|
|
140
158
|
break unless process_message(message)
|
141
159
|
end
|
142
160
|
end
|
161
|
+
logger.trace 'Async: Queue Closed'
|
143
162
|
end
|
144
163
|
|
145
164
|
# Returns false when message processing should be stopped
|
@@ -0,0 +1,120 @@
|
|
1
|
+
begin
|
2
|
+
require 'bunny'
|
3
|
+
rescue LoadError
|
4
|
+
raise 'Gem bunny is required for logging to RabbitMQ. Please add the gem "bunny" to your Gemfile.'
|
5
|
+
end
|
6
|
+
|
7
|
+
# Forward all log messages to RabbitMQ.
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
#
|
11
|
+
# SemanticLogger.add_appender(
|
12
|
+
# appender: :rabbitmq,
|
13
|
+
#
|
14
|
+
# # Name of the queue in RabbitMQ where to publish the logs. This queue will be bound to "amqp.direct" exchange.
|
15
|
+
# queue: 'semantic_logger',
|
16
|
+
#
|
17
|
+
# # This host will be used for RabbitMQ connection.
|
18
|
+
# # NOTE this is different than :host option which is used by the logger directly.
|
19
|
+
# rabbitmq_host: '127.0.0.1',
|
20
|
+
#
|
21
|
+
# # RabbitMQ credentials
|
22
|
+
# username: 'my-username',
|
23
|
+
# password: 'my-secrect-pass',
|
24
|
+
#
|
25
|
+
# # All other options accepted by Bunny.new call
|
26
|
+
# vhost: 'production',
|
27
|
+
# )
|
28
|
+
module SemanticLogger
|
29
|
+
module Appender
|
30
|
+
class Rabbitmq < SemanticLogger::Subscriber
|
31
|
+
# Create RabbitMQ appender using Bunny gem
|
32
|
+
#
|
33
|
+
# Parameters:
|
34
|
+
#
|
35
|
+
# queue_name: [String]
|
36
|
+
# Name of RabbitMQ queue where to stream logs to.
|
37
|
+
# This will be a queue bound to AMQP Default exchange
|
38
|
+
# Default: semantic_logger
|
39
|
+
#
|
40
|
+
# level: [:trace | :debug | :info | :warn | :error | :fatal]
|
41
|
+
# Override the log level for this appender.
|
42
|
+
# Default: SemanticLogger.default_level
|
43
|
+
#
|
44
|
+
# formatter: [Object|Proc|Symbol|Hash]
|
45
|
+
# An instance of a class that implements #call, or a Proc to be used to format
|
46
|
+
# the output from this appender
|
47
|
+
# Default: :json (See: #call)
|
48
|
+
#
|
49
|
+
# filter: [Regexp|Proc]
|
50
|
+
# RegExp: Only include log messages where the class name matches the supplied.
|
51
|
+
# regular expression. All other messages will be ignored.
|
52
|
+
# Proc: Only include log messages where the supplied Proc returns true
|
53
|
+
# The Proc must return true or false.
|
54
|
+
#
|
55
|
+
# host: [String]
|
56
|
+
# Name of this host to appear in log messages.
|
57
|
+
# Default: SemanticLogger.host
|
58
|
+
#
|
59
|
+
# application: [String]
|
60
|
+
# Name of this application to appear in log messages.
|
61
|
+
# Default: SemanticLogger.application
|
62
|
+
#
|
63
|
+
# RabbitMQ Parameters:
|
64
|
+
#
|
65
|
+
# rabbitmq_host: [String]
|
66
|
+
# Host for AMQP connection. in Bunny this is called :host but here it has
|
67
|
+
# been remapped to avoid conflicting with SemanticLogger's :host param.
|
68
|
+
# Default: localhost
|
69
|
+
#
|
70
|
+
# username: [String]
|
71
|
+
# Username for AMQP connection
|
72
|
+
# Default: nil
|
73
|
+
#
|
74
|
+
# password: [String]
|
75
|
+
# Password for AMQP connection
|
76
|
+
# Default: nil
|
77
|
+
#
|
78
|
+
# more parameters supported by Bunny: http://rubybunny.info/articles/connecting.html
|
79
|
+
def initialize(queue_name: 'semantic_logger', rabbitmq_host: nil, metrics: false, **args, &block)
|
80
|
+
@queue_name = queue_name
|
81
|
+
@rabbitmq_args = args.dup
|
82
|
+
@rabbitmq_args[:host] = rabbitmq_host
|
83
|
+
@rabbitmq_args[:logger] = logger
|
84
|
+
|
85
|
+
super(level: level, formatter: formatter, filter: filter, application: application, host: host, metrics: metrics, &block)
|
86
|
+
reopen
|
87
|
+
end
|
88
|
+
|
89
|
+
def reopen
|
90
|
+
@connection = Bunny.new(@rabbitmq_args)
|
91
|
+
@connection.start
|
92
|
+
@channel = @connection.create_channel
|
93
|
+
end
|
94
|
+
|
95
|
+
def close
|
96
|
+
@channel&.close
|
97
|
+
@channel = nil
|
98
|
+
@connection&.close
|
99
|
+
@connection = nil
|
100
|
+
end
|
101
|
+
|
102
|
+
def log(log)
|
103
|
+
queue.publish(formatter.call(log, self))
|
104
|
+
end
|
105
|
+
|
106
|
+
def flush
|
107
|
+
# NOOP
|
108
|
+
end
|
109
|
+
|
110
|
+
# Use JSON Formatter by default.
|
111
|
+
def default_formatter
|
112
|
+
SemanticLogger::Formatters::Json.new
|
113
|
+
end
|
114
|
+
|
115
|
+
def queue
|
116
|
+
@queue ||= @channel.queue(@queue_name)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module SemanticLogger
|
2
|
+
# Manage a collection of appenders.
|
3
|
+
class Appenders < Concurrent::Array
|
4
|
+
attr_accessor :logger
|
5
|
+
|
6
|
+
def initialize(logger = Processor.logger.dup)
|
7
|
+
@logger = logger
|
8
|
+
@logger.name = self.class.name
|
9
|
+
end
|
10
|
+
|
11
|
+
def add(options, deprecated_level = nil, &block)
|
12
|
+
options = options.is_a?(Hash) ? options.dup : convert_old_appender_args(options, deprecated_level)
|
13
|
+
appender = SemanticLogger::Appender.factory(options, &block)
|
14
|
+
self << appender
|
15
|
+
appender
|
16
|
+
end
|
17
|
+
|
18
|
+
def log(log)
|
19
|
+
each do |appender|
|
20
|
+
begin
|
21
|
+
appender.log(log) if appender.should_log?(log)
|
22
|
+
rescue Exception => exc
|
23
|
+
logger.error "Failed to log to appender: #{appender.inspect}", exc
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def flush
|
29
|
+
each do |appender|
|
30
|
+
begin
|
31
|
+
logger.trace "Flushing appender: #{appender.name}"
|
32
|
+
appender.flush
|
33
|
+
rescue Exception => exc
|
34
|
+
logger.error "Failed to flush appender: #{appender.inspect}", exc
|
35
|
+
end
|
36
|
+
end
|
37
|
+
logger.trace 'All appenders flushed'
|
38
|
+
end
|
39
|
+
|
40
|
+
def close
|
41
|
+
each do |appender|
|
42
|
+
begin
|
43
|
+
logger.trace "Closing appender: #{appender.name}"
|
44
|
+
appender.flush
|
45
|
+
appender.close
|
46
|
+
appenders.delete(appender)
|
47
|
+
rescue Exception => exc
|
48
|
+
logger.error "Failed to close appender: #{appender.inspect}", exc
|
49
|
+
end
|
50
|
+
end
|
51
|
+
logger.trace 'All appenders closed and removed from appender list'
|
52
|
+
end
|
53
|
+
|
54
|
+
# After a fork the appender thread is not running, start it if it is not running.
|
55
|
+
def reopen
|
56
|
+
each do |appender|
|
57
|
+
begin
|
58
|
+
next unless appender.respond_to?(:reopen)
|
59
|
+
|
60
|
+
logger.trace "Reopening appender: #{appender.name}"
|
61
|
+
appender.reopen
|
62
|
+
rescue Exception => exc
|
63
|
+
logger.error "Failed to re-open appender: #{appender.inspect}", exc
|
64
|
+
end
|
65
|
+
end
|
66
|
+
logger.trace 'All appenders re-opened'
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
# Backward compatibility
|
72
|
+
def convert_old_appender_args(appender, level)
|
73
|
+
options = {}
|
74
|
+
options[:level] = level if level
|
75
|
+
|
76
|
+
if appender.is_a?(String)
|
77
|
+
options[:file_name] = appender
|
78
|
+
elsif appender.is_a?(IO)
|
79
|
+
options[:io] = appender
|
80
|
+
elsif appender.is_a?(Symbol) || appender.is_a?(Subscriber)
|
81
|
+
options[:appender] = appender
|
82
|
+
else
|
83
|
+
options[:logger] = appender
|
84
|
+
end
|
85
|
+
warn "[DEPRECATED] SemanticLogger.add_appender parameters have changed. Please use: #{options.inspect}"
|
86
|
+
options
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/lib/semantic_logger/base.rb
CHANGED
@@ -23,8 +23,8 @@ module SemanticLogger
|
|
23
23
|
@level_index = nil
|
24
24
|
@level = nil
|
25
25
|
else
|
26
|
-
@level_index =
|
27
|
-
@level =
|
26
|
+
@level_index = Levels.index(level)
|
27
|
+
@level = Levels.level(@level_index)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -112,7 +112,7 @@ module SemanticLogger
|
|
112
112
|
|
113
113
|
# Dynamically supply the log level with every measurement call
|
114
114
|
def measure(level, message, params = {}, &block)
|
115
|
-
index =
|
115
|
+
index = Levels.index(level)
|
116
116
|
if level_index <= index
|
117
117
|
measure_internal(level, index, message, params, &block)
|
118
118
|
elsif block
|
@@ -38,9 +38,9 @@ module SemanticLogger
|
|
38
38
|
|
39
39
|
# :nodoc:
|
40
40
|
def add(severity, message = nil, progname = nil, &block)
|
41
|
-
index =
|
41
|
+
index = Levels.index(severity)
|
42
42
|
if level_index <= index
|
43
|
-
level =
|
43
|
+
level = Levels.level(index)
|
44
44
|
log_internal(level, index, message, progname, &block)
|
45
45
|
true
|
46
46
|
else
|
@@ -9,6 +9,7 @@ module SemanticLogger
|
|
9
9
|
autoload :OneLine, 'semantic_logger/formatters/one_line'
|
10
10
|
autoload :Signalfx, 'semantic_logger/formatters/signalfx'
|
11
11
|
autoload :Syslog, 'semantic_logger/formatters/syslog'
|
12
|
+
autoload :Fluentd, 'semantic_logger/formatters/fluentd'
|
12
13
|
# @formatter:on
|
13
14
|
|
14
15
|
# Return formatter that responds to call.
|
@@ -2,7 +2,7 @@ require 'time'
|
|
2
2
|
module SemanticLogger
|
3
3
|
module Formatters
|
4
4
|
class Base
|
5
|
-
attr_accessor :time_format, :log_host, :log_application
|
5
|
+
attr_accessor :time_format, :log_host, :log_application, :precision
|
6
6
|
|
7
7
|
# Time precision varies by Ruby interpreter
|
8
8
|
# JRuby 9.1.8.0 supports microseconds
|
@@ -17,7 +17,6 @@ module SemanticLogger
|
|
17
17
|
else
|
18
18
|
6
|
19
19
|
end
|
20
|
-
TIME_FORMAT = "%Y-%m-%d %H:%M:%S.%#{PRECISION}N".freeze
|
21
20
|
|
22
21
|
# Parameters
|
23
22
|
# time_format: [String|Symbol|nil]
|
@@ -25,11 +24,32 @@ module SemanticLogger
|
|
25
24
|
# :iso_8601 Outputs an ISO8601 Formatted timestamp.
|
26
25
|
# :ms Output in miliseconds since epoch.
|
27
26
|
# nil: Returns Empty string for time ( no time is output ).
|
28
|
-
# Default: '%Y-%m-%d %H:%M:%S
|
29
|
-
|
30
|
-
|
27
|
+
# Default: '%Y-%m-%d %H:%M:%S.%<precision>N'
|
28
|
+
# log_host: [Boolean]
|
29
|
+
# Whether or not to include hostname in logs
|
30
|
+
# Default: true
|
31
|
+
# log_application: [Boolean]
|
32
|
+
# Whether or not to include application name in logs
|
33
|
+
# Default: true
|
34
|
+
# precision: [Integer]
|
35
|
+
# How many fractional digits to log times with.
|
36
|
+
# Default: PRECISION (6, except on older JRuby, where 3)
|
37
|
+
def initialize(time_format: nil, log_host: true, log_application: true,
|
38
|
+
precision: PRECISION)
|
39
|
+
@time_format = time_format || self.class.build_time_format(precision)
|
31
40
|
@log_host = log_host
|
32
41
|
@log_application = log_application
|
42
|
+
@precision = precision
|
43
|
+
end
|
44
|
+
|
45
|
+
# Return default time format string
|
46
|
+
#
|
47
|
+
# Parameters
|
48
|
+
# precision: [Integer]
|
49
|
+
# How many fractional digits to log times with.
|
50
|
+
# Default: PRECISION (6, except on older JRuby, where 3)
|
51
|
+
def self.build_time_format(precision=PRECISION)
|
52
|
+
"%Y-%m-%d %H:%M:%S.%#{precision}N"
|
33
53
|
end
|
34
54
|
|
35
55
|
# Date & time
|
@@ -42,8 +62,10 @@ module SemanticLogger
|
|
42
62
|
# Return the Time as a formatted string
|
43
63
|
def format_time(time)
|
44
64
|
case time_format
|
65
|
+
when :rfc_3339
|
66
|
+
time.utc.to_datetime.rfc3339
|
45
67
|
when :iso_8601
|
46
|
-
time.utc.iso8601(
|
68
|
+
time.utc.iso8601(precision)
|
47
69
|
when :ms
|
48
70
|
(time.to_f * 1_000).to_i
|
49
71
|
when :none
|