fluentd 1.7.4 → 1.8.0.rc1
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.
Potentially problematic release.
This version of fluentd might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/example/out_forward_sd.conf +17 -0
- data/example/sd.yaml +8 -0
- data/lib/fluent/command/cat.rb +1 -2
- data/lib/fluent/compat/call_super_mixin.rb +9 -0
- data/lib/fluent/compat/exec_util.rb +1 -1
- data/lib/fluent/counter/base_socket.rb +2 -4
- data/lib/fluent/engine.rb +1 -8
- data/lib/fluent/event.rb +5 -7
- data/lib/fluent/msgpack_factory.rb +19 -2
- data/lib/fluent/plugin.rb +10 -1
- data/lib/fluent/plugin/buf_file.rb +9 -1
- data/lib/fluent/plugin/buf_file_single.rb +6 -0
- data/lib/fluent/plugin/buffer/file_chunk.rb +2 -3
- data/lib/fluent/plugin/buffer/file_single_chunk.rb +1 -2
- data/lib/fluent/plugin/formatter_csv.rb +22 -0
- data/lib/fluent/plugin/in_forward.rb +1 -1
- 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/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/record_accessor.rb +10 -19
- 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/supervisor.rb +9 -8
- data/lib/fluent/system_config.rb +0 -2
- data/lib/fluent/version.rb +1 -1
- data/test/config/test_system_config.rb +0 -1
- 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_socket_cache.rb +2 -2
- data/test/plugin/test_formatter_csv.rb +9 -0
- data/test/plugin/test_in_forward.rb +9 -9
- data/test/plugin/test_in_unix.rb +5 -5
- data/test/plugin/test_out_forward.rb +45 -1
- data/test/plugin/test_out_stream.rb +3 -3
- 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_service_discovery.rb +72 -0
- data/test/test_event.rb +15 -15
- metadata +29 -3
@@ -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
|
@@ -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)
|
@@ -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
|
@@ -0,0 +1,43 @@
|
|
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
|
+
module Fluent
|
18
|
+
module PluginHelper
|
19
|
+
module ServiceDiscovery
|
20
|
+
class RoundRobinBalancer
|
21
|
+
def initialize
|
22
|
+
@services = []
|
23
|
+
@mutex = Mutex.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def rebalance(services)
|
27
|
+
@mutex.synchronize do
|
28
|
+
@services = services
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def select_service
|
33
|
+
s = @mutex.synchronize do
|
34
|
+
s = @services.shift
|
35
|
+
@services.push(s)
|
36
|
+
s
|
37
|
+
end
|
38
|
+
yield(s)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|