fluentd 0.12.43 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fluentd might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE.md +6 -0
- data/.gitignore +2 -0
- data/.travis.yml +33 -21
- data/CONTRIBUTING.md +1 -0
- data/ChangeLog +1239 -0
- data/README.md +0 -25
- data/Rakefile +2 -1
- data/Vagrantfile +17 -0
- data/appveyor.yml +35 -0
- data/example/filter_stdout.conf +5 -5
- data/example/in_forward.conf +2 -2
- data/example/in_http.conf +2 -2
- data/example/in_out_forward.conf +17 -0
- data/example/in_syslog.conf +2 -2
- data/example/in_tail.conf +2 -2
- data/example/in_tcp.conf +2 -2
- data/example/in_udp.conf +2 -2
- data/example/out_copy.conf +4 -4
- data/example/out_file.conf +2 -2
- data/example/out_forward.conf +2 -2
- data/example/out_forward_buf_file.conf +23 -0
- data/example/v0_12_filter.conf +8 -8
- data/fluent.conf +29 -0
- data/fluentd.gemspec +18 -11
- data/lib/fluent/agent.rb +60 -58
- data/lib/fluent/command/cat.rb +1 -1
- data/lib/fluent/command/debug.rb +7 -5
- data/lib/fluent/command/fluentd.rb +97 -2
- data/lib/fluent/compat/call_super_mixin.rb +67 -0
- data/lib/fluent/compat/filter.rb +50 -0
- data/lib/fluent/compat/formatter.rb +109 -0
- data/lib/fluent/compat/input.rb +50 -0
- data/lib/fluent/compat/output.rb +617 -0
- data/lib/fluent/compat/output_chain.rb +60 -0
- data/lib/fluent/compat/parser.rb +163 -0
- data/lib/fluent/compat/propagate_default.rb +62 -0
- data/lib/fluent/config.rb +23 -20
- data/lib/fluent/config/configure_proxy.rb +119 -70
- data/lib/fluent/config/dsl.rb +5 -18
- data/lib/fluent/config/element.rb +72 -8
- data/lib/fluent/config/error.rb +0 -3
- data/lib/fluent/config/literal_parser.rb +0 -2
- data/lib/fluent/config/parser.rb +4 -4
- data/lib/fluent/config/section.rb +39 -28
- data/lib/fluent/config/types.rb +2 -13
- data/lib/fluent/config/v1_parser.rb +1 -3
- data/lib/fluent/configurable.rb +48 -16
- data/lib/fluent/daemon.rb +15 -0
- data/lib/fluent/engine.rb +26 -52
- data/lib/fluent/env.rb +6 -4
- data/lib/fluent/event.rb +58 -11
- data/lib/fluent/event_router.rb +5 -5
- data/lib/fluent/filter.rb +2 -50
- data/lib/fluent/formatter.rb +4 -293
- data/lib/fluent/input.rb +2 -32
- data/lib/fluent/label.rb +2 -2
- data/lib/fluent/load.rb +3 -2
- data/lib/fluent/log.rb +107 -38
- data/lib/fluent/match.rb +0 -36
- data/lib/fluent/mixin.rb +117 -7
- data/lib/fluent/msgpack_factory.rb +62 -0
- data/lib/fluent/output.rb +7 -612
- data/lib/fluent/output_chain.rb +23 -0
- data/lib/fluent/parser.rb +4 -800
- data/lib/fluent/plugin.rb +100 -121
- data/lib/fluent/plugin/bare_output.rb +63 -0
- data/lib/fluent/plugin/base.rb +121 -0
- data/lib/fluent/plugin/buf_file.rb +101 -182
- data/lib/fluent/plugin/buf_memory.rb +9 -92
- data/lib/fluent/plugin/buffer.rb +473 -0
- data/lib/fluent/plugin/buffer/chunk.rb +135 -0
- data/lib/fluent/plugin/buffer/file_chunk.rb +339 -0
- data/lib/fluent/plugin/buffer/memory_chunk.rb +100 -0
- data/lib/fluent/plugin/exec_util.rb +80 -75
- data/lib/fluent/plugin/file_util.rb +33 -28
- data/lib/fluent/plugin/file_wrapper.rb +120 -0
- data/lib/fluent/plugin/filter.rb +51 -0
- data/lib/fluent/plugin/filter_grep.rb +13 -40
- data/lib/fluent/plugin/filter_record_transformer.rb +22 -18
- data/lib/fluent/plugin/formatter.rb +93 -0
- data/lib/fluent/plugin/formatter_csv.rb +48 -0
- data/lib/fluent/plugin/formatter_hash.rb +32 -0
- data/lib/fluent/plugin/formatter_json.rb +47 -0
- data/lib/fluent/plugin/formatter_ltsv.rb +42 -0
- data/lib/fluent/plugin/formatter_msgpack.rb +32 -0
- data/lib/fluent/plugin/formatter_out_file.rb +45 -0
- data/lib/fluent/plugin/formatter_single_value.rb +34 -0
- data/lib/fluent/plugin/formatter_stdout.rb +39 -0
- data/lib/fluent/plugin/in_debug_agent.rb +4 -0
- data/lib/fluent/plugin/in_dummy.rb +22 -18
- data/lib/fluent/plugin/in_exec.rb +18 -8
- data/lib/fluent/plugin/in_forward.rb +36 -79
- data/lib/fluent/plugin/in_gc_stat.rb +4 -0
- data/lib/fluent/plugin/in_http.rb +21 -18
- data/lib/fluent/plugin/in_monitor_agent.rb +15 -48
- data/lib/fluent/plugin/in_object_space.rb +6 -1
- data/lib/fluent/plugin/in_stream.rb +7 -3
- data/lib/fluent/plugin/in_syslog.rb +46 -95
- data/lib/fluent/plugin/in_tail.rb +58 -640
- data/lib/fluent/plugin/in_tcp.rb +8 -1
- data/lib/fluent/plugin/in_udp.rb +8 -18
- data/lib/fluent/plugin/input.rb +33 -0
- data/lib/fluent/plugin/multi_output.rb +95 -0
- data/lib/fluent/plugin/out_buffered_null.rb +59 -0
- data/lib/fluent/plugin/out_copy.rb +11 -7
- data/lib/fluent/plugin/out_exec.rb +15 -11
- data/lib/fluent/plugin/out_exec_filter.rb +18 -10
- data/lib/fluent/plugin/out_file.rb +34 -5
- data/lib/fluent/plugin/out_forward.rb +25 -19
- data/lib/fluent/plugin/out_null.rb +0 -14
- data/lib/fluent/plugin/out_roundrobin.rb +11 -7
- data/lib/fluent/plugin/out_stdout.rb +5 -7
- data/lib/fluent/plugin/out_stream.rb +3 -1
- data/lib/fluent/plugin/output.rb +979 -0
- data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
- data/lib/fluent/plugin/parser.rb +244 -0
- data/lib/fluent/plugin/parser_apache.rb +24 -0
- data/lib/fluent/plugin/parser_apache2.rb +84 -0
- data/lib/fluent/plugin/parser_apache_error.rb +21 -0
- data/lib/fluent/plugin/parser_csv.rb +31 -0
- data/lib/fluent/plugin/parser_json.rb +79 -0
- data/lib/fluent/plugin/parser_ltsv.rb +50 -0
- data/lib/fluent/plugin/parser_multiline.rb +102 -0
- data/lib/fluent/plugin/parser_nginx.rb +24 -0
- data/lib/fluent/plugin/parser_none.rb +36 -0
- data/lib/fluent/plugin/parser_syslog.rb +82 -0
- data/lib/fluent/plugin/parser_tsv.rb +37 -0
- data/lib/fluent/plugin/socket_util.rb +119 -117
- data/lib/fluent/plugin/storage.rb +84 -0
- data/lib/fluent/plugin/storage_local.rb +116 -0
- data/lib/fluent/plugin/string_util.rb +16 -13
- data/lib/fluent/plugin_helper.rb +39 -0
- data/lib/fluent/plugin_helper/child_process.rb +298 -0
- data/lib/fluent/plugin_helper/compat_parameters.rb +99 -0
- data/lib/fluent/plugin_helper/event_emitter.rb +80 -0
- data/lib/fluent/plugin_helper/event_loop.rb +118 -0
- data/lib/fluent/plugin_helper/retry_state.rb +177 -0
- data/lib/fluent/plugin_helper/storage.rb +308 -0
- data/lib/fluent/plugin_helper/thread.rb +147 -0
- data/lib/fluent/plugin_helper/timer.rb +85 -0
- data/lib/fluent/plugin_id.rb +63 -0
- data/lib/fluent/process.rb +21 -30
- data/lib/fluent/registry.rb +21 -9
- data/lib/fluent/root_agent.rb +115 -40
- data/lib/fluent/supervisor.rb +330 -320
- data/lib/fluent/system_config.rb +42 -18
- data/lib/fluent/test.rb +6 -1
- data/lib/fluent/test/base.rb +23 -3
- data/lib/fluent/test/driver/base.rb +247 -0
- data/lib/fluent/test/driver/event_feeder.rb +98 -0
- data/lib/fluent/test/driver/filter.rb +35 -0
- data/lib/fluent/test/driver/input.rb +31 -0
- data/lib/fluent/test/driver/output.rb +78 -0
- data/lib/fluent/test/driver/test_event_router.rb +45 -0
- data/lib/fluent/test/filter_test.rb +0 -1
- data/lib/fluent/test/formatter_test.rb +2 -1
- data/lib/fluent/test/input_test.rb +23 -17
- data/lib/fluent/test/output_test.rb +28 -39
- data/lib/fluent/test/parser_test.rb +1 -1
- data/lib/fluent/time.rb +104 -1
- data/lib/fluent/{status.rb → unique_id.rb} +15 -24
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +72 -0
- data/test/compat/test_calls_super.rb +164 -0
- data/test/config/test_config_parser.rb +83 -0
- data/test/config/test_configurable.rb +547 -274
- data/test/config/test_configure_proxy.rb +146 -29
- data/test/config/test_dsl.rb +3 -181
- data/test/config/test_element.rb +274 -0
- data/test/config/test_literal_parser.rb +1 -1
- data/test/config/test_section.rb +79 -7
- data/test/config/test_system_config.rb +21 -0
- data/test/config/test_types.rb +3 -26
- data/test/helper.rb +78 -8
- data/test/plugin/test_bare_output.rb +118 -0
- data/test/plugin/test_base.rb +75 -0
- data/test/plugin/test_buf_file.rb +420 -521
- data/test/plugin/test_buf_memory.rb +32 -194
- data/test/plugin/test_buffer.rb +981 -0
- data/test/plugin/test_buffer_chunk.rb +110 -0
- data/test/plugin/test_buffer_file_chunk.rb +770 -0
- data/test/plugin/test_buffer_memory_chunk.rb +265 -0
- data/test/plugin/test_filter.rb +255 -0
- data/test/plugin/test_filter_grep.rb +2 -73
- data/test/plugin/test_filter_record_transformer.rb +24 -68
- data/test/plugin/test_filter_stdout.rb +6 -6
- data/test/plugin/test_in_debug_agent.rb +2 -0
- data/test/plugin/test_in_dummy.rb +11 -17
- data/test/plugin/test_in_exec.rb +6 -25
- data/test/plugin/test_in_forward.rb +112 -151
- data/test/plugin/test_in_gc_stat.rb +2 -0
- data/test/plugin/test_in_http.rb +106 -157
- data/test/plugin/test_in_object_space.rb +21 -5
- data/test/plugin/test_in_stream.rb +14 -13
- data/test/plugin/test_in_syslog.rb +30 -275
- data/test/plugin/test_in_tail.rb +95 -282
- data/test/plugin/test_in_tcp.rb +14 -0
- data/test/plugin/test_in_udp.rb +21 -67
- data/test/plugin/test_input.rb +122 -0
- data/test/plugin/test_multi_output.rb +180 -0
- data/test/plugin/test_out_buffered_null.rb +79 -0
- data/test/plugin/test_out_copy.rb +15 -2
- data/test/plugin/test_out_exec.rb +75 -25
- data/test/plugin/test_out_exec_filter.rb +74 -8
- data/test/plugin/test_out_file.rb +61 -7
- data/test/plugin/test_out_forward.rb +92 -15
- data/test/plugin/test_out_roundrobin.rb +1 -0
- data/test/plugin/test_out_stdout.rb +22 -13
- data/test/plugin/test_out_stream.rb +18 -0
- data/test/plugin/test_output.rb +515 -0
- data/test/plugin/test_output_as_buffered.rb +1540 -0
- data/test/plugin/test_output_as_buffered_overflow.rb +247 -0
- data/test/plugin/test_output_as_buffered_retries.rb +808 -0
- data/test/plugin/test_output_as_buffered_secondary.rb +776 -0
- data/test/plugin/test_output_as_standard.rb +362 -0
- data/test/plugin/test_owned_by.rb +35 -0
- data/test/plugin/test_storage.rb +167 -0
- data/test/plugin/test_storage_local.rb +8 -0
- data/test/plugin_helper/test_child_process.rb +599 -0
- data/test/plugin_helper/test_compat_parameters.rb +175 -0
- data/test/plugin_helper/test_event_emitter.rb +51 -0
- data/test/plugin_helper/test_event_loop.rb +52 -0
- data/test/plugin_helper/test_retry_state.rb +399 -0
- data/test/plugin_helper/test_storage.rb +411 -0
- data/test/plugin_helper/test_thread.rb +164 -0
- data/test/plugin_helper/test_timer.rb +100 -0
- data/test/scripts/exec_script.rb +0 -6
- data/test/scripts/fluent/plugin/out_test.rb +3 -0
- data/test/test_config.rb +13 -4
- data/test/test_event.rb +24 -13
- data/test/test_event_router.rb +8 -7
- data/test/test_event_time.rb +187 -0
- data/test/test_formatter.rb +13 -51
- data/test/test_input.rb +1 -1
- data/test/test_log.rb +239 -16
- data/test/test_mixin.rb +1 -1
- data/test/test_output.rb +53 -66
- data/test/test_parser.rb +105 -323
- data/test/test_plugin_helper.rb +81 -0
- data/test/test_root_agent.rb +4 -52
- data/test/test_supervisor.rb +272 -0
- data/test/test_unique_id.rb +47 -0
- metadata +181 -55
- data/CHANGELOG.md +0 -710
- data/lib/fluent/buffer.rb +0 -365
- data/lib/fluent/plugin/filter_parser.rb +0 -107
- data/lib/fluent/plugin/in_status.rb +0 -76
- data/lib/fluent/test/helpers.rb +0 -86
- data/test/plugin/data/log/foo/bar2 +0 -0
- data/test/plugin/test_filter_parser.rb +0 -744
- data/test/plugin/test_in_status.rb +0 -38
- data/test/test_buffer.rb +0 -624
@@ -0,0 +1,85 @@
|
|
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/plugin_helper/event_loop'
|
18
|
+
|
19
|
+
module Fluent
|
20
|
+
module PluginHelper
|
21
|
+
module Timer
|
22
|
+
include Fluent::PluginHelper::EventLoop
|
23
|
+
|
24
|
+
# stop : turn checker into false (callbacks not called anymore)
|
25
|
+
# shutdown : [-]
|
26
|
+
# close : [-]
|
27
|
+
# terminate: [-]
|
28
|
+
|
29
|
+
attr_reader :_timers # for tests
|
30
|
+
|
31
|
+
# interval: integer/float, repeat: true/false
|
32
|
+
def timer_execute(title, interval, repeat: true, &block)
|
33
|
+
raise ArgumentError, "BUG: title must be a symbol" unless title.is_a? Symbol
|
34
|
+
raise ArgumentError, "BUG: block not specified for callback" unless block_given?
|
35
|
+
checker = ->(){ @_timer_running }
|
36
|
+
timer = TimerWatcher.new(title, interval, repeat, log, checker, &block)
|
37
|
+
@_timers << title
|
38
|
+
event_loop_attach(timer)
|
39
|
+
end
|
40
|
+
|
41
|
+
def timer_running?
|
42
|
+
defined?(@_timer_running) && @_timer_running
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize
|
46
|
+
super
|
47
|
+
@_timers = []
|
48
|
+
end
|
49
|
+
|
50
|
+
def start
|
51
|
+
super
|
52
|
+
@_timer_running = true
|
53
|
+
end
|
54
|
+
|
55
|
+
def stop
|
56
|
+
super
|
57
|
+
@_timer_running = false
|
58
|
+
end
|
59
|
+
|
60
|
+
def terminate
|
61
|
+
super
|
62
|
+
@_timers = []
|
63
|
+
end
|
64
|
+
|
65
|
+
class TimerWatcher < Coolio::TimerWatcher
|
66
|
+
def initialize(title, interval, repeat, log, checker, &callback)
|
67
|
+
@title = title
|
68
|
+
@callback = callback
|
69
|
+
@log = log
|
70
|
+
@checker = checker
|
71
|
+
super(interval, repeat)
|
72
|
+
end
|
73
|
+
|
74
|
+
def on_timer
|
75
|
+
@callback.call if @checker.call
|
76
|
+
rescue => e
|
77
|
+
@log.error "Unexpected error raised. Stopping the timer.", title: @title, error: e
|
78
|
+
@log.error_backtrace
|
79
|
+
self.detach
|
80
|
+
@log.error "Timer detached.", title: @title
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#
|
2
|
+
# Fluent
|
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 'set'
|
18
|
+
|
19
|
+
module Fluent
|
20
|
+
module PluginId
|
21
|
+
@@configured_ids = Set.new
|
22
|
+
|
23
|
+
def configure(conf)
|
24
|
+
@id = conf['@id']
|
25
|
+
@_id_configured = !!@id # plugin id is explicitly configured by users (or not)
|
26
|
+
if @id
|
27
|
+
@id = @id.to_s
|
28
|
+
if @@configured_ids.include?(@id) && !plugin_id_for_test?
|
29
|
+
raise Fluent::ConfigError, "Duplicated plugin id `#{@id}`. Check whole configuration and fix it."
|
30
|
+
end
|
31
|
+
@@configured_ids.add(@id)
|
32
|
+
end
|
33
|
+
|
34
|
+
super
|
35
|
+
end
|
36
|
+
|
37
|
+
def plugin_id_for_test?
|
38
|
+
caller_locations.each do |location|
|
39
|
+
# Thread::Backtrace::Location#path returns base filename or absolute path.
|
40
|
+
# #absolute_path returns absolute_path always.
|
41
|
+
# https://bugs.ruby-lang.org/issues/12159
|
42
|
+
if location.absolute_path =~ /\/test_[^\/]+\.rb$/ # location.path =~ /test_.+\.rb$/
|
43
|
+
return true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
false
|
47
|
+
end
|
48
|
+
|
49
|
+
def plugin_id_configured?
|
50
|
+
if instance_variable_defined?("@_id_configured")
|
51
|
+
@_id_configured
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def plugin_id
|
56
|
+
if instance_variable_defined?("@id")
|
57
|
+
@id || "object:#{object_id.to_s(16)}"
|
58
|
+
else
|
59
|
+
"object:#{object_id.to_s(16)}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/fluent/process.rb
CHANGED
@@ -40,23 +40,23 @@ module Fluent
|
|
40
40
|
@parent_uri = DRb.uri
|
41
41
|
end
|
42
42
|
|
43
|
-
def fork(
|
43
|
+
def fork(delegate_object)
|
44
44
|
ipr, ipw = IO.pipe # child Engine.emit_stream -> parent Engine.emit_stream
|
45
|
-
opr, opw = IO.pipe # parent target.
|
45
|
+
opr, opw = IO.pipe # parent target.emit_events -> child target.emit_events
|
46
46
|
|
47
47
|
pid = Process.fork
|
48
48
|
if pid
|
49
49
|
# parent process
|
50
50
|
ipw.close
|
51
51
|
opr.close
|
52
|
-
forward_thread = process_parent(ipr, opw, pid,
|
52
|
+
forward_thread = process_parent(ipr, opw, pid, delegate_object)
|
53
53
|
return pid, forward_thread
|
54
54
|
end
|
55
55
|
|
56
56
|
# child process
|
57
57
|
ipr.close
|
58
58
|
opw.close
|
59
|
-
forward_thread = process_child(ipw, opr,
|
59
|
+
forward_thread = process_child(ipw, opr, delegate_object)
|
60
60
|
return nil, forward_thread
|
61
61
|
end
|
62
62
|
|
@@ -77,14 +77,14 @@ module Fluent
|
|
77
77
|
end
|
78
78
|
|
79
79
|
private
|
80
|
-
def process_child(ipw, opr,
|
80
|
+
def process_child(ipw, opr, delegate_object)
|
81
81
|
DRb.start_service(create_drb_uri, delegate_object)
|
82
82
|
child_uri = DRb.uri
|
83
83
|
|
84
84
|
send_header(ipw, child_uri)
|
85
85
|
|
86
86
|
# override target.emit_stream to write event stream to the pipe
|
87
|
-
fwd = new_forwarder(ipw,
|
87
|
+
fwd = new_forwarder(ipw, 0.5) # TODO interval
|
88
88
|
Engine.define_singleton_method(:emit_stream) do |tag,es|
|
89
89
|
fwd.emit(tag, es)
|
90
90
|
end
|
@@ -115,8 +115,8 @@ module Fluent
|
|
115
115
|
]
|
116
116
|
end
|
117
117
|
|
118
|
-
def process_parent(ipr, opw, pid,
|
119
|
-
child_uri = read_header(ipr)
|
118
|
+
def process_parent(ipr, opw, pid, delegate_object)
|
119
|
+
# child_uri = read_header(ipr)
|
120
120
|
|
121
121
|
# read event stream from the pipe and forward to Engine.emit_stream
|
122
122
|
forward_thread = Thread.new(ipr, pid, &method(:input_forward_main))
|
@@ -127,7 +127,7 @@ module Fluent
|
|
127
127
|
|
128
128
|
# return forwarder for DetachProcessMixin to
|
129
129
|
# override target.emit and write event stream to the pipe
|
130
|
-
fwd = new_forwarder(opw,
|
130
|
+
fwd = new_forwarder(opw, 0.5) # TODO interval
|
131
131
|
# note: override emit method on DetachProcessMixin
|
132
132
|
forward_thread.define_singleton_method(:forwarder) do
|
133
133
|
fwd
|
@@ -153,7 +153,7 @@ module Fluent
|
|
153
153
|
read_event_stream(opr) {|tag,es|
|
154
154
|
# FIXME error handling
|
155
155
|
begin
|
156
|
-
target.
|
156
|
+
target.emit_events(tag, es)
|
157
157
|
rescue
|
158
158
|
$log.warn "failed to emit", error: $!.to_s, pid: Process.pid
|
159
159
|
$log.warn_backtrace
|
@@ -300,11 +300,11 @@ module Fluent
|
|
300
300
|
|
301
301
|
private
|
302
302
|
|
303
|
-
def detach_process_impl(num,
|
303
|
+
def detach_process_impl(num, &block)
|
304
304
|
children = []
|
305
305
|
|
306
306
|
num.times do |i|
|
307
|
-
pid, forward_thread = DetachProcessManager.instance.fork(
|
307
|
+
pid, forward_thread = DetachProcessManager.instance.fork(self)
|
308
308
|
|
309
309
|
if pid
|
310
310
|
# parent process
|
@@ -365,7 +365,7 @@ module Fluent
|
|
365
365
|
}
|
366
366
|
end
|
367
367
|
|
368
|
-
# override target.
|
368
|
+
# override target.emit_events and write event stream to the pipe
|
369
369
|
forwarders = children.map {|pair| pair[1].forwarder }
|
370
370
|
if forwarders.length > 1
|
371
371
|
# use roundrobin
|
@@ -373,9 +373,8 @@ module Fluent
|
|
373
373
|
else
|
374
374
|
fwd = forwarders[0]
|
375
375
|
end
|
376
|
-
define_singleton_method(:
|
377
|
-
|
378
|
-
fwd.emit(tag, es)
|
376
|
+
define_singleton_method(:emit_events) do |tag,es|
|
377
|
+
fwd.emit_events(tag, es)
|
379
378
|
end
|
380
379
|
end
|
381
380
|
|
@@ -418,6 +417,8 @@ module Fluent
|
|
418
417
|
def configure(conf)
|
419
418
|
super
|
420
419
|
|
420
|
+
@detach_process = nil
|
421
|
+
|
421
422
|
if detach_process = conf['detach_process']
|
422
423
|
b3v = Config.bool_value(detach_process)
|
423
424
|
case b3v
|
@@ -438,17 +439,11 @@ module Fluent
|
|
438
439
|
@detach_process = false
|
439
440
|
end
|
440
441
|
end
|
441
|
-
|
442
|
-
if forward_interval = conf['detach_process_forward_interval']
|
443
|
-
@forward_interval = Config.time_value(forward_interval)
|
444
|
-
else
|
445
|
-
@forward_interval = 0.5
|
446
|
-
end
|
447
442
|
end
|
448
443
|
|
449
444
|
def detach_process(&block)
|
450
445
|
if @detach_process
|
451
|
-
detach_process_impl(1,
|
446
|
+
detach_process_impl(1, &block)
|
452
447
|
else
|
453
448
|
block.call
|
454
449
|
end
|
@@ -467,6 +462,8 @@ module Fluent
|
|
467
462
|
def configure(conf)
|
468
463
|
super
|
469
464
|
|
465
|
+
@detach_process = nil
|
466
|
+
|
470
467
|
if detach_process = conf['detach_process']
|
471
468
|
b3v = Config.bool_value(detach_process)
|
472
469
|
case b3v
|
@@ -486,19 +483,13 @@ module Fluent
|
|
486
483
|
@detach_process = false
|
487
484
|
end
|
488
485
|
end
|
489
|
-
|
490
|
-
if forward_interval = conf['detach_process_forward_interval']
|
491
|
-
@forward_interval = Config.time_value(forward_interval)
|
492
|
-
else
|
493
|
-
@forward_interval = 0.5
|
494
|
-
end
|
495
486
|
end
|
496
487
|
|
497
488
|
private
|
498
489
|
|
499
490
|
def detach_multi_process(&block)
|
500
491
|
if @detach_process
|
501
|
-
detach_process_impl(@detach_process_num,
|
492
|
+
detach_process_impl(@detach_process_num, &block)
|
502
493
|
else
|
503
494
|
block.call
|
504
495
|
end
|
data/lib/fluent/registry.rb
CHANGED
@@ -18,13 +18,16 @@ require 'fluent/config/error'
|
|
18
18
|
|
19
19
|
module Fluent
|
20
20
|
class Registry
|
21
|
+
DEFAULT_PLUGIN_PATH = File.expand_path('plugin', __FILE__)
|
22
|
+
|
21
23
|
def initialize(kind, search_prefix)
|
22
24
|
@kind = kind
|
23
25
|
@search_prefix = search_prefix
|
24
26
|
@map = {}
|
27
|
+
@paths = [DEFAULT_PLUGIN_PATH]
|
25
28
|
end
|
26
29
|
|
27
|
-
attr_reader :kind
|
30
|
+
attr_reader :kind, :paths
|
28
31
|
|
29
32
|
def register(type, value)
|
30
33
|
type = type.to_sym
|
@@ -43,18 +46,27 @@ module Fluent
|
|
43
46
|
raise ConfigError, "Unknown #{@kind} plugin '#{type}'. Run 'gem search -rd fluent-plugin' to find plugins" # TODO error class
|
44
47
|
end
|
45
48
|
|
49
|
+
def reverse_lookup(value)
|
50
|
+
@map.each do |k, v|
|
51
|
+
return k if v == value
|
52
|
+
end
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
|
46
56
|
def search(type)
|
47
57
|
path = "#{@search_prefix}#{type}"
|
48
58
|
|
49
59
|
# prefer LOAD_PATH than gems
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
60
|
+
[@paths, $LOAD_PATH].each do |paths|
|
61
|
+
files = paths.map { |lp|
|
62
|
+
lpath = File.expand_path(File.join(lp, "#{path}.rb"))
|
63
|
+
File.exist?(lpath) ? lpath : nil
|
64
|
+
}.compact
|
65
|
+
unless files.empty?
|
66
|
+
# prefer newer version
|
67
|
+
require files.sort.last
|
68
|
+
return
|
69
|
+
end
|
58
70
|
end
|
59
71
|
|
60
72
|
specs = Gem::Specification.find_all { |spec|
|
data/lib/fluent/root_agent.rb
CHANGED
@@ -18,10 +18,10 @@ require 'delegate'
|
|
18
18
|
|
19
19
|
require 'fluent/config/error'
|
20
20
|
require 'fluent/agent'
|
21
|
-
require 'fluent/engine'
|
22
21
|
require 'fluent/label'
|
23
22
|
require 'fluent/plugin'
|
24
23
|
require 'fluent/system_config'
|
24
|
+
require 'fluent/time'
|
25
25
|
|
26
26
|
module Fluent
|
27
27
|
#
|
@@ -47,14 +47,14 @@ module Fluent
|
|
47
47
|
class RootAgent < Agent
|
48
48
|
ERROR_LABEL = "@ERROR".freeze # @ERROR is built-in error label
|
49
49
|
|
50
|
-
def initialize(system_config
|
51
|
-
super
|
50
|
+
def initialize(log:, system_config: SystemConfig.new)
|
51
|
+
super(log: log)
|
52
52
|
|
53
53
|
@labels = {}
|
54
54
|
@inputs = []
|
55
|
-
@started_inputs = []
|
56
55
|
@suppress_emit_error_log_interval = 0
|
57
56
|
@next_emit_error_log_time = nil
|
57
|
+
@without_source = false
|
58
58
|
|
59
59
|
suppress_interval(system_config.emit_error_log_interval) unless system_config.emit_error_log_interval.nil?
|
60
60
|
@without_source = system_config.without_source unless system_config.without_source.nil?
|
@@ -68,7 +68,7 @@ module Fluent
|
|
68
68
|
|
69
69
|
# initialize <label> elements before configuring all plugins to avoid 'label not found' in input, filter and output.
|
70
70
|
label_configs = {}
|
71
|
-
conf.elements
|
71
|
+
conf.elements(name: 'label').each { |e|
|
72
72
|
name = e.arg
|
73
73
|
raise ConfigError, "Missing symbol argument on <label> directive" if name.empty?
|
74
74
|
|
@@ -89,9 +89,9 @@ module Fluent
|
|
89
89
|
if @without_source
|
90
90
|
log.info "'--without-source' is applied. Ignore <source> sections"
|
91
91
|
else
|
92
|
-
conf.elements
|
93
|
-
type = e['@type']
|
94
|
-
raise ConfigError, "Missing '
|
92
|
+
conf.elements(name: 'source').each { |e|
|
93
|
+
type = e['@type']
|
94
|
+
raise ConfigError, "Missing 'type' parameter on <source> directive" unless type
|
95
95
|
add_source(type, e)
|
96
96
|
}
|
97
97
|
end
|
@@ -104,43 +104,118 @@ module Fluent
|
|
104
104
|
@error_collector = error_label.event_router
|
105
105
|
end
|
106
106
|
|
107
|
-
def
|
108
|
-
|
107
|
+
def lifecycle(desc: false, kind_callback: nil)
|
108
|
+
kind_or_label_list = if desc
|
109
|
+
[:output, :filter, @labels.values.reverse, :output_with_router, :input].flatten
|
110
|
+
else
|
111
|
+
[:input, :output_with_router, @labels.values, :filter, :output].flatten
|
112
|
+
end
|
113
|
+
kind_or_label_list.each do |kind|
|
114
|
+
if kind.respond_to?(:lifecycle)
|
115
|
+
label = kind
|
116
|
+
label.lifecycle(desc: desc) do |plugin, display_kind|
|
117
|
+
yield plugin, display_kind
|
118
|
+
end
|
119
|
+
else
|
120
|
+
list = if desc
|
121
|
+
lifecycle_control_list[kind].reverse
|
122
|
+
else
|
123
|
+
lifecycle_control_list[kind]
|
124
|
+
end
|
125
|
+
display_kind = (kind == :output_with_router ? :output : kind)
|
126
|
+
list.each do |instance|
|
127
|
+
yield instance, display_kind
|
128
|
+
end
|
129
|
+
end
|
130
|
+
if kind_callback
|
131
|
+
kind_callback.call
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
109
135
|
|
110
|
-
|
111
|
-
|
112
|
-
|
136
|
+
def start
|
137
|
+
lifecycle(desc: true) do |i| # instance
|
138
|
+
i.start unless i.started?
|
139
|
+
end
|
140
|
+
end
|
113
141
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
142
|
+
def flush!
|
143
|
+
log.info "flushing all buffer forcedly"
|
144
|
+
flushing_threads = []
|
145
|
+
lifecycle(desc: true) do |instance|
|
146
|
+
if instance.respond_to?(:force_flush)
|
147
|
+
t = Thread.new do
|
148
|
+
Thread.current.abort_on_exception = true
|
149
|
+
begin
|
150
|
+
instance.force_flush
|
151
|
+
rescue => e
|
152
|
+
log.warn "unexpected error while flushing buffer", plugin: instance.class, plugin_id: instance.plugin_id, error: e
|
153
|
+
log.warn_backtrace
|
154
|
+
end
|
155
|
+
end
|
156
|
+
flushing_threads << t
|
157
|
+
end
|
158
|
+
end
|
159
|
+
flushing_threads.each{|t| t.join }
|
118
160
|
end
|
119
161
|
|
120
|
-
def shutdown
|
121
|
-
#
|
122
|
-
|
123
|
-
|
162
|
+
def shutdown # Fluentd's shutdown sequence is stop, before_shutdown, shutdown, after_shutdown, close, terminate for plugins
|
163
|
+
# Thesee method callers does `rescue Exception` to call methods of shutdown sequence as far as possible
|
164
|
+
# if plugin methods does something like infinite recursive call, `exit`, unregistering signal handlers or others.
|
165
|
+
# Plugins should be separated and be in sandbox to protect data in each plugins/buffers.
|
166
|
+
|
167
|
+
lifecycle_safe_sequence = ->(method, checker) {
|
168
|
+
lifecycle do |instance, kind|
|
124
169
|
begin
|
125
|
-
log.
|
126
|
-
|
127
|
-
rescue => e
|
128
|
-
log.warn "unexpected error while
|
170
|
+
log.debug "calling #{method} on #{kind} plugin", type: Plugin.lookup_type_from_class(instance.class), plugin_id: instance.plugin_id
|
171
|
+
instance.send(method) unless instance.send(checker)
|
172
|
+
rescue Exception => e
|
173
|
+
log.warn "unexpected error while calling #{method} on #{kind} plugin", pluguin: instance.class, plugin_id: instance.plugin_id, error: e
|
129
174
|
log.warn_backtrace
|
130
175
|
end
|
131
176
|
end
|
132
|
-
}
|
177
|
+
}
|
133
178
|
|
134
|
-
|
135
|
-
|
179
|
+
lifecycle_unsafe_sequence = ->(method, checker) {
|
180
|
+
operation = case method
|
181
|
+
when :before_shutdown then "preparing shutdown"
|
182
|
+
when :shutdown then "shutting down"
|
183
|
+
when :close then "closing"
|
184
|
+
else
|
185
|
+
raise "BUG: unknown method name '#{method}'"
|
186
|
+
end
|
187
|
+
operation_threads = []
|
188
|
+
callback = ->(){
|
189
|
+
operation_threads.each{|t| t.join }
|
190
|
+
operation_threads.clear
|
191
|
+
}
|
192
|
+
lifecycle(kind_callback: callback) do |instance, kind|
|
193
|
+
t = Thread.new do
|
194
|
+
Thread.current.abort_on_exception = true
|
195
|
+
begin
|
196
|
+
log.info "#{operation} #{kind} plugin", type: Plugin.lookup_type_from_class(instance.class), plugin_id: instance.plugin_id
|
197
|
+
instance.send(method) unless instance.send(checker)
|
198
|
+
rescue Exception => e
|
199
|
+
log.warn "unexpected error while #{operation} on #{kind} plugin", plugin: instance.class, plugin_id: instance.plugin_id, error: e
|
200
|
+
log.warn_backtrace
|
201
|
+
end
|
202
|
+
end
|
203
|
+
operation_threads << t
|
204
|
+
end
|
136
205
|
}
|
137
206
|
|
138
|
-
|
139
|
-
end
|
207
|
+
lifecycle_safe_sequence.call(:stop, :stopped?)
|
140
208
|
|
141
|
-
|
142
|
-
|
143
|
-
|
209
|
+
# before_shutdown does force_flush for output plugins: it should block, so it's unsafe operation
|
210
|
+
lifecycle_unsafe_sequence.call(:before_shutdown, :before_shutdown?)
|
211
|
+
|
212
|
+
lifecycle_unsafe_sequence.call(:shutdown, :shutdown?)
|
213
|
+
|
214
|
+
lifecycle_safe_sequence.call(:after_shutdown, :after_shutdown?)
|
215
|
+
|
216
|
+
lifecycle_unsafe_sequence.call(:close, :closed?)
|
217
|
+
|
218
|
+
lifecycle_safe_sequence.call(:terminate, :terminated?)
|
144
219
|
end
|
145
220
|
|
146
221
|
def suppress_interval(interval_time)
|
@@ -163,7 +238,7 @@ module Fluent
|
|
163
238
|
end
|
164
239
|
|
165
240
|
def add_label(name)
|
166
|
-
label = Label.new(name)
|
241
|
+
label = Label.new(name, log: log)
|
167
242
|
label.root_agent = self
|
168
243
|
@labels[name] = label
|
169
244
|
end
|
@@ -177,7 +252,7 @@ module Fluent
|
|
177
252
|
end
|
178
253
|
|
179
254
|
def emit_error_event(tag, time, record, error)
|
180
|
-
error_info = {
|
255
|
+
error_info = {error: error, tag: tag, time: time}
|
181
256
|
if @error_collector
|
182
257
|
# A record is not included in the logs because <@ERROR> handles it. This warn is for the notification
|
183
258
|
log.warn "send an error event to @ERROR:", error_info
|
@@ -189,12 +264,12 @@ module Fluent
|
|
189
264
|
end
|
190
265
|
|
191
266
|
def handle_emits_error(tag, es, error)
|
192
|
-
error_info = {
|
267
|
+
error_info = {error: error, tag: tag}
|
193
268
|
if @error_collector
|
194
269
|
log.warn "send an error event stream to @ERROR:", error_info
|
195
270
|
@error_collector.emit_stream(tag, es)
|
196
271
|
else
|
197
|
-
now =
|
272
|
+
now = Time.now
|
198
273
|
if @suppress_emit_error_log_interval.zero? || now > @next_emit_error_log_time
|
199
274
|
log.warn "emit transaction failed:", error_info
|
200
275
|
log.warn_backtrace
|
@@ -218,14 +293,14 @@ module Fluent
|
|
218
293
|
end
|
219
294
|
|
220
295
|
def emit_error_event(tag, time, record, error)
|
221
|
-
error_info = {
|
296
|
+
error_info = {error: error, tag: tag, time: time, record: record}
|
222
297
|
log.warn "dump an error event in @ERROR:", error_info
|
223
298
|
end
|
224
299
|
|
225
300
|
def handle_emits_error(tag, es, e)
|
226
|
-
now =
|
301
|
+
now = EventTime.now
|
227
302
|
if @suppress_emit_error_log_interval.zero? || now > @next_emit_error_log_time
|
228
|
-
log.warn "emit transaction failed in @ERROR:",
|
303
|
+
log.warn "emit transaction failed in @ERROR:", error: e, tag: tag
|
229
304
|
log.warn_backtrace
|
230
305
|
@next_emit_error_log_time = now + @suppress_emit_error_log_interval
|
231
306
|
end
|