fluentd 0.14.17-x64-mingw32 → 1.3.1-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/.travis.yml +16 -5
- data/ADOPTERS.md +5 -0
- data/{ChangeLog → CHANGELOG.md} +495 -6
- data/CONTRIBUTING.md +5 -2
- data/GOVERNANCE.md +55 -0
- data/LICENSE +202 -0
- data/MAINTAINERS.md +7 -5
- data/README.md +17 -10
- data/bin/fluent-ca-generate +6 -0
- data/example/counter.conf +18 -0
- data/example/secondary_file.conf +3 -2
- data/fluentd.gemspec +3 -3
- data/lib/fluent/agent.rb +1 -1
- data/lib/fluent/command/binlog_reader.rb +11 -2
- data/lib/fluent/command/ca_generate.rb +181 -0
- data/lib/fluent/command/cat.rb +28 -15
- data/lib/fluent/command/debug.rb +4 -4
- data/lib/fluent/command/fluentd.rb +2 -2
- data/lib/fluent/command/plugin_config_formatter.rb +24 -2
- data/lib/fluent/command/plugin_generator.rb +26 -8
- data/lib/fluent/config/configure_proxy.rb +7 -1
- data/lib/fluent/config/dsl.rb +8 -5
- data/lib/fluent/config/element.rb +5 -0
- data/lib/fluent/config/literal_parser.rb +7 -1
- data/lib/fluent/config/types.rb +28 -2
- data/lib/fluent/config/v1_parser.rb +1 -2
- data/lib/fluent/configurable.rb +1 -0
- data/lib/fluent/counter.rb +23 -0
- data/lib/fluent/counter/base_socket.rb +46 -0
- data/lib/fluent/counter/client.rb +297 -0
- data/lib/fluent/counter/error.rb +86 -0
- data/lib/fluent/counter/mutex_hash.rb +163 -0
- data/lib/fluent/counter/server.rb +273 -0
- data/lib/fluent/counter/store.rb +205 -0
- data/lib/fluent/counter/validator.rb +145 -0
- data/lib/fluent/env.rb +1 -0
- data/lib/fluent/event_router.rb +1 -1
- data/lib/fluent/log.rb +119 -29
- data/lib/fluent/plugin/base.rb +12 -0
- data/lib/fluent/plugin/buf_file.rb +20 -16
- data/lib/fluent/plugin/buffer.rb +130 -32
- data/lib/fluent/plugin/buffer/file_chunk.rb +23 -4
- data/lib/fluent/plugin/compressable.rb +1 -1
- data/lib/fluent/plugin/filter_grep.rb +135 -21
- data/lib/fluent/plugin/filter_parser.rb +13 -2
- data/lib/fluent/plugin/filter_record_transformer.rb +16 -14
- data/lib/fluent/plugin/formatter_stdout.rb +3 -2
- data/lib/fluent/plugin/formatter_tsv.rb +5 -1
- data/lib/fluent/plugin/in_debug_agent.rb +8 -1
- data/lib/fluent/plugin/in_forward.rb +1 -1
- data/lib/fluent/plugin/in_http.rb +84 -3
- data/lib/fluent/plugin/in_monitor_agent.rb +7 -1
- data/lib/fluent/plugin/in_syslog.rb +31 -10
- data/lib/fluent/plugin/in_tail.rb +142 -53
- data/lib/fluent/plugin/in_tcp.rb +5 -6
- data/lib/fluent/plugin/in_udp.rb +6 -2
- data/lib/fluent/plugin/in_unix.rb +1 -1
- data/lib/fluent/plugin/multi_output.rb +1 -0
- data/lib/fluent/plugin/out_copy.rb +25 -2
- data/lib/fluent/plugin/out_file.rb +26 -7
- data/lib/fluent/plugin/out_forward.rb +81 -42
- data/lib/fluent/plugin/out_secondary_file.rb +2 -2
- data/lib/fluent/plugin/out_stdout.rb +0 -1
- data/lib/fluent/plugin/out_stream.rb +1 -1
- data/lib/fluent/plugin/output.rb +221 -57
- data/lib/fluent/plugin/parser_apache.rb +1 -1
- data/lib/fluent/plugin/parser_apache2.rb +5 -1
- data/lib/fluent/plugin/parser_apache_error.rb +1 -1
- data/lib/fluent/plugin/parser_json.rb +10 -3
- data/lib/fluent/plugin/parser_ltsv.rb +7 -0
- data/lib/fluent/plugin/parser_multiline.rb +2 -1
- data/lib/fluent/plugin/parser_nginx.rb +1 -1
- data/lib/fluent/plugin/parser_none.rb +1 -0
- data/lib/fluent/plugin/parser_regexp.rb +15 -14
- data/lib/fluent/plugin/parser_syslog.rb +9 -5
- data/lib/fluent/plugin_helper.rb +2 -0
- data/lib/fluent/plugin_helper/cert_option.rb +28 -9
- data/lib/fluent/plugin_helper/compat_parameters.rb +3 -1
- data/lib/fluent/plugin_helper/counter.rb +51 -0
- data/lib/fluent/plugin_helper/event_loop.rb +9 -0
- data/lib/fluent/plugin_helper/record_accessor.rb +210 -0
- data/lib/fluent/plugin_helper/retry_state.rb +15 -7
- data/lib/fluent/plugin_helper/server.rb +87 -25
- data/lib/fluent/plugin_helper/socket_option.rb +5 -2
- data/lib/fluent/plugin_helper/timer.rb +8 -7
- data/lib/fluent/root_agent.rb +18 -9
- data/lib/fluent/supervisor.rb +63 -23
- data/lib/fluent/system_config.rb +30 -2
- data/lib/fluent/test/helpers.rb +1 -1
- data/lib/fluent/time.rb +15 -7
- data/lib/fluent/timezone.rb +26 -2
- data/lib/fluent/version.rb +1 -1
- data/templates/new_gem/README.md.erb +2 -2
- data/templates/new_gem/lib/fluent/plugin/filter.rb.erb +1 -1
- data/templates/new_gem/lib/fluent/plugin/input.rb.erb +1 -1
- data/templates/new_gem/lib/fluent/plugin/output.rb.erb +1 -1
- data/templates/new_gem/lib/fluent/plugin/parser.rb.erb +4 -4
- data/test/command/test_ca_generate.rb +70 -0
- data/test/command/test_fluentd.rb +2 -2
- data/test/command/test_plugin_config_formatter.rb +8 -7
- data/test/command/test_plugin_generator.rb +65 -39
- data/test/config/test_config_parser.rb +7 -2
- data/test/config/test_configurable.rb +7 -2
- data/test/config/test_configure_proxy.rb +41 -3
- data/test/config/test_dsl.rb +10 -10
- data/test/config/test_element.rb +10 -0
- data/test/config/test_literal_parser.rb +8 -0
- data/test/config/test_plugin_configuration.rb +56 -0
- data/test/config/test_system_config.rb +19 -1
- data/test/config/test_types.rb +37 -0
- data/test/counter/test_client.rb +559 -0
- data/test/counter/test_error.rb +44 -0
- data/test/counter/test_mutex_hash.rb +179 -0
- data/test/counter/test_server.rb +589 -0
- data/test/counter/test_store.rb +258 -0
- data/test/counter/test_validator.rb +137 -0
- data/test/plugin/test_buf_file.rb +124 -0
- data/test/plugin/test_buffer.rb +3 -2
- data/test/plugin/test_filter_grep.rb +580 -2
- data/test/plugin/test_filter_parser.rb +33 -2
- data/test/plugin/test_filter_record_transformer.rb +22 -1
- data/test/plugin/test_formatter_ltsv.rb +3 -0
- data/test/plugin/test_formatter_tsv.rb +68 -0
- data/test/plugin/test_in_debug_agent.rb +21 -0
- data/test/plugin/test_in_exec.rb +3 -5
- data/test/plugin/test_in_http.rb +178 -0
- data/test/plugin/test_in_monitor_agent.rb +1 -1
- data/test/plugin/test_in_syslog.rb +64 -0
- data/test/plugin/test_in_tail.rb +116 -6
- data/test/plugin/test_in_tcp.rb +21 -0
- data/test/plugin/test_in_udp.rb +78 -0
- data/test/plugin/test_metadata.rb +89 -0
- data/test/plugin/test_out_copy.rb +31 -0
- data/test/plugin/test_out_file.rb +108 -2
- data/test/plugin/test_out_forward.rb +195 -2
- data/test/plugin/test_out_secondary_file.rb +14 -0
- data/test/plugin/test_output.rb +159 -45
- data/test/plugin/test_output_as_buffered.rb +19 -0
- data/test/plugin/test_output_as_buffered_backup.rb +307 -0
- data/test/plugin/test_output_as_buffered_retries.rb +70 -0
- data/test/plugin/test_output_as_buffered_secondary.rb +1 -1
- data/test/plugin/test_parser_apache2.rb +1 -0
- data/test/plugin/test_parser_labeled_tsv.rb +17 -0
- data/test/plugin/test_parser_nginx.rb +40 -0
- data/test/plugin/test_parser_regexp.rb +6 -7
- data/test/plugin/test_parser_syslog.rb +155 -5
- data/test/plugin_helper/test_child_process.rb +4 -4
- data/test/plugin_helper/test_compat_parameters.rb +22 -0
- data/test/plugin_helper/test_record_accessor.rb +197 -0
- data/test/plugin_helper/test_retry_state.rb +20 -0
- data/test/plugin_helper/test_server.rb +30 -2
- data/test/test_config.rb +3 -3
- data/test/test_configdsl.rb +2 -2
- data/test/test_log.rb +51 -1
- data/test/test_root_agent.rb +33 -0
- data/test/test_supervisor.rb +105 -0
- metadata +68 -8
- data/COPYING +0 -14
@@ -156,5 +156,36 @@ class CopyOutputTest < Test::Unit::TestCase
|
|
156
156
|
end
|
157
157
|
end
|
158
158
|
end
|
159
|
+
|
160
|
+
IGNORE_ERROR_CONFIG = %[
|
161
|
+
<store ignore_error>
|
162
|
+
@type test
|
163
|
+
name c0
|
164
|
+
</store>
|
165
|
+
<store ignore_error>
|
166
|
+
@type test
|
167
|
+
name c1
|
168
|
+
</store>
|
169
|
+
<store>
|
170
|
+
@type test
|
171
|
+
name c2
|
172
|
+
</store>
|
173
|
+
]
|
174
|
+
|
175
|
+
def test_ignore_error
|
176
|
+
d = create_driver(IGNORE_ERROR_CONFIG)
|
177
|
+
|
178
|
+
# override to raise an error
|
179
|
+
d.instance.outputs[0].define_singleton_method(:process) do |tag, es|
|
180
|
+
raise ArgumentError, 'Failed'
|
181
|
+
end
|
182
|
+
|
183
|
+
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
184
|
+
assert_nothing_raised do
|
185
|
+
d.run(default_tag: 'test') do
|
186
|
+
d.feed(time, {"a"=>1})
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
159
190
|
end
|
160
191
|
|
@@ -304,7 +304,11 @@ class FileOutputTest < Test::Unit::TestCase
|
|
304
304
|
assert_equal r4, d.formatted[3]
|
305
305
|
assert_equal r5, d.formatted[4]
|
306
306
|
|
307
|
-
read_gunzip = ->(path){
|
307
|
+
read_gunzip = ->(path){
|
308
|
+
File.open(path){ |fio|
|
309
|
+
Zlib::GzipReader.new(StringIO.new(fio.read)).read
|
310
|
+
}
|
311
|
+
}
|
308
312
|
assert_equal r1 + r2, read_gunzip.call("#{TMP_DIR}/my.data/a/full.20161003.2345.log.gz")
|
309
313
|
assert_equal r3, read_gunzip.call("#{TMP_DIR}/your.data/a/full.20161003.2345.log.gz")
|
310
314
|
assert_equal r4, read_gunzip.call("#{TMP_DIR}/my.data/a/full.20161004.0000.log.gz")
|
@@ -370,7 +374,7 @@ class FileOutputTest < Test::Unit::TestCase
|
|
370
374
|
result = ''
|
371
375
|
File.open(path, "rb") { |io|
|
372
376
|
loop do
|
373
|
-
gzr = Zlib::GzipReader.new(io)
|
377
|
+
gzr = Zlib::GzipReader.new(StringIO.new(io.read))
|
374
378
|
result << gzr.read
|
375
379
|
unused = gzr.unused
|
376
380
|
gzr.finish
|
@@ -557,6 +561,108 @@ class FileOutputTest < Test::Unit::TestCase
|
|
557
561
|
check_gzipped_result(path, formatted_lines * 3)
|
558
562
|
end
|
559
563
|
|
564
|
+
test 'append when JST' do
|
565
|
+
with_timezone(Fluent.windows? ? "JST-9" : "Asia/Tokyo") do
|
566
|
+
time = event_time("2011-01-02 03:14:15+09:00")
|
567
|
+
formatted_lines = %[2011-01-02T03:14:15+09:00\ttest\t{"a":1}\n] + %[2011-01-02T03:14:15+09:00\ttest\t{"a":2}\n]
|
568
|
+
|
569
|
+
write_once = ->(){
|
570
|
+
d = create_driver %[
|
571
|
+
path #{TMP_DIR}/out_file_test
|
572
|
+
compress gz
|
573
|
+
append true
|
574
|
+
<buffer>
|
575
|
+
timekey_use_utc false
|
576
|
+
timekey_zone Asia/Tokyo
|
577
|
+
</buffer>
|
578
|
+
]
|
579
|
+
d.run(default_tag: 'test'){
|
580
|
+
d.feed(time, {"a"=>1})
|
581
|
+
d.feed(time, {"a"=>2})
|
582
|
+
}
|
583
|
+
d.instance.last_written_path
|
584
|
+
}
|
585
|
+
|
586
|
+
path = write_once.call
|
587
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102.log.gz", path
|
588
|
+
check_gzipped_result(path, formatted_lines)
|
589
|
+
|
590
|
+
path = write_once.call
|
591
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102.log.gz", path
|
592
|
+
check_gzipped_result(path, formatted_lines * 2)
|
593
|
+
|
594
|
+
path = write_once.call
|
595
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102.log.gz", path
|
596
|
+
check_gzipped_result(path, formatted_lines * 3)
|
597
|
+
end
|
598
|
+
end
|
599
|
+
|
600
|
+
test 'append when UTC-02 but timekey_zone is +0900' do
|
601
|
+
with_timezone("UTC-02") do # +0200
|
602
|
+
time = event_time("2011-01-02 17:14:15+02:00")
|
603
|
+
formatted_lines = %[2011-01-02T17:14:15+02:00\ttest\t{"a":1}\n] + %[2011-01-02T17:14:15+02:00\ttest\t{"a":2}\n]
|
604
|
+
|
605
|
+
write_once = ->(){
|
606
|
+
d = create_driver %[
|
607
|
+
path #{TMP_DIR}/out_file_test
|
608
|
+
compress gz
|
609
|
+
append true
|
610
|
+
<buffer>
|
611
|
+
timekey_use_utc false
|
612
|
+
timekey_zone +0900
|
613
|
+
</buffer>
|
614
|
+
]
|
615
|
+
d.run(default_tag: 'test'){
|
616
|
+
d.feed(time, {"a"=>1})
|
617
|
+
d.feed(time, {"a"=>2})
|
618
|
+
}
|
619
|
+
d.instance.last_written_path
|
620
|
+
}
|
621
|
+
|
622
|
+
path = write_once.call
|
623
|
+
# Rotated at 2011-01-02 17:00:00+02:00
|
624
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110103.log.gz", path
|
625
|
+
check_gzipped_result(path, formatted_lines)
|
626
|
+
|
627
|
+
path = write_once.call
|
628
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110103.log.gz", path
|
629
|
+
check_gzipped_result(path, formatted_lines * 2)
|
630
|
+
|
631
|
+
path = write_once.call
|
632
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110103.log.gz", path
|
633
|
+
check_gzipped_result(path, formatted_lines * 3)
|
634
|
+
end
|
635
|
+
end
|
636
|
+
|
637
|
+
test '${chunk_id}' do
|
638
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
639
|
+
formatted_lines = %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] + %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n]
|
640
|
+
|
641
|
+
write_once = ->(){
|
642
|
+
d = create_driver %[
|
643
|
+
path #{TMP_DIR}/out_file_chunk_id_${chunk_id}
|
644
|
+
utc
|
645
|
+
append true
|
646
|
+
<buffer>
|
647
|
+
timekey_use_utc true
|
648
|
+
</buffer>
|
649
|
+
]
|
650
|
+
d.run(default_tag: 'test'){
|
651
|
+
d.feed(time, {"a"=>1})
|
652
|
+
d.feed(time, {"a"=>2})
|
653
|
+
}
|
654
|
+
d.instance.last_written_path
|
655
|
+
}
|
656
|
+
|
657
|
+
path = write_once.call
|
658
|
+
if File.basename(path) =~ /out_file_chunk_id_([-_.@a-zA-Z0-9].*).20110102.log/
|
659
|
+
unique_id = Fluent::UniqueId.hex(Fluent::UniqueId.generate)
|
660
|
+
assert_equal unique_id.size, $1.size, "chunk_id size is mismatched"
|
661
|
+
else
|
662
|
+
flunk "chunk_id is not included in the path"
|
663
|
+
end
|
664
|
+
end
|
665
|
+
|
560
666
|
test 'symlink' do
|
561
667
|
omit "Windows doesn't support symlink" if Fluent.windows?
|
562
668
|
conf = CONFIG + %[
|
@@ -9,6 +9,8 @@ require 'fluent/plugin/in_forward'
|
|
9
9
|
class ForwardOutputTest < Test::Unit::TestCase
|
10
10
|
def setup
|
11
11
|
Fluent::Test.setup
|
12
|
+
FileUtils.rm_rf(TMP_DIR)
|
13
|
+
FileUtils.mkdir_p(TMP_DIR)
|
12
14
|
@d = nil
|
13
15
|
end
|
14
16
|
|
@@ -16,6 +18,8 @@ class ForwardOutputTest < Test::Unit::TestCase
|
|
16
18
|
@d.instance_shutdown if @d
|
17
19
|
end
|
18
20
|
|
21
|
+
TMP_DIR = File.join(__dir__, "../tmp/out_forward#{ENV['TEST_ENV_NUMBER']}")
|
22
|
+
|
19
23
|
TARGET_HOST = '127.0.0.1'
|
20
24
|
TARGET_PORT = unused_port
|
21
25
|
CONFIG = %[
|
@@ -153,6 +157,27 @@ EOL
|
|
153
157
|
assert{ logs.any?{|log| log.include?(expected_log) && log.include?(expected_detail) } }
|
154
158
|
end
|
155
159
|
|
160
|
+
data('CA cert' => 'tls_ca_cert_path',
|
161
|
+
'non CA cert' => 'tls_cert_path')
|
162
|
+
test 'configure tls_cert_path/tls_ca_cert_path' do |param|
|
163
|
+
dummy_cert_path = File.join(TMP_DIR, "dummy_cert.pem")
|
164
|
+
FileUtils.touch(dummy_cert_path)
|
165
|
+
conf = %[
|
166
|
+
send_timeout 5
|
167
|
+
transport tls
|
168
|
+
tls_insecure_mode true
|
169
|
+
#{param} #{dummy_cert_path}
|
170
|
+
<server>
|
171
|
+
host #{TARGET_HOST}
|
172
|
+
port #{TARGET_PORT}
|
173
|
+
</server>
|
174
|
+
]
|
175
|
+
|
176
|
+
@d = d = create_driver(conf)
|
177
|
+
# In the plugin, tls_ca_cert_path is used for both cases
|
178
|
+
assert_equal([dummy_cert_path], d.instance.tls_ca_cert_path)
|
179
|
+
end
|
180
|
+
|
156
181
|
test 'compress_default_value' do
|
157
182
|
@d = d = create_driver
|
158
183
|
assert_equal :text, d.instance.compress
|
@@ -217,6 +242,18 @@ EOL
|
|
217
242
|
assert_equal 2, d.instance.ack_response_timeout
|
218
243
|
end
|
219
244
|
|
245
|
+
test 'verify_connection_at_startup is disabled in default' do
|
246
|
+
@d = d = create_driver(CONFIG)
|
247
|
+
assert_false d.instance.verify_connection_at_startup
|
248
|
+
end
|
249
|
+
|
250
|
+
test 'verify_connection_at_startup can be enabled' do
|
251
|
+
@d = d = create_driver(CONFIG + %[
|
252
|
+
verify_connection_at_startup true
|
253
|
+
])
|
254
|
+
assert_true d.instance.verify_connection_at_startup
|
255
|
+
end
|
256
|
+
|
220
257
|
test 'send tags in str (utf-8 strings)' do
|
221
258
|
target_input_driver = create_target_input_driver
|
222
259
|
|
@@ -486,6 +523,7 @@ EOL
|
|
486
523
|
retry_type periodic
|
487
524
|
retry_wait 30s
|
488
525
|
flush_at_shutdown false # suppress errors in d.instance_shutdown
|
526
|
+
flush_thread_interval 30s
|
489
527
|
</buffer>
|
490
528
|
])
|
491
529
|
|
@@ -501,7 +539,7 @@ EOL
|
|
501
539
|
target_input_driver.end_if{ d.instance.rollback_count > 0 }
|
502
540
|
target_input_driver.end_if{ !node.available }
|
503
541
|
target_input_driver.run(expect_records: 2, timeout: 25) do
|
504
|
-
d.run(default_tag: 'test', timeout: 20, wait_flush_completion: false, shutdown: false) do
|
542
|
+
d.run(default_tag: 'test', timeout: 20, wait_flush_completion: false, shutdown: false, flush: false) do
|
505
543
|
delayed_commit_timeout_value = d.instance.delayed_commit_timeout
|
506
544
|
d.feed([[time, records[0]], [time,records[1]]])
|
507
545
|
end
|
@@ -530,6 +568,7 @@ EOL
|
|
530
568
|
retry_type periodic
|
531
569
|
retry_wait 30s
|
532
570
|
flush_at_shutdown false # suppress errors in d.instance_shutdown
|
571
|
+
flush_thread_interval 30s
|
533
572
|
</buffer>
|
534
573
|
])
|
535
574
|
|
@@ -545,7 +584,7 @@ EOL
|
|
545
584
|
target_input_driver.end_if{ d.instance.rollback_count > 0 }
|
546
585
|
target_input_driver.end_if{ !node.available }
|
547
586
|
target_input_driver.run(expect_records: 2, timeout: 25) do
|
548
|
-
d.run(default_tag: 'test', timeout: 20, wait_flush_completion: false, shutdown: false) do
|
587
|
+
d.run(default_tag: 'test', timeout: 20, wait_flush_completion: false, shutdown: false, flush: false) do
|
549
588
|
delayed_commit_timeout_value = d.instance.delayed_commit_timeout
|
550
589
|
d.feed([[time, records[0]], [time,records[1]]])
|
551
590
|
end
|
@@ -664,6 +703,51 @@ EOL
|
|
664
703
|
assert_equal(['test', time, records[1]], events[1])
|
665
704
|
end
|
666
705
|
|
706
|
+
# This test is not 100% but test failed with previous Node implementation which has race condition
|
707
|
+
test 'Node with security is thread-safe on multi threads' do
|
708
|
+
input_conf = TARGET_CONFIG + %[
|
709
|
+
<security>
|
710
|
+
self_hostname in.localhost
|
711
|
+
shared_key fluentd-sharedkey
|
712
|
+
<client>
|
713
|
+
host 127.0.0.1
|
714
|
+
</client>
|
715
|
+
</security>
|
716
|
+
]
|
717
|
+
target_input_driver = create_target_input_driver(conf: input_conf)
|
718
|
+
output_conf = %[
|
719
|
+
send_timeout 51
|
720
|
+
<security>
|
721
|
+
self_hostname localhost
|
722
|
+
shared_key fluentd-sharedkey
|
723
|
+
</security>
|
724
|
+
<server>
|
725
|
+
name test
|
726
|
+
host #{TARGET_HOST}
|
727
|
+
port #{TARGET_PORT}
|
728
|
+
shared_key fluentd-sharedkey
|
729
|
+
</server>
|
730
|
+
]
|
731
|
+
@d = d = create_driver(output_conf)
|
732
|
+
|
733
|
+
chunk = Fluent::Plugin::Buffer::MemoryChunk.new(Fluent::Plugin::Buffer::Metadata.new(nil, nil, nil))
|
734
|
+
target_input_driver.run(timeout: 15) do
|
735
|
+
d.run(shutdown: false) do
|
736
|
+
node = d.instance.nodes.first
|
737
|
+
arr = []
|
738
|
+
4.times {
|
739
|
+
arr << Thread.new {
|
740
|
+
node.send_data('test', chunk) rescue nil
|
741
|
+
}
|
742
|
+
}
|
743
|
+
arr.each { |a| a.join }
|
744
|
+
end
|
745
|
+
end
|
746
|
+
|
747
|
+
logs = d.logs
|
748
|
+
assert_false(logs.any? { |log| log.include?("invalid format for PONG message") || log.include?("shared key mismatch") }, "'#{logs.last.strip}' happens")
|
749
|
+
end
|
750
|
+
|
667
751
|
def create_target_input_driver(response_stub: nil, disconnect: false, conf: TARGET_CONFIG)
|
668
752
|
require 'fluent/plugin/in_forward'
|
669
753
|
|
@@ -727,4 +811,113 @@ EOL
|
|
727
811
|
i.configure(conf)
|
728
812
|
end
|
729
813
|
end
|
814
|
+
|
815
|
+
sub_test_case 'verify_connection_at_startup' do
|
816
|
+
test 'nodes are not available' do
|
817
|
+
@d = d = create_driver(CONFIG + %[
|
818
|
+
verify_connection_at_startup true
|
819
|
+
<buffer tag>
|
820
|
+
flush_mode immediate
|
821
|
+
retry_type periodic
|
822
|
+
retry_wait 30s
|
823
|
+
flush_at_shutdown false # suppress errors in d.instance_shutdown
|
824
|
+
</buffer>
|
825
|
+
])
|
826
|
+
assert_raise Fluent::UnrecoverableError do
|
827
|
+
d.instance_start
|
828
|
+
end
|
829
|
+
d.instance_shutdown
|
830
|
+
end
|
831
|
+
|
832
|
+
test 'nodes_shared_key_miss_match' do
|
833
|
+
input_conf = TARGET_CONFIG + %[
|
834
|
+
<security>
|
835
|
+
self_hostname in.localhost
|
836
|
+
shared_key fluentd-sharedkey
|
837
|
+
</security>
|
838
|
+
]
|
839
|
+
target_input_driver = create_target_input_driver(conf: input_conf)
|
840
|
+
output_conf = %[
|
841
|
+
send_timeout 30
|
842
|
+
heartbeat_type transport
|
843
|
+
transport tls
|
844
|
+
tls_verify_hostname false
|
845
|
+
verify_connection_at_startup true
|
846
|
+
require_ack_response true
|
847
|
+
ack_response_timeout 5s
|
848
|
+
<security>
|
849
|
+
self_hostname localhost
|
850
|
+
shared_key key_miss_match
|
851
|
+
</security>
|
852
|
+
<buffer tag>
|
853
|
+
flush_mode immediate
|
854
|
+
retry_type periodic
|
855
|
+
retry_wait 30s
|
856
|
+
flush_at_shutdown false # suppress errors in d.instance_shutdown
|
857
|
+
flush_thread_interval 31s
|
858
|
+
</buffer>
|
859
|
+
|
860
|
+
<server>
|
861
|
+
host #{TARGET_HOST}
|
862
|
+
port #{TARGET_PORT}
|
863
|
+
</server>
|
864
|
+
]
|
865
|
+
@d = d = create_driver(output_conf)
|
866
|
+
|
867
|
+
target_input_driver.run(expect_records: 1, timeout: 15) do
|
868
|
+
assert_raise Fluent::UnrecoverableError do
|
869
|
+
d.instance_start
|
870
|
+
end
|
871
|
+
d.instance_shutdown
|
872
|
+
end
|
873
|
+
end
|
874
|
+
|
875
|
+
test 'nodes_shared_key_match' do
|
876
|
+
input_conf = TARGET_CONFIG + %[
|
877
|
+
<security>
|
878
|
+
self_hostname in.localhost
|
879
|
+
shared_key fluentd-sharedkey
|
880
|
+
<client>
|
881
|
+
host 127.0.0.1
|
882
|
+
</client>
|
883
|
+
</security>
|
884
|
+
]
|
885
|
+
target_input_driver = create_target_input_driver(conf: input_conf)
|
886
|
+
|
887
|
+
output_conf = %[
|
888
|
+
send_timeout 51
|
889
|
+
verify_connection_at_startup true
|
890
|
+
<security>
|
891
|
+
self_hostname localhost
|
892
|
+
shared_key fluentd-sharedkey
|
893
|
+
</security>
|
894
|
+
<server>
|
895
|
+
name test
|
896
|
+
host #{TARGET_HOST}
|
897
|
+
port #{TARGET_PORT}
|
898
|
+
shared_key fluentd-sharedkey
|
899
|
+
</server>
|
900
|
+
]
|
901
|
+
@d = d = create_driver(output_conf)
|
902
|
+
|
903
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
904
|
+
records = [
|
905
|
+
{"a" => 1},
|
906
|
+
{"a" => 2}
|
907
|
+
]
|
908
|
+
|
909
|
+
target_input_driver.run(expect_records: 2, timeout: 15) do
|
910
|
+
d.run(default_tag: 'test') do
|
911
|
+
records.each do |record|
|
912
|
+
d.feed(time, record)
|
913
|
+
end
|
914
|
+
end
|
915
|
+
end
|
916
|
+
|
917
|
+
events = target_input_driver.events
|
918
|
+
assert{ events != [] }
|
919
|
+
assert_equal(['test', time, records[0]], events[0])
|
920
|
+
assert_equal(['test', time, records[1]], events[1])
|
921
|
+
end
|
922
|
+
end
|
730
923
|
end
|
@@ -260,6 +260,20 @@ class FileOutputSecondaryTest < Test::Unit::TestCase
|
|
260
260
|
assert_equal "#{TMP_DIR}/dump.bin", path
|
261
261
|
end
|
262
262
|
|
263
|
+
test 'path with ${chunk_id}' do
|
264
|
+
d = create_driver %[
|
265
|
+
directory #{TMP_DIR}
|
266
|
+
basename out_file_chunk_id_${chunk_id}
|
267
|
+
]
|
268
|
+
path = d.instance.write(@c)
|
269
|
+
if File.basename(path) =~ /out_file_chunk_id_([-_.@a-zA-Z0-9].*).0/
|
270
|
+
unique_id = Fluent::UniqueId.hex(Fluent::UniqueId.generate)
|
271
|
+
assert_equal unique_id.size, $1.size, "chunk_id size is mismatched"
|
272
|
+
else
|
273
|
+
flunk "chunk_id is not included in the path"
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
263
277
|
data(
|
264
278
|
invalid_tag: [/tag/, '${tag}'],
|
265
279
|
invalid_tag0: [/tag\[0\]/, '${tag[0]}'],
|
data/test/plugin/test_output.rb
CHANGED
@@ -125,6 +125,10 @@ class OutputTest < Test::Unit::TestCase
|
|
125
125
|
def create_metadata(timekey: nil, tag: nil, variables: nil)
|
126
126
|
Fluent::Plugin::Buffer::Metadata.new(timekey, tag, variables)
|
127
127
|
end
|
128
|
+
def create_chunk(timekey: nil, tag: nil, variables: nil)
|
129
|
+
m = Fluent::Plugin::Buffer::Metadata.new(timekey, tag, variables)
|
130
|
+
Fluent::Plugin::Buffer::MemoryChunk.new(m)
|
131
|
+
end
|
128
132
|
def waiting(seconds)
|
129
133
|
begin
|
130
134
|
Timeout.timeout(seconds) do
|
@@ -219,7 +223,9 @@ class OutputTest < Test::Unit::TestCase
|
|
219
223
|
assert @i.terminated?
|
220
224
|
end
|
221
225
|
|
222
|
-
|
226
|
+
data(:new_api => :chunk,
|
227
|
+
:old_api => :metadata)
|
228
|
+
test '#extract_placeholders does nothing if chunk key is not specified' do |api|
|
223
229
|
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
|
224
230
|
assert !@i.chunk_key_time
|
225
231
|
assert !@i.chunk_key_tag
|
@@ -227,11 +233,17 @@ class OutputTest < Test::Unit::TestCase
|
|
227
233
|
tmpl = "/mypath/%Y/%m/%d/${tag}/${tag[1]}/${tag[2]}/${key1}/${key2}/tail"
|
228
234
|
t = event_time('2016-04-11 20:30:00 +0900')
|
229
235
|
v = {key1: "value1", key2: "value2"}
|
230
|
-
|
231
|
-
|
236
|
+
c = if api == :chunk
|
237
|
+
create_chunk(timekey: t, tag: 'fluentd.test.output', variables: v)
|
238
|
+
else
|
239
|
+
create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
|
240
|
+
end
|
241
|
+
assert_equal tmpl, @i.extract_placeholders(tmpl, c)
|
232
242
|
end
|
233
243
|
|
234
|
-
|
244
|
+
data(:new_api => :chunk,
|
245
|
+
:old_api => :metadata)
|
246
|
+
test '#extract_placeholders can extract time if time key and range are configured' do |api|
|
235
247
|
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'time', {'timekey' => 60*30, 'timekey_zone' => "+0900"})]))
|
236
248
|
assert @i.chunk_key_time
|
237
249
|
assert !@i.chunk_key_tag
|
@@ -239,11 +251,17 @@ class OutputTest < Test::Unit::TestCase
|
|
239
251
|
tmpl = "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[1]}/${tag[2]}/${key1}/${key2}/tail"
|
240
252
|
t = event_time('2016-04-11 20:30:00 +0900')
|
241
253
|
v = {key1: "value1", key2: "value2"}
|
242
|
-
|
243
|
-
|
254
|
+
c = if api == :chunk
|
255
|
+
create_chunk(timekey: t, tag: 'fluentd.test.output', variables: v)
|
256
|
+
else
|
257
|
+
create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
|
258
|
+
end
|
259
|
+
assert_equal "/mypath/2016/04/11/20-30/${tag}/${tag[1]}/${tag[2]}/${key1}/${key2}/tail", @i.extract_placeholders(tmpl, c)
|
244
260
|
end
|
245
261
|
|
246
|
-
|
262
|
+
data(:new_api => :chunk,
|
263
|
+
:old_api => :metadata)
|
264
|
+
test '#extract_placeholders can extract tag and parts of tag if tag is configured' do |api|
|
247
265
|
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'tag', {})]))
|
248
266
|
assert !@i.chunk_key_time
|
249
267
|
assert @i.chunk_key_tag
|
@@ -251,11 +269,17 @@ class OutputTest < Test::Unit::TestCase
|
|
251
269
|
tmpl = "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[1]}/${tag[2]}/${key1}/${key2}/tail"
|
252
270
|
t = event_time('2016-04-11 20:30:00 +0900')
|
253
271
|
v = {key1: "value1", key2: "value2"}
|
254
|
-
|
255
|
-
|
272
|
+
c = if api == :chunk
|
273
|
+
create_chunk(timekey: t, tag: 'fluentd.test.output', variables: v)
|
274
|
+
else
|
275
|
+
create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
|
276
|
+
end
|
277
|
+
assert_equal "/mypath/%Y/%m/%d/%H-%M/fluentd.test.output/test/output/${key1}/${key2}/tail", @i.extract_placeholders(tmpl, c)
|
256
278
|
end
|
257
279
|
|
258
|
-
|
280
|
+
data(:new_api => :chunk,
|
281
|
+
:old_api => :metadata)
|
282
|
+
test '#extract_placeholders can extract variables if variables are configured' do |api|
|
259
283
|
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'key1,key2', {})]))
|
260
284
|
assert !@i.chunk_key_time
|
261
285
|
assert !@i.chunk_key_tag
|
@@ -263,32 +287,95 @@ class OutputTest < Test::Unit::TestCase
|
|
263
287
|
tmpl = "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[1]}/${tag[2]}/${key1}/${key2}/tail"
|
264
288
|
t = event_time('2016-04-11 20:30:00 +0900')
|
265
289
|
v = {key1: "value1", key2: "value2"}
|
266
|
-
|
267
|
-
|
290
|
+
c = if api == :chunk
|
291
|
+
create_chunk(timekey: t, tag: 'fluentd.test.output', variables: v)
|
292
|
+
else
|
293
|
+
create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
|
294
|
+
end
|
295
|
+
assert_equal "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[1]}/${tag[2]}/value1/value2/tail", @i.extract_placeholders(tmpl, c)
|
296
|
+
end
|
297
|
+
|
298
|
+
data(:new_api => :chunk,
|
299
|
+
:old_api => :metadata)
|
300
|
+
test '#extract_placeholders can extract nested variables if variables are configured with dot notation' do |api|
|
301
|
+
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'key,$.nest.key', {})]))
|
302
|
+
assert !@i.chunk_key_time
|
303
|
+
assert !@i.chunk_key_tag
|
304
|
+
assert_equal ['key','$.nest.key'], @i.chunk_keys
|
305
|
+
tmpl = "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[1]}/${tag[2]}/${key}/${$.nest.key}/tail"
|
306
|
+
t = event_time('2016-04-11 20:30:00 +0900')
|
307
|
+
v = {:key => "value1", :"$.nest.key" => "value2"}
|
308
|
+
c = if api == :chunk
|
309
|
+
create_chunk(timekey: t, tag: 'fluentd.test.output', variables: v)
|
310
|
+
else
|
311
|
+
create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
|
312
|
+
end
|
313
|
+
assert_equal "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[1]}/${tag[2]}/value1/value2/tail", @i.extract_placeholders(tmpl, c)
|
314
|
+
end
|
315
|
+
|
316
|
+
data(:new_api => :chunk,
|
317
|
+
:old_api => :metadata)
|
318
|
+
test '#extract_placeholders can extract all chunk keys if configured' do |api|
|
319
|
+
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'time,tag,key1,key2', {'timekey' => 60*30, 'timekey_zone' => "+0900"})]))
|
320
|
+
assert @i.chunk_key_time
|
321
|
+
assert @i.chunk_key_tag
|
322
|
+
assert_equal ['key1','key2'], @i.chunk_keys
|
323
|
+
tmpl = "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[1]}/${tag[2]}/${key1}/${key2}/tail"
|
324
|
+
t = event_time('2016-04-11 20:30:00 +0900')
|
325
|
+
v = {key1: "value1", key2: "value2"}
|
326
|
+
c = if api == :chunk
|
327
|
+
create_chunk(timekey: t, tag: 'fluentd.test.output', variables: v)
|
328
|
+
else
|
329
|
+
create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
|
330
|
+
end
|
331
|
+
assert_equal "/mypath/2016/04/11/20-30/fluentd.test.output/test/output/value1/value2/tail", @i.extract_placeholders(tmpl, c)
|
268
332
|
end
|
269
333
|
|
270
|
-
|
334
|
+
data(:new_api => :chunk,
|
335
|
+
:old_api => :metadata)
|
336
|
+
test '#extract_placeholders can extract negative index with tag' do |api|
|
271
337
|
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'time,tag,key1,key2', {'timekey' => 60*30, 'timekey_zone' => "+0900"})]))
|
272
338
|
assert @i.chunk_key_time
|
273
339
|
assert @i.chunk_key_tag
|
274
340
|
assert_equal ['key1','key2'], @i.chunk_keys
|
275
|
-
tmpl = "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[1]}/${tag[2]}/${key1}/${key2}/tail"
|
341
|
+
tmpl = "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[-1]}/${tag[-2]}/${key1}/${key2}/tail"
|
276
342
|
t = event_time('2016-04-11 20:30:00 +0900')
|
277
343
|
v = {key1: "value1", key2: "value2"}
|
278
|
-
|
279
|
-
|
344
|
+
c = if api == :chunk
|
345
|
+
create_chunk(timekey: t, tag: 'fluentd.test.output', variables: v)
|
346
|
+
else
|
347
|
+
create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
|
348
|
+
end
|
349
|
+
assert_equal "/mypath/2016/04/11/20-30/fluentd.test.output/output/test/value1/value2/tail", @i.extract_placeholders(tmpl, c)
|
280
350
|
end
|
281
351
|
|
282
|
-
|
352
|
+
data(:new_api => :chunk,
|
353
|
+
:old_api => :metadata)
|
354
|
+
test '#extract_placeholders removes out-of-range tag part and unknown variable placeholders' do |api|
|
283
355
|
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'time,tag,key1,key2', {'timekey' => 60*30, 'timekey_zone' => "+0900"})]))
|
284
356
|
assert @i.chunk_key_time
|
285
357
|
assert @i.chunk_key_tag
|
286
358
|
assert_equal ['key1','key2'], @i.chunk_keys
|
287
|
-
tmpl = "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[3]}/${tag[4]}/${key3}/${key4}/tail"
|
359
|
+
tmpl = "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[3]}/${tag[-4]}/${key3}/${key4}/tail"
|
360
|
+
t = event_time('2016-04-11 20:30:00 +0900')
|
361
|
+
v = {key1: "value1", key2: "value2"}
|
362
|
+
c = if api == :chunk
|
363
|
+
create_chunk(timekey: t, tag: 'fluentd.test.output', variables: v)
|
364
|
+
else
|
365
|
+
create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
|
366
|
+
end
|
367
|
+
assert_equal "/mypath/2016/04/11/20-30/fluentd.test.output/////tail", @i.extract_placeholders(tmpl, c)
|
368
|
+
end
|
369
|
+
|
370
|
+
test '#extract_placeholders logs warn message if metadata is passed for ${chunk_id} placeholder' do
|
371
|
+
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
|
372
|
+
tmpl = "/mypath/${chunk_id}/tail"
|
288
373
|
t = event_time('2016-04-11 20:30:00 +0900')
|
289
374
|
v = {key1: "value1", key2: "value2"}
|
290
375
|
m = create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
|
291
|
-
|
376
|
+
@i.extract_placeholders(tmpl, m)
|
377
|
+
logs = @i.log.out.logs
|
378
|
+
assert { logs.any? { |log| log.include?("${chunk_id} is not allowed in this plugin") } }
|
292
379
|
end
|
293
380
|
|
294
381
|
sub_test_case '#placeholder_validators' do
|
@@ -372,7 +459,7 @@ class OutputTest < Test::Unit::TestCase
|
|
372
459
|
end
|
373
460
|
|
374
461
|
sub_test_case '#placeholder_validate!' do
|
375
|
-
test 'raises configuration error for a
|
462
|
+
test 'raises configuration error for a template when timestamp placeholders exist but time key is missing' do
|
376
463
|
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
|
377
464
|
assert_raise Fluent::ConfigError.new("Parameter 'path: /path/without/timestamp/file.%Y%m%d-%H%M.log' has timestamp placeholders, but chunk key 'time' is not configured") do
|
378
465
|
@i.placeholder_validate!(:path, "/path/without/timestamp/file.%Y%m%d-%H%M.log")
|
@@ -414,6 +501,9 @@ class OutputTest < Test::Unit::TestCase
|
|
414
501
|
assert_nothing_raised do
|
415
502
|
@i.placeholder_validate!(:path, "/my/path/${tag}/file.${tag[2]}.log")
|
416
503
|
end
|
504
|
+
assert_nothing_raised do
|
505
|
+
@i.placeholder_validate!(:path, "/my/path/${tag}/file.${tag[-1]}.log")
|
506
|
+
end
|
417
507
|
end
|
418
508
|
|
419
509
|
test 'raises configuration error for a template when variable key placeholders exist but chunk keys are missing' do
|
@@ -493,11 +583,21 @@ class OutputTest < Test::Unit::TestCase
|
|
493
583
|
assert_equal ['.hidden', '0001', '@timestamp', 'a_key', 'my-domain'], @i.get_placeholders_keys("http://${my-domain}/${.hidden}/${0001}/${a_key}?timestamp=${@timestamp}")
|
494
584
|
end
|
495
585
|
|
586
|
+
data('include space' => 'ke y',
|
587
|
+
'bracket notation' => "$['key']",
|
588
|
+
'invalid notation' => "$.ke y")
|
589
|
+
test 'configure checks invalid chunk keys' do |chunk_keys|
|
590
|
+
i = create_output(:buffered)
|
591
|
+
assert_raise Fluent::ConfigError do
|
592
|
+
i.configure(config_element('ROOT' , '', {}, [config_element('buffer', chunk_keys)]))
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
496
596
|
test '#metadata returns object which contains tag/timekey/variables from records as specified in configuration' do
|
497
597
|
tag = 'test.output'
|
498
598
|
time = event_time('2016-04-12 15:31:23 -0700')
|
499
599
|
timekey = event_time('2016-04-12 15:00:00 -0700')
|
500
|
-
record = {"key1" => "value1", "num1" => 1, "message" => "my message"}
|
600
|
+
record = {"key1" => "value1", "num1" => 1, "message" => "my message", "nest" => {"key" => "nested value"}}
|
501
601
|
|
502
602
|
i1 = create_output(:buffered)
|
503
603
|
i1.configure(config_element('ROOT','',{},[config_element('buffer', '')]))
|
@@ -530,6 +630,10 @@ class OutputTest < Test::Unit::TestCase
|
|
530
630
|
i8 = create_output(:buffered)
|
531
631
|
i8.configure(config_element('ROOT','',{},[config_element('buffer', 'time,tag,key1', {"timekey" => 3600, "timekey_zone" => "-0700"})]))
|
532
632
|
assert_equal create_metadata(timekey: timekey, tag: tag, variables: {key1: "value1"}), i8.metadata(tag, time, record)
|
633
|
+
|
634
|
+
i9 = create_output(:buffered)
|
635
|
+
i9.configure(config_element('ROOT','',{},[config_element('buffer', 'key1,$.nest.key', {})]))
|
636
|
+
assert_equal create_metadata(variables: {:key1 => "value1", :"$.nest.key" => 'nested value'}), i9.metadata(tag, time, record)
|
533
637
|
end
|
534
638
|
|
535
639
|
test '#emit calls #process via #emit_sync for non-buffered output' do
|
@@ -724,34 +828,43 @@ class OutputTest < Test::Unit::TestCase
|
|
724
828
|
assert_equal :interval, @i.instance_variable_get(:@flush_mode)
|
725
829
|
end
|
726
830
|
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
831
|
+
sub_test_case 'configure secondary' do
|
832
|
+
test "Warn if primary type is different from secondary type and either primary or secondary has custom_format" do
|
833
|
+
o = create_output(:buffered)
|
834
|
+
mock(o.log).warn("secondary type should be same with primary one",
|
835
|
+
{ primary: o.class.to_s, secondary: "Fluent::Plugin::TestOutput" })
|
731
836
|
|
732
|
-
|
733
|
-
|
734
|
-
|
837
|
+
o.configure(config_element('ROOT','',{},[config_element('secondary','',{'@type'=>'test', 'name' => "cool"})]))
|
838
|
+
assert_not_nil o.instance_variable_get(:@secondary)
|
839
|
+
end
|
735
840
|
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
841
|
+
test "don't warn if primary type is the same as secondary type" do
|
842
|
+
o = Fluent::Plugin::TestOutput.new
|
843
|
+
mock(o.log).warn("secondary type should be same with primary one",
|
844
|
+
{ primary: o.class.to_s, secondary: "Fluent::Plugin::TestOutput" }).never
|
740
845
|
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
846
|
+
o.configure(config_element('ROOT','',{'name' => "cool2"},
|
847
|
+
[config_element('secondary','',{'@type'=>'test', 'name' => "cool"}),
|
848
|
+
config_element('buffer','',{'@type'=>'memory'})]
|
849
|
+
))
|
850
|
+
assert_not_nil o.instance_variable_get(:@secondary)
|
851
|
+
end
|
747
852
|
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
853
|
+
test "don't warn if primary type is different from secondary type and both don't have custom_format" do
|
854
|
+
o = create_output(:standard)
|
855
|
+
mock(o.log).warn("secondary type should be same with primary one",
|
856
|
+
{ primary: o.class.to_s, secondary: "Fluent::Plugin::TestOutput" }).never
|
752
857
|
|
753
|
-
|
754
|
-
|
858
|
+
o.configure(config_element('ROOT','',{},[config_element('secondary','',{'@type'=>'test', 'name' => "cool"})]))
|
859
|
+
assert_not_nil o.instance_variable_get(:@secondary)
|
860
|
+
end
|
861
|
+
|
862
|
+
test "raise configuration error if secondary type specifies non buffered output" do
|
863
|
+
o = create_output(:standard)
|
864
|
+
assert_raise Fluent::ConfigError do
|
865
|
+
o.configure(config_element('ROOT','',{},[config_element('secondary','',{'@type'=>'copy'})]))
|
866
|
+
end
|
867
|
+
end
|
755
868
|
end
|
756
869
|
end
|
757
870
|
|
@@ -824,7 +937,8 @@ class OutputTest < Test::Unit::TestCase
|
|
824
937
|
|
825
938
|
sub_test_case 'slow_flush_log_threshold' do
|
826
939
|
def invoke_slow_flush_log_threshold_test(i)
|
827
|
-
i.configure(config_element('ROOT', '', {'slow_flush_log_threshold' => 0.5},
|
940
|
+
i.configure(config_element('ROOT', '', {'slow_flush_log_threshold' => 0.5},
|
941
|
+
[config_element('buffer', '', {"flush_mode" => "immediate", "flush_thread_interval" => 30})]))
|
828
942
|
i.start
|
829
943
|
i.after_start
|
830
944
|
|