fluentd 1.7.4-x64-mingw32 → 1.8.0-x64-mingw32
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/bug_report.md +0 -1
- data/.travis.yml +4 -0
- data/CHANGELOG.md +70 -0
- data/MAINTAINERS.md +1 -0
- data/example/out_forward_sd.conf +17 -0
- data/example/sd.yaml +8 -0
- data/fluentd.gemspec +1 -1
- data/lib/fluent/agent.rb +3 -1
- data/lib/fluent/command/cat.rb +1 -2
- data/lib/fluent/command/fluentd.rb +16 -8
- data/lib/fluent/compat/call_super_mixin.rb +9 -0
- data/lib/fluent/compat/exec_util.rb +1 -1
- data/lib/fluent/config/configure_proxy.rb +4 -4
- data/lib/fluent/config/element.rb +28 -15
- data/lib/fluent/config/error.rb +6 -0
- data/lib/fluent/config/literal_parser.rb +24 -2
- data/lib/fluent/config/section.rb +43 -6
- data/lib/fluent/config/types.rb +98 -26
- data/lib/fluent/configurable.rb +2 -2
- data/lib/fluent/counter/base_socket.rb +2 -4
- data/lib/fluent/engine.rb +41 -122
- data/lib/fluent/event.rb +5 -7
- data/lib/fluent/fluent_log_event_router.rb +141 -0
- data/lib/fluent/msgpack_factory.rb +19 -2
- data/lib/fluent/plugin.rb +10 -1
- data/lib/fluent/plugin/base.rb +2 -2
- data/lib/fluent/plugin/buf_file.rb +11 -7
- data/lib/fluent/plugin/buf_file_single.rb +8 -5
- data/lib/fluent/plugin/buffer/chunk.rb +1 -1
- data/lib/fluent/plugin/buffer/file_chunk.rb +4 -6
- data/lib/fluent/plugin/buffer/file_single_chunk.rb +3 -5
- data/lib/fluent/plugin/formatter_csv.rb +23 -1
- data/lib/fluent/plugin/formatter_stdout.rb +1 -1
- data/lib/fluent/plugin/in_forward.rb +1 -1
- data/lib/fluent/plugin/in_monitor_agent.rb +4 -2
- data/lib/fluent/plugin/in_tail.rb +6 -0
- data/lib/fluent/plugin/in_unix.rb +1 -1
- data/lib/fluent/plugin/out_forward.rb +77 -28
- data/lib/fluent/plugin/out_forward/ack_handler.rb +1 -1
- data/lib/fluent/plugin/out_forward/load_balancer.rb +5 -2
- data/lib/fluent/plugin/out_stream.rb +1 -1
- data/lib/fluent/plugin/output.rb +11 -3
- data/lib/fluent/plugin/parser.rb +1 -0
- data/lib/fluent/plugin/sd_file.rb +155 -0
- data/lib/fluent/plugin/sd_static.rb +58 -0
- data/lib/fluent/plugin/service_discovery.rb +80 -0
- data/lib/fluent/plugin_helper.rb +1 -0
- data/lib/fluent/plugin_helper/child_process.rb +3 -3
- data/lib/fluent/plugin_helper/compat_parameters.rb +11 -1
- data/lib/fluent/plugin_helper/extract.rb +1 -1
- data/lib/fluent/plugin_helper/inject.rb +1 -1
- data/lib/fluent/plugin_helper/record_accessor.rb +10 -19
- data/lib/fluent/plugin_helper/server.rb +8 -4
- data/lib/fluent/plugin_helper/service_discovery.rb +80 -0
- data/lib/fluent/plugin_helper/service_discovery/manager.rb +132 -0
- data/lib/fluent/plugin_helper/service_discovery/round_robin_balancer.rb +43 -0
- data/lib/fluent/plugin_id.rb +7 -0
- data/lib/fluent/root_agent.rb +7 -9
- data/lib/fluent/supervisor.rb +192 -211
- data/lib/fluent/system_config.rb +26 -52
- data/lib/fluent/test/driver/base_owned.rb +15 -2
- data/lib/fluent/time.rb +8 -6
- data/lib/fluent/version.rb +1 -1
- data/test/command/test_fluentd.rb +12 -7
- data/test/config/test_configurable.rb +154 -0
- data/test/config/test_element.rb +18 -0
- data/test/config/test_literal_parser.rb +4 -0
- data/test/config/test_system_config.rb +48 -91
- data/test/config/test_types.rb +293 -120
- data/test/counter/test_client.rb +8 -4
- data/test/plugin/data/sd_file/config +11 -0
- data/test/plugin/data/sd_file/config.json +17 -0
- data/test/plugin/data/sd_file/config.yaml +11 -0
- data/test/plugin/data/sd_file/config.yml +11 -0
- data/test/plugin/data/sd_file/invalid_config.yml +7 -0
- data/test/plugin/out_forward/test_handshake_protocol.rb +2 -2
- data/test/plugin/out_forward/test_load_balancer.rb +1 -1
- data/test/plugin/out_forward/test_socket_cache.rb +2 -2
- data/test/plugin/test_buf_file.rb +40 -0
- data/test/plugin/test_buf_file_single.rb +32 -0
- data/test/plugin/test_buffer_file_chunk.rb +0 -11
- data/test/plugin/test_buffer_file_single_chunk.rb +0 -10
- data/test/plugin/test_formatter_csv.rb +9 -0
- data/test/plugin/test_in_forward.rb +9 -9
- data/test/plugin/test_in_monitor_agent.rb +37 -10
- data/test/plugin/test_in_unix.rb +5 -5
- data/test/plugin/test_out_forward.rb +45 -1
- data/test/plugin/test_out_stdout.rb +36 -1
- data/test/plugin/test_out_stream.rb +3 -3
- data/test/plugin/test_output.rb +25 -1
- data/test/plugin/test_sd_file.rb +211 -0
- data/test/plugin_helper/service_discovery/test_manager.rb +93 -0
- data/test/plugin_helper/service_discovery/test_round_robin_balancer.rb +21 -0
- data/test/plugin_helper/test_server.rb +13 -0
- data/test/plugin_helper/test_service_discovery.rb +72 -0
- data/test/test_event.rb +15 -15
- data/test/test_fluent_log_event_router.rb +99 -0
- data/test/test_logger_initializer.rb +26 -0
- data/test/test_supervisor.rb +30 -59
- metadata +43 -6
@@ -0,0 +1,58 @@
|
|
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/service_discovery'
|
18
|
+
|
19
|
+
module Fluent
|
20
|
+
module Plugin
|
21
|
+
class StaticServiceDiscovery < ServiceDiscovery
|
22
|
+
Plugin.register_sd('static', self)
|
23
|
+
|
24
|
+
LISTEN_PORT = 24224
|
25
|
+
|
26
|
+
config_section :service, param_name: :service_configs do
|
27
|
+
desc 'The IP address or host name of the server.'
|
28
|
+
config_param :host, :string
|
29
|
+
desc 'The name of the server. Used for logging and certificate verification in TLS transport (when host is address).'
|
30
|
+
config_param :name, :string, default: nil
|
31
|
+
desc 'The port number of the host.'
|
32
|
+
config_param :port, :integer, default: LISTEN_PORT
|
33
|
+
desc 'The shared key per server.'
|
34
|
+
config_param :shared_key, :string, default: nil, secret: true
|
35
|
+
desc 'The username for authentication.'
|
36
|
+
config_param :username, :string, default: ''
|
37
|
+
desc 'The password for authentication.'
|
38
|
+
config_param :password, :string, default: '', secret: true
|
39
|
+
desc 'Marks a node as the standby node for an Active-Standby model between Fluentd nodes.'
|
40
|
+
config_param :standby, :bool, default: false
|
41
|
+
desc 'The load balancing weight.'
|
42
|
+
config_param :weight, :integer, default: 60
|
43
|
+
end
|
44
|
+
|
45
|
+
def configure(conf)
|
46
|
+
super
|
47
|
+
|
48
|
+
@services = @service_configs.map do |s|
|
49
|
+
ServiceDiscovery::Service.new(:static, s.host, s.port, s.name, s.weight, s.standby, s.username, s.password, s.shared_key)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def start(queue = nil)
|
54
|
+
super()
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,80 @@
|
|
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
|
+
# Fluentd
|
18
|
+
#
|
19
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
20
|
+
# you may not use this file except in compliance with the License.
|
21
|
+
# You may obtain a copy of the License at
|
22
|
+
#
|
23
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
24
|
+
#
|
25
|
+
# Unless required by applicable law or agreed to in writing, software
|
26
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
27
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
28
|
+
# See the License for the specific language governing permissions and
|
29
|
+
# limitations under the License.
|
30
|
+
#
|
31
|
+
|
32
|
+
require 'fluent/plugin/base'
|
33
|
+
|
34
|
+
require 'fluent/log'
|
35
|
+
require 'fluent/unique_id'
|
36
|
+
require 'fluent/plugin_id'
|
37
|
+
|
38
|
+
module Fluent
|
39
|
+
module Plugin
|
40
|
+
class ServiceDiscovery < Base
|
41
|
+
include PluginId
|
42
|
+
include PluginLoggerMixin
|
43
|
+
include UniqueId::Mixin
|
44
|
+
|
45
|
+
configured_in :service_discovery
|
46
|
+
|
47
|
+
attr_reader :services
|
48
|
+
|
49
|
+
Service = Struct.new(:plugin_name, :host, :port, :name, :weight, :standby, :username, :password, :shared_key) do
|
50
|
+
def discovery_id
|
51
|
+
@discovery_id ||= Base64.encode64(to_h.to_s)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
SERVICE_IN = :service_in
|
56
|
+
SERVICE_OUT = :service_out
|
57
|
+
DiscoveryMessage = Struct.new(:type, :service)
|
58
|
+
|
59
|
+
class << self
|
60
|
+
def service_in_msg(service)
|
61
|
+
DiscoveryMessage.new(SERVICE_IN, service)
|
62
|
+
end
|
63
|
+
|
64
|
+
def service_out_msg(service)
|
65
|
+
DiscoveryMessage.new(SERVICE_OUT, service)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def initialize
|
70
|
+
@services = []
|
71
|
+
|
72
|
+
super
|
73
|
+
end
|
74
|
+
|
75
|
+
def start(queue = nil)
|
76
|
+
super()
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/fluent/plugin_helper.rb
CHANGED
@@ -31,6 +31,7 @@ require 'fluent/plugin_helper/counter'
|
|
31
31
|
require 'fluent/plugin_helper/retry_state'
|
32
32
|
require 'fluent/plugin_helper/record_accessor'
|
33
33
|
require 'fluent/plugin_helper/compat_parameters'
|
34
|
+
require 'fluent/plugin_helper/service_discovery'
|
34
35
|
|
35
36
|
module Fluent
|
36
37
|
module PluginHelper
|
@@ -267,19 +267,19 @@ module Fluent
|
|
267
267
|
end
|
268
268
|
|
269
269
|
if mode.include?(:write)
|
270
|
-
writeio.set_encoding(external_encoding, internal_encoding, encoding_options)
|
270
|
+
writeio.set_encoding(external_encoding, internal_encoding, **encoding_options)
|
271
271
|
writeio_in_use = true
|
272
272
|
else
|
273
273
|
writeio.reopen(IO::NULL) if writeio
|
274
274
|
end
|
275
275
|
if mode.include?(:read) || mode.include?(:read_with_stderr)
|
276
|
-
readio.set_encoding(external_encoding, internal_encoding, encoding_options)
|
276
|
+
readio.set_encoding(external_encoding, internal_encoding, **encoding_options)
|
277
277
|
readio_in_use = true
|
278
278
|
else
|
279
279
|
readio.reopen(IO::NULL) if readio
|
280
280
|
end
|
281
281
|
if mode.include?(:stderr)
|
282
|
-
stderrio.set_encoding(external_encoding, internal_encoding, encoding_options)
|
282
|
+
stderrio.set_encoding(external_encoding, internal_encoding, **encoding_options)
|
283
283
|
stderrio_in_use = true
|
284
284
|
else
|
285
285
|
stderrio.reopen(IO::NULL) if stderrio && stderr == :discard
|
@@ -194,7 +194,9 @@ module Fluent
|
|
194
194
|
hash['time_type'] = 'unixtime'
|
195
195
|
end
|
196
196
|
if conf.has_key?('localtime') || conf.has_key?('utc')
|
197
|
-
|
197
|
+
utc = to_bool(conf['utc'])
|
198
|
+
localtime = to_bool(conf['localtime'])
|
199
|
+
if conf.has_key?('localtime') && conf.has_key?('utc') && !(localtime ^ utc)
|
198
200
|
raise Fluent::ConfigError, "both of utc and localtime are specified, use only one of them"
|
199
201
|
elsif conf.has_key?('localtime')
|
200
202
|
hash['localtime'] = Fluent::Config.bool_value(conf['localtime'])
|
@@ -217,6 +219,14 @@ module Fluent
|
|
217
219
|
conf
|
218
220
|
end
|
219
221
|
|
222
|
+
def to_bool(v)
|
223
|
+
if v.is_a?(FalseClass) || v == 'false' || v.nil?
|
224
|
+
false
|
225
|
+
else
|
226
|
+
true
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
220
230
|
def compat_parameters_extract(conf)
|
221
231
|
return unless conf.elements('extract').empty?
|
222
232
|
return if EXTRACT_PARAMS.keys.all?{|k| !conf.has_key?(k) } && !conf.has_key?('format')
|
@@ -31,6 +31,10 @@ module Fluent
|
|
31
31
|
Accessor.new(param)
|
32
32
|
end
|
33
33
|
|
34
|
+
def record_accessor_nested?(param)
|
35
|
+
Accessor.parse_parameter(param).is_a?(Array)
|
36
|
+
end
|
37
|
+
|
34
38
|
class Accessor
|
35
39
|
attr_reader :keys
|
36
40
|
|
@@ -42,25 +46,19 @@ module Fluent
|
|
42
46
|
@dig_keys = @keys[0..-2]
|
43
47
|
if @dig_keys.empty?
|
44
48
|
@keys = @keys.first
|
45
|
-
mcall = method(:call_index)
|
46
|
-
mdelete = method(:delete_top)
|
47
49
|
else
|
48
50
|
mcall = method(:call_dig)
|
49
51
|
mdelete = method(:delete_nest)
|
52
|
+
singleton_class.module_eval do
|
53
|
+
define_method(:call, mcall)
|
54
|
+
define_method(:delete, mdelete)
|
55
|
+
end
|
50
56
|
end
|
51
|
-
else
|
52
|
-
# Call [] for single key to reduce dig overhead
|
53
|
-
mcall = method(:call_index)
|
54
|
-
mdelete = method(:delete_top)
|
55
|
-
end
|
56
|
-
|
57
|
-
singleton_class.module_eval do
|
58
|
-
define_method(:call, mcall)
|
59
|
-
define_method(:delete, mdelete)
|
60
57
|
end
|
61
58
|
end
|
62
59
|
|
63
60
|
def call(r)
|
61
|
+
r[@keys]
|
64
62
|
end
|
65
63
|
|
66
64
|
# To optimize the performance, use class_eval with pre-expanding @keys
|
@@ -69,11 +67,8 @@ module Fluent
|
|
69
67
|
r.dig(*@keys)
|
70
68
|
end
|
71
69
|
|
72
|
-
def call_index(r)
|
73
|
-
r[@keys]
|
74
|
-
end
|
75
|
-
|
76
70
|
def delete(r)
|
71
|
+
r.delete(@keys)
|
77
72
|
end
|
78
73
|
|
79
74
|
def delete_nest(r)
|
@@ -88,10 +83,6 @@ module Fluent
|
|
88
83
|
nil
|
89
84
|
end
|
90
85
|
|
91
|
-
def delete_top(r)
|
92
|
-
r.delete(@keys)
|
93
|
-
end
|
94
|
-
|
95
86
|
def self.parse_parameter(param)
|
96
87
|
if param.start_with?('$.')
|
97
88
|
parse_dot_notation(param)
|
@@ -355,7 +355,11 @@ module Fluent
|
|
355
355
|
sock = if shared
|
356
356
|
server_socket_manager_client.listen_tcp(bind, port)
|
357
357
|
else
|
358
|
-
TCPServer.new
|
358
|
+
# TCPServer.new doesn't set IPV6_V6ONLY flag, so use Addrinfo class instead.
|
359
|
+
# backlog will be set by the caller, we don't need to set backlog here
|
360
|
+
tsock = Addrinfo.tcp(bind, port).listen
|
361
|
+
tsock.autoclose = false
|
362
|
+
TCPServer.for_fd(tsock.fileno)
|
359
363
|
end
|
360
364
|
# close-on-exec is set by default in Ruby 2.0 or later (, and it's unavailable on Windows)
|
361
365
|
sock.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK) # nonblock
|
@@ -690,9 +694,9 @@ module Fluent
|
|
690
694
|
end
|
691
695
|
|
692
696
|
if RUBY_VERSION.to_f >= 2.3
|
693
|
-
NONBLOCK_ARG = {exception: false}
|
697
|
+
NONBLOCK_ARG = { exception: false }
|
694
698
|
def try_handshake
|
695
|
-
@_handler_socket.accept_nonblock(NONBLOCK_ARG)
|
699
|
+
@_handler_socket.accept_nonblock(**NONBLOCK_ARG)
|
696
700
|
end
|
697
701
|
else
|
698
702
|
def try_handshake
|
@@ -722,7 +726,7 @@ module Fluent
|
|
722
726
|
|
723
727
|
return true
|
724
728
|
end
|
725
|
-
rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ETIMEDOUT, OpenSSL::SSL::SSLError => e
|
729
|
+
rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::ECONNREFUSED, OpenSSL::SSL::SSLError => e
|
726
730
|
@log.trace "unexpected error before accepting TLS connection", error: e
|
727
731
|
close rescue nil
|
728
732
|
end
|
@@ -0,0 +1,80 @@
|
|
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/timer'
|
18
|
+
require 'fluent/plugin_helper/service_discovery/manager'
|
19
|
+
|
20
|
+
module Fluent
|
21
|
+
module PluginHelper
|
22
|
+
module ServiceDiscovery
|
23
|
+
include Fluent::PluginHelper::Timer
|
24
|
+
|
25
|
+
def self.included(mod)
|
26
|
+
mod.include ServiceDiscoveryParams
|
27
|
+
end
|
28
|
+
|
29
|
+
def start
|
30
|
+
unless @discovery_manager
|
31
|
+
log.warn('There is no discovery_manager. skip start them')
|
32
|
+
super
|
33
|
+
return
|
34
|
+
end
|
35
|
+
|
36
|
+
@discovery_manager.start
|
37
|
+
unless @discovery_manager.static_config?
|
38
|
+
timer_execute(@_plugin_helper_service_discovery_title, @_plugin_helper_service_discovery_iterval) do
|
39
|
+
@discovery_manager.run_once
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
super
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# @param title [Symbol] the thread name. this value should be unique.
|
49
|
+
# @param configurations [Hash] hash which must has discivery_service type and its configuration like `{ type: :static, conf: <Fluent::Config::Element> }`
|
50
|
+
# @param load_balancer [Object] object which has two methods #rebalance and #select_service
|
51
|
+
# @param custom_build_method [Proc]
|
52
|
+
def service_discovery_create_manager(title, configurations:, load_balancer: nil, custom_build_method: nil, interval: 3)
|
53
|
+
@_plugin_helper_service_discovery_title = title
|
54
|
+
@_plugin_helper_service_discovery_iterval = interval
|
55
|
+
|
56
|
+
@discovery_manager = Fluent::PluginHelper::ServiceDiscovery::Manager.new(
|
57
|
+
log: log,
|
58
|
+
load_balancer: load_balancer,
|
59
|
+
custom_build_method: custom_build_method,
|
60
|
+
)
|
61
|
+
|
62
|
+
@discovery_manager.configure(configurations, parent: self)
|
63
|
+
|
64
|
+
@discovery_manager
|
65
|
+
end
|
66
|
+
|
67
|
+
def discovery_manager
|
68
|
+
@discovery_manager
|
69
|
+
end
|
70
|
+
|
71
|
+
module ServiceDiscoveryParams
|
72
|
+
include Fluent::Configurable
|
73
|
+
|
74
|
+
config_section :service_discovery do
|
75
|
+
config_param :@type, :string
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,132 @@
|
|
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/service_discovery'
|
18
|
+
require 'fluent/plugin_helper/service_discovery/round_robin_balancer'
|
19
|
+
|
20
|
+
module Fluent
|
21
|
+
module PluginHelper
|
22
|
+
module ServiceDiscovery
|
23
|
+
class Manager
|
24
|
+
def initialize(log:, load_balancer: nil, custom_build_method: nil)
|
25
|
+
@log = log
|
26
|
+
@load_balancer = load_balancer || RoundRobinBalancer.new
|
27
|
+
@custom_build_method = custom_build_method
|
28
|
+
|
29
|
+
@discoveries = []
|
30
|
+
@services = {}
|
31
|
+
@queue = Queue.new
|
32
|
+
@static_config = true
|
33
|
+
end
|
34
|
+
|
35
|
+
def configure(opts, parent: nil)
|
36
|
+
opts.each do |opt|
|
37
|
+
sd = Fluent::Plugin.new_sd(opt[:type], parent: parent)
|
38
|
+
sd.configure(opt[:conf])
|
39
|
+
|
40
|
+
sd.services.each do |s|
|
41
|
+
@services[s.discovery_id] = build_service(s)
|
42
|
+
end
|
43
|
+
@discoveries << sd
|
44
|
+
|
45
|
+
if @static_config && opt[:type] != :static
|
46
|
+
@static_config = false
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
rebalance
|
51
|
+
end
|
52
|
+
|
53
|
+
def static_config?
|
54
|
+
@static_config
|
55
|
+
end
|
56
|
+
|
57
|
+
def start
|
58
|
+
@discoveries.each do |d|
|
59
|
+
d.start(@queue)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def run_once
|
64
|
+
# Don't care race in this loop intentionally
|
65
|
+
s = @queue.size
|
66
|
+
|
67
|
+
if s == 0
|
68
|
+
return
|
69
|
+
end
|
70
|
+
|
71
|
+
s.times do
|
72
|
+
msg = @queue.pop
|
73
|
+
|
74
|
+
unless msg.is_a?(Fluent::Plugin::ServiceDiscovery::DiscoveryMessage)
|
75
|
+
@log.warn("BUG: #{msg}")
|
76
|
+
next
|
77
|
+
end
|
78
|
+
|
79
|
+
begin
|
80
|
+
handle_message(msg)
|
81
|
+
rescue => e
|
82
|
+
@log.error(e)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
rebalance
|
87
|
+
end
|
88
|
+
|
89
|
+
def rebalance
|
90
|
+
@load_balancer.rebalance(services)
|
91
|
+
end
|
92
|
+
|
93
|
+
def select_service(&block)
|
94
|
+
@load_balancer.select_service(&block)
|
95
|
+
end
|
96
|
+
|
97
|
+
def services
|
98
|
+
@services.values
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def handle_message(msg)
|
104
|
+
service = msg.service
|
105
|
+
|
106
|
+
case msg.type
|
107
|
+
when Fluent::Plugin::ServiceDiscovery::SERVICE_IN
|
108
|
+
if (n = build_service(service))
|
109
|
+
@log.info("Service in: name=#{service.name} #{service.host}:#{service.port}")
|
110
|
+
@services[service.discovery_id] = n
|
111
|
+
else
|
112
|
+
raise "failed to build service in name=#{service.name} #{service.host}:#{service.port}"
|
113
|
+
end
|
114
|
+
when Fluent::Plugin::ServiceDiscovery::SERVICE_OUT
|
115
|
+
s = @services.delete(service.discovery_id)
|
116
|
+
if s
|
117
|
+
@log.info("Service out: name=#{service.name} #{service.host}:#{service.port}")
|
118
|
+
else
|
119
|
+
@log.warn("Not found service: name=#{service.name} #{service.host}:#{service.port}")
|
120
|
+
end
|
121
|
+
else
|
122
|
+
@log.error("BUG: unknow message type: #{msg.type}")
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def build_service(n)
|
127
|
+
@custom_build_method ? @custom_build_method.call(n) : n
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|