fluentd 1.17.1-x64-mingw-ucrt → 1.18.0-x64-mingw-ucrt
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 +58 -4
- data/lib/fluent/command/fluentd.rb +7 -1
- data/lib/fluent/config/literal_parser.rb +9 -2
- data/lib/fluent/engine.rb +49 -33
- data/lib/fluent/env.rb +3 -0
- data/lib/fluent/event_router.rb +2 -2
- data/lib/fluent/plugin/filter_parser.rb +27 -51
- data/lib/fluent/plugin/in_http.rb +5 -0
- data/lib/fluent/plugin/in_syslog.rb +4 -0
- data/lib/fluent/plugin/in_tcp.rb +4 -0
- data/lib/fluent/plugin/in_udp.rb +10 -1
- data/lib/fluent/plugin/input.rb +4 -0
- data/lib/fluent/plugin/out_buffer.rb +40 -0
- data/lib/fluent/plugin/output.rb +2 -0
- data/lib/fluent/plugin_helper/cert_option.rb +8 -0
- data/lib/fluent/plugin_helper/event_emitter.rb +12 -0
- data/lib/fluent/plugin_helper/http_server/server.rb +23 -7
- data/lib/fluent/plugin_helper/server.rb +9 -0
- data/lib/fluent/root_agent.rb +114 -19
- data/lib/fluent/source_only_buffer_agent.rb +102 -0
- data/lib/fluent/supervisor.rb +207 -34
- data/lib/fluent/system_config.rb +15 -3
- data/lib/fluent/version.rb +1 -1
- metadata +7 -19
@@ -39,7 +39,8 @@ module Fluent
|
|
39
39
|
scheme = tls_context ? 'https' : 'http'
|
40
40
|
@uri = URI("#{scheme}://#{@addr}:#{@port}").to_s
|
41
41
|
@router = Router.new(default_app)
|
42
|
-
@
|
42
|
+
@server_task = nil
|
43
|
+
Console.logger = Fluent::Log::ConsoleAdapter.wrap(@logger)
|
43
44
|
|
44
45
|
opts = if tls_context
|
45
46
|
{ ssl_context: tls_context }
|
@@ -54,24 +55,35 @@ module Fluent
|
|
54
55
|
end
|
55
56
|
|
56
57
|
def start(notify = nil)
|
58
|
+
Console.logger = Fluent::Log::ConsoleAdapter.wrap(@logger)
|
57
59
|
@logger.debug("Start async HTTP server listening #{@uri}")
|
58
|
-
task = @reactor.run do
|
59
|
-
@server.run
|
60
60
|
|
61
|
+
Async do |task|
|
62
|
+
Console.logger = Fluent::Log::ConsoleAdapter.wrap(@logger)
|
63
|
+
@server_task = task.async do
|
64
|
+
Console.logger = Fluent::Log::ConsoleAdapter.wrap(@logger)
|
65
|
+
@server.run
|
66
|
+
end
|
61
67
|
if notify
|
62
68
|
notify.push(:ready)
|
63
69
|
end
|
70
|
+
|
71
|
+
if async_v2?
|
72
|
+
@server_task_queue = ::Thread::Queue.new
|
73
|
+
@server_task_queue.pop
|
74
|
+
@server_task&.stop
|
75
|
+
end
|
64
76
|
end
|
65
77
|
|
66
|
-
task.stop
|
67
78
|
@logger.debug('Finished HTTP server')
|
68
79
|
end
|
69
80
|
|
70
81
|
def stop
|
71
82
|
@logger.debug('closing HTTP server')
|
72
|
-
|
73
|
-
|
74
|
-
|
83
|
+
if async_v2?
|
84
|
+
@server_task_queue&.push(:stop)
|
85
|
+
else
|
86
|
+
@server_task&.stop
|
75
87
|
end
|
76
88
|
end
|
77
89
|
|
@@ -88,6 +100,10 @@ module Fluent
|
|
88
100
|
@router.mount(name, path, app || block)
|
89
101
|
end
|
90
102
|
end
|
103
|
+
|
104
|
+
private def async_v2?
|
105
|
+
Gem::Version.new(Async::VERSION) >= Gem::Version.new('2.0')
|
106
|
+
end
|
91
107
|
end
|
92
108
|
end
|
93
109
|
end
|
@@ -84,6 +84,8 @@ module Fluent
|
|
84
84
|
socket_options[:linger_timeout] ||= @transport_config&.linger_timeout || 0
|
85
85
|
end
|
86
86
|
|
87
|
+
socket_options[:receive_buffer_size] ||= @transport_config&.receive_buffer_size
|
88
|
+
|
87
89
|
socket_option_validate!(proto, **socket_options)
|
88
90
|
socket_option_setter = ->(sock){ socket_option_set(sock, **socket_options) }
|
89
91
|
|
@@ -136,6 +138,8 @@ module Fluent
|
|
136
138
|
socket_options[:linger_timeout] ||= @transport_config&.linger_timeout || 0
|
137
139
|
end
|
138
140
|
|
141
|
+
socket_options[:receive_buffer_size] ||= @transport_config&.receive_buffer_size
|
142
|
+
|
139
143
|
unless socket
|
140
144
|
socket_option_validate!(proto, **socket_options)
|
141
145
|
socket_option_setter = ->(sock){ socket_option_set(sock, **socket_options) }
|
@@ -247,6 +251,7 @@ module Fluent
|
|
247
251
|
:generate_cert_country, :generate_cert_state, :generate_cert_state,
|
248
252
|
:generate_cert_locality, :generate_cert_common_name,
|
249
253
|
:generate_cert_expiration, :generate_cert_digest,
|
254
|
+
:ensure_fips,
|
250
255
|
]
|
251
256
|
|
252
257
|
def server_create_transport_section_object(opts)
|
@@ -266,6 +271,9 @@ module Fluent
|
|
266
271
|
|
267
272
|
### Socket Params ###
|
268
273
|
|
274
|
+
desc "The max size of socket receive buffer. SO_RCVBUF"
|
275
|
+
config_param :receive_buffer_size, :size, default: nil
|
276
|
+
|
269
277
|
# SO_LINGER 0 to send RST rather than FIN to avoid lots of connections sitting in TIME_WAIT at src.
|
270
278
|
# Set positive value if needing to send FIN on closing on non-Windows.
|
271
279
|
# (On Windows, Fluentd can send FIN with zero `linger_timeout` since Fluentd doesn't set 0 to SO_LINGER on Windows.
|
@@ -287,6 +295,7 @@ module Fluent
|
|
287
295
|
config_param :max_version, :enum, list: Fluent::TLS::SUPPORTED_VERSIONS, default: nil
|
288
296
|
config_param :ciphers, :string, default: Fluent::TLS::CIPHERS_DEFAULT
|
289
297
|
config_param :insecure, :bool, default: false
|
298
|
+
config_param :ensure_fips, :bool, default: false
|
290
299
|
|
291
300
|
# Cert signed by public CA
|
292
301
|
config_param :ca_path, :string, default: nil
|
data/lib/fluent/root_agent.rb
CHANGED
@@ -22,6 +22,7 @@ require 'fluent/label'
|
|
22
22
|
require 'fluent/plugin'
|
23
23
|
require 'fluent/system_config'
|
24
24
|
require 'fluent/time'
|
25
|
+
require 'fluent/source_only_buffer_agent'
|
25
26
|
|
26
27
|
module Fluent
|
27
28
|
#
|
@@ -47,24 +48,57 @@ module Fluent
|
|
47
48
|
class RootAgent < Agent
|
48
49
|
ERROR_LABEL = "@ERROR".freeze # @ERROR is built-in error label
|
49
50
|
|
50
|
-
|
51
|
+
class SourceOnlyMode
|
52
|
+
DISABLED = 0
|
53
|
+
NORMAL = 1
|
54
|
+
ONLY_ZERO_DOWNTIME_RESTART_READY = 2
|
55
|
+
|
56
|
+
def initialize(with_source_only, start_in_parallel)
|
57
|
+
if start_in_parallel
|
58
|
+
@mode = ONLY_ZERO_DOWNTIME_RESTART_READY
|
59
|
+
elsif with_source_only
|
60
|
+
@mode = NORMAL
|
61
|
+
else
|
62
|
+
@mode = DISABLED
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def enabled?
|
67
|
+
@mode != DISABLED
|
68
|
+
end
|
69
|
+
|
70
|
+
def only_zero_downtime_restart_ready?
|
71
|
+
@mode == ONLY_ZERO_DOWNTIME_RESTART_READY
|
72
|
+
end
|
73
|
+
|
74
|
+
def disable!
|
75
|
+
@mode = DISABLED
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def initialize(log:, system_config: SystemConfig.new, start_in_parallel: false)
|
51
80
|
super(log: log)
|
52
81
|
|
53
82
|
@labels = {}
|
54
83
|
@inputs = []
|
55
84
|
@suppress_emit_error_log_interval = 0
|
56
85
|
@next_emit_error_log_time = nil
|
57
|
-
@without_source = false
|
58
|
-
@
|
86
|
+
@without_source = system_config.without_source || false
|
87
|
+
@source_only_mode = SourceOnlyMode.new(system_config.with_source_only, start_in_parallel)
|
88
|
+
@source_only_buffer_agent = nil
|
89
|
+
@enable_input_metrics = system_config.enable_input_metrics || false
|
59
90
|
|
60
91
|
suppress_interval(system_config.emit_error_log_interval) unless system_config.emit_error_log_interval.nil?
|
61
|
-
@without_source = system_config.without_source unless system_config.without_source.nil?
|
62
|
-
@enable_input_metrics = !!system_config.enable_input_metrics
|
63
92
|
end
|
64
93
|
|
65
94
|
attr_reader :inputs
|
66
95
|
attr_reader :labels
|
67
96
|
|
97
|
+
def source_only_router
|
98
|
+
raise "[BUG] 'RootAgent#source_only_router' should not be called when 'with_source_only' is false" unless @source_only_mode.enabled?
|
99
|
+
@source_only_buffer_agent.event_router
|
100
|
+
end
|
101
|
+
|
68
102
|
def configure(conf)
|
69
103
|
used_worker_ids = []
|
70
104
|
available_worker_ids = (0..Fluent::Engine.system_config.workers - 1).to_a
|
@@ -148,6 +182,8 @@ module Fluent
|
|
148
182
|
|
149
183
|
super
|
150
184
|
|
185
|
+
setup_source_only_buffer_agent if @source_only_mode.enabled?
|
186
|
+
|
151
187
|
# initialize <source> elements
|
152
188
|
if @without_source
|
153
189
|
log.info :worker0, "'--without-source' is applied. Ignore <source> sections"
|
@@ -169,16 +205,36 @@ module Fluent
|
|
169
205
|
@error_collector = error_label.event_router
|
170
206
|
end
|
171
207
|
|
172
|
-
def
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
208
|
+
def setup_source_only_buffer_agent(flush: false)
|
209
|
+
@source_only_buffer_agent = SourceOnlyBufferAgent.new(log: log, system_config: Fluent::Engine.system_config)
|
210
|
+
@source_only_buffer_agent.configure(flush: flush)
|
211
|
+
end
|
212
|
+
|
213
|
+
def cleanup_source_only_buffer_agent
|
214
|
+
@source_only_buffer_agent&.cleanup
|
215
|
+
end
|
216
|
+
|
217
|
+
def lifecycle(desc: false, kind_callback: nil, kind_or_agent_list: nil)
|
218
|
+
only_zero_downtime_restart_ready = false
|
219
|
+
|
220
|
+
unless kind_or_agent_list
|
221
|
+
if @source_only_mode.enabled?
|
222
|
+
kind_or_agent_list = [:input, @source_only_buffer_agent]
|
223
|
+
only_zero_downtime_restart_ready = @source_only_mode.only_zero_downtime_restart_ready?
|
224
|
+
elsif @source_only_buffer_agent
|
225
|
+
# source_only_buffer_agent can re-reroute events, so the priority is equal to output_with_router.
|
226
|
+
kind_or_agent_list = [:input, :output_with_router, @source_only_buffer_agent, @labels.values, :filter, :output].flatten
|
227
|
+
else
|
228
|
+
kind_or_agent_list = [:input, :output_with_router, @labels.values, :filter, :output].flatten
|
229
|
+
end
|
230
|
+
|
231
|
+
kind_or_agent_list.reverse! if desc
|
232
|
+
end
|
233
|
+
|
234
|
+
kind_or_agent_list.each do |kind|
|
179
235
|
if kind.respond_to?(:lifecycle)
|
180
|
-
|
181
|
-
|
236
|
+
agent = kind
|
237
|
+
agent.lifecycle(desc: desc) do |plugin, display_kind|
|
182
238
|
yield plugin, display_kind
|
183
239
|
end
|
184
240
|
else
|
@@ -189,6 +245,9 @@ module Fluent
|
|
189
245
|
end
|
190
246
|
display_kind = (kind == :output_with_router ? :output : kind)
|
191
247
|
list.each do |instance|
|
248
|
+
if only_zero_downtime_restart_ready
|
249
|
+
next unless instance.respond_to?(:zero_downtime_restart_ready?) and instance.zero_downtime_restart_ready?
|
250
|
+
end
|
192
251
|
yield instance, display_kind
|
193
252
|
end
|
194
253
|
end
|
@@ -198,8 +257,8 @@ module Fluent
|
|
198
257
|
end
|
199
258
|
end
|
200
259
|
|
201
|
-
def start
|
202
|
-
lifecycle(desc: true) do |i| # instance
|
260
|
+
def start(kind_or_agent_list: nil)
|
261
|
+
lifecycle(desc: true, kind_or_agent_list: kind_or_agent_list) do |i| # instance
|
203
262
|
i.start unless i.started?
|
204
263
|
# Input#start sometimes emits lots of events with in_tail/`read_from_head true` case
|
205
264
|
# and it causes deadlock for small buffer/queue output. To avoid such problem,
|
@@ -231,13 +290,46 @@ module Fluent
|
|
231
290
|
flushing_threads.each{|t| t.join }
|
232
291
|
end
|
233
292
|
|
234
|
-
def
|
293
|
+
def cancel_source_only!
|
294
|
+
unless @source_only_mode.enabled?
|
295
|
+
log.info "do nothing for canceling with-source-only because the current mode is not with-source-only."
|
296
|
+
return
|
297
|
+
end
|
298
|
+
|
299
|
+
log.info "cancel with-source-only mode and start the other plugins"
|
300
|
+
all_plugins = [:input, :output_with_router, @labels.values, :filter, :output].flatten.reverse
|
301
|
+
start(kind_or_agent_list: all_plugins)
|
302
|
+
|
303
|
+
lifecycle_control_list[:input].each(&:event_emitter_cancel_source_only)
|
304
|
+
|
305
|
+
# Want to make sure that the source_only_router finishes all process before
|
306
|
+
# shutting down the agent.
|
307
|
+
# Strictly speaking, it would be necessary to have exclusive lock between
|
308
|
+
# EventRouter and the shutting down process of this agent.
|
309
|
+
# However, adding lock to EventRouter would worsen its performance, and
|
310
|
+
# the entire shutting down process does not care about it either.
|
311
|
+
# So, sleep here just in case.
|
312
|
+
sleep 1
|
313
|
+
|
314
|
+
shutdown(kind_or_agent_list: [@source_only_buffer_agent])
|
315
|
+
@source_only_buffer_agent = nil
|
316
|
+
|
317
|
+
# This agent can stop after flushing its all buffer, but it is not implemented for now.
|
318
|
+
log.info "starts the loading agent for with-source-only"
|
319
|
+
setup_source_only_buffer_agent(flush: true)
|
320
|
+
start(kind_or_agent_list: [@source_only_buffer_agent])
|
321
|
+
|
322
|
+
@source_only_mode.disable!
|
323
|
+
end
|
324
|
+
|
325
|
+
def shutdown(kind_or_agent_list: nil)
|
326
|
+
# Fluentd's shutdown sequence is stop, before_shutdown, shutdown, after_shutdown, close, terminate for plugins
|
235
327
|
# These method callers does `rescue Exception` to call methods of shutdown sequence as far as possible
|
236
328
|
# if plugin methods does something like infinite recursive call, `exit`, unregistering signal handlers or others.
|
237
329
|
# Plugins should be separated and be in sandbox to protect data in each plugins/buffers.
|
238
330
|
|
239
331
|
lifecycle_safe_sequence = ->(method, checker) {
|
240
|
-
lifecycle do |instance, kind|
|
332
|
+
lifecycle(kind_or_agent_list: kind_or_agent_list) do |instance, kind|
|
241
333
|
begin
|
242
334
|
log.debug "calling #{method} on #{kind} plugin", type: Plugin.lookup_type_from_class(instance.class), plugin_id: instance.plugin_id
|
243
335
|
instance.__send__(method) unless instance.__send__(checker)
|
@@ -260,7 +352,7 @@ module Fluent
|
|
260
352
|
operation_threads.each{|t| t.join }
|
261
353
|
operation_threads.clear
|
262
354
|
}
|
263
|
-
lifecycle(kind_callback: callback) do |instance, kind|
|
355
|
+
lifecycle(kind_callback: callback, kind_or_agent_list: kind_or_agent_list) do |instance, kind|
|
264
356
|
t = Thread.new do
|
265
357
|
Thread.current.abort_on_exception = true
|
266
358
|
begin
|
@@ -301,6 +393,8 @@ module Fluent
|
|
301
393
|
lifecycle_unsafe_sequence.call(:close, :closed?)
|
302
394
|
|
303
395
|
lifecycle_safe_sequence.call(:terminate, :terminated?)
|
396
|
+
|
397
|
+
cleanup_source_only_buffer_agent unless kind_or_agent_list
|
304
398
|
end
|
305
399
|
|
306
400
|
def suppress_interval(interval_time)
|
@@ -318,6 +412,7 @@ module Fluent
|
|
318
412
|
# See also 'fluentd/plugin/input.rb'
|
319
413
|
input.context_router = @event_router
|
320
414
|
input.configure(conf)
|
415
|
+
input.event_emitter_apply_source_only if @source_only_mode.enabled?
|
321
416
|
if @enable_input_metrics
|
322
417
|
@event_router.add_metric_callbacks(input.plugin_id, Proc.new {|es| input.metric_callback(es) })
|
323
418
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'fluent/agent'
|
18
|
+
require 'fluent/system_config'
|
19
|
+
|
20
|
+
module Fluent
|
21
|
+
class SourceOnlyBufferAgent < Agent
|
22
|
+
# Use INSTANCE_ID to use the same base dir as the other workers.
|
23
|
+
# This will make recovery easier.
|
24
|
+
BUFFER_DIR_NAME = Fluent::INSTANCE_ID
|
25
|
+
|
26
|
+
def initialize(log:, system_config:)
|
27
|
+
super(log: log)
|
28
|
+
|
29
|
+
@default_buffer_path = File.join(system_config.root_dir || DEFAULT_BACKUP_DIR, 'source-only-buffer', BUFFER_DIR_NAME)
|
30
|
+
@optional_buffer_config = system_config.source_only_buffer.to_h.transform_keys(&:to_s)
|
31
|
+
@base_buffer_dir = nil
|
32
|
+
@actual_buffer_dir = nil
|
33
|
+
end
|
34
|
+
|
35
|
+
def configure(flush: false)
|
36
|
+
buffer_config = @optional_buffer_config.compact
|
37
|
+
buffer_config['flush_at_shutdown'] = flush ? 'true' : 'false'
|
38
|
+
buffer_config['flush_thread_count'] = 0 unless flush
|
39
|
+
buffer_config['path'] ||= @default_buffer_path
|
40
|
+
|
41
|
+
super(
|
42
|
+
Config::Element.new('SOURCE_ONLY_BUFFER', '', {}, [
|
43
|
+
Config::Element.new('match', '**', {'@type' => 'buffer', '@label' => '@ROOT'}, [
|
44
|
+
Config::Element.new('buffer', '', buffer_config, [])
|
45
|
+
])
|
46
|
+
])
|
47
|
+
)
|
48
|
+
|
49
|
+
@base_buffer_dir = buffer_config['path']
|
50
|
+
# It can be "#{@base_buffer_dir}/worker#{fluentd_worker_id}/" when using multiple workers
|
51
|
+
@actual_buffer_dir = File.dirname(outputs[0].buffer.path)
|
52
|
+
|
53
|
+
unless flush
|
54
|
+
log.info "with-source-only: the emitted data will be stored in the buffer files under" +
|
55
|
+
" #{@base_buffer_dir}. You can send SIGWINCH to the supervisor process to cancel" +
|
56
|
+
" with-source-only mode and process data."
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def cleanup
|
61
|
+
unless (Dir.empty?(@actual_buffer_dir) rescue true)
|
62
|
+
log.warn "some buffer files remain in #{@base_buffer_dir}." +
|
63
|
+
" Please consider recovering or saving the buffer files in the directory." +
|
64
|
+
" To recover them, you can set the buffer path manually to system config and" +
|
65
|
+
" retry, i.e., restart Fluentd with with-source-only mode and send SIGWINCH again." +
|
66
|
+
" Config Example:\n#{config_example_to_recover(@base_buffer_dir)}"
|
67
|
+
return
|
68
|
+
end
|
69
|
+
|
70
|
+
begin
|
71
|
+
FileUtils.remove_dir(@base_buffer_dir)
|
72
|
+
rescue Errno::ENOENT
|
73
|
+
# This worker doesn't need to do anything. Another worker may remove the dir first.
|
74
|
+
rescue => e
|
75
|
+
log.warn "failed to remove the buffer directory: #{@base_buffer_dir}", error: e
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def emit_error_event(tag, time, record, error)
|
80
|
+
error_info = {error: error, location: (error.backtrace ? error.backtrace.first : nil), tag: tag, time: time, record: record}
|
81
|
+
log.warn "SourceOnlyBufferAgent: dump an error event:", error_info
|
82
|
+
end
|
83
|
+
|
84
|
+
def handle_emits_error(tag, es, error)
|
85
|
+
error_info = {error: error, location: (error.backtrace ? error.backtrace.first : nil), tag: tag}
|
86
|
+
log.warn "SourceOnlyBufferAgent: emit transaction failed:", error_info
|
87
|
+
log.warn_backtrace
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def config_example_to_recover(path)
|
93
|
+
<<~EOC
|
94
|
+
<system>
|
95
|
+
<source_only_buffer>
|
96
|
+
path #{path}
|
97
|
+
</source_only_buffer>
|
98
|
+
</system>
|
99
|
+
EOC
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|