fluentd 1.10.1 → 1.11.1
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/CHANGELOG.md +112 -1
- data/CONTRIBUTING.md +1 -1
- data/lib/fluent/command/debug.rb +1 -0
- data/lib/fluent/command/fluentd.rb +12 -1
- data/lib/fluent/config.rb +1 -0
- data/lib/fluent/log.rb +45 -6
- data/lib/fluent/match.rb +1 -1
- data/lib/fluent/plugin/in_dummy.rb +2 -2
- data/lib/fluent/plugin/in_forward.rb +2 -2
- data/lib/fluent/plugin/in_gc_stat.rb +16 -0
- data/lib/fluent/plugin/in_http.rb +146 -75
- data/lib/fluent/plugin/in_monitor_agent.rb +1 -1
- data/lib/fluent/plugin/in_syslog.rb +4 -4
- data/lib/fluent/plugin/in_tail.rb +4 -4
- data/lib/fluent/plugin/in_unix.rb +77 -77
- data/lib/fluent/plugin/out_copy.rb +1 -1
- data/lib/fluent/plugin/out_file.rb +1 -1
- data/lib/fluent/plugin/out_forward.rb +23 -18
- data/lib/fluent/plugin/out_forward/load_balancer.rb +1 -1
- data/lib/fluent/plugin/out_http.rb +15 -2
- data/lib/fluent/plugin/parser_multiline.rb +1 -1
- data/lib/fluent/plugin/parser_syslog.rb +215 -54
- data/lib/fluent/plugin_helper/child_process.rb +3 -2
- data/lib/fluent/plugin_helper/record_accessor.rb +14 -0
- data/lib/fluent/plugin_helper/service_discovery.rb +7 -0
- data/lib/fluent/plugin_helper/service_discovery/manager.rb +8 -0
- data/lib/fluent/plugin_helper/socket.rb +20 -2
- data/lib/fluent/plugin_helper/socket_option.rb +2 -2
- data/lib/fluent/supervisor.rb +21 -9
- data/lib/fluent/system_config.rb +2 -1
- data/lib/fluent/test/filter_test.rb +2 -2
- data/lib/fluent/test/output_test.rb +3 -3
- data/lib/fluent/version.rb +1 -1
- data/test/command/test_fluentd.rb +57 -10
- data/test/config/test_system_config.rb +2 -0
- data/test/plugin/out_forward/test_load_balancer.rb +46 -0
- data/test/plugin/test_in_gc_stat.rb +24 -1
- data/test/plugin/test_in_http.rb +57 -0
- data/test/plugin/test_in_syslog.rb +1 -1
- data/test/plugin/test_in_tail.rb +20 -16
- data/test/plugin/test_in_unix.rb +128 -73
- data/test/plugin/test_out_forward.rb +11 -2
- data/test/plugin/test_out_http.rb +38 -0
- data/test/plugin/test_out_null.rb +1 -1
- data/test/plugin/test_output_as_buffered_retries.rb +12 -4
- data/test/plugin/test_parser_syslog.rb +66 -29
- data/test/plugin_helper/data/cert/cert_chains/ca-cert-key.pem +27 -0
- data/test/plugin_helper/data/cert/cert_chains/ca-cert.pem +20 -0
- data/test/plugin_helper/data/cert/cert_chains/cert-key.pem +27 -0
- data/test/plugin_helper/data/cert/cert_chains/cert.pem +40 -0
- data/test/plugin_helper/data/cert/generate_cert.rb +38 -0
- data/test/plugin_helper/http_server/test_app.rb +1 -1
- data/test/plugin_helper/http_server/test_route.rb +1 -1
- data/test/plugin_helper/test_child_process.rb +15 -0
- data/test/plugin_helper/test_http_server_helper.rb +2 -2
- data/test/plugin_helper/test_record_accessor.rb +41 -0
- data/test/plugin_helper/test_server.rb +1 -1
- data/test/plugin_helper/test_service_discovery.rb +37 -4
- data/test/plugin_helper/test_socket.rb +131 -0
- data/test/test_log.rb +44 -0
- metadata +12 -2
@@ -60,6 +60,14 @@ module Fluent
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
+
%i[after_start stop before_shutdown shutdown after_shutdown close terminate].each do |mth|
|
64
|
+
define_method(mth) do
|
65
|
+
@discoveries.each do |d|
|
66
|
+
d.__send__(mth)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
63
71
|
def run_once
|
64
72
|
# Don't care race in this loop intentionally
|
65
73
|
s = @queue.size
|
@@ -145,9 +145,16 @@ module Fluent
|
|
145
145
|
context.ciphers = ciphers
|
146
146
|
context.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
147
147
|
context.cert_store = cert_store
|
148
|
-
context.verify_hostname =
|
149
|
-
context.cert = OpenSSL::X509::Certificate.new(File.read(cert_path)) if cert_path
|
148
|
+
context.verify_hostname = verify_fqdn && fqdn
|
150
149
|
context.key = OpenSSL::PKey::read(File.read(private_key_path), private_key_passphrase) if private_key_path
|
150
|
+
|
151
|
+
if cert_path
|
152
|
+
certs = socket_certificates_from_file(cert_path)
|
153
|
+
context.cert = certs.shift
|
154
|
+
unless certs.empty?
|
155
|
+
context.extra_chain_cert = certs
|
156
|
+
end
|
157
|
+
end
|
151
158
|
end
|
152
159
|
Fluent::TLS.set_version_to_context(context, version, min_version, max_version)
|
153
160
|
|
@@ -186,6 +193,17 @@ module Fluent
|
|
186
193
|
end
|
187
194
|
end
|
188
195
|
|
196
|
+
def socket_certificates_from_file(path)
|
197
|
+
data = File.read(path)
|
198
|
+
pattern = Regexp.compile('-+BEGIN CERTIFICATE-+\r?\n(?:[^-]*\r?\n)+-+END CERTIFICATE-+\r?\n?', Regexp::MULTILINE)
|
199
|
+
list = []
|
200
|
+
data.scan(pattern) { |match| list << OpenSSL::X509::Certificate.new(match) }
|
201
|
+
if list.length == 0
|
202
|
+
log.warn "cert_path does not contain a valid certificate"
|
203
|
+
end
|
204
|
+
list
|
205
|
+
end
|
206
|
+
|
189
207
|
def self.tls_verify_result_name(code)
|
190
208
|
case code
|
191
209
|
when OpenSSL::X509::V_OK then 'V_OK'
|
@@ -67,8 +67,8 @@ module Fluent
|
|
67
67
|
end
|
68
68
|
else
|
69
69
|
if linger_timeout
|
70
|
-
|
71
|
-
|
70
|
+
optval = [1, linger_timeout.to_i].pack(FORMAT_STRUCT_LINGER)
|
71
|
+
socket_option_set_one(sock, :SO_LINGER, optval)
|
72
72
|
end
|
73
73
|
end
|
74
74
|
if recv_timeout
|
data/lib/fluent/supervisor.rb
CHANGED
@@ -301,6 +301,7 @@ module Fluent
|
|
301
301
|
|
302
302
|
log_level = params['log_level']
|
303
303
|
suppress_repeated_stacktrace = params['suppress_repeated_stacktrace']
|
304
|
+
ignore_repeated_log_interval = params['ignore_repeated_log_interval']
|
304
305
|
|
305
306
|
log_path = params['log_path']
|
306
307
|
chuser = params['chuser']
|
@@ -308,7 +309,7 @@ module Fluent
|
|
308
309
|
log_rotate_age = params['log_rotate_age']
|
309
310
|
log_rotate_size = params['log_rotate_size']
|
310
311
|
|
311
|
-
log_opts = {suppress_repeated_stacktrace: suppress_repeated_stacktrace}
|
312
|
+
log_opts = {suppress_repeated_stacktrace: suppress_repeated_stacktrace, ignore_repeated_log_interval: ignore_repeated_log_interval}
|
312
313
|
logger_initializer = Supervisor::LoggerInitializer.new(
|
313
314
|
log_path, log_level, chuser, chgroup, log_opts,
|
314
315
|
log_rotate_age: log_rotate_age,
|
@@ -345,6 +346,7 @@ module Fluent
|
|
345
346
|
chgroup: chgroup,
|
346
347
|
chumask: 0,
|
347
348
|
suppress_repeated_stacktrace: suppress_repeated_stacktrace,
|
349
|
+
ignore_repeated_log_interval: ignore_repeated_log_interval,
|
348
350
|
daemonize: daemonize,
|
349
351
|
rpc_endpoint: params['rpc_endpoint'],
|
350
352
|
counter_server: params['counter_server'],
|
@@ -439,9 +441,10 @@ module Fluent
|
|
439
441
|
self
|
440
442
|
end
|
441
443
|
|
442
|
-
def apply_options(format: nil, time_format: nil, log_dir_perm: nil)
|
444
|
+
def apply_options(format: nil, time_format: nil, log_dir_perm: nil, ignore_repeated_log_interval: nil)
|
443
445
|
$log.format = format if format
|
444
446
|
$log.time_format = time_format if time_format
|
447
|
+
$log.ignore_repeated_log_interval = ignore_repeated_log_interval if ignore_repeated_log_interval
|
445
448
|
|
446
449
|
if @path && log_dir_perm
|
447
450
|
File.chmod(log_dir_perm || 0755, File.dirname(@path))
|
@@ -468,6 +471,7 @@ module Fluent
|
|
468
471
|
root_dir: nil,
|
469
472
|
suppress_interval: 0,
|
470
473
|
suppress_repeated_stacktrace: true,
|
474
|
+
ignore_repeated_log_interval: nil,
|
471
475
|
without_source: nil,
|
472
476
|
use_v1_config: true,
|
473
477
|
strict_config_value: nil,
|
@@ -507,7 +511,7 @@ module Fluent
|
|
507
511
|
@cl_opt = opt
|
508
512
|
@conf = nil
|
509
513
|
|
510
|
-
log_opts = {
|
514
|
+
log_opts = {suppress_repeated_stacktrace: opt[:suppress_repeated_stacktrace], ignore_repeated_log_interval: opt[:ignore_repeated_log_interval]}
|
511
515
|
@log = LoggerInitializer.new(
|
512
516
|
@log_path, opt[:log_level], @chuser, @chgroup, log_opts,
|
513
517
|
log_rotate_age: @log_rotate_age,
|
@@ -552,7 +556,7 @@ module Fluent
|
|
552
556
|
end
|
553
557
|
|
554
558
|
if dry_run
|
555
|
-
$log.info '
|
559
|
+
$log.info 'finished dry run mode'
|
556
560
|
exit 0
|
557
561
|
else
|
558
562
|
supervise
|
@@ -589,7 +593,10 @@ module Fluent
|
|
589
593
|
|
590
594
|
main_process do
|
591
595
|
create_socket_manager if @standalone_worker
|
592
|
-
|
596
|
+
if @standalone_worker
|
597
|
+
ServerEngine::Privilege.change(@chuser, @chgroup)
|
598
|
+
File.umask(0)
|
599
|
+
end
|
593
600
|
MessagePackFactory.init(enable_time_support: @system_config.enable_msgpack_time_support)
|
594
601
|
Fluent::Engine.init(@system_config)
|
595
602
|
Fluent::Engine.run_configure(@conf)
|
@@ -628,6 +635,7 @@ module Fluent
|
|
628
635
|
format: @system_config.log.format,
|
629
636
|
time_format: @system_config.log.time_format,
|
630
637
|
log_dir_perm: @system_config.dir_permission,
|
638
|
+
ignore_repeated_log_interval: @system_config.ignore_repeated_log_interval
|
631
639
|
)
|
632
640
|
|
633
641
|
$log.info :supervisor, 'parsing config file is succeeded', path: @config_path
|
@@ -690,6 +698,7 @@ module Fluent
|
|
690
698
|
'root_dir' => @system_config.root_dir,
|
691
699
|
'log_level' => @system_config.log_level,
|
692
700
|
'suppress_repeated_stacktrace' => @system_config.suppress_repeated_stacktrace,
|
701
|
+
'ignore_repeated_log_interval' => @system_config.ignore_repeated_log_interval,
|
693
702
|
'rpc_endpoint' => @system_config.rpc_endpoint,
|
694
703
|
'enable_get_dump' => @system_config.enable_get_dump,
|
695
704
|
'counter_server' => @system_config.counter_server,
|
@@ -882,7 +891,11 @@ module Fluent
|
|
882
891
|
RUBY_ENCODING_OPTIONS_REGEX = %r{\A(-E|--encoding=|--internal-encoding=|--external-encoding=)}.freeze
|
883
892
|
|
884
893
|
def build_spawn_command
|
885
|
-
|
894
|
+
if ENV['TEST_RUBY_PATH']
|
895
|
+
fluentd_spawn_cmd = [ENV['TEST_RUBY_PATH']]
|
896
|
+
else
|
897
|
+
fluentd_spawn_cmd = [ServerEngine.ruby_bin_path]
|
898
|
+
end
|
886
899
|
|
887
900
|
rubyopt = ENV['RUBYOPT']
|
888
901
|
if rubyopt
|
@@ -897,10 +910,9 @@ module Fluent
|
|
897
910
|
|
898
911
|
# Adding `-h` so that it can avoid ruby's command blocking
|
899
912
|
# e.g. `ruby -Eascii-8bit:ascii-8bit` will block. but `ruby -Eascii-8bit:ascii-8bit -h` won't.
|
900
|
-
|
901
|
-
_, e, s = Open3.capture3("#{cmd} -h")
|
913
|
+
_, e, s = Open3.capture3(*fluentd_spawn_cmd, "-h")
|
902
914
|
if s.exitstatus != 0
|
903
|
-
$log.error('Invalid option is passed to RUBYOPT', command:
|
915
|
+
$log.error('Invalid option is passed to RUBYOPT', command: fluentd_spawn_cmd, error: e)
|
904
916
|
exit s.exitstatus
|
905
917
|
end
|
906
918
|
|
data/lib/fluent/system_config.rb
CHANGED
@@ -24,7 +24,7 @@ module Fluent
|
|
24
24
|
SYSTEM_CONFIG_PARAMETERS = [
|
25
25
|
:workers, :root_dir, :log_level,
|
26
26
|
:suppress_repeated_stacktrace, :emit_error_log_interval, :suppress_config_dump,
|
27
|
-
:log_event_verbose,
|
27
|
+
:log_event_verbose, :ignore_repeated_log_interval,
|
28
28
|
:without_source, :rpc_endpoint, :enable_get_dump, :process_name,
|
29
29
|
:file_permission, :dir_permission, :counter_server, :counter_client,
|
30
30
|
:strict_config_value, :enable_msgpack_time_support
|
@@ -34,6 +34,7 @@ module Fluent
|
|
34
34
|
config_param :root_dir, :string, default: nil
|
35
35
|
config_param :log_level, :enum, list: [:trace, :debug, :info, :warn, :error, :fatal], default: 'info'
|
36
36
|
config_param :suppress_repeated_stacktrace, :bool, default: nil
|
37
|
+
config_param :ignore_repeated_log_interval, :time, default: nil
|
37
38
|
config_param :emit_error_log_interval, :time, default: nil
|
38
39
|
config_param :suppress_config_dump, :bool, default: nil
|
39
40
|
config_param :log_event_verbose, :bool, default: nil
|
@@ -30,12 +30,12 @@ module Fluent
|
|
30
30
|
attr_reader :filtered
|
31
31
|
attr_accessor :tag
|
32
32
|
|
33
|
-
def emit(record, time =
|
33
|
+
def emit(record, time = EventTime.now)
|
34
34
|
emit_with_tag(@tag, record, time)
|
35
35
|
end
|
36
36
|
alias_method :filter, :emit
|
37
37
|
|
38
|
-
def emit_with_tag(tag, record, time =
|
38
|
+
def emit_with_tag(tag, record, time = EventTime.now)
|
39
39
|
@events[tag] ||= MultiEventStream.new
|
40
40
|
@events[tag].add(time, record)
|
41
41
|
end
|
@@ -41,7 +41,7 @@ module Fluent
|
|
41
41
|
|
42
42
|
attr_accessor :tag
|
43
43
|
|
44
|
-
def emit(record, time=
|
44
|
+
def emit(record, time=EventTime.now)
|
45
45
|
es = OneEventStream.new(time, record)
|
46
46
|
@instance.emit_events(@tag, es)
|
47
47
|
end
|
@@ -62,7 +62,7 @@ module Fluent
|
|
62
62
|
|
63
63
|
attr_accessor :tag
|
64
64
|
|
65
|
-
def emit(record, time=
|
65
|
+
def emit(record, time=EventTime.now)
|
66
66
|
@entries << [time, record]
|
67
67
|
self
|
68
68
|
end
|
@@ -110,7 +110,7 @@ module Fluent
|
|
110
110
|
|
111
111
|
attr_accessor :tag
|
112
112
|
|
113
|
-
def emit(record, time=
|
113
|
+
def emit(record, time=EventTime.now)
|
114
114
|
@entries << [time, record]
|
115
115
|
self
|
116
116
|
end
|
data/lib/fluent/version.rb
CHANGED
@@ -16,6 +16,7 @@ class TestFluentdCommand < ::Test::Unit::TestCase
|
|
16
16
|
FileUtils.mkdir_p(TMP_DIR)
|
17
17
|
@supervisor_pid = nil
|
18
18
|
@worker_pids = []
|
19
|
+
ENV["TEST_RUBY_PATH"] = nil
|
19
20
|
end
|
20
21
|
|
21
22
|
def process_exist?(pid)
|
@@ -98,7 +99,8 @@ class TestFluentdCommand < ::Test::Unit::TestCase
|
|
98
99
|
|
99
100
|
def assert_log_matches(cmdline, *pattern_list, patterns_not_match: [], timeout: 10, env: {})
|
100
101
|
matched = false
|
101
|
-
|
102
|
+
matched_wrongly = false
|
103
|
+
assert_error_msg = ""
|
102
104
|
stdio_buf = ""
|
103
105
|
begin
|
104
106
|
execute_command(cmdline, TMP_DIR, env) do |pid, stdout|
|
@@ -128,13 +130,18 @@ class TestFluentdCommand < ::Test::Unit::TestCase
|
|
128
130
|
end
|
129
131
|
end
|
130
132
|
rescue Timeout::Error
|
131
|
-
assert_error_msg = "execution timeout
|
133
|
+
assert_error_msg = "execution timeout"
|
132
134
|
rescue => e
|
133
|
-
assert_error_msg = "unexpected error in launching fluentd: #{e.inspect}
|
135
|
+
assert_error_msg = "unexpected error in launching fluentd: #{e.inspect}"
|
136
|
+
else
|
137
|
+
assert_error_msg = "log doesn't match" unless matched
|
134
138
|
end
|
135
|
-
assert matched, assert_error_msg
|
136
139
|
|
137
|
-
|
140
|
+
if patterns_not_match.empty?
|
141
|
+
assert_error_msg = build_message(assert_error_msg,
|
142
|
+
"<?>\nwas expected to include:\n<?>",
|
143
|
+
stdio_buf, pattern_list)
|
144
|
+
else
|
138
145
|
lines = stdio_buf.split("\n")
|
139
146
|
patterns_not_match.each do |ptn|
|
140
147
|
matched_wrongly = if ptn.is_a? Regexp
|
@@ -142,9 +149,17 @@ class TestFluentdCommand < ::Test::Unit::TestCase
|
|
142
149
|
else
|
143
150
|
lines.any?{|line| line.include?(ptn) }
|
144
151
|
end
|
145
|
-
|
152
|
+
if matched_wrongly
|
153
|
+
assert_error_msg << "\n" unless assert_error_msg.empty?
|
154
|
+
assert_error_msg << "pattern exists in logs wrongly: #{ptn}"
|
155
|
+
end
|
146
156
|
end
|
157
|
+
assert_error_msg = build_message(assert_error_msg,
|
158
|
+
"<?>\nwas expected to include:\n<?>\nand not include:\n<?>",
|
159
|
+
stdio_buf, pattern_list, patterns_not_match)
|
147
160
|
end
|
161
|
+
|
162
|
+
assert matched && !matched_wrongly, assert_error_msg
|
148
163
|
end
|
149
164
|
|
150
165
|
def assert_fluentd_fails_to_start(cmdline, *pattern_list, timeout: 10)
|
@@ -842,8 +857,7 @@ CONF
|
|
842
857
|
'-external-encoding' => '--external-encoding=utf-8',
|
843
858
|
'-internal-encoding' => '--internal-encoding=utf-8',
|
844
859
|
)
|
845
|
-
test "-E option is set to
|
846
|
-
omit "hard to run correctly on Windows. Need to debug." if Fluent.windows?
|
860
|
+
test "-E option is set to RUBYOPT" do |opt|
|
847
861
|
conf = <<CONF
|
848
862
|
<source>
|
849
863
|
@type dummy
|
@@ -854,6 +868,7 @@ CONF
|
|
854
868
|
</match>
|
855
869
|
CONF
|
856
870
|
conf_path = create_conf_file('rubyopt_test.conf', conf)
|
871
|
+
opt << " #{ENV['RUBYOPT']}" if ENV['RUBYOPT']
|
857
872
|
assert_log_matches(
|
858
873
|
create_cmdline(conf_path),
|
859
874
|
*opt.split(' '),
|
@@ -862,7 +877,7 @@ CONF
|
|
862
877
|
)
|
863
878
|
end
|
864
879
|
|
865
|
-
|
880
|
+
test "without RUBYOPT" do
|
866
881
|
conf = <<CONF
|
867
882
|
<source>
|
868
883
|
@type dummy
|
@@ -877,7 +892,7 @@ CONF
|
|
877
892
|
end
|
878
893
|
|
879
894
|
test 'invalid values are set to RUBYOPT' do
|
880
|
-
omit "hard to run correctly on Windows
|
895
|
+
omit "hard to run correctly because RUBYOPT=-r/path/to/bundler/setup is required on Windows while this test set invalid RUBYOPT" if Fluent.windows?
|
881
896
|
conf = <<CONF
|
882
897
|
<source>
|
883
898
|
@type dummy
|
@@ -895,6 +910,38 @@ CONF
|
|
895
910
|
)
|
896
911
|
end
|
897
912
|
|
913
|
+
# https://github.com/fluent/fluentd/issues/2915
|
914
|
+
test "ruby path contains spaces" do
|
915
|
+
conf = <<CONF
|
916
|
+
<source>
|
917
|
+
@type dummy
|
918
|
+
tag dummy
|
919
|
+
</source>
|
920
|
+
<match>
|
921
|
+
@type null
|
922
|
+
</match>
|
923
|
+
CONF
|
924
|
+
ruby_path = ServerEngine.ruby_bin_path
|
925
|
+
tmp_ruby_path = File.join(TMP_DIR, "ruby with spaces")
|
926
|
+
if Fluent.windows?
|
927
|
+
tmp_ruby_path << ".bat"
|
928
|
+
File.open(tmp_ruby_path, "w") do |file|
|
929
|
+
file.write "#{ruby_path} %*"
|
930
|
+
end
|
931
|
+
else
|
932
|
+
FileUtils.ln_sf(ruby_path, tmp_ruby_path)
|
933
|
+
end
|
934
|
+
ENV["TEST_RUBY_PATH"] = tmp_ruby_path
|
935
|
+
cmd_path = File.expand_path(File.dirname(__FILE__) + "../../../bin/fluentd")
|
936
|
+
conf_path = create_conf_file('space_mixed_ruby_path_test.conf', conf)
|
937
|
+
args = ["bundle", "exec", tmp_ruby_path, cmd_path, "-c", conf_path]
|
938
|
+
assert_log_matches(
|
939
|
+
args,
|
940
|
+
'spawn command to main:',
|
941
|
+
'-Eascii-8bit:ascii-8bit'
|
942
|
+
)
|
943
|
+
end
|
944
|
+
|
898
945
|
test 'success to start workers when file buffer is configured in non-workers way only for specific worker' do
|
899
946
|
conf = <<CONF
|
900
947
|
<system>
|
@@ -73,6 +73,7 @@ module Fluent::Config
|
|
73
73
|
assert_nil(sc.root_dir)
|
74
74
|
assert_equal(Fluent::Log::LEVEL_INFO, sc.log_level)
|
75
75
|
assert_nil(sc.suppress_repeated_stacktrace)
|
76
|
+
assert_nil(sc.ignore_repeated_log_interval)
|
76
77
|
assert_nil(sc.emit_error_log_interval)
|
77
78
|
assert_nil(sc.suppress_config_dump)
|
78
79
|
assert_nil(sc.without_source)
|
@@ -86,6 +87,7 @@ module Fluent::Config
|
|
86
87
|
'root_dir' => ['root_dir', File.join(TMP_DIR, 'root')],
|
87
88
|
'log_level' => ['log_level', 'error'],
|
88
89
|
'suppress_repeated_stacktrace' => ['suppress_repeated_stacktrace', true],
|
90
|
+
'ignore_repeated_log_interval' => ['ignore_repeated_log_interval', 10],
|
89
91
|
'log_event_verbose' => ['log_event_verbose', true],
|
90
92
|
'suppress_config_dump' => ['suppress_config_dump', true],
|
91
93
|
'without_source' => ['without_source', true],
|
@@ -49,6 +49,44 @@ class LoadBalancerTest < Test::Unit::TestCase
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
+
test 'call like round robin without weight=0 node' do
|
53
|
+
lb = Fluent::Plugin::ForwardOutput::LoadBalancer.new($log)
|
54
|
+
n1 = flexmock('node', :'standby?' => false, :'available?' => true, weight: 1)
|
55
|
+
n2 = flexmock('node', :'standby?' => false, :'available?' => true, weight: 1)
|
56
|
+
n3 = flexmock('node', :'standby?' => false, :'available?' => true, weight: 0)
|
57
|
+
|
58
|
+
lb.rebuild_weight_array([n1, n2, n3])
|
59
|
+
|
60
|
+
lb.select_healthy_node do |node|
|
61
|
+
# to handle random choice
|
62
|
+
if node == n1
|
63
|
+
lb.select_healthy_node do |node|
|
64
|
+
assert_equal(node, n2)
|
65
|
+
end
|
66
|
+
|
67
|
+
lb.select_healthy_node do |node|
|
68
|
+
assert_equal(node, n1)
|
69
|
+
end
|
70
|
+
|
71
|
+
lb.select_healthy_node do |node|
|
72
|
+
assert_equal(node, n2)
|
73
|
+
end
|
74
|
+
else
|
75
|
+
lb.select_healthy_node do |node|
|
76
|
+
assert_equal(node, n1)
|
77
|
+
end
|
78
|
+
|
79
|
+
lb.select_healthy_node do |node|
|
80
|
+
assert_equal(node, n2)
|
81
|
+
end
|
82
|
+
|
83
|
+
lb.select_healthy_node do |node|
|
84
|
+
assert_equal(node, n1)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
52
90
|
test 'raise an error if all node are unavialble' do
|
53
91
|
lb = Fluent::Plugin::ForwardOutput::LoadBalancer.new($log)
|
54
92
|
lb.rebuild_weight_array([flexmock('node', :'standby?' => false, :'available?' => false, weight: 1)])
|
@@ -56,5 +94,13 @@ class LoadBalancerTest < Test::Unit::TestCase
|
|
56
94
|
lb.select_healthy_node
|
57
95
|
end
|
58
96
|
end
|
97
|
+
|
98
|
+
test 'it regards weight=0 node as unavialble' do
|
99
|
+
lb = Fluent::Plugin::ForwardOutput::LoadBalancer.new($log)
|
100
|
+
lb.rebuild_weight_array([flexmock('node', :'standby?' => false, :'available?' => true, weight: 0)])
|
101
|
+
assert_raise(Fluent::Plugin::ForwardOutput::NoNodesAvailable) do
|
102
|
+
lb.select_healthy_node
|
103
|
+
end
|
104
|
+
end
|
59
105
|
end
|
60
106
|
end
|