fluentd 0.14.7-x86-mingw32 → 0.14.10-x86-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/.gitignore +2 -0
- data/.travis.yml +2 -0
- data/CONTRIBUTING.md +6 -1
- data/ChangeLog +95 -0
- data/Rakefile +21 -0
- data/appveyor.yml +1 -0
- data/code-of-conduct.md +3 -0
- data/example/out_exec_filter.conf +42 -0
- data/fluentd.gemspec +1 -1
- data/lib/fluent/agent.rb +2 -2
- data/lib/fluent/command/binlog_reader.rb +1 -1
- data/lib/fluent/command/cat.rb +15 -4
- data/lib/fluent/compat/output.rb +14 -9
- data/lib/fluent/compat/parser.rb +141 -11
- data/lib/fluent/config/configure_proxy.rb +2 -11
- data/lib/fluent/config/section.rb +8 -1
- data/lib/fluent/configurable.rb +1 -3
- data/lib/fluent/env.rb +1 -1
- data/lib/fluent/log.rb +1 -1
- data/lib/fluent/plugin/base.rb +17 -0
- data/lib/fluent/plugin/filter_parser.rb +108 -0
- data/lib/fluent/plugin/filter_record_transformer.rb +14 -35
- data/lib/fluent/plugin/filter_stdout.rb +1 -1
- data/lib/fluent/plugin/formatter.rb +5 -0
- data/lib/fluent/plugin/formatter_msgpack.rb +4 -0
- data/lib/fluent/plugin/formatter_stdout.rb +3 -2
- data/lib/fluent/plugin/formatter_tsv.rb +34 -0
- data/lib/fluent/plugin/in_exec.rb +48 -93
- data/lib/fluent/plugin/in_forward.rb +66 -265
- data/lib/fluent/plugin/in_http.rb +68 -65
- data/lib/fluent/plugin/in_monitor_agent.rb +8 -4
- data/lib/fluent/plugin/in_syslog.rb +42 -58
- data/lib/fluent/plugin/in_tail.rb +29 -14
- data/lib/fluent/plugin/in_tcp.rb +54 -14
- data/lib/fluent/plugin/in_udp.rb +49 -13
- data/lib/fluent/plugin/multi_output.rb +1 -3
- data/lib/fluent/plugin/out_exec.rb +58 -71
- data/lib/fluent/plugin/out_exec_filter.rb +199 -279
- data/lib/fluent/plugin/out_file.rb +172 -81
- data/lib/fluent/plugin/out_forward.rb +229 -206
- data/lib/fluent/plugin/out_stdout.rb +6 -21
- data/lib/fluent/plugin/output.rb +90 -59
- data/lib/fluent/plugin/parser.rb +121 -61
- data/lib/fluent/plugin/parser_csv.rb +9 -3
- data/lib/fluent/plugin/parser_json.rb +37 -35
- data/lib/fluent/plugin/parser_ltsv.rb +11 -19
- data/lib/fluent/plugin/parser_msgpack.rb +50 -0
- data/lib/fluent/plugin/parser_regexp.rb +15 -42
- data/lib/fluent/plugin/parser_tsv.rb +8 -3
- data/lib/fluent/plugin_helper.rb +10 -1
- data/lib/fluent/plugin_helper/child_process.rb +139 -73
- data/lib/fluent/plugin_helper/compat_parameters.rb +93 -4
- data/lib/fluent/plugin_helper/event_emitter.rb +14 -1
- data/lib/fluent/plugin_helper/event_loop.rb +24 -6
- data/lib/fluent/plugin_helper/extract.rb +16 -4
- data/lib/fluent/plugin_helper/formatter.rb +9 -11
- data/lib/fluent/plugin_helper/inject.rb +16 -1
- data/lib/fluent/plugin_helper/parser.rb +3 -3
- data/lib/fluent/plugin_helper/server.rb +494 -0
- data/lib/fluent/plugin_helper/socket.rb +101 -0
- data/lib/fluent/plugin_helper/socket_option.rb +84 -0
- data/lib/fluent/plugin_helper/timer.rb +1 -0
- data/lib/fluent/root_agent.rb +1 -1
- data/lib/fluent/test/driver/base.rb +95 -49
- data/lib/fluent/test/driver/base_owner.rb +18 -8
- data/lib/fluent/test/driver/multi_output.rb +2 -1
- data/lib/fluent/test/driver/output.rb +29 -6
- data/lib/fluent/test/helpers.rb +3 -1
- data/lib/fluent/test/log.rb +4 -0
- data/lib/fluent/test/startup_shutdown.rb +13 -0
- data/lib/fluent/time.rb +14 -8
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +1 -1
- data/test/command/test_binlog_reader.rb +5 -1
- data/test/compat/test_parser.rb +10 -0
- data/test/config/test_configurable.rb +193 -0
- data/test/config/test_configure_proxy.rb +0 -43
- data/test/helper.rb +36 -1
- data/test/plugin/test_base.rb +16 -0
- data/test/plugin/test_filter_parser.rb +665 -0
- data/test/plugin/test_filter_record_transformer.rb +36 -100
- data/test/plugin/test_filter_stdout.rb +18 -27
- data/test/plugin/test_in_dummy.rb +1 -1
- data/test/plugin/test_in_exec.rb +206 -94
- data/test/plugin/test_in_forward.rb +268 -347
- data/test/plugin/test_in_http.rb +310 -186
- data/test/plugin/test_in_monitor_agent.rb +65 -35
- data/test/plugin/test_in_syslog.rb +39 -3
- data/test/plugin/test_in_tcp.rb +78 -62
- data/test/plugin/test_in_udp.rb +101 -80
- data/test/plugin/test_out_exec.rb +223 -68
- data/test/plugin/test_out_exec_filter.rb +520 -169
- data/test/plugin/test_out_file.rb +637 -177
- data/test/plugin/test_out_forward.rb +242 -234
- data/test/plugin/test_out_null.rb +1 -1
- data/test/plugin/test_out_secondary_file.rb +4 -2
- data/test/plugin/test_out_stdout.rb +14 -35
- data/test/plugin/test_output_as_buffered.rb +60 -2
- data/test/plugin/test_parser.rb +359 -0
- data/test/plugin/test_parser_csv.rb +1 -2
- data/test/plugin/test_parser_json.rb +3 -4
- data/test/plugin/test_parser_labeled_tsv.rb +1 -2
- data/test/plugin/test_parser_none.rb +1 -2
- data/test/plugin/test_parser_regexp.rb +8 -4
- data/test/plugin/test_parser_tsv.rb +4 -3
- data/test/plugin_helper/test_child_process.rb +184 -0
- data/test/plugin_helper/test_compat_parameters.rb +88 -1
- data/test/plugin_helper/test_extract.rb +0 -1
- data/test/plugin_helper/test_formatter.rb +5 -2
- data/test/plugin_helper/test_inject.rb +21 -0
- data/test/plugin_helper/test_parser.rb +6 -5
- data/test/plugin_helper/test_server.rb +905 -0
- data/test/test_event_time.rb +3 -1
- data/test/test_output.rb +53 -2
- data/test/test_plugin_classes.rb +20 -0
- data/test/test_root_agent.rb +139 -0
- data/test/test_test_drivers.rb +135 -0
- metadata +28 -8
- data/test/plugin/test_parser_base.rb +0 -32
@@ -37,8 +37,7 @@ class CSVParserTest < ::Test::Unit::TestCase
|
|
37
37
|
}
|
38
38
|
|
39
39
|
d = Fluent::Test::Driver::Parser.new(Fluent::Plugin::CSVParser)
|
40
|
-
d.
|
41
|
-
d.configure('keys' => param)
|
40
|
+
d.configure('keys' => param, 'estimate_current_event' => 'no')
|
42
41
|
d.instance.parse("192.168.0.1,111") { |time, record|
|
43
42
|
assert_equal({
|
44
43
|
'c' => '192.168.0.1',
|
@@ -44,8 +44,7 @@ class JsonParserTest < ::Test::Unit::TestCase
|
|
44
44
|
}
|
45
45
|
|
46
46
|
parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::JSONParser)
|
47
|
-
parser.
|
48
|
-
parser.configure('json_parser' => data)
|
47
|
+
parser.configure('json_parser' => data, 'estimate_current_event' => 'false')
|
49
48
|
parser.instance.parse('{"host":"192.168.0.1","size":777,"method":"PUT"}') { |time, record|
|
50
49
|
assert_equal({
|
51
50
|
'host' => '192.168.0.1',
|
@@ -78,8 +77,8 @@ class JsonParserTest < ::Test::Unit::TestCase
|
|
78
77
|
parser.configure('json_parser' => data)
|
79
78
|
text = "100.1"
|
80
79
|
parser.instance.parse("{\"time\":\"#{text}\"}") do |time, record|
|
81
|
-
assert_equal
|
82
|
-
assert_equal
|
80
|
+
assert_equal 100, time.sec
|
81
|
+
assert_equal 100_000_000, time.nsec
|
83
82
|
end
|
84
83
|
end
|
85
84
|
|
@@ -78,8 +78,7 @@ class LabeledTSVParserTest < ::Test::Unit::TestCase
|
|
78
78
|
}
|
79
79
|
|
80
80
|
parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::LabeledTSVParser)
|
81
|
-
parser.
|
82
|
-
parser.configure({})
|
81
|
+
parser.configure({'estimate_current_event' => 'no'})
|
83
82
|
parser.instance.parse("host:192.168.0.1\treq_id:111") { |time, record|
|
84
83
|
assert_equal({
|
85
84
|
'host' => '192.168.0.1',
|
@@ -43,8 +43,7 @@ class NoneParserTest < ::Test::Unit::TestCase
|
|
43
43
|
}
|
44
44
|
|
45
45
|
parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin.new_parser('none'))
|
46
|
-
parser.
|
47
|
-
parser.configure({})
|
46
|
+
parser.configure({'estimate_current_event' => 'false'})
|
48
47
|
parser.instance.parse('log message!') { |time, record|
|
49
48
|
assert_equal({'message' => 'log message!'}, record)
|
50
49
|
assert_nil time, "parser returns nil w/o time if configured so"
|
@@ -28,7 +28,12 @@ class RegexpParserTest < ::Test::Unit::TestCase
|
|
28
28
|
if initialize_conf
|
29
29
|
Fluent::Test::Driver::Parser.new(Fluent::Compat::TextParser::RegexpParser.new(regexp, conf))
|
30
30
|
else
|
31
|
-
Fluent::Test::Driver::Parser.new(Fluent::Compat::TextParser::RegexpParser.new(regexp)).configure(conf)
|
31
|
+
# Fluent::Test::Driver::Parser.new(Fluent::Compat::TextParser::RegexpParser.new(regexp)).configure(conf)
|
32
|
+
instance = Fluent::Compat::TextParser::RegexpParser.new(regexp)
|
33
|
+
instance.configure(conf)
|
34
|
+
d = Struct.new(:instance).new
|
35
|
+
d.instance = instance
|
36
|
+
d
|
32
37
|
end
|
33
38
|
end
|
34
39
|
|
@@ -188,12 +193,11 @@ class RegexpParserTest < ::Test::Unit::TestCase
|
|
188
193
|
internal_test_case(d.instance)
|
189
194
|
end
|
190
195
|
|
191
|
-
def
|
196
|
+
def test_parse_with_typed_by_json_hash
|
192
197
|
conf = {
|
193
198
|
'expression' => %q!/^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] \[(?<date>[^\]]*)\] "(?<flag>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)$/!,
|
194
199
|
'time_format' => "%d/%b/%Y:%H:%M:%S %z",
|
195
|
-
'types' => 'user
|
196
|
-
'types_label_delimiter' => '|'
|
200
|
+
'types' => '{"user":"string","date":"time:%d/%b/%Y:%H:%M:%S %z","flag":"bool","path":"array","code":"float","size":"integer"}',
|
197
201
|
}
|
198
202
|
d = create_driver(conf)
|
199
203
|
internal_test_case(d.instance)
|
@@ -13,7 +13,9 @@ class TSVParserTest < ::Test::Unit::TestCase
|
|
13
13
|
|
14
14
|
data('array param' => '["a","b"]', 'string param' => 'a,b')
|
15
15
|
def test_config_params(param)
|
16
|
-
d = create_driver
|
16
|
+
d = create_driver(
|
17
|
+
'keys' => param,
|
18
|
+
)
|
17
19
|
|
18
20
|
assert_equal "\t", d.instance.delimiter
|
19
21
|
|
@@ -51,8 +53,7 @@ class TSVParserTest < ::Test::Unit::TestCase
|
|
51
53
|
}
|
52
54
|
|
53
55
|
d = Fluent::Test::Driver::Parser.new(Fluent::Plugin::TSVParser)
|
54
|
-
d.
|
55
|
-
d.configure('keys' => 'a,b', 'time_key' => 'time')
|
56
|
+
d.configure('keys' => 'a,b', 'time_key' => 'time', 'estimate_current_event' => 'no')
|
56
57
|
d.instance.parse("192.168.0.1\t111") { |time, record|
|
57
58
|
assert_equal({
|
58
59
|
'a' => '192.168.0.1',
|
@@ -2,6 +2,7 @@ require_relative '../helper'
|
|
2
2
|
require 'fluent/plugin_helper/child_process'
|
3
3
|
require 'fluent/plugin/base'
|
4
4
|
require 'timeout'
|
5
|
+
require 'tempfile'
|
5
6
|
|
6
7
|
class ChildProcessTest < Test::Unit::TestCase
|
7
8
|
TEST_DEADLOCK_TIMEOUT = 30
|
@@ -605,4 +606,187 @@ class ChildProcessTest < Test::Unit::TestCase
|
|
605
606
|
end
|
606
607
|
end
|
607
608
|
end
|
609
|
+
|
610
|
+
sub_test_case 'on_exit_callback is specified' do
|
611
|
+
setup do
|
612
|
+
@temp = Tempfile.create("child_process_wait_with_on_exit_callback")
|
613
|
+
@temp_path = @temp.path
|
614
|
+
@temp.close
|
615
|
+
end
|
616
|
+
|
617
|
+
teardown do
|
618
|
+
File.unlink @temp_path if File.exist?(@temp_path)
|
619
|
+
end
|
620
|
+
|
621
|
+
test 'can return exit status for child process successfully exits using on_exit_callback' do
|
622
|
+
assert File.exist?(@temp_path)
|
623
|
+
|
624
|
+
block_exits = false
|
625
|
+
callback_called = false
|
626
|
+
exit_status = nil
|
627
|
+
args = ['-e', 'sleep ARGV[0].to_i; puts "yay"; File.unlink ARGV[1]', '1', @temp_path]
|
628
|
+
cb = ->(status){ exit_status = status; callback_called = true }
|
629
|
+
|
630
|
+
str = nil
|
631
|
+
|
632
|
+
Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
|
633
|
+
pid = nil
|
634
|
+
@d.child_process_execute(:st1, "ruby", arguments: args, mode: [:read], on_exit_callback: cb) do |readio|
|
635
|
+
pid = @d.instance_eval{ child_process_id }
|
636
|
+
str = readio.read.chomp
|
637
|
+
block_exits = true
|
638
|
+
end
|
639
|
+
sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING while @d.child_process_exist?(pid) # to get exit status
|
640
|
+
sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until block_exits
|
641
|
+
sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until callback_called
|
642
|
+
end
|
643
|
+
|
644
|
+
assert callback_called
|
645
|
+
assert exit_status
|
646
|
+
assert_equal 0, exit_status.exitstatus
|
647
|
+
assert !File.exist?(@temp_path)
|
648
|
+
|
649
|
+
assert_equal "yay", str
|
650
|
+
end
|
651
|
+
|
652
|
+
test 'can return exit status with signal code for child process killed by signal using on_exit_callback' do
|
653
|
+
omit "SIGQUIT is unsupported on Windows" if Fluent.windows?
|
654
|
+
|
655
|
+
assert File.exist?(@temp_path)
|
656
|
+
|
657
|
+
block_exits = false
|
658
|
+
callback_called = false
|
659
|
+
exit_status = nil
|
660
|
+
args = ['-e', 'sleep ARGV[0].to_i; puts "yay"; File.unlink ARGV[1]', '25', @temp_path]
|
661
|
+
cb = ->(status){ exit_status = status; callback_called = true }
|
662
|
+
|
663
|
+
str = nil
|
664
|
+
|
665
|
+
Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
|
666
|
+
pid = nil
|
667
|
+
@d.child_process_execute(:st1, "ruby", arguments: args, mode: [:read], on_exit_callback: cb) do |readio|
|
668
|
+
pid = @d.instance_eval{ child_process_id }
|
669
|
+
Process.kill(:QUIT, pid)
|
670
|
+
Process.kill(:QUIT, pid) rescue nil # once more to kill certainly
|
671
|
+
str = readio.read.chomp rescue nil # empty string before EOF
|
672
|
+
block_exits = true
|
673
|
+
end
|
674
|
+
sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING while @d.child_process_exist?(pid) # to get exit status
|
675
|
+
sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until block_exits
|
676
|
+
sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until callback_called
|
677
|
+
end
|
678
|
+
|
679
|
+
assert callback_called
|
680
|
+
assert exit_status
|
681
|
+
|
682
|
+
assert_equal [nil, 3], [exit_status.exitstatus, exit_status.termsig] # SIGQUIT
|
683
|
+
|
684
|
+
assert File.exist?(@temp_path)
|
685
|
+
assert_equal "", str
|
686
|
+
end
|
687
|
+
|
688
|
+
test 'calls on_exit_callback for each process exits for interval call using on_exit_callback' do
|
689
|
+
read_data_list = []
|
690
|
+
exit_status_list = []
|
691
|
+
|
692
|
+
args = ['-e', 'puts "yay"', '1']
|
693
|
+
cb = ->(status){ exit_status_list << status }
|
694
|
+
|
695
|
+
Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
|
696
|
+
@d.child_process_execute(:st1, "ruby", arguments: args, immediate: true, interval: 2, mode: [:read], on_exit_callback: cb) do |readio|
|
697
|
+
read_data_list << readio.read.chomp
|
698
|
+
end
|
699
|
+
sleep 10
|
700
|
+
end
|
701
|
+
|
702
|
+
assert{ read_data_list.size >= 3 }
|
703
|
+
assert{ exit_status_list.size >= 3 }
|
704
|
+
end
|
705
|
+
|
706
|
+
test 'waits lasting child process until wait_timeout if block is not specified' do
|
707
|
+
assert File.exist?(@temp_path)
|
708
|
+
|
709
|
+
callback_called = false
|
710
|
+
exit_status = nil
|
711
|
+
args = ['-e', 'sleep ARGV[0].to_i; File.unlink ARGV[1]', '1', @temp_path]
|
712
|
+
cb = ->(status){ exit_status = status; callback_called = true }
|
713
|
+
|
714
|
+
Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
|
715
|
+
@d.child_process_execute(:t17, "ruby", arguments: args, on_exit_callback: cb, wait_timeout: 5)
|
716
|
+
sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until callback_called
|
717
|
+
end
|
718
|
+
|
719
|
+
assert callback_called
|
720
|
+
assert exit_status
|
721
|
+
assert_equal 0, exit_status.exitstatus
|
722
|
+
assert !File.exist?(@temp_path)
|
723
|
+
end
|
724
|
+
|
725
|
+
test 'waits lasting child process until wait_timeout after block rans if block is specified' do
|
726
|
+
assert File.exist?(@temp_path)
|
727
|
+
|
728
|
+
callback_called = false
|
729
|
+
exit_status = nil
|
730
|
+
args = ['-e', 'sleep ARGV[0].to_i; File.unlink ARGV[1]', '3', @temp_path]
|
731
|
+
cb = ->(status){ exit_status = status; callback_called = true }
|
732
|
+
|
733
|
+
Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
|
734
|
+
@d.child_process_execute(:t17, "ruby", arguments: args, mode: nil, on_exit_callback: cb, wait_timeout: 10) do
|
735
|
+
sleep 1
|
736
|
+
end
|
737
|
+
sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until callback_called
|
738
|
+
end
|
739
|
+
|
740
|
+
assert callback_called
|
741
|
+
assert exit_status
|
742
|
+
assert_equal 0, exit_status.exitstatus
|
743
|
+
assert !File.exist?(@temp_path)
|
744
|
+
end
|
745
|
+
|
746
|
+
test 'kills lasting child process after wait_timeout if block is not specified' do
|
747
|
+
assert File.exist?(@temp_path)
|
748
|
+
|
749
|
+
callback_called = false
|
750
|
+
exit_status = nil
|
751
|
+
args = ['-e', 'sleep ARGV[0].to_i; File.unlink ARGV[1]', '20', @temp_path]
|
752
|
+
cb = ->(status){ exit_status = status; callback_called = true }
|
753
|
+
|
754
|
+
Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
|
755
|
+
@d.child_process_execute(:t17, "ruby", arguments: args, on_exit_callback: cb, wait_timeout: 3)
|
756
|
+
sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until callback_called
|
757
|
+
end
|
758
|
+
|
759
|
+
assert callback_called
|
760
|
+
assert exit_status
|
761
|
+
unless Fluent.windows? # On Windows, exitstatus is always 0 and termsig is nil
|
762
|
+
assert_nil exit_status.exitstatus
|
763
|
+
assert_equal 9, exit_status.termsig # SIGKILL
|
764
|
+
end
|
765
|
+
assert File.exist?(@temp_path)
|
766
|
+
end
|
767
|
+
|
768
|
+
test 'kills lasting child process after block ran and wait_timeout expires if block is specified' do
|
769
|
+
assert File.exist?(@temp_path)
|
770
|
+
|
771
|
+
callback_called = false
|
772
|
+
exit_status = nil
|
773
|
+
args = ['-e', 'sleep ARGV[0].to_i; File.unlink ARGV[1]', '20', @temp_path]
|
774
|
+
cb = ->(status){ exit_status = status; callback_called = true }
|
775
|
+
|
776
|
+
Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
|
777
|
+
@d.child_process_execute(:t17, "ruby", arguments: args, mode: nil, on_exit_callback: cb, wait_timeout: 3) do
|
778
|
+
sleep 3
|
779
|
+
end
|
780
|
+
sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until callback_called
|
781
|
+
end
|
782
|
+
|
783
|
+
assert callback_called
|
784
|
+
assert exit_status
|
785
|
+
unless Fluent.windows? # On Windows, exitstatus is always 0 and termsig is nil
|
786
|
+
assert_nil exit_status.exitstatus
|
787
|
+
assert_equal 9, exit_status.termsig # SIGKILL
|
788
|
+
end
|
789
|
+
assert File.exist?(@temp_path)
|
790
|
+
end
|
791
|
+
end
|
608
792
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require_relative '../helper'
|
2
2
|
require 'fluent/plugin_helper/compat_parameters'
|
3
|
-
require 'fluent/plugin/
|
3
|
+
require 'fluent/plugin/input'
|
4
|
+
require 'fluent/plugin/output'
|
5
|
+
require 'fluent/time'
|
4
6
|
|
5
7
|
require 'time'
|
6
8
|
|
@@ -21,6 +23,26 @@ class CompatParameterTest < Test::Unit::TestCase
|
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
26
|
+
class DummyI0 < Fluent::Plugin::Input
|
27
|
+
helpers :compat_parameters, :parser, :extract
|
28
|
+
attr_reader :parser
|
29
|
+
def configure(conf)
|
30
|
+
compat_parameters_convert(conf, :extract, :parser)
|
31
|
+
super
|
32
|
+
end
|
33
|
+
def start
|
34
|
+
super
|
35
|
+
@parser = parser_create
|
36
|
+
end
|
37
|
+
def produce_events(input_data)
|
38
|
+
emit_events = [] # tag, time, record
|
39
|
+
@parser.parse(input_data) do |time, record|
|
40
|
+
tag = extract_tag_from_record(record) || 'dummy_tag'
|
41
|
+
emit_events << [tag, time, record]
|
42
|
+
end
|
43
|
+
emit_events
|
44
|
+
end
|
45
|
+
end
|
24
46
|
class DummyO0 < Fluent::Plugin::Output
|
25
47
|
helpers :compat_parameters
|
26
48
|
def configure(conf)
|
@@ -239,4 +261,69 @@ class CompatParameterTest < Test::Unit::TestCase
|
|
239
261
|
assert_equal "value%1,tag%tag.test,time%#{iso8601str}\n", formatted
|
240
262
|
end
|
241
263
|
end
|
264
|
+
|
265
|
+
sub_test_case 'input plugins' do
|
266
|
+
test 'plugin helper converts parameters into plugin configuration parameters for extract and parser' do
|
267
|
+
hash = {
|
268
|
+
'format' => 'ltsv',
|
269
|
+
'delimiter' => ',',
|
270
|
+
'label_delimiter' => '%',
|
271
|
+
'tag_key' => 't2',
|
272
|
+
'time_key' => 't',
|
273
|
+
'time_format' => '%Y-%m-%d.%H:%M:%S.%N',
|
274
|
+
'utc' => 'yes',
|
275
|
+
'types' => 'A integer|B string|C bool',
|
276
|
+
'types_delimiter' => '|',
|
277
|
+
'types_label_delimiter' => ' ',
|
278
|
+
}
|
279
|
+
conf = config_element('ROOT', '', hash)
|
280
|
+
@i = DummyI0.new
|
281
|
+
@i.configure(conf)
|
282
|
+
@i.start
|
283
|
+
@i.after_start
|
284
|
+
|
285
|
+
parser = @i.parser
|
286
|
+
assert{ parser.is_a? Fluent::Plugin::LabeledTSVParser }
|
287
|
+
assert_equal ',', parser.delimiter
|
288
|
+
assert_equal '%', parser.label_delimiter
|
289
|
+
|
290
|
+
events = @i.produce_events("A%1,B%x,C%true,t2%mytag,t%2016-10-20.03:50:11.987654321")
|
291
|
+
assert_equal 1, events.size
|
292
|
+
|
293
|
+
tag, time, record = events.first
|
294
|
+
assert_equal 'mytag', tag
|
295
|
+
assert_equal_event_time event_time("2016-10-20 03:50:11.987654321 +0000"), time
|
296
|
+
assert_equal 3, record.keys.size
|
297
|
+
assert_equal ['A','B','C'], record.keys.sort
|
298
|
+
assert_equal 1, record['A']
|
299
|
+
assert_equal 'x', record['B']
|
300
|
+
assert_equal true, record['C']
|
301
|
+
end
|
302
|
+
|
303
|
+
test 'plugin helper converts parameters into plugin configuration parameters for extract and parser, using numeric time' do
|
304
|
+
hash = {
|
305
|
+
'format' => 'ltsv',
|
306
|
+
'delimiter' => ',',
|
307
|
+
'label_delimiter' => '%',
|
308
|
+
'tag_key' => 't2',
|
309
|
+
'time_key' => 't',
|
310
|
+
'time_type' => 'float',
|
311
|
+
'localtime' => 'yes',
|
312
|
+
}
|
313
|
+
conf = config_element('ROOT', '', hash)
|
314
|
+
@i = DummyI0.new
|
315
|
+
@i.configure(conf)
|
316
|
+
@i.start
|
317
|
+
@i.after_start
|
318
|
+
|
319
|
+
parser = @i.parser
|
320
|
+
assert{ parser.is_a? Fluent::Plugin::LabeledTSVParser }
|
321
|
+
assert_equal ',', parser.delimiter
|
322
|
+
assert_equal '%', parser.label_delimiter
|
323
|
+
end
|
324
|
+
|
325
|
+
test 'plugin helper setups time extraction as unix time (integer from epoch)' do
|
326
|
+
# TODO:
|
327
|
+
end
|
328
|
+
end
|
242
329
|
end
|
@@ -50,7 +50,6 @@ class ExtractHelperTest < Test::Unit::TestCase
|
|
50
50
|
assert_nil @d.instance_eval{ @_extract_time_key }
|
51
51
|
assert_nil @d.instance_eval{ @_extract_time_parser }
|
52
52
|
|
53
|
-
time = event_time()
|
54
53
|
record = {"key1" => "value1", "key2" => 2, "tag" => "yay", "time" => Time.now.to_i}
|
55
54
|
|
56
55
|
assert_nil @d.extract_tag_from_record(record)
|
@@ -17,6 +17,9 @@ class FormatterHelperTest < Test::Unit::TestCase
|
|
17
17
|
end
|
18
18
|
class Dummy < Fluent::Plugin::TestBase
|
19
19
|
helpers :formatter
|
20
|
+
config_section :format do
|
21
|
+
config_set_default :@type, 'example'
|
22
|
+
end
|
20
23
|
end
|
21
24
|
|
22
25
|
class Dummy2 < Fluent::Plugin::TestBase
|
@@ -77,12 +80,12 @@ class FormatterHelperTest < Test::Unit::TestCase
|
|
77
80
|
end
|
78
81
|
end
|
79
82
|
|
80
|
-
test 'can be configured without format sections' do
|
83
|
+
test 'can be configured with default type without format sections' do
|
81
84
|
d = Dummy.new
|
82
85
|
assert_nothing_raised do
|
83
86
|
d.configure(config_element())
|
84
87
|
end
|
85
|
-
assert_equal
|
88
|
+
assert_equal 1, d._formatters.size
|
86
89
|
end
|
87
90
|
|
88
91
|
test 'can be configured with a format section' do
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative '../helper'
|
2
2
|
require 'fluent/plugin_helper/inject'
|
3
|
+
require 'fluent/plugin/output'
|
3
4
|
require 'fluent/event'
|
4
5
|
require 'time'
|
5
6
|
|
@@ -15,6 +16,13 @@ class InjectHelperTest < Test::Unit::TestCase
|
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
19
|
+
class Dummy3 < Fluent::Plugin::Output
|
20
|
+
helpers :inject
|
21
|
+
def write(chunk)
|
22
|
+
# dummy
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
18
26
|
def config_inject_section(hash = {})
|
19
27
|
config_element('ROOT', '', {}, [config_element('inject', '', hash)])
|
20
28
|
end
|
@@ -27,7 +35,9 @@ class InjectHelperTest < Test::Unit::TestCase
|
|
27
35
|
teardown do
|
28
36
|
if @d
|
29
37
|
@d.stop unless @d.stopped?
|
38
|
+
@d.before_shutdown unless @d.before_shutdown?
|
30
39
|
@d.shutdown unless @d.shutdown?
|
40
|
+
@d.after_shutdown unless @d.after_shutdown?
|
31
41
|
@d.close unless @d.closed?
|
32
42
|
@d.terminate unless @d.terminated?
|
33
43
|
end
|
@@ -93,6 +103,17 @@ class InjectHelperTest < Test::Unit::TestCase
|
|
93
103
|
assert_not_nil @d.instance_eval{ @_inject_time_formatter }
|
94
104
|
end
|
95
105
|
|
106
|
+
test 'raise an error when injected hostname is used in buffer chunk key too' do
|
107
|
+
@d = Dummy3.new
|
108
|
+
conf = config_element('ROOT', '', {}, [
|
109
|
+
config_element('inject', '', {'hostname_key' => 'h'}),
|
110
|
+
config_element('buffer', 'tag,h'),
|
111
|
+
])
|
112
|
+
assert_raise Fluent::ConfigError.new("the key specified by 'hostname_key' in <inject> cannot be used in buffering chunk key.") do
|
113
|
+
@d.configure(conf)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
96
117
|
sub_test_case 'using inject_values_to_record' do
|
97
118
|
test 'injects hostname automatically detected' do
|
98
119
|
detected_hostname = `hostname`.chomp
|