legion-logging 1.5.6 → 1.5.19
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/CHANGELOG.md +84 -0
- data/CLAUDE.md +18 -10
- data/README.md +44 -10
- data/lib/legion/logging/async_writer.rb +125 -36
- data/lib/legion/logging/builder.rb +65 -37
- data/lib/legion/logging/event_builder.rb +9 -6
- data/lib/legion/logging/helper.rb +11 -19
- data/lib/legion/logging/method_tracer.rb +13 -2
- data/lib/legion/logging/methods.rb +152 -53
- data/lib/legion/logging/output_logger.rb +60 -0
- data/lib/legion/logging/redactor.rb +3 -2
- data/lib/legion/logging/settings.rb +21 -5
- data/lib/legion/logging/shipper/file_transport.rb +2 -1
- data/lib/legion/logging/shipper/http_transport.rb +4 -2
- data/lib/legion/logging/shipper.rb +118 -69
- data/lib/legion/logging/siem_exporter.rb +1 -1
- data/lib/legion/logging/version.rb +1 -1
- data/lib/legion/logging.rb +31 -30
- metadata +2 -1
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'logger'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Logging
|
|
7
|
+
# Keeps the standard Logger interface used by Sinatra/APM on the async queue.
|
|
8
|
+
class OutputLogger < ::Logger
|
|
9
|
+
attr_accessor :async_writer
|
|
10
|
+
|
|
11
|
+
def add(severity, message = nil, progname = nil)
|
|
12
|
+
writer = @async_writer
|
|
13
|
+
return super unless writer && !writer.current_thread?
|
|
14
|
+
|
|
15
|
+
severity ||= UNKNOWN
|
|
16
|
+
return true if @logdev.nil? || severity < level
|
|
17
|
+
|
|
18
|
+
progname ||= @progname
|
|
19
|
+
if message.nil?
|
|
20
|
+
if block_given?
|
|
21
|
+
message = yield
|
|
22
|
+
else
|
|
23
|
+
message = progname
|
|
24
|
+
progname = @progname
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
enqueue_output(severity: severity, message: message, progname: progname)
|
|
28
|
+
end
|
|
29
|
+
alias log add
|
|
30
|
+
|
|
31
|
+
def <<(message)
|
|
32
|
+
writer = @async_writer
|
|
33
|
+
return super unless writer && !writer.current_thread?
|
|
34
|
+
|
|
35
|
+
enqueue_output(severity: nil, message: message, progname: nil)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def enqueue_output(severity:, message:, progname:) # rubocop:disable Naming/PredicateMethod
|
|
41
|
+
entry = Legion::Logging::AsyncWriter::OutputEntry.new(
|
|
42
|
+
severity: severity,
|
|
43
|
+
message: Legion::Logging::AsyncWriter.snapshot_value(value: message),
|
|
44
|
+
progname: Legion::Logging::AsyncWriter.snapshot_value(value: progname),
|
|
45
|
+
segments: Legion::Logging::AsyncWriter.snapshot_value(value: Thread.current[:legion_log_segments]),
|
|
46
|
+
method_ctx: Legion::Logging::AsyncWriter.snapshot_value(value: Thread.current[:legion_log_method]),
|
|
47
|
+
caller_trace: Legion::Logging::AsyncWriter.snapshot_value(value: Thread.current[:legion_log_caller]),
|
|
48
|
+
conv_id: Legion::Logging::AsyncWriter.snapshot_value(value: Thread.current[:legion_log_conv_id]),
|
|
49
|
+
request_id: Legion::Logging::AsyncWriter.snapshot_value(value: Thread.current[:legion_log_request_id]),
|
|
50
|
+
exchange_id: Legion::Logging::AsyncWriter.snapshot_value(value: Thread.current[:legion_log_exchange_id]),
|
|
51
|
+
chain_id: Legion::Logging::AsyncWriter.snapshot_value(value: Thread.current[:legion_log_chain_id]),
|
|
52
|
+
origin: { timestamp: Time.now.utc, thread: Thread.current.object_id }
|
|
53
|
+
)
|
|
54
|
+
raise ClosedQueueError, 'async logging writer is unavailable' unless @async_writer.alive? && @async_writer.push(entry)
|
|
55
|
+
|
|
56
|
+
true
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -74,6 +74,9 @@ module Legion
|
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
def all_patterns
|
|
77
|
+
return PATTERNS unless defined?(Legion::Settings)
|
|
78
|
+
return PATTERNS unless Legion::Settings.respond_to?(:loaded?) ? Legion::Settings.loaded? : true
|
|
79
|
+
|
|
77
80
|
@all_patterns ||= build_patterns
|
|
78
81
|
end
|
|
79
82
|
|
|
@@ -85,8 +88,6 @@ module Legion
|
|
|
85
88
|
end
|
|
86
89
|
|
|
87
90
|
def custom_patterns
|
|
88
|
-
return {} unless defined?(Legion::Settings)
|
|
89
|
-
|
|
90
91
|
raw = Legion::Settings.dig(:logging, :redactor, :custom_patterns)
|
|
91
92
|
return {} unless raw.is_a?(Hash)
|
|
92
93
|
|
|
@@ -3,15 +3,31 @@
|
|
|
3
3
|
module Legion
|
|
4
4
|
module Logging
|
|
5
5
|
module Settings
|
|
6
|
+
# Log levels forwarded to the transport bus (and in-process Hooks) by
|
|
7
|
+
# default. Preserves historic behavior: only warn/error/fatal logs build a
|
|
8
|
+
# structured event. Override at runtime via logging.transport.log_levels
|
|
9
|
+
# (e.g. add :debug/:info) — see Methods#forwardable_log_levels.
|
|
10
|
+
DEFAULT_FORWARD_LOG_LEVELS = %i[warn error fatal].freeze
|
|
11
|
+
|
|
6
12
|
def self.default
|
|
7
13
|
{
|
|
8
|
-
level:
|
|
9
|
-
trace:
|
|
10
|
-
trace_size:
|
|
11
|
-
extended:
|
|
12
|
-
backtrace_limit:
|
|
14
|
+
level: :info,
|
|
15
|
+
trace: true,
|
|
16
|
+
trace_size: 4,
|
|
17
|
+
extended: true,
|
|
18
|
+
backtrace_limit: nil,
|
|
19
|
+
forward_log_levels: DEFAULT_FORWARD_LOG_LEVELS
|
|
13
20
|
}
|
|
14
21
|
end
|
|
22
|
+
|
|
23
|
+
def self.async_buffer_size
|
|
24
|
+
return 10_000 unless defined?(Legion::Settings) && Legion::Settings.respond_to?(:[])
|
|
25
|
+
return 10_000 unless Legion::Settings.respond_to?(:loaded?) ? Legion::Settings.loaded? : true
|
|
26
|
+
|
|
27
|
+
logging = Legion::Settings[:logging]
|
|
28
|
+
async = logging[:async] if logging.is_a?(Hash)
|
|
29
|
+
async.is_a?(Hash) ? (async[:buffer_size] || 10_000) : 10_000
|
|
30
|
+
end
|
|
15
31
|
end
|
|
16
32
|
end
|
|
17
33
|
end
|
|
@@ -26,7 +26,7 @@ module Legion
|
|
|
26
26
|
end
|
|
27
27
|
true
|
|
28
28
|
rescue StandardError => e
|
|
29
|
-
|
|
29
|
+
Kernel.warn("FileTransport ship failed: #{e.message}")
|
|
30
30
|
false
|
|
31
31
|
end
|
|
32
32
|
|
|
@@ -40,6 +40,7 @@ module Legion
|
|
|
40
40
|
|
|
41
41
|
def settings_path
|
|
42
42
|
return nil unless defined?(Legion::Settings)
|
|
43
|
+
return nil unless Legion::Settings.respond_to?(:loaded?) ? Legion::Settings.loaded? : true
|
|
43
44
|
|
|
44
45
|
Legion::Settings.dig(:logging, :shipper, :file, :path)
|
|
45
46
|
end
|
|
@@ -24,7 +24,7 @@ module Legion
|
|
|
24
24
|
response = post(uri, body)
|
|
25
25
|
response.is_a?(Net::HTTPSuccess)
|
|
26
26
|
rescue StandardError => e
|
|
27
|
-
|
|
27
|
+
Kernel.warn("HttpTransport ship failed: #{e.message}")
|
|
28
28
|
false
|
|
29
29
|
end
|
|
30
30
|
|
|
@@ -36,7 +36,7 @@ module Legion
|
|
|
36
36
|
apply_auth(req, uri)
|
|
37
37
|
|
|
38
38
|
Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https',
|
|
39
|
-
open_timeout: 5, read_timeout: 10) do |http|
|
|
39
|
+
open_timeout: 5, read_timeout: 10, write_timeout: 10) do |http|
|
|
40
40
|
http.request(req, body)
|
|
41
41
|
end
|
|
42
42
|
end
|
|
@@ -67,12 +67,14 @@ module Legion
|
|
|
67
67
|
|
|
68
68
|
def auth_token
|
|
69
69
|
return nil unless defined?(Legion::Settings)
|
|
70
|
+
return nil unless Legion::Settings.respond_to?(:loaded?) ? Legion::Settings.loaded? : true
|
|
70
71
|
|
|
71
72
|
Legion::Settings.dig(:logging, :shipper, :auth_token)
|
|
72
73
|
end
|
|
73
74
|
|
|
74
75
|
def resolve_endpoint
|
|
75
76
|
return nil unless defined?(Legion::Settings)
|
|
77
|
+
return nil unless Legion::Settings.respond_to?(:loaded?) ? Legion::Settings.loaded? : true
|
|
76
78
|
|
|
77
79
|
Legion::Settings.dig(:logging, :shipper, :endpoint)
|
|
78
80
|
end
|
|
@@ -8,134 +8,183 @@ module Legion
|
|
|
8
8
|
module Logging
|
|
9
9
|
module Shipper
|
|
10
10
|
LEVEL_ORDER = %w[debug info warn error fatal].freeze
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
TRANSPORTS = { file: FileTransport, http: HttpTransport }.freeze
|
|
12
|
+
MUTEX = Mutex.new
|
|
13
|
+
WAKE = ConditionVariable.new
|
|
14
|
+
CHANGED = ConditionVariable.new
|
|
15
|
+
private_constant :MUTEX, :WAKE, :CHANGED
|
|
16
|
+
|
|
17
|
+
@buffer = []
|
|
18
|
+
@accepted = 0
|
|
19
|
+
@delivered = 0
|
|
20
|
+
@attempt = 0
|
|
21
|
+
@flush_target = 0
|
|
16
22
|
|
|
17
23
|
class << self
|
|
18
24
|
def ship(event)
|
|
19
25
|
return unless enabled?
|
|
20
26
|
return unless shippable_level?(event[:level] || event['level'])
|
|
27
|
+
return unless TRANSPORTS.key?(transport_type)
|
|
21
28
|
|
|
22
|
-
redacted
|
|
23
|
-
|
|
24
|
-
buffer_event(redacted) if transport
|
|
25
|
-
end
|
|
29
|
+
redacted = Redactor.redact(event)
|
|
30
|
+
raise ClosedQueueError, 'log shipper is stopping' unless start
|
|
26
31
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
batch = @mutex.synchronize do
|
|
30
|
-
return true if @buffer.nil? || @buffer.empty?
|
|
32
|
+
MUTEX.synchronize do
|
|
33
|
+
raise ThreadError, 'log shipper cannot enqueue from its delivery thread' if Thread.current.equal?(@flush_thread)
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
@
|
|
34
|
-
|
|
35
|
+
CHANGED.wait(MUTEX) while !@stopping && @accepted - @delivered >= @capacity
|
|
36
|
+
raise ClosedQueueError, 'log shipper is stopping' if @stopping
|
|
37
|
+
|
|
38
|
+
@buffer << redacted
|
|
39
|
+
@accepted += 1
|
|
40
|
+
@flush_requested = true if @buffer.size >= @batch_size
|
|
41
|
+
WAKE.signal if @flush_requested
|
|
35
42
|
end
|
|
43
|
+
true
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def flush(timeout: 5)
|
|
47
|
+
return true if MUTEX.synchronize { @accepted == @delivered }
|
|
48
|
+
return false unless start
|
|
49
|
+
|
|
50
|
+
deadline = timeout && (::Process.clock_gettime(::Process::CLOCK_MONOTONIC) + timeout)
|
|
51
|
+
MUTEX.synchronize do
|
|
52
|
+
return false if Thread.current.equal?(@flush_thread)
|
|
53
|
+
|
|
54
|
+
target = @accepted
|
|
55
|
+
attempt = @attempt
|
|
56
|
+
@flush_target = [@flush_target, target].max
|
|
57
|
+
@flush_requested = true
|
|
58
|
+
WAKE.signal
|
|
59
|
+
while @delivered < target
|
|
60
|
+
return false if @attempt > attempt && !@last_success
|
|
61
|
+
return false unless @flush_thread&.alive?
|
|
36
62
|
|
|
37
|
-
|
|
38
|
-
|
|
63
|
+
remaining = deadline && (deadline - ::Process.clock_gettime(::Process::CLOCK_MONOTONIC))
|
|
64
|
+
return false if remaining && remaining <= 0
|
|
39
65
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
66
|
+
CHANGED.wait(MUTEX, remaining)
|
|
67
|
+
end
|
|
68
|
+
true
|
|
69
|
+
end
|
|
43
70
|
end
|
|
44
71
|
|
|
45
72
|
def start
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return if @flush_thread&.alive?
|
|
50
|
-
|
|
51
|
-
@
|
|
52
|
-
@
|
|
53
|
-
@
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
sleep interval
|
|
58
|
-
flush
|
|
59
|
-
end
|
|
73
|
+
return false unless enabled?
|
|
74
|
+
|
|
75
|
+
MUTEX.synchronize do
|
|
76
|
+
return !@stopping if @flush_thread&.alive?
|
|
77
|
+
|
|
78
|
+
@capacity = Legion::Settings.dig(:logging, :shipper, :buffer_size) || 10_000
|
|
79
|
+
@batch_size = [batch_size, @capacity].min
|
|
80
|
+
@interval = flush_interval
|
|
81
|
+
unless @capacity.is_a?(Integer) && @capacity.positive? && @batch_size.is_a?(Integer) && @batch_size.positive? &&
|
|
82
|
+
@interval.is_a?(Numeric) && @interval.positive?
|
|
83
|
+
raise ArgumentError, 'shipper buffer_size, batch_size, and flush_interval must be positive'
|
|
60
84
|
end
|
|
85
|
+
|
|
86
|
+
@transport = TRANSPORTS[transport_type]
|
|
87
|
+
return false unless @transport
|
|
88
|
+
|
|
89
|
+
@stopping = false
|
|
90
|
+
@flush_requested = @buffer.size >= @batch_size
|
|
91
|
+
@flush_thread = Thread.new { consume }
|
|
61
92
|
@flush_thread.name = 'legion-log-shipper'
|
|
62
93
|
@flush_thread.abort_on_exception = false
|
|
94
|
+
true
|
|
63
95
|
end
|
|
64
96
|
end
|
|
65
97
|
|
|
66
|
-
def stop
|
|
67
|
-
|
|
68
|
-
thread =
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
98
|
+
def stop(timeout: 5)
|
|
99
|
+
deadline = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) + timeout if timeout
|
|
100
|
+
thread = MUTEX.synchronize do
|
|
101
|
+
@stopping = true
|
|
102
|
+
WAKE.broadcast
|
|
103
|
+
CHANGED.broadcast
|
|
104
|
+
if !@flush_thread&.alive? && @accepted > @delivered
|
|
105
|
+
@flush_thread = Thread.new { consume }
|
|
106
|
+
@flush_thread.name = 'legion-log-shipper'
|
|
107
|
+
@flush_thread.abort_on_exception = false
|
|
108
|
+
end
|
|
109
|
+
@flush_thread
|
|
110
|
+
end
|
|
111
|
+
return MUTEX.synchronize { @accepted == @delivered } unless thread
|
|
112
|
+
return false if Thread.current.equal?(thread)
|
|
113
|
+
|
|
114
|
+
remaining = [deadline - ::Process.clock_gettime(::Process::CLOCK_MONOTONIC), 0].max if deadline
|
|
115
|
+
thread.join(remaining)
|
|
116
|
+
MUTEX.synchronize { !thread.alive? && @accepted == @delivered }
|
|
72
117
|
end
|
|
73
118
|
|
|
74
119
|
def enabled?
|
|
75
120
|
return false unless defined?(Legion::Settings)
|
|
121
|
+
return false unless Legion::Settings.respond_to?(:loaded?) ? Legion::Settings.loaded? : true
|
|
76
122
|
|
|
77
123
|
Legion::Settings.dig(:logging, :shipper, :enabled) == true
|
|
78
124
|
end
|
|
79
125
|
|
|
80
126
|
private
|
|
81
127
|
|
|
82
|
-
def
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
128
|
+
def consume
|
|
129
|
+
loop do
|
|
130
|
+
batch = MUTEX.synchronize do
|
|
131
|
+
WAKE.wait(MUTEX, @interval) unless @flush_requested || @stopping
|
|
132
|
+
@flush_requested = false
|
|
133
|
+
@buffer.shift(@batch_size)
|
|
134
|
+
end
|
|
135
|
+
delivered = batch.empty? || deliver(@transport, batch)
|
|
136
|
+
stopping = MUTEX.synchronize do
|
|
137
|
+
@attempt += 1
|
|
138
|
+
@last_success = delivered
|
|
139
|
+
if delivered
|
|
140
|
+
@delivered += batch.size
|
|
141
|
+
@flush_requested = @buffer.size >= @batch_size || @delivered < @flush_target
|
|
142
|
+
else
|
|
143
|
+
@buffer.prepend(*batch)
|
|
144
|
+
end
|
|
145
|
+
CHANGED.broadcast
|
|
146
|
+
@stopping && (!delivered || @buffer.empty?)
|
|
147
|
+
end
|
|
148
|
+
break if stopping
|
|
149
|
+
end
|
|
150
|
+
ensure
|
|
151
|
+
MUTEX.synchronize do
|
|
152
|
+
@stopping = true
|
|
153
|
+
CHANGED.broadcast
|
|
90
154
|
end
|
|
91
|
-
|
|
92
|
-
flush if full
|
|
93
155
|
end
|
|
94
156
|
|
|
95
157
|
def deliver(transport, batch)
|
|
96
|
-
|
|
97
|
-
transport.ship_batch(batch)
|
|
98
|
-
else
|
|
99
|
-
batch.all? { |event| transport.ship(event) }
|
|
100
|
-
end
|
|
158
|
+
transport.ship_batch(batch)
|
|
101
159
|
rescue StandardError => e
|
|
102
|
-
|
|
160
|
+
Kernel.warn("Shipper deliver failed: #{e.message}")
|
|
103
161
|
false
|
|
104
162
|
end
|
|
105
163
|
|
|
106
164
|
def shippable_level?(level)
|
|
107
165
|
return true if level.nil?
|
|
108
166
|
|
|
109
|
-
|
|
110
|
-
LEVEL_ORDER.index(level.to_s.downcase).to_i >= LEVEL_ORDER.index(min).to_i
|
|
167
|
+
LEVEL_ORDER.index(level.to_s.downcase).to_i >= LEVEL_ORDER.index(minimum_level).to_i
|
|
111
168
|
end
|
|
112
169
|
|
|
113
170
|
def transport_type
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
key = Legion::Settings.dig(:logging, :shipper, :transport)
|
|
171
|
+
key = Legion::Settings.dig(:logging, :shipper, :transport) if defined?(Legion::Settings)
|
|
117
172
|
key ? key.to_sym : :file
|
|
118
173
|
end
|
|
119
174
|
|
|
120
175
|
def batch_size
|
|
121
|
-
return 100 unless defined?(Legion::Settings)
|
|
122
|
-
|
|
123
176
|
Legion::Settings.dig(:logging, :shipper, :batch_size) || 100
|
|
124
177
|
end
|
|
125
178
|
|
|
126
179
|
def flush_interval
|
|
127
|
-
return 5 unless defined?(Legion::Settings)
|
|
128
|
-
|
|
129
180
|
Legion::Settings.dig(:logging, :shipper, :flush_interval) || 5
|
|
130
181
|
end
|
|
131
182
|
|
|
132
183
|
def minimum_level
|
|
133
|
-
return 'warn' unless defined?(Legion::Settings)
|
|
134
|
-
|
|
135
184
|
levels = Legion::Settings.dig(:logging, :shipper, :levels)
|
|
136
185
|
return 'warn' unless levels.is_a?(Array) && !levels.empty?
|
|
137
186
|
|
|
138
|
-
levels.min_by { |
|
|
187
|
+
levels.min_by { |level| LEVEL_ORDER.index(level.to_s) || 99 }.to_s
|
|
139
188
|
end
|
|
140
189
|
end
|
|
141
190
|
end
|
|
@@ -29,7 +29,7 @@ module Legion
|
|
|
29
29
|
req.body = ::JSON.dump({ event: redact_phi(event.to_s), time: Time.now.to_f })
|
|
30
30
|
|
|
31
31
|
Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https',
|
|
32
|
-
open_timeout: 5, read_timeout: 10) do |http|
|
|
32
|
+
open_timeout: 5, read_timeout: 10, write_timeout: 10) do |http|
|
|
33
33
|
http.request(req)
|
|
34
34
|
end
|
|
35
35
|
rescue StandardError => e
|
data/lib/legion/logging.rb
CHANGED
|
@@ -76,36 +76,37 @@ module Legion
|
|
|
76
76
|
Hooks.clear_hooks!
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
-
def setup(level: 'debug', format: :text, async: true, **options)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
format:
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
79
|
+
def setup(level: 'debug', format: :text, async: true, shutdown_timeout: 2, **options)
|
|
80
|
+
with_lifecycle_lock do
|
|
81
|
+
return false if @async_writer && stop_async_writer(timeout: shutdown_timeout) == false
|
|
82
|
+
return false if output(**options) == false
|
|
83
|
+
|
|
84
|
+
log_level(level)
|
|
85
|
+
log_format(format: format, **options)
|
|
86
|
+
@color = options[:color]
|
|
87
|
+
@color = format != :json && (options[:color] || (options[:color].nil? && options[:log_file].nil?))
|
|
88
|
+
@current_settings = {
|
|
89
|
+
level: level,
|
|
90
|
+
format: format.to_sym,
|
|
91
|
+
async: async,
|
|
92
|
+
trace: options.fetch(:trace, true),
|
|
93
|
+
trace_size: options.fetch(:trace_size, 4),
|
|
94
|
+
extended: options.fetch(:extended, true),
|
|
95
|
+
log_file: options[:log_file],
|
|
96
|
+
log_stdout: options[:log_stdout],
|
|
97
|
+
include_pid: options.fetch(:include_pid, false),
|
|
98
|
+
color: @color
|
|
99
|
+
}.freeze
|
|
100
|
+
@configuration_generation = configuration_generation + 1
|
|
101
|
+
Legion::Logging::Redactor.refresh_patterns! if defined?(Legion::Logging::Redactor)
|
|
102
|
+
if async
|
|
103
|
+
start_async_writer(buffer_size: Legion::Logging::Settings.async_buffer_size)
|
|
104
|
+
else
|
|
105
|
+
@async_writer = nil
|
|
106
|
+
@async = false
|
|
107
|
+
log.async_writer = nil
|
|
108
|
+
true
|
|
109
|
+
end
|
|
109
110
|
end
|
|
110
111
|
end
|
|
111
112
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: legion-logging
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.5.
|
|
4
|
+
version: 1.5.19
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
@@ -70,6 +70,7 @@ files:
|
|
|
70
70
|
- lib/legion/logging/method_tracer.rb
|
|
71
71
|
- lib/legion/logging/methods.rb
|
|
72
72
|
- lib/legion/logging/multi_io.rb
|
|
73
|
+
- lib/legion/logging/output_logger.rb
|
|
73
74
|
- lib/legion/logging/redactor.rb
|
|
74
75
|
- lib/legion/logging/settings.rb
|
|
75
76
|
- lib/legion/logging/shipper.rb
|