fluentd 0.12.40 → 0.14.0
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.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE.md +6 -0
- data/.gitignore +2 -0
- data/.travis.yml +33 -21
- data/CONTRIBUTING.md +1 -0
- data/ChangeLog +810 -237
- data/README.md +0 -25
- data/Rakefile +2 -1
- data/Vagrantfile +17 -0
- data/appveyor.yml +35 -0
- data/example/filter_stdout.conf +5 -5
- data/example/in_forward.conf +2 -2
- data/example/in_http.conf +2 -2
- data/example/in_out_forward.conf +17 -0
- data/example/in_syslog.conf +2 -2
- data/example/in_tail.conf +2 -2
- data/example/in_tcp.conf +2 -2
- data/example/in_udp.conf +2 -2
- data/example/out_copy.conf +4 -4
- data/example/out_file.conf +2 -2
- data/example/out_forward.conf +2 -2
- data/example/out_forward_buf_file.conf +23 -0
- data/example/v0_12_filter.conf +8 -8
- data/fluent.conf +29 -0
- data/fluentd.gemspec +18 -11
- data/lib/fluent/agent.rb +60 -58
- data/lib/fluent/command/cat.rb +1 -1
- data/lib/fluent/command/debug.rb +7 -5
- data/lib/fluent/command/fluentd.rb +97 -2
- data/lib/fluent/compat/call_super_mixin.rb +67 -0
- data/lib/fluent/compat/filter.rb +50 -0
- data/lib/fluent/compat/formatter.rb +109 -0
- data/lib/fluent/compat/input.rb +50 -0
- data/lib/fluent/compat/output.rb +617 -0
- data/lib/fluent/compat/output_chain.rb +60 -0
- data/lib/fluent/compat/parser.rb +163 -0
- data/lib/fluent/compat/propagate_default.rb +62 -0
- data/lib/fluent/config.rb +23 -20
- data/lib/fluent/config/configure_proxy.rb +119 -70
- data/lib/fluent/config/dsl.rb +5 -18
- data/lib/fluent/config/element.rb +72 -8
- data/lib/fluent/config/error.rb +0 -3
- data/lib/fluent/config/literal_parser.rb +0 -2
- data/lib/fluent/config/parser.rb +4 -4
- data/lib/fluent/config/section.rb +39 -28
- data/lib/fluent/config/types.rb +2 -13
- data/lib/fluent/config/v1_parser.rb +1 -3
- data/lib/fluent/configurable.rb +48 -16
- data/lib/fluent/daemon.rb +15 -0
- data/lib/fluent/engine.rb +26 -52
- data/lib/fluent/env.rb +6 -4
- data/lib/fluent/event.rb +58 -11
- data/lib/fluent/event_router.rb +5 -5
- data/lib/fluent/filter.rb +2 -50
- data/lib/fluent/formatter.rb +4 -293
- data/lib/fluent/input.rb +2 -32
- data/lib/fluent/label.rb +2 -2
- data/lib/fluent/load.rb +3 -2
- data/lib/fluent/log.rb +107 -38
- data/lib/fluent/match.rb +0 -36
- data/lib/fluent/mixin.rb +117 -7
- data/lib/fluent/msgpack_factory.rb +62 -0
- data/lib/fluent/output.rb +7 -612
- data/lib/fluent/output_chain.rb +23 -0
- data/lib/fluent/parser.rb +4 -800
- data/lib/fluent/plugin.rb +100 -121
- data/lib/fluent/plugin/bare_output.rb +63 -0
- data/lib/fluent/plugin/base.rb +121 -0
- data/lib/fluent/plugin/buf_file.rb +101 -182
- data/lib/fluent/plugin/buf_memory.rb +9 -92
- data/lib/fluent/plugin/buffer.rb +473 -0
- data/lib/fluent/plugin/buffer/chunk.rb +135 -0
- data/lib/fluent/plugin/buffer/file_chunk.rb +339 -0
- data/lib/fluent/plugin/buffer/memory_chunk.rb +100 -0
- data/lib/fluent/plugin/exec_util.rb +80 -75
- data/lib/fluent/plugin/file_util.rb +33 -28
- data/lib/fluent/plugin/file_wrapper.rb +120 -0
- data/lib/fluent/plugin/filter.rb +51 -0
- data/lib/fluent/plugin/filter_grep.rb +13 -40
- data/lib/fluent/plugin/filter_record_transformer.rb +22 -18
- data/lib/fluent/plugin/formatter.rb +93 -0
- data/lib/fluent/plugin/formatter_csv.rb +48 -0
- data/lib/fluent/plugin/formatter_hash.rb +32 -0
- data/lib/fluent/plugin/formatter_json.rb +47 -0
- data/lib/fluent/plugin/formatter_ltsv.rb +42 -0
- data/lib/fluent/plugin/formatter_msgpack.rb +32 -0
- data/lib/fluent/plugin/formatter_out_file.rb +45 -0
- data/lib/fluent/plugin/formatter_single_value.rb +34 -0
- data/lib/fluent/plugin/formatter_stdout.rb +39 -0
- data/lib/fluent/plugin/in_debug_agent.rb +4 -0
- data/lib/fluent/plugin/in_dummy.rb +22 -18
- data/lib/fluent/plugin/in_exec.rb +18 -8
- data/lib/fluent/plugin/in_forward.rb +36 -79
- data/lib/fluent/plugin/in_gc_stat.rb +4 -0
- data/lib/fluent/plugin/in_http.rb +21 -18
- data/lib/fluent/plugin/in_monitor_agent.rb +15 -48
- data/lib/fluent/plugin/in_object_space.rb +6 -1
- data/lib/fluent/plugin/in_stream.rb +7 -3
- data/lib/fluent/plugin/in_syslog.rb +46 -95
- data/lib/fluent/plugin/in_tail.rb +51 -595
- data/lib/fluent/plugin/in_tcp.rb +8 -1
- data/lib/fluent/plugin/in_udp.rb +8 -14
- data/lib/fluent/plugin/input.rb +33 -0
- data/lib/fluent/plugin/multi_output.rb +95 -0
- data/lib/fluent/plugin/out_buffered_null.rb +59 -0
- data/lib/fluent/plugin/out_copy.rb +11 -7
- data/lib/fluent/plugin/out_exec.rb +15 -11
- data/lib/fluent/plugin/out_exec_filter.rb +18 -10
- data/lib/fluent/plugin/out_file.rb +34 -5
- data/lib/fluent/plugin/out_forward.rb +19 -9
- data/lib/fluent/plugin/out_null.rb +0 -14
- data/lib/fluent/plugin/out_roundrobin.rb +11 -7
- data/lib/fluent/plugin/out_stdout.rb +5 -7
- data/lib/fluent/plugin/out_stream.rb +3 -1
- data/lib/fluent/plugin/output.rb +979 -0
- data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
- data/lib/fluent/plugin/parser.rb +244 -0
- data/lib/fluent/plugin/parser_apache.rb +24 -0
- data/lib/fluent/plugin/parser_apache2.rb +84 -0
- data/lib/fluent/plugin/parser_apache_error.rb +21 -0
- data/lib/fluent/plugin/parser_csv.rb +31 -0
- data/lib/fluent/plugin/parser_json.rb +79 -0
- data/lib/fluent/plugin/parser_ltsv.rb +50 -0
- data/lib/fluent/plugin/parser_multiline.rb +102 -0
- data/lib/fluent/plugin/parser_nginx.rb +24 -0
- data/lib/fluent/plugin/parser_none.rb +36 -0
- data/lib/fluent/plugin/parser_syslog.rb +82 -0
- data/lib/fluent/plugin/parser_tsv.rb +37 -0
- data/lib/fluent/plugin/socket_util.rb +120 -114
- data/lib/fluent/plugin/storage.rb +84 -0
- data/lib/fluent/plugin/storage_local.rb +116 -0
- data/lib/fluent/plugin/string_util.rb +16 -13
- data/lib/fluent/plugin_helper.rb +39 -0
- data/lib/fluent/plugin_helper/child_process.rb +298 -0
- data/lib/fluent/plugin_helper/compat_parameters.rb +99 -0
- data/lib/fluent/plugin_helper/event_emitter.rb +80 -0
- data/lib/fluent/plugin_helper/event_loop.rb +118 -0
- data/lib/fluent/plugin_helper/retry_state.rb +177 -0
- data/lib/fluent/plugin_helper/storage.rb +308 -0
- data/lib/fluent/plugin_helper/thread.rb +147 -0
- data/lib/fluent/plugin_helper/timer.rb +85 -0
- data/lib/fluent/plugin_id.rb +63 -0
- data/lib/fluent/process.rb +21 -30
- data/lib/fluent/registry.rb +21 -9
- data/lib/fluent/root_agent.rb +115 -40
- data/lib/fluent/supervisor.rb +330 -320
- data/lib/fluent/system_config.rb +42 -18
- data/lib/fluent/test.rb +6 -1
- data/lib/fluent/test/base.rb +23 -3
- data/lib/fluent/test/driver/base.rb +247 -0
- data/lib/fluent/test/driver/event_feeder.rb +98 -0
- data/lib/fluent/test/driver/filter.rb +35 -0
- data/lib/fluent/test/driver/input.rb +31 -0
- data/lib/fluent/test/driver/output.rb +78 -0
- data/lib/fluent/test/driver/test_event_router.rb +45 -0
- data/lib/fluent/test/filter_test.rb +0 -1
- data/lib/fluent/test/formatter_test.rb +2 -1
- data/lib/fluent/test/input_test.rb +23 -17
- data/lib/fluent/test/output_test.rb +28 -39
- data/lib/fluent/test/parser_test.rb +1 -1
- data/lib/fluent/time.rb +104 -1
- data/lib/fluent/{status.rb → unique_id.rb} +15 -24
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +72 -0
- data/test/compat/test_calls_super.rb +164 -0
- data/test/config/test_config_parser.rb +83 -0
- data/test/config/test_configurable.rb +547 -274
- data/test/config/test_configure_proxy.rb +146 -29
- data/test/config/test_dsl.rb +3 -181
- data/test/config/test_element.rb +274 -0
- data/test/config/test_literal_parser.rb +1 -1
- data/test/config/test_section.rb +79 -7
- data/test/config/test_system_config.rb +21 -0
- data/test/config/test_types.rb +3 -26
- data/test/helper.rb +78 -8
- data/test/plugin/test_bare_output.rb +118 -0
- data/test/plugin/test_base.rb +75 -0
- data/test/plugin/test_buf_file.rb +420 -521
- data/test/plugin/test_buf_memory.rb +32 -194
- data/test/plugin/test_buffer.rb +981 -0
- data/test/plugin/test_buffer_chunk.rb +110 -0
- data/test/plugin/test_buffer_file_chunk.rb +770 -0
- data/test/plugin/test_buffer_memory_chunk.rb +265 -0
- data/test/plugin/test_filter.rb +255 -0
- data/test/plugin/test_filter_grep.rb +2 -73
- data/test/plugin/test_filter_record_transformer.rb +24 -68
- data/test/plugin/test_filter_stdout.rb +6 -6
- data/test/plugin/test_in_debug_agent.rb +2 -0
- data/test/plugin/test_in_dummy.rb +11 -17
- data/test/plugin/test_in_exec.rb +6 -25
- data/test/plugin/test_in_forward.rb +112 -151
- data/test/plugin/test_in_gc_stat.rb +2 -0
- data/test/plugin/test_in_http.rb +106 -157
- data/test/plugin/test_in_object_space.rb +21 -5
- data/test/plugin/test_in_stream.rb +14 -13
- data/test/plugin/test_in_syslog.rb +30 -275
- data/test/plugin/test_in_tail.rb +95 -234
- data/test/plugin/test_in_tcp.rb +14 -0
- data/test/plugin/test_in_udp.rb +21 -13
- data/test/plugin/test_input.rb +122 -0
- data/test/plugin/test_multi_output.rb +180 -0
- data/test/plugin/test_out_buffered_null.rb +79 -0
- data/test/plugin/test_out_copy.rb +15 -2
- data/test/plugin/test_out_exec.rb +75 -25
- data/test/plugin/test_out_exec_filter.rb +74 -8
- data/test/plugin/test_out_file.rb +61 -7
- data/test/plugin/test_out_forward.rb +92 -15
- data/test/plugin/test_out_roundrobin.rb +1 -0
- data/test/plugin/test_out_stdout.rb +22 -13
- data/test/plugin/test_out_stream.rb +18 -0
- data/test/plugin/test_output.rb +515 -0
- data/test/plugin/test_output_as_buffered.rb +1540 -0
- data/test/plugin/test_output_as_buffered_overflow.rb +247 -0
- data/test/plugin/test_output_as_buffered_retries.rb +808 -0
- data/test/plugin/test_output_as_buffered_secondary.rb +776 -0
- data/test/plugin/test_output_as_standard.rb +362 -0
- data/test/plugin/test_owned_by.rb +35 -0
- data/test/plugin/test_storage.rb +167 -0
- data/test/plugin/test_storage_local.rb +8 -0
- data/test/plugin_helper/test_child_process.rb +599 -0
- data/test/plugin_helper/test_compat_parameters.rb +175 -0
- data/test/plugin_helper/test_event_emitter.rb +51 -0
- data/test/plugin_helper/test_event_loop.rb +52 -0
- data/test/plugin_helper/test_retry_state.rb +399 -0
- data/test/plugin_helper/test_storage.rb +411 -0
- data/test/plugin_helper/test_thread.rb +164 -0
- data/test/plugin_helper/test_timer.rb +100 -0
- data/test/scripts/exec_script.rb +0 -6
- data/test/scripts/fluent/plugin/out_test.rb +3 -0
- data/test/test_config.rb +13 -4
- data/test/test_event.rb +24 -13
- data/test/test_event_router.rb +8 -7
- data/test/test_event_time.rb +187 -0
- data/test/test_formatter.rb +13 -51
- data/test/test_input.rb +1 -1
- data/test/test_log.rb +239 -16
- data/test/test_mixin.rb +1 -1
- data/test/test_output.rb +53 -66
- data/test/test_parser.rb +105 -323
- data/test/test_plugin_helper.rb +81 -0
- data/test/test_root_agent.rb +4 -52
- data/test/test_supervisor.rb +272 -0
- data/test/test_unique_id.rb +47 -0
- metadata +180 -54
- data/lib/fluent/buffer.rb +0 -365
- data/lib/fluent/plugin/filter_parser.rb +0 -107
- data/lib/fluent/plugin/in_status.rb +0 -76
- data/lib/fluent/test/helpers.rb +0 -86
- data/test/plugin/data/log/foo/bar2 +0 -0
- data/test/plugin/test_filter_parser.rb +0 -744
- data/test/plugin/test_in_status.rb +0 -38
- data/test/test_buffer.rb +0 -624
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require_relative '../helper'
|
|
2
2
|
require 'fluent/test'
|
|
3
|
+
require 'fluent/plugin/out_copy'
|
|
3
4
|
|
|
4
5
|
class CopyOutputTest < Test::Unit::TestCase
|
|
5
6
|
class << self
|
|
@@ -107,7 +108,19 @@ class CopyOutputTest < Test::Unit::TestCase
|
|
|
107
108
|
|
|
108
109
|
def create_event_test_driver(is_deep_copy = false)
|
|
109
110
|
deep_copy_config = %[
|
|
110
|
-
deep_copy
|
|
111
|
+
deep_copy #{is_deep_copy}
|
|
112
|
+
<store>
|
|
113
|
+
type test
|
|
114
|
+
name c0
|
|
115
|
+
</store>
|
|
116
|
+
<store>
|
|
117
|
+
type test
|
|
118
|
+
name c1
|
|
119
|
+
</store>
|
|
120
|
+
<store>
|
|
121
|
+
type test
|
|
122
|
+
name c2
|
|
123
|
+
</store>
|
|
111
124
|
]
|
|
112
125
|
|
|
113
126
|
output1 = Fluent::Plugin.new_output('test')
|
|
@@ -130,7 +143,7 @@ deep_copy true
|
|
|
130
143
|
outputs = [output1, output2]
|
|
131
144
|
|
|
132
145
|
d = Fluent::Test::OutputTestDriver.new(Fluent::CopyOutput)
|
|
133
|
-
d = d.configure(deep_copy_config)
|
|
146
|
+
d = d.configure(deep_copy_config)
|
|
134
147
|
d.instance.instance_eval { @outputs = outputs }
|
|
135
148
|
d
|
|
136
149
|
end
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
require_relative '../helper'
|
|
2
|
-
require 'fluent/test'
|
|
2
|
+
require 'fluent/test/driver/output'
|
|
3
|
+
require 'fluent/plugin/out_exec'
|
|
3
4
|
require 'fileutils'
|
|
4
5
|
|
|
5
6
|
class ExecOutputTest < Test::Unit::TestCase
|
|
6
7
|
def setup
|
|
7
8
|
Fluent::Test.setup
|
|
8
|
-
FileUtils.rm_rf(TMP_DIR)
|
|
9
|
+
FileUtils.rm_rf(TMP_DIR, secure: true)
|
|
10
|
+
if File.exist?(TMP_DIR)
|
|
11
|
+
# ensure files are closed for Windows, on which deleted files
|
|
12
|
+
# are still visible from filesystem
|
|
13
|
+
GC.start(full_mark: true, immediate_sweep: true)
|
|
14
|
+
FileUtils.remove_entry_secure(TMP_DIR)
|
|
15
|
+
end
|
|
9
16
|
FileUtils.mkdir_p(TMP_DIR)
|
|
10
17
|
end
|
|
11
18
|
|
|
@@ -25,7 +32,7 @@ class ExecOutputTest < Test::Unit::TestCase
|
|
|
25
32
|
|
|
26
33
|
def create_driver(conf = TSV_CONFIG)
|
|
27
34
|
config = CONFIG + conf
|
|
28
|
-
Fluent::Test::
|
|
35
|
+
Fluent::Test::Driver::Output.new(Fluent::Plugin::ExecOutput).configure(config)
|
|
29
36
|
end
|
|
30
37
|
|
|
31
38
|
def create_test_case
|
|
@@ -44,55 +51,98 @@ class ExecOutputTest < Test::Unit::TestCase
|
|
|
44
51
|
assert_equal true, d.instance.localtime
|
|
45
52
|
end
|
|
46
53
|
|
|
54
|
+
def test_configure_with_compat_buffer_parameters
|
|
55
|
+
conf = TSV_CONFIG + %[
|
|
56
|
+
buffer_type memory
|
|
57
|
+
time_slice_format %Y%m%d%H
|
|
58
|
+
num_threads 5
|
|
59
|
+
buffer_chunk_limit 50m
|
|
60
|
+
buffer_queue_limit 128
|
|
61
|
+
flush_at_shutdown yes
|
|
62
|
+
]
|
|
63
|
+
d = create_driver(conf)
|
|
64
|
+
assert_equal 3600, d.instance.buffer_config.timekey
|
|
65
|
+
assert_equal 5, d.instance.buffer_config.flush_thread_count
|
|
66
|
+
assert_equal 50*1024*1024, d.instance.buffer.chunk_limit_size
|
|
67
|
+
assert_equal 128, d.instance.buffer.queue_length_limit
|
|
68
|
+
assert d.instance.buffer_config.flush_at_shutdown
|
|
69
|
+
end
|
|
70
|
+
|
|
47
71
|
def test_format
|
|
48
72
|
d = create_driver
|
|
49
73
|
time, tests = create_test_case
|
|
50
74
|
|
|
51
|
-
|
|
52
|
-
d.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
d.expect_format %[2011-01-02 13:14:15\ttest\tv1\n]
|
|
56
|
-
d.expect_format %[2011-01-02 13:14:15\ttest\tv2\n]
|
|
75
|
+
d.run(default_tag: 'test') do
|
|
76
|
+
d.feed(time, tests[0])
|
|
77
|
+
d.feed(time, tests[1])
|
|
78
|
+
end
|
|
57
79
|
|
|
58
|
-
d.
|
|
80
|
+
assert_equal %[2011-01-02 13:14:15\ttest\tv1\n], d.formatted[0]
|
|
81
|
+
assert_equal %[2011-01-02 13:14:15\ttest\tv2\n], d.formatted[1]
|
|
59
82
|
end
|
|
60
83
|
|
|
61
84
|
def test_format_json
|
|
62
85
|
d = create_driver("format json")
|
|
63
86
|
time, tests = create_test_case
|
|
64
87
|
|
|
65
|
-
|
|
66
|
-
d.
|
|
67
|
-
d.
|
|
68
|
-
|
|
88
|
+
d.run(default_tag: 'test') do
|
|
89
|
+
d.feed(time, tests[0])
|
|
90
|
+
d.feed(time, tests[1])
|
|
91
|
+
end
|
|
69
92
|
|
|
70
|
-
d.
|
|
93
|
+
assert_equal Yajl.dump(tests[0]) + "\n", d.formatted[0]
|
|
94
|
+
assert_equal Yajl.dump(tests[1]) + "\n", d.formatted[1]
|
|
71
95
|
end
|
|
72
96
|
|
|
73
97
|
def test_format_msgpack
|
|
74
98
|
d = create_driver("format msgpack")
|
|
75
99
|
time, tests = create_test_case
|
|
76
100
|
|
|
77
|
-
|
|
78
|
-
d.
|
|
79
|
-
d.
|
|
80
|
-
|
|
101
|
+
d.run(default_tag: 'test') do
|
|
102
|
+
d.feed(time, tests[0])
|
|
103
|
+
d.feed(time, tests[1])
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
assert_equal tests[0].to_msgpack, d.formatted[0]
|
|
107
|
+
assert_equal tests[1].to_msgpack, d.formatted[1]
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def test_format_time
|
|
111
|
+
config = %[
|
|
112
|
+
keys "time,tag,k1"
|
|
113
|
+
tag_key "tag"
|
|
114
|
+
time_key "time"
|
|
115
|
+
time_format %Y-%m-%d %H:%M:%S.%3N
|
|
116
|
+
]
|
|
117
|
+
d = create_driver(config)
|
|
81
118
|
|
|
82
|
-
|
|
119
|
+
time = event_time("2011-01-02 13:14:15.123")
|
|
120
|
+
tests = [{"k1"=>"v1","kx"=>"vx"}, {"k1"=>"v2","kx"=>"vx"}]
|
|
121
|
+
|
|
122
|
+
d.run(default_tag: 'test') do
|
|
123
|
+
d.feed(time, tests[0])
|
|
124
|
+
d.feed(time, tests[1])
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
assert_equal %[2011-01-02 13:14:15.123\ttest\tv1\n], d.formatted[0]
|
|
128
|
+
assert_equal %[2011-01-02 13:14:15.123\ttest\tv2\n], d.formatted[1]
|
|
83
129
|
end
|
|
84
130
|
|
|
85
131
|
def test_write
|
|
86
132
|
d = create_driver
|
|
87
133
|
time, tests = create_test_case
|
|
88
134
|
|
|
89
|
-
|
|
90
|
-
d.
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
d.run
|
|
135
|
+
d.run(default_tag: 'test', flush: true) do
|
|
136
|
+
d.feed(time, tests[0])
|
|
137
|
+
d.feed(time, tests[1])
|
|
138
|
+
end
|
|
94
139
|
|
|
95
140
|
expect_path = "#{TMP_DIR}/out"
|
|
141
|
+
|
|
142
|
+
waiting(10, plugin: d.instance) do
|
|
143
|
+
sleep(0.1) until File.exist?(expect_path)
|
|
144
|
+
end
|
|
145
|
+
|
|
96
146
|
assert_equal true, File.exist?(expect_path)
|
|
97
147
|
|
|
98
148
|
data = File.read(expect_path)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require_relative '../helper'
|
|
2
2
|
require 'fluent/test'
|
|
3
|
+
require 'fluent/plugin/out_exec_filter'
|
|
3
4
|
require 'fileutils'
|
|
4
5
|
|
|
5
6
|
class ExecFilterOutputTest < Test::Unit::TestCase
|
|
@@ -20,12 +21,12 @@ class ExecFilterOutputTest < Test::Unit::TestCase
|
|
|
20
21
|
]
|
|
21
22
|
|
|
22
23
|
def create_driver(conf = CONFIG, tag = 'test')
|
|
23
|
-
Fluent::Test::
|
|
24
|
+
Fluent::Test::BufferedOutputTestDriver.new(Fluent::ExecFilterOutput, tag).configure(conf)
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
def sed_unbuffered_support?
|
|
27
28
|
@sed_unbuffered_support ||= lambda {
|
|
28
|
-
system("echo xxx | sed --unbuffered -l -e 's/x/y/g'
|
|
29
|
+
system("echo xxx | sed --unbuffered -l -e 's/x/y/g' >#{IO::NULL} 2>&1")
|
|
29
30
|
$?.success?
|
|
30
31
|
}.call
|
|
31
32
|
end
|
|
@@ -37,6 +38,8 @@ class ExecFilterOutputTest < Test::Unit::TestCase
|
|
|
37
38
|
def test_configure
|
|
38
39
|
d = create_driver
|
|
39
40
|
|
|
41
|
+
assert d.instance.instance_eval{ @overrides_format_stream }
|
|
42
|
+
|
|
40
43
|
assert_equal ["time_in","tag","k1"], d.instance.in_keys
|
|
41
44
|
assert_equal ["time_out","tag","k2"], d.instance.out_keys
|
|
42
45
|
assert_equal "tag", d.instance.out_tag_key
|
|
@@ -69,8 +72,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
|
|
|
69
72
|
def test_emit_1
|
|
70
73
|
d = create_driver
|
|
71
74
|
|
|
72
|
-
time =
|
|
75
|
+
time = Fluent::EventTime.parse("2011-01-02 13:14:15")
|
|
73
76
|
|
|
77
|
+
d.expected_emits_length = 2
|
|
74
78
|
d.run do
|
|
75
79
|
d.emit({"k1"=>1}, time)
|
|
76
80
|
d.emit({"k1"=>2}, time)
|
|
@@ -79,7 +83,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
|
|
|
79
83
|
emits = d.emits
|
|
80
84
|
assert_equal 2, emits.length
|
|
81
85
|
assert_equal ["test", time, {"k2"=>"1"}], emits[0]
|
|
86
|
+
assert_equal_event_time time, emits[0][1]
|
|
82
87
|
assert_equal ["test", time, {"k2"=>"2"}], emits[1]
|
|
88
|
+
assert_equal_event_time time, emits[1][1]
|
|
83
89
|
end
|
|
84
90
|
|
|
85
91
|
def test_emit_2
|
|
@@ -92,8 +98,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
|
|
|
92
98
|
num_children 3
|
|
93
99
|
]
|
|
94
100
|
|
|
95
|
-
time =
|
|
101
|
+
time = Fluent::EventTime.parse("2011-01-02 13:14:15")
|
|
96
102
|
|
|
103
|
+
d.expected_emits_length = 2
|
|
97
104
|
d.run do
|
|
98
105
|
d.emit({"k1"=>1}, time)
|
|
99
106
|
d.emit({"k1"=>2}, time)
|
|
@@ -102,7 +109,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
|
|
|
102
109
|
emits = d.emits
|
|
103
110
|
assert_equal 2, emits.length
|
|
104
111
|
assert_equal ["xxx", time, {"k2"=>"1"}], emits[0]
|
|
112
|
+
assert_equal_event_time time, emits[0][1]
|
|
105
113
|
assert_equal ["xxx", time, {"k2"=>"2"}], emits[1]
|
|
114
|
+
assert_equal_event_time time, emits[1][1]
|
|
106
115
|
end
|
|
107
116
|
|
|
108
117
|
def test_emit_3
|
|
@@ -115,8 +124,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
|
|
|
115
124
|
num_children 3
|
|
116
125
|
]
|
|
117
126
|
|
|
118
|
-
time =
|
|
127
|
+
time = Fluent::EventTime.parse("2011-01-02 13:14:15")
|
|
119
128
|
|
|
129
|
+
d.expected_emits_length = 2
|
|
120
130
|
d.run do
|
|
121
131
|
d.emit({"val1"=>"sed-ed value foo"}, time)
|
|
122
132
|
d.emit({"val1"=>"sed-ed value poo"}, time)
|
|
@@ -125,6 +135,7 @@ class ExecFilterOutputTest < Test::Unit::TestCase
|
|
|
125
135
|
emits = d.emits
|
|
126
136
|
assert_equal 1, emits.length
|
|
127
137
|
assert_equal ["xxx", time, {"val2"=>"sed-ed value foo"}], emits[0]
|
|
138
|
+
assert_equal_event_time time, emits[0][1]
|
|
128
139
|
|
|
129
140
|
d = create_driver %[
|
|
130
141
|
command sed #{sed_unbuffered_option} -l -e s/foo/bar/
|
|
@@ -135,8 +146,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
|
|
|
135
146
|
num_children 3
|
|
136
147
|
]
|
|
137
148
|
|
|
138
|
-
time =
|
|
149
|
+
time = Fluent::EventTime.parse("2011-01-02 13:14:15")
|
|
139
150
|
|
|
151
|
+
d.expected_emits_length = 2
|
|
140
152
|
d.run do
|
|
141
153
|
d.emit({"val1"=>"sed-ed value foo"}, time)
|
|
142
154
|
d.emit({"val1"=>"sed-ed value poo"}, time)
|
|
@@ -145,7 +157,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
|
|
|
145
157
|
emits = d.emits
|
|
146
158
|
assert_equal 2, emits.length
|
|
147
159
|
assert_equal ["xxx", time, {"val2"=>"sed-ed value bar"}], emits[0]
|
|
160
|
+
assert_equal_event_time time, emits[0][1]
|
|
148
161
|
assert_equal ["xxx", time, {"val2"=>"sed-ed value poo"}], emits[1]
|
|
162
|
+
assert_equal_event_time time, emits[1][1]
|
|
149
163
|
end
|
|
150
164
|
|
|
151
165
|
def test_emit_4
|
|
@@ -160,8 +174,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
|
|
|
160
174
|
num_children 3
|
|
161
175
|
], 'input.test')
|
|
162
176
|
|
|
163
|
-
time =
|
|
177
|
+
time = Fluent::EventTime.parse("2011-01-02 13:14:15")
|
|
164
178
|
|
|
179
|
+
d.expected_emits_length = 2
|
|
165
180
|
d.run do
|
|
166
181
|
d.emit({"val1"=>"sed-ed value foo"}, time)
|
|
167
182
|
d.emit({"val1"=>"sed-ed value poo"}, time)
|
|
@@ -170,7 +185,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
|
|
|
170
185
|
emits = d.emits
|
|
171
186
|
assert_equal 2, emits.length
|
|
172
187
|
assert_equal ["output.test", time, {"val2"=>"sed-ed value bar"}], emits[0]
|
|
188
|
+
assert_equal_event_time time, emits[0][1]
|
|
173
189
|
assert_equal ["output.test", time, {"val2"=>"sed-ed value poo"}], emits[1]
|
|
190
|
+
assert_equal_event_time time, emits[1][1]
|
|
174
191
|
end
|
|
175
192
|
|
|
176
193
|
def test_json_1
|
|
@@ -182,8 +199,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
|
|
|
182
199
|
tag_key tag
|
|
183
200
|
], 'input.test')
|
|
184
201
|
|
|
185
|
-
time =
|
|
202
|
+
time = Fluent::EventTime.parse("2011-01-02 13:14:15")
|
|
186
203
|
|
|
204
|
+
d.expected_emits_length = 1
|
|
187
205
|
d.run do
|
|
188
206
|
d.emit({"message"=>%[{"time":#{time},"tag":"t1","k1":"v1"}]}, time+10)
|
|
189
207
|
end
|
|
@@ -191,6 +209,54 @@ class ExecFilterOutputTest < Test::Unit::TestCase
|
|
|
191
209
|
emits = d.emits
|
|
192
210
|
assert_equal 1, emits.length
|
|
193
211
|
assert_equal ["t1", time, {"k1"=>"v1"}], emits[0]
|
|
212
|
+
assert_equal_event_time time, emits[0][1]
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def test_json_with_float_time
|
|
216
|
+
d = create_driver(%[
|
|
217
|
+
command cat
|
|
218
|
+
in_keys message
|
|
219
|
+
out_format json
|
|
220
|
+
time_key time
|
|
221
|
+
tag_key tag
|
|
222
|
+
], 'input.test')
|
|
223
|
+
|
|
224
|
+
float_time = Time.parse("2011-01-02 13:14:15").to_f
|
|
225
|
+
time = Fluent::EventTime.from_time(Time.at(float_time))
|
|
226
|
+
|
|
227
|
+
d.expected_emits_length = 1
|
|
228
|
+
d.run do
|
|
229
|
+
d.emit({"message"=>%[{"time":#{float_time},"tag":"t1","k1":"v1"}]}, time+10)
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
emits = d.emits
|
|
233
|
+
assert_equal 1, emits.length
|
|
234
|
+
assert_equal ["t1", time, {"k1"=>"v1"}], emits[0]
|
|
235
|
+
assert_equal_event_time time, emits[0][1]
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def test_json_with_time_format
|
|
239
|
+
d = create_driver(%[
|
|
240
|
+
command cat
|
|
241
|
+
in_keys message
|
|
242
|
+
out_format json
|
|
243
|
+
time_key time
|
|
244
|
+
time_format %d/%b/%Y %H:%M:%S.%N %z
|
|
245
|
+
tag_key tag
|
|
246
|
+
], 'input.test')
|
|
247
|
+
|
|
248
|
+
time_str = "28/Feb/2013 12:00:00.123456789 +0900"
|
|
249
|
+
time = Fluent::EventTime.from_time(Time.strptime(time_str, "%d/%b/%Y %H:%M:%S.%N %z"))
|
|
250
|
+
|
|
251
|
+
d.expected_emits_length = 1
|
|
252
|
+
d.run do
|
|
253
|
+
d.emit({"message"=>%[{"time":"#{time_str}","tag":"t1","k1":"v1"}]}, time+10)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
emits = d.emits
|
|
257
|
+
assert_equal 1, emits.length
|
|
258
|
+
assert_equal ["t1", time, {"k1"=>"v1"}], emits[0]
|
|
259
|
+
assert_equal_event_time time, emits[0][1]
|
|
194
260
|
end
|
|
195
261
|
end
|
|
196
262
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require_relative '../helper'
|
|
2
2
|
require 'fluent/test'
|
|
3
|
+
require 'fluent/plugin/out_file'
|
|
3
4
|
require 'fileutils'
|
|
4
5
|
require 'time'
|
|
5
6
|
|
|
@@ -62,7 +63,7 @@ class FileOutputTest < Test::Unit::TestCase
|
|
|
62
63
|
d = create_driver(%[path #{TMP_DIR}/out_file_test])
|
|
63
64
|
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
|
64
65
|
|
|
65
|
-
with_timezone('Asia/Taipei') do
|
|
66
|
+
with_timezone(Fluent.windows? ? 'NST-8' : 'Asia/Taipei') do
|
|
66
67
|
d.emit({"a"=>1}, time)
|
|
67
68
|
d.expect_format %[2011-01-02T21:14:15+08:00\ttest\t{"a":1}\n]
|
|
68
69
|
d.run
|
|
@@ -121,7 +122,7 @@ class FileOutputTest < Test::Unit::TestCase
|
|
|
121
122
|
# Zlib::GzipReader has a bug of concatenated file: https://bugs.ruby-lang.org/issues/9790
|
|
122
123
|
# Following code from https://www.ruby-forum.com/topic/971591#979520
|
|
123
124
|
result = ''
|
|
124
|
-
File.open(path) { |io|
|
|
125
|
+
File.open(path, "rb") { |io|
|
|
125
126
|
loop do
|
|
126
127
|
gzr = Zlib::GzipReader.new(io)
|
|
127
128
|
result << gzr.read
|
|
@@ -150,6 +151,54 @@ class FileOutputTest < Test::Unit::TestCase
|
|
|
150
151
|
check_gzipped_result(paths[0], %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] + %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n])
|
|
151
152
|
end
|
|
152
153
|
|
|
154
|
+
class TestWithSystem < self
|
|
155
|
+
TMP_DIR_WITH_SYSTEM = File.expand_path(File.dirname(__FILE__) + "/../tmp/out_file_system#{ENV['TEST_ENV_NUMBER']}")
|
|
156
|
+
# 0750 interprets as "488". "488".to_i(8) # => 4. So, it makes wrong permission. Umm....
|
|
157
|
+
OVERRIDE_DIR_PERMISSION = 750
|
|
158
|
+
OVERRIDE_FILE_PERMISSION = 0620
|
|
159
|
+
CONFIG_WITH_SYSTEM = %[
|
|
160
|
+
path #{TMP_DIR_WITH_SYSTEM}/out_file_test
|
|
161
|
+
compress gz
|
|
162
|
+
utc
|
|
163
|
+
<system>
|
|
164
|
+
file_permission #{OVERRIDE_FILE_PERMISSION}
|
|
165
|
+
dir_permission #{OVERRIDE_DIR_PERMISSION}
|
|
166
|
+
</system>
|
|
167
|
+
]
|
|
168
|
+
|
|
169
|
+
def setup
|
|
170
|
+
omit "NTFS doesn't support UNIX like permissions" if Fluent.windows?
|
|
171
|
+
FileUtils.rm_rf(TMP_DIR_WITH_SYSTEM)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def parse_system(text)
|
|
175
|
+
basepath = File.expand_path(File.dirname(__FILE__) + '/../../')
|
|
176
|
+
Fluent::Config.parse(text, '(test)', basepath, true).elements.find { |e| e.name == 'system' }
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def test_write_with_system
|
|
180
|
+
system_conf = parse_system(CONFIG_WITH_SYSTEM)
|
|
181
|
+
sc = Fluent::SystemConfig.new(system_conf)
|
|
182
|
+
Fluent::Engine.init(sc)
|
|
183
|
+
d = create_driver CONFIG_WITH_SYSTEM
|
|
184
|
+
|
|
185
|
+
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
|
186
|
+
d.emit({"a"=>1}, time)
|
|
187
|
+
d.emit({"a"=>2}, time)
|
|
188
|
+
|
|
189
|
+
# FileOutput#write returns path
|
|
190
|
+
paths = d.run
|
|
191
|
+
expect_paths = ["#{TMP_DIR_WITH_SYSTEM}/out_file_test.20110102_0.log.gz"]
|
|
192
|
+
assert_equal expect_paths, paths
|
|
193
|
+
|
|
194
|
+
check_gzipped_result(paths[0], %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] + %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n])
|
|
195
|
+
dir_mode = "%o" % File::stat(TMP_DIR_WITH_SYSTEM).mode
|
|
196
|
+
assert_equal(OVERRIDE_DIR_PERMISSION, dir_mode[-3, 3].to_i)
|
|
197
|
+
file_mode = "%o" % File::stat(paths[0]).mode
|
|
198
|
+
assert_equal(OVERRIDE_FILE_PERMISSION, file_mode[-3, 3].to_i)
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
153
202
|
def test_write_with_format_json
|
|
154
203
|
d = create_driver [CONFIG, 'format json', 'include_time_key true', 'time_as_epoch'].join("\n")
|
|
155
204
|
|
|
@@ -245,28 +294,33 @@ class FileOutputTest < Test::Unit::TestCase
|
|
|
245
294
|
end
|
|
246
295
|
|
|
247
296
|
def test_write_with_symlink
|
|
297
|
+
omit "Windows doesn't support symlink" if Fluent.windows?
|
|
248
298
|
conf = CONFIG + %[
|
|
249
299
|
symlink_path #{SYMLINK_PATH}
|
|
250
300
|
]
|
|
251
301
|
symlink_path = "#{SYMLINK_PATH}"
|
|
252
302
|
|
|
253
|
-
Fluent::FileBuffer.clear_buffer_paths
|
|
254
303
|
d = Fluent::Test::TestDriver.new(Fluent::FileOutput).configure(conf)
|
|
255
304
|
|
|
256
305
|
begin
|
|
257
306
|
d.instance.start
|
|
258
307
|
10.times { sleep 0.05 }
|
|
308
|
+
|
|
259
309
|
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
|
260
310
|
es = Fluent::OneEventStream.new(time, {"a"=>1})
|
|
261
|
-
d.instance.
|
|
311
|
+
d.instance.emit_events('tag', es)
|
|
262
312
|
|
|
263
|
-
assert File.
|
|
313
|
+
assert File.exist?(symlink_path)
|
|
264
314
|
assert File.symlink?(symlink_path)
|
|
265
315
|
|
|
266
|
-
|
|
316
|
+
es = Fluent::OneEventStream.new(event_time("2011-01-03 14:15:16 UTC"), {"a"=>2})
|
|
317
|
+
d.instance.emit_events('tag', es)
|
|
267
318
|
|
|
268
|
-
assert
|
|
319
|
+
assert File.exist?(symlink_path)
|
|
269
320
|
assert File.symlink?(symlink_path)
|
|
321
|
+
|
|
322
|
+
meta = d.instance.metadata('tag', event_time("2011-01-03 14:15:16 UTC"), {})
|
|
323
|
+
assert_equal d.instance.buffer.instance_eval{ @stage[meta].path }, File.readlink(symlink_path)
|
|
270
324
|
ensure
|
|
271
325
|
d.instance.shutdown
|
|
272
326
|
FileUtils.rm_rf(symlink_path)
|