fluentd 0.14.8 → 0.14.9
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/.gitignore +2 -0
- data/CONTRIBUTING.md +6 -1
- data/ChangeLog +38 -0
- data/Rakefile +21 -0
- data/example/out_exec_filter.conf +42 -0
- data/lib/fluent/agent.rb +2 -2
- data/lib/fluent/command/binlog_reader.rb +1 -1
- data/lib/fluent/command/cat.rb +5 -2
- data/lib/fluent/compat/output.rb +7 -8
- data/lib/fluent/compat/parser.rb +139 -11
- data/lib/fluent/config/configure_proxy.rb +2 -11
- data/lib/fluent/config/section.rb +7 -0
- data/lib/fluent/configurable.rb +1 -3
- 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 +4 -7
- 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 +25 -105
- data/lib/fluent/plugin/in_http.rb +68 -65
- data/lib/fluent/plugin/in_syslog.rb +29 -51
- 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 +155 -80
- data/lib/fluent/plugin/out_forward.rb +44 -47
- data/lib/fluent/plugin/out_stdout.rb +6 -21
- data/lib/fluent/plugin/output.rb +23 -17
- 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 +8 -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/extract.rb +16 -4
- data/lib/fluent/plugin_helper/formatter.rb +9 -11
- data/lib/fluent/plugin_helper/inject.rb +4 -0
- data/lib/fluent/plugin_helper/parser.rb +3 -3
- data/lib/fluent/root_agent.rb +1 -1
- data/lib/fluent/test/driver/base.rb +51 -37
- 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/test/command/test_binlog_reader.rb +5 -1
- data/test/config/test_configurable.rb +173 -0
- data/test/config/test_configure_proxy.rb +0 -43
- 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 +11 -3
- 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 +310 -327
- data/test/plugin/test_in_http.rb +310 -186
- 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 +620 -177
- data/test/plugin/test_out_forward.rb +110 -132
- 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_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_parser.rb +6 -5
- data/test/test_output.rb +24 -2
- data/test/test_plugin_classes.rb +20 -0
- data/test/test_root_agent.rb +139 -0
- data/test/test_test_drivers.rb +132 -0
- metadata +12 -4
- data/test/plugin/test_parser_base.rb +0 -32
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
require_relative '../helper'
|
|
2
|
-
require 'fluent/test'
|
|
2
|
+
require 'fluent/test/driver/output'
|
|
3
3
|
require 'fluent/plugin/out_file'
|
|
4
4
|
require 'fileutils'
|
|
5
5
|
require 'time'
|
|
6
|
+
require 'timecop'
|
|
7
|
+
require 'zlib'
|
|
6
8
|
|
|
7
9
|
class FileOutputTest < Test::Unit::TestCase
|
|
8
10
|
def setup
|
|
@@ -21,92 +23,303 @@ class FileOutputTest < Test::Unit::TestCase
|
|
|
21
23
|
]
|
|
22
24
|
|
|
23
25
|
def create_driver(conf = CONFIG)
|
|
24
|
-
Fluent::Test::
|
|
26
|
+
Fluent::Test::Driver::Output.new(Fluent::Plugin::FileOutput).configure(conf)
|
|
25
27
|
end
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
sub_test_case 'configuration' do
|
|
30
|
+
test 'basic configuration' do
|
|
31
|
+
d = create_driver %[
|
|
32
|
+
path test_path
|
|
33
|
+
compress gz
|
|
34
|
+
]
|
|
35
|
+
assert_equal 'test_path', d.instance.path
|
|
36
|
+
assert_equal :gz, d.instance.compress
|
|
37
|
+
assert_equal :gzip, d.instance.instance_eval{ @compress_method }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
test 'path should be writable' do
|
|
41
|
+
assert_nothing_raised do
|
|
42
|
+
create_driver %[path #{TMP_DIR}/test_path]
|
|
43
|
+
end
|
|
35
44
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
45
|
+
assert_nothing_raised do
|
|
46
|
+
FileUtils.mkdir_p("#{TMP_DIR}/test_dir")
|
|
47
|
+
File.chmod(0777, "#{TMP_DIR}/test_dir")
|
|
48
|
+
create_driver %[path #{TMP_DIR}/test_dir/foo/bar/baz]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
assert_raise(Fluent::ConfigError) do
|
|
52
|
+
FileUtils.mkdir_p("#{TMP_DIR}/test_dir")
|
|
53
|
+
File.chmod(0555, "#{TMP_DIR}/test_dir")
|
|
54
|
+
create_driver %[path #{TMP_DIR}/test_dir/foo/bar/baz]
|
|
55
|
+
end
|
|
39
56
|
end
|
|
40
57
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
58
|
+
test 'default timezone is localtime' do
|
|
59
|
+
d = create_driver(%[path #{TMP_DIR}/out_file_test])
|
|
60
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
|
61
|
+
|
|
62
|
+
with_timezone(Fluent.windows? ? 'NST-8' : 'Asia/Taipei') do
|
|
63
|
+
d.run(default_tag: 'test') do
|
|
64
|
+
d.feed(time, {"a"=>1})
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
assert_equal 1, d.formatted.size
|
|
68
|
+
assert_equal %[2011-01-02T21:14:15+08:00\ttest\t{"a":1}\n], d.formatted[0]
|
|
45
69
|
end
|
|
46
70
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
71
|
+
test 'no configuration error raised for basic configuration using "*" (v0.12 style)' do
|
|
72
|
+
conf = config_element('match', '**', {
|
|
73
|
+
'path' => "#{TMP_DIR}/test_out.*.log",
|
|
74
|
+
'time_slice_format' => '%Y%m%d',
|
|
75
|
+
})
|
|
76
|
+
assert_nothing_raised do
|
|
77
|
+
create_driver(conf)
|
|
78
|
+
end
|
|
51
79
|
end
|
|
52
|
-
end
|
|
53
80
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
81
|
+
test 'configuration error raised if specified directory via template is not writable' do
|
|
82
|
+
Timecop.freeze(Time.parse("2016-10-04 21:33:27 UTC")) do
|
|
83
|
+
conf = config_element('match', '**', {
|
|
84
|
+
'path' => "#{TMP_DIR}/prohibited/${tag}/file.%Y%m%d.log",
|
|
85
|
+
}, [ config_element('buffer', 'time,tag', {'timekey' => 86400, 'timekey_zone' => '+0000'}) ])
|
|
86
|
+
FileUtils.mkdir_p("#{TMP_DIR}/prohibited")
|
|
87
|
+
File.chmod(0555, "#{TMP_DIR}/prohibited")
|
|
88
|
+
assert_raise Fluent::ConfigError.new("out_file: `#{TMP_DIR}/prohibited/a/file.20161004.log_**.log` is not writable") do
|
|
89
|
+
create_driver(conf)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
57
93
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
94
|
+
test 'configuration using inject/format/buffer sections fully' do
|
|
95
|
+
conf = config_element('match', '**', {
|
|
96
|
+
'path' => "#{TMP_DIR}/${tag}/${type}/conf_test.%Y%m%d.%H%M.log",
|
|
97
|
+
'add_path_suffix' => 'false',
|
|
98
|
+
'append' => "true",
|
|
99
|
+
'symlink_path' => "#{TMP_DIR}/conf_test.current.log",
|
|
100
|
+
'compress' => 'gzip',
|
|
101
|
+
'recompress' => 'true',
|
|
102
|
+
}, [
|
|
103
|
+
config_element('inject', '', {
|
|
104
|
+
'hostname_key' => 'hostname',
|
|
105
|
+
'hostname' => 'testing.local',
|
|
106
|
+
'tag_key' => 'tag',
|
|
107
|
+
'time_key' => 'time',
|
|
108
|
+
'time_type' => 'string',
|
|
109
|
+
'time_format' => '%Y/%m/%d %H:%M:%S %z',
|
|
110
|
+
'timezone' => '+0900',
|
|
111
|
+
}),
|
|
112
|
+
config_element('format', '', {
|
|
113
|
+
'@type' => 'out_file',
|
|
114
|
+
'include_tag' => 'true',
|
|
115
|
+
'include_time' => 'true',
|
|
116
|
+
'delimiter' => 'COMMA',
|
|
117
|
+
'time_type' => 'string',
|
|
118
|
+
'time_format' => '%Y-%m-%d %H:%M:%S %z',
|
|
119
|
+
'utc' => 'true',
|
|
120
|
+
}),
|
|
121
|
+
config_element('buffer', 'time,tag,type', {
|
|
122
|
+
'@type' => 'file',
|
|
123
|
+
'timekey' => '15m',
|
|
124
|
+
'timekey_wait' => '5s',
|
|
125
|
+
'timekey_zone' => '+0000',
|
|
126
|
+
'path' => "#{TMP_DIR}/buf_conf_test",
|
|
127
|
+
'chunk_limit_size' => '50m',
|
|
128
|
+
'total_limit_size' => '1g',
|
|
129
|
+
'compress' => 'gzip',
|
|
130
|
+
}),
|
|
131
|
+
])
|
|
132
|
+
assert_nothing_raised do
|
|
133
|
+
create_driver(conf)
|
|
134
|
+
end
|
|
62
135
|
end
|
|
63
136
|
end
|
|
64
137
|
|
|
65
|
-
|
|
66
|
-
|
|
138
|
+
sub_test_case 'fully configured output' do
|
|
139
|
+
setup do
|
|
140
|
+
Timecop.freeze(Time.parse("2016-10-03 23:58:00 UTC"))
|
|
141
|
+
conf = config_element('match', '**', {
|
|
142
|
+
'path' => "#{TMP_DIR}/${tag}/${type}/full.%Y%m%d.%H%M.log",
|
|
143
|
+
'add_path_suffix' => 'false',
|
|
144
|
+
'append' => "true",
|
|
145
|
+
'symlink_path' => "#{TMP_DIR}/full.current.log",
|
|
146
|
+
'compress' => 'gzip',
|
|
147
|
+
'recompress' => 'true',
|
|
148
|
+
}, [
|
|
149
|
+
config_element('inject', '', {
|
|
150
|
+
'hostname_key' => 'hostname',
|
|
151
|
+
'hostname' => 'testing.local',
|
|
152
|
+
'tag_key' => 'tag',
|
|
153
|
+
'time_key' => 'time',
|
|
154
|
+
'time_type' => 'string',
|
|
155
|
+
'time_format' => '%Y/%m/%d %H:%M:%S %z',
|
|
156
|
+
'timezone' => '+0900',
|
|
157
|
+
}),
|
|
158
|
+
config_element('format', '', {
|
|
159
|
+
'@type' => 'out_file',
|
|
160
|
+
'include_tag' => 'true',
|
|
161
|
+
'include_time' => 'true',
|
|
162
|
+
'delimiter' => 'COMMA',
|
|
163
|
+
'time_type' => 'string',
|
|
164
|
+
'time_format' => '%Y-%m-%d %H:%M:%S %z',
|
|
165
|
+
'utc' => 'true',
|
|
166
|
+
}),
|
|
167
|
+
config_element('buffer', 'time,tag,type', {
|
|
168
|
+
'@type' => 'file',
|
|
169
|
+
'timekey' => '15m',
|
|
170
|
+
'timekey_wait' => '5s',
|
|
171
|
+
'timekey_zone' => '+0000',
|
|
172
|
+
'path' => "#{TMP_DIR}/buf_full",
|
|
173
|
+
'chunk_limit_size' => '50m',
|
|
174
|
+
'total_limit_size' => '1g',
|
|
175
|
+
'compress' => 'gzip',
|
|
176
|
+
}),
|
|
177
|
+
])
|
|
178
|
+
@d = create_driver(conf)
|
|
179
|
+
end
|
|
67
180
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
181
|
+
teardown do
|
|
182
|
+
FileUtils.rm_rf("#{TMP_DIR}/buf_full")
|
|
183
|
+
FileUtils.rm_rf("#{TMP_DIR}/my.data")
|
|
184
|
+
FileUtils.rm_rf("#{TMP_DIR}/your.data")
|
|
185
|
+
FileUtils.rm_rf("#{TMP_DIR}/full.current.log")
|
|
186
|
+
Timecop.return
|
|
187
|
+
end
|
|
71
188
|
|
|
72
|
-
|
|
73
|
-
|
|
189
|
+
test 'can format/write data correctly' do
|
|
190
|
+
d = @d
|
|
74
191
|
|
|
75
|
-
|
|
76
|
-
|
|
192
|
+
assert_equal 50*1024*1024, d.instance.buffer.chunk_limit_size
|
|
193
|
+
assert_equal 1*1024*1024*1024, d.instance.buffer.total_limit_size
|
|
77
194
|
|
|
78
|
-
|
|
79
|
-
d = create_driver %[
|
|
80
|
-
path #{TMP_DIR}/out_file_test
|
|
81
|
-
timezone Asia/Taipei
|
|
82
|
-
]
|
|
195
|
+
assert !(File.symlink?("#{TMP_DIR}/full.current.log"))
|
|
83
196
|
|
|
84
|
-
|
|
197
|
+
t1 = event_time("2016-10-03 23:58:09 UTC")
|
|
198
|
+
t2 = event_time("2016-10-03 23:59:33 UTC")
|
|
199
|
+
t3 = event_time("2016-10-03 23:59:57 UTC")
|
|
200
|
+
t4 = event_time("2016-10-04 00:00:17 UTC")
|
|
201
|
+
t5 = event_time("2016-10-04 00:01:59 UTC")
|
|
85
202
|
|
|
86
|
-
|
|
87
|
-
d.expect_format %[2011-01-02T21:14:15+08:00\ttest\t{"a":1}\n]
|
|
88
|
-
d.run
|
|
89
|
-
end
|
|
203
|
+
Timecop.freeze(Time.parse("2016-10-03 23:58:30 UTC"))
|
|
90
204
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
205
|
+
d.run(start: true, flush: false, shutdown: false) do
|
|
206
|
+
d.feed('my.data', t1, {"type" => "a", "message" => "data raw content"})
|
|
207
|
+
d.feed('my.data', t2, {"type" => "a", "message" => "data raw content"})
|
|
208
|
+
d.feed('your.data', t3, {"type" => "a", "message" => "data raw content"})
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
assert_equal 3, d.formatted.size
|
|
212
|
+
|
|
213
|
+
assert Dir.exist?("#{TMP_DIR}/buf_full")
|
|
214
|
+
assert !(Dir.exist?("#{TMP_DIR}/my.data/a"))
|
|
215
|
+
assert !(Dir.exist?("#{TMP_DIR}/your.data/a"))
|
|
216
|
+
buffer_files = Dir.entries("#{TMP_DIR}/buf_full").reject{|e| e =~ /^\.+$/ }
|
|
217
|
+
assert_equal 2, buffer_files.select{|n| n.end_with?('.meta') }.size
|
|
218
|
+
assert_equal 2, buffer_files.select{|n| !n.end_with?('.meta') }.size
|
|
219
|
+
|
|
220
|
+
m1 = d.instance.metadata('my.data', t1, {"type" => "a"})
|
|
221
|
+
m2 = d.instance.metadata('your.data', t3, {"type" => "a"})
|
|
96
222
|
|
|
97
|
-
|
|
223
|
+
assert_equal 2, d.instance.buffer.stage.size
|
|
224
|
+
b1_path = d.instance.buffer.stage[m1].path
|
|
225
|
+
b1_size = File.lstat(b1_path).size
|
|
98
226
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
227
|
+
unless Fluent.windows?
|
|
228
|
+
assert File.symlink?("#{TMP_DIR}/full.current.log")
|
|
229
|
+
assert_equal d.instance.buffer.stage[m2].path, File.readlink("#{TMP_DIR}/full.current.log")
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
Timecop.freeze(Time.parse("2016-10-04 00:00:06 UTC"))
|
|
233
|
+
|
|
234
|
+
d.run(start: false, flush: true, shutdown: true) do
|
|
235
|
+
d.feed('my.data', t4, {"type" => "a", "message" => "data raw content"})
|
|
236
|
+
d.feed('your.data', t5, {"type" => "a", "message" => "data raw content"})
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
assert Dir.exist?("#{TMP_DIR}/buf_full")
|
|
240
|
+
assert Dir.exist?("#{TMP_DIR}/my.data/a")
|
|
241
|
+
assert Dir.exist?("#{TMP_DIR}/your.data/a")
|
|
242
|
+
|
|
243
|
+
buffer_files = Dir.entries("#{TMP_DIR}/buf_full").reject{|e| e =~ /^\.+$/ }
|
|
244
|
+
assert_equal 0, buffer_files.size
|
|
245
|
+
|
|
246
|
+
assert File.exist?("#{TMP_DIR}/my.data/a/full.20161003.2345.log.gz")
|
|
247
|
+
assert File.exist?("#{TMP_DIR}/my.data/a/full.20161004.0000.log.gz")
|
|
248
|
+
assert File.exist?("#{TMP_DIR}/your.data/a/full.20161003.2345.log.gz")
|
|
249
|
+
assert File.exist?("#{TMP_DIR}/your.data/a/full.20161004.0000.log.gz")
|
|
250
|
+
|
|
251
|
+
assert{ File.lstat("#{TMP_DIR}/my.data/a/full.20161003.2345.log.gz").size < b1_size } # recompress
|
|
252
|
+
|
|
253
|
+
assert_equal 5, d.formatted.size
|
|
254
|
+
|
|
255
|
+
r1 = %!2016-10-03 23:58:09 +0000,my.data,{"type":"a","message":"data raw content","hostname":"testing.local","tag":"my.data","time":"2016/10/04 08:58:09 +0900"}\n!
|
|
256
|
+
r2 = %!2016-10-03 23:59:33 +0000,my.data,{"type":"a","message":"data raw content","hostname":"testing.local","tag":"my.data","time":"2016/10/04 08:59:33 +0900"}\n!
|
|
257
|
+
r3 = %!2016-10-03 23:59:57 +0000,your.data,{"type":"a","message":"data raw content","hostname":"testing.local","tag":"your.data","time":"2016/10/04 08:59:57 +0900"}\n!
|
|
258
|
+
r4 = %!2016-10-04 00:00:17 +0000,my.data,{"type":"a","message":"data raw content","hostname":"testing.local","tag":"my.data","time":"2016/10/04 09:00:17 +0900"}\n!
|
|
259
|
+
r5 = %!2016-10-04 00:01:59 +0000,your.data,{"type":"a","message":"data raw content","hostname":"testing.local","tag":"your.data","time":"2016/10/04 09:01:59 +0900"}\n!
|
|
260
|
+
assert_equal r1, d.formatted[0]
|
|
261
|
+
assert_equal r2, d.formatted[1]
|
|
262
|
+
assert_equal r3, d.formatted[2]
|
|
263
|
+
assert_equal r4, d.formatted[3]
|
|
264
|
+
assert_equal r5, d.formatted[4]
|
|
265
|
+
|
|
266
|
+
read_gunzip = ->(path){ File.open(path){|fio| Zlib::GzipReader.open(fio){|io| io.read } } }
|
|
267
|
+
assert_equal r1 + r2, read_gunzip.call("#{TMP_DIR}/my.data/a/full.20161003.2345.log.gz")
|
|
268
|
+
assert_equal r3, read_gunzip.call("#{TMP_DIR}/your.data/a/full.20161003.2345.log.gz")
|
|
269
|
+
assert_equal r4, read_gunzip.call("#{TMP_DIR}/my.data/a/full.20161004.0000.log.gz")
|
|
270
|
+
assert_equal r5, read_gunzip.call("#{TMP_DIR}/your.data/a/full.20161004.0000.log.gz")
|
|
271
|
+
end
|
|
102
272
|
end
|
|
103
273
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
create_driver
|
|
274
|
+
sub_test_case 'format' do
|
|
275
|
+
test 'timezone UTC specified' do
|
|
276
|
+
d = create_driver
|
|
277
|
+
|
|
278
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
|
279
|
+
d.run(default_tag: 'test') do
|
|
280
|
+
d.feed(time, {"a"=>1})
|
|
281
|
+
d.feed(time, {"a"=>2})
|
|
282
|
+
end
|
|
283
|
+
assert_equal 2, d.formatted.size
|
|
284
|
+
assert_equal %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n], d.formatted[0]
|
|
285
|
+
assert_equal %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n], d.formatted[1]
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
test 'time formatted with specified timezone, using area name' do
|
|
289
|
+
d = create_driver %[
|
|
107
290
|
path #{TMP_DIR}/out_file_test
|
|
108
|
-
timezone
|
|
291
|
+
timezone Asia/Taipei
|
|
109
292
|
]
|
|
293
|
+
|
|
294
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
|
295
|
+
d.run(default_tag: 'test') do
|
|
296
|
+
d.feed(time, {"a"=>1})
|
|
297
|
+
end
|
|
298
|
+
assert_equal 1, d.formatted.size
|
|
299
|
+
assert_equal %[2011-01-02T21:14:15+08:00\ttest\t{"a":1}\n], d.formatted[0]
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
test 'time formatted with specified timezone, using offset' do
|
|
303
|
+
d = create_driver %[
|
|
304
|
+
path #{TMP_DIR}/out_file_test
|
|
305
|
+
timezone -03:30
|
|
306
|
+
]
|
|
307
|
+
|
|
308
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
|
309
|
+
d.run(default_tag: 'test') do
|
|
310
|
+
d.feed(time, {"a"=>1})
|
|
311
|
+
end
|
|
312
|
+
assert_equal 1, d.formatted.size
|
|
313
|
+
assert_equal %[2011-01-02T09:44:15-03:30\ttest\t{"a":1}\n], d.formatted[0]
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
test 'configuration error raised for invalid timezone' do
|
|
317
|
+
assert_raise(Fluent::ConfigError) do
|
|
318
|
+
create_driver %[
|
|
319
|
+
path #{TMP_DIR}/out_file_test
|
|
320
|
+
timezone Invalid/Invalid
|
|
321
|
+
]
|
|
322
|
+
end
|
|
110
323
|
end
|
|
111
324
|
end
|
|
112
325
|
|
|
@@ -128,22 +341,24 @@ class FileOutputTest < Test::Unit::TestCase
|
|
|
128
341
|
assert_equal expect, result
|
|
129
342
|
end
|
|
130
343
|
|
|
131
|
-
|
|
132
|
-
|
|
344
|
+
sub_test_case 'write' do
|
|
345
|
+
test 'basic case' do
|
|
346
|
+
d = create_driver
|
|
133
347
|
|
|
134
|
-
|
|
135
|
-
d.emit({"a"=>1}, time)
|
|
136
|
-
d.emit({"a"=>2}, time)
|
|
348
|
+
assert_false File.exist?("#{TMP_DIR}/out_file_test.20110102_0.log.gz")
|
|
137
349
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
350
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
|
351
|
+
d.run(default_tag: 'test') do
|
|
352
|
+
d.feed(time, {"a"=>1})
|
|
353
|
+
d.feed(time, {"a"=>2})
|
|
354
|
+
end
|
|
142
355
|
|
|
143
|
-
|
|
356
|
+
assert File.exist?("#{TMP_DIR}/out_file_test.20110102_0.log.gz")
|
|
357
|
+
check_gzipped_result("#{TMP_DIR}/out_file_test.20110102_0.log.gz", %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] + %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n])
|
|
358
|
+
end
|
|
144
359
|
end
|
|
145
360
|
|
|
146
|
-
|
|
361
|
+
sub_test_case 'file/directory permissions' do
|
|
147
362
|
TMP_DIR_WITH_SYSTEM = File.expand_path(File.dirname(__FILE__) + "/../tmp/out_file_system#{ENV['TEST_ENV_NUMBER']}")
|
|
148
363
|
# 0750 interprets as "488". "488".to_i(8) # => 4. So, it makes wrong permission. Umm....
|
|
149
364
|
OVERRIDE_DIR_PERMISSION = 750
|
|
@@ -158,7 +373,7 @@ class FileOutputTest < Test::Unit::TestCase
|
|
|
158
373
|
</system>
|
|
159
374
|
]
|
|
160
375
|
|
|
161
|
-
|
|
376
|
+
setup do
|
|
162
377
|
omit "NTFS doesn't support UNIX like permissions" if Fluent.windows?
|
|
163
378
|
FileUtils.rm_rf(TMP_DIR_WITH_SYSTEM)
|
|
164
379
|
end
|
|
@@ -168,97 +383,104 @@ class FileOutputTest < Test::Unit::TestCase
|
|
|
168
383
|
Fluent::Config.parse(text, '(test)', basepath, true).elements.find { |e| e.name == 'system' }
|
|
169
384
|
end
|
|
170
385
|
|
|
171
|
-
|
|
386
|
+
test 'write to file with permission specifications' do
|
|
172
387
|
system_conf = parse_system(CONFIG_WITH_SYSTEM)
|
|
173
388
|
sc = Fluent::SystemConfig.new(system_conf)
|
|
174
389
|
Fluent::Engine.init(sc)
|
|
175
390
|
d = create_driver CONFIG_WITH_SYSTEM
|
|
176
391
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
392
|
+
assert_false File.exist?("#{TMP_DIR_WITH_SYSTEM}/out_file_test.20110102_0.log.gz")
|
|
393
|
+
|
|
394
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
|
395
|
+
d.run(default_tag: 'test') do
|
|
396
|
+
d.feed(time, {"a"=>1})
|
|
397
|
+
d.feed(time, {"a"=>2})
|
|
398
|
+
end
|
|
180
399
|
|
|
181
|
-
|
|
182
|
-
paths = d.run
|
|
183
|
-
expect_paths = ["#{TMP_DIR_WITH_SYSTEM}/out_file_test.20110102_0.log.gz"]
|
|
184
|
-
assert_equal expect_paths, paths
|
|
400
|
+
assert File.exist?("#{TMP_DIR_WITH_SYSTEM}/out_file_test.20110102_0.log.gz")
|
|
185
401
|
|
|
186
|
-
check_gzipped_result(
|
|
402
|
+
check_gzipped_result("#{TMP_DIR_WITH_SYSTEM}/out_file_test.20110102_0.log.gz", %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] + %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n])
|
|
187
403
|
dir_mode = "%o" % File::stat(TMP_DIR_WITH_SYSTEM).mode
|
|
188
404
|
assert_equal(OVERRIDE_DIR_PERMISSION, dir_mode[-3, 3].to_i)
|
|
189
|
-
file_mode = "%o" % File::stat(
|
|
405
|
+
file_mode = "%o" % File::stat("#{TMP_DIR_WITH_SYSTEM}/out_file_test.20110102_0.log.gz").mode
|
|
190
406
|
assert_equal(OVERRIDE_FILE_PERMISSION, file_mode[-3, 3].to_i)
|
|
191
407
|
end
|
|
192
408
|
end
|
|
193
409
|
|
|
194
|
-
|
|
195
|
-
|
|
410
|
+
sub_test_case 'format specified' do
|
|
411
|
+
test 'json' do
|
|
412
|
+
d = create_driver [CONFIG, 'format json', 'include_time_key true', 'time_as_epoch'].join("\n")
|
|
196
413
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
414
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
|
415
|
+
d.run(default_tag: 'test') do
|
|
416
|
+
d.feed(time, {"a"=>1})
|
|
417
|
+
d.feed(time, {"a"=>2})
|
|
418
|
+
end
|
|
200
419
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
end
|
|
420
|
+
path = d.instance.last_written_path
|
|
421
|
+
check_gzipped_result(path, %[#{Yajl.dump({"a" => 1, 'time' => time.to_i})}\n] + %[#{Yajl.dump({"a" => 2, 'time' => time.to_i})}\n])
|
|
422
|
+
end
|
|
205
423
|
|
|
206
|
-
|
|
207
|
-
|
|
424
|
+
test 'ltsv' do
|
|
425
|
+
d = create_driver [CONFIG, 'format ltsv', 'include_time_key true'].join("\n")
|
|
208
426
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
427
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
|
428
|
+
d.run(default_tag: 'test') do
|
|
429
|
+
d.feed(time, {"a"=>1})
|
|
430
|
+
d.feed(time, {"a"=>2})
|
|
431
|
+
end
|
|
212
432
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
end
|
|
433
|
+
path = d.instance.last_written_path
|
|
434
|
+
check_gzipped_result(path, %[a:1\ttime:2011-01-02T13:14:15Z\n] + %[a:2\ttime:2011-01-02T13:14:15Z\n])
|
|
435
|
+
end
|
|
217
436
|
|
|
218
|
-
|
|
219
|
-
|
|
437
|
+
test 'single_value' do
|
|
438
|
+
d = create_driver [CONFIG, 'format single_value', 'message_key a'].join("\n")
|
|
220
439
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
440
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
|
441
|
+
d.run(default_tag: 'test') do
|
|
442
|
+
d.feed(time, {"a"=>1})
|
|
443
|
+
d.feed(time, {"a"=>2})
|
|
444
|
+
end
|
|
224
445
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
446
|
+
path = d.instance.last_written_path
|
|
447
|
+
check_gzipped_result(path, %[1\n] + %[2\n])
|
|
448
|
+
end
|
|
228
449
|
end
|
|
229
450
|
|
|
230
|
-
|
|
231
|
-
time =
|
|
451
|
+
test 'path with index number' do
|
|
452
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
|
232
453
|
formatted_lines = %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] + %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n]
|
|
233
454
|
|
|
234
455
|
write_once = ->(){
|
|
235
456
|
d = create_driver
|
|
236
|
-
d.
|
|
237
|
-
|
|
238
|
-
|
|
457
|
+
d.run(default_tag: 'test'){
|
|
458
|
+
d.feed(time, {"a"=>1})
|
|
459
|
+
d.feed(time, {"a"=>2})
|
|
460
|
+
}
|
|
461
|
+
d.instance.last_written_path
|
|
239
462
|
}
|
|
240
463
|
|
|
241
464
|
assert !File.exist?("#{TMP_DIR}/out_file_test.20110102_0.log.gz")
|
|
242
465
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
check_gzipped_result(paths[0], formatted_lines)
|
|
466
|
+
path = write_once.call
|
|
467
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102_0.log.gz", path
|
|
468
|
+
check_gzipped_result(path, formatted_lines)
|
|
247
469
|
assert_equal 1, Dir.glob("#{TMP_DIR}/out_file_test.*").size
|
|
248
470
|
|
|
249
|
-
|
|
250
|
-
assert_equal
|
|
251
|
-
check_gzipped_result(
|
|
471
|
+
path = write_once.call
|
|
472
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102_1.log.gz", path
|
|
473
|
+
check_gzipped_result(path, formatted_lines)
|
|
252
474
|
assert_equal 2, Dir.glob("#{TMP_DIR}/out_file_test.*").size
|
|
253
475
|
|
|
254
|
-
|
|
255
|
-
assert_equal
|
|
256
|
-
check_gzipped_result(
|
|
476
|
+
path = write_once.call
|
|
477
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102_2.log.gz", path
|
|
478
|
+
check_gzipped_result(path, formatted_lines)
|
|
257
479
|
assert_equal 3, Dir.glob("#{TMP_DIR}/out_file_test.*").size
|
|
258
480
|
end
|
|
259
481
|
|
|
260
|
-
|
|
261
|
-
time =
|
|
482
|
+
test 'append' do
|
|
483
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
|
262
484
|
formatted_lines = %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] + %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n]
|
|
263
485
|
|
|
264
486
|
write_once = ->(){
|
|
@@ -268,53 +490,52 @@ class FileOutputTest < Test::Unit::TestCase
|
|
|
268
490
|
utc
|
|
269
491
|
append true
|
|
270
492
|
]
|
|
271
|
-
d.
|
|
272
|
-
|
|
273
|
-
|
|
493
|
+
d.run(default_tag: 'test'){
|
|
494
|
+
d.feed(time, {"a"=>1})
|
|
495
|
+
d.feed(time, {"a"=>2})
|
|
496
|
+
}
|
|
497
|
+
d.instance.last_written_path
|
|
274
498
|
}
|
|
275
499
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
assert_equal
|
|
282
|
-
check_gzipped_result(
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
500
|
+
path = write_once.call
|
|
501
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102.log.gz", path
|
|
502
|
+
check_gzipped_result(path, formatted_lines)
|
|
503
|
+
|
|
504
|
+
path = write_once.call
|
|
505
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102.log.gz", path
|
|
506
|
+
check_gzipped_result(path, formatted_lines * 2)
|
|
507
|
+
|
|
508
|
+
path = write_once.call
|
|
509
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102.log.gz", path
|
|
510
|
+
check_gzipped_result(path, formatted_lines * 3)
|
|
286
511
|
end
|
|
287
512
|
|
|
288
|
-
|
|
513
|
+
test 'symlink' do
|
|
289
514
|
omit "Windows doesn't support symlink" if Fluent.windows?
|
|
290
515
|
conf = CONFIG + %[
|
|
291
516
|
symlink_path #{SYMLINK_PATH}
|
|
292
517
|
]
|
|
293
518
|
symlink_path = "#{SYMLINK_PATH}"
|
|
294
519
|
|
|
295
|
-
d =
|
|
296
|
-
|
|
520
|
+
d = create_driver(conf)
|
|
297
521
|
begin
|
|
298
|
-
d.
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
|
302
|
-
es = Fluent::OneEventStream.new(time, {"a"=>1})
|
|
303
|
-
d.instance.emit_events('tag', es)
|
|
522
|
+
d.run(default_tag: 'tag') do
|
|
523
|
+
es = Fluent::OneEventStream.new(event_time("2011-01-02 13:14:15 UTC"), {"a"=>1})
|
|
524
|
+
d.feed(es)
|
|
304
525
|
|
|
305
|
-
|
|
306
|
-
|
|
526
|
+
assert File.symlink?(symlink_path)
|
|
527
|
+
assert File.exist?(symlink_path) # This checks dest of symlink exists or not.
|
|
307
528
|
|
|
308
|
-
|
|
309
|
-
|
|
529
|
+
es = Fluent::OneEventStream.new(event_time("2011-01-03 14:15:16 UTC"), {"a"=>2})
|
|
530
|
+
d.feed(es)
|
|
310
531
|
|
|
311
|
-
|
|
312
|
-
|
|
532
|
+
assert File.symlink?(symlink_path)
|
|
533
|
+
assert File.exist?(symlink_path)
|
|
313
534
|
|
|
314
|
-
|
|
315
|
-
|
|
535
|
+
meta = d.instance.metadata('tag', event_time("2011-01-03 14:15:16 UTC"), {})
|
|
536
|
+
assert_equal d.instance.buffer.instance_eval{ @stage[meta].path }, File.readlink(symlink_path)
|
|
537
|
+
end
|
|
316
538
|
ensure
|
|
317
|
-
d.instance.shutdown
|
|
318
539
|
FileUtils.rm_rf(symlink_path)
|
|
319
540
|
end
|
|
320
541
|
end
|
|
@@ -326,11 +547,12 @@ class FileOutputTest < Test::Unit::TestCase
|
|
|
326
547
|
time_slice_format %Y-%m-%d-%H
|
|
327
548
|
utc true
|
|
328
549
|
])
|
|
329
|
-
time =
|
|
330
|
-
d.
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
550
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
|
551
|
+
d.run(default_tag: 'test') do
|
|
552
|
+
d.feed(time, {"a"=>1})
|
|
553
|
+
end
|
|
554
|
+
path = d.instance.last_written_path
|
|
555
|
+
assert_equal "#{TMP_DIR}/out_file_test.2011-01-02-13_0.log", path
|
|
334
556
|
end
|
|
335
557
|
|
|
336
558
|
test 'normal with append' do
|
|
@@ -340,22 +562,26 @@ class FileOutputTest < Test::Unit::TestCase
|
|
|
340
562
|
utc true
|
|
341
563
|
append true
|
|
342
564
|
])
|
|
343
|
-
time =
|
|
344
|
-
d.
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
565
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
|
566
|
+
d.run(default_tag: 'test') do
|
|
567
|
+
d.feed(time, {"a"=>1})
|
|
568
|
+
end
|
|
569
|
+
path = d.instance.last_written_path
|
|
570
|
+
assert_equal "#{TMP_DIR}/out_file_test.2011-01-02-13.log", path
|
|
571
|
+
end
|
|
348
572
|
|
|
349
|
-
|
|
573
|
+
test '*' do
|
|
350
574
|
d = create_driver(%[
|
|
351
575
|
path #{TMP_DIR}/out_file_test.*.txt
|
|
352
576
|
time_slice_format %Y-%m-%d-%H
|
|
353
577
|
utc true
|
|
354
578
|
])
|
|
355
|
-
time =
|
|
356
|
-
d.
|
|
357
|
-
|
|
358
|
-
|
|
579
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
|
580
|
+
d.run(default_tag: 'test') do
|
|
581
|
+
d.feed(time, {"a"=>1})
|
|
582
|
+
end
|
|
583
|
+
path = d.instance.last_written_path
|
|
584
|
+
assert_equal "#{TMP_DIR}/out_file_test.2011-01-02-13_0.txt", path
|
|
359
585
|
end
|
|
360
586
|
|
|
361
587
|
test '* with append' do
|
|
@@ -365,11 +591,228 @@ class FileOutputTest < Test::Unit::TestCase
|
|
|
365
591
|
utc true
|
|
366
592
|
append true
|
|
367
593
|
])
|
|
368
|
-
time =
|
|
369
|
-
d.
|
|
370
|
-
|
|
371
|
-
|
|
594
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
|
595
|
+
d.run(default_tag: 'test') do
|
|
596
|
+
d.feed(time, {"a"=>1})
|
|
597
|
+
end
|
|
598
|
+
path = d.instance.last_written_path
|
|
599
|
+
assert_equal "#{TMP_DIR}/out_file_test.2011-01-02-13.txt", path
|
|
372
600
|
end
|
|
373
601
|
end
|
|
374
|
-
end
|
|
375
602
|
|
|
603
|
+
sub_test_case '#timekey_to_timeformat' do
|
|
604
|
+
setup do
|
|
605
|
+
@d = create_driver
|
|
606
|
+
@i = @d.instance
|
|
607
|
+
end
|
|
608
|
+
|
|
609
|
+
test 'returns empty string for nil' do
|
|
610
|
+
assert_equal '', @i.timekey_to_timeformat(nil)
|
|
611
|
+
end
|
|
612
|
+
|
|
613
|
+
test 'returns timestamp string with seconds for timekey smaller than 60' do
|
|
614
|
+
assert_equal '%Y%m%d%H%M%S', @i.timekey_to_timeformat(1)
|
|
615
|
+
assert_equal '%Y%m%d%H%M%S', @i.timekey_to_timeformat(30)
|
|
616
|
+
assert_equal '%Y%m%d%H%M%S', @i.timekey_to_timeformat(59)
|
|
617
|
+
end
|
|
618
|
+
|
|
619
|
+
test 'returns timestamp string with minutes for timekey smaller than 3600' do
|
|
620
|
+
assert_equal '%Y%m%d%H%M', @i.timekey_to_timeformat(60)
|
|
621
|
+
assert_equal '%Y%m%d%H%M', @i.timekey_to_timeformat(180)
|
|
622
|
+
assert_equal '%Y%m%d%H%M', @i.timekey_to_timeformat(1800)
|
|
623
|
+
assert_equal '%Y%m%d%H%M', @i.timekey_to_timeformat(3599)
|
|
624
|
+
end
|
|
625
|
+
|
|
626
|
+
test 'returns timestamp string with hours for timekey smaller than 86400 (1 day)' do
|
|
627
|
+
assert_equal '%Y%m%d%H', @i.timekey_to_timeformat(3600)
|
|
628
|
+
assert_equal '%Y%m%d%H', @i.timekey_to_timeformat(7200)
|
|
629
|
+
assert_equal '%Y%m%d%H', @i.timekey_to_timeformat(86399)
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
test 'returns timestamp string with days for timekey equal or greater than 86400' do
|
|
633
|
+
assert_equal '%Y%m%d', @i.timekey_to_timeformat(86400)
|
|
634
|
+
assert_equal '%Y%m%d', @i.timekey_to_timeformat(1000000)
|
|
635
|
+
assert_equal '%Y%m%d', @i.timekey_to_timeformat(1000000000)
|
|
636
|
+
end
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
sub_test_case '#compression_suffix' do
|
|
640
|
+
setup do
|
|
641
|
+
@i = create_driver.instance
|
|
642
|
+
end
|
|
643
|
+
|
|
644
|
+
test 'returns empty string for nil (no compression method specified)' do
|
|
645
|
+
assert_equal '', @i.compression_suffix(nil)
|
|
646
|
+
end
|
|
647
|
+
|
|
648
|
+
test 'returns .gz for gzip' do
|
|
649
|
+
assert_equal '.gz', @i.compression_suffix(:gzip)
|
|
650
|
+
end
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
sub_test_case '#generate_path_template' do
|
|
654
|
+
setup do
|
|
655
|
+
@i = create_driver.instance
|
|
656
|
+
end
|
|
657
|
+
|
|
658
|
+
data(
|
|
659
|
+
'day' => [86400, '%Y%m%d', '%Y-%m-%d'],
|
|
660
|
+
'hour' => [3600, '%Y%m%d%H', '%Y-%m-%d_%H'],
|
|
661
|
+
'minute' => [60, '%Y%m%d%H%M', '%Y-%m-%d_%H%M'],
|
|
662
|
+
)
|
|
663
|
+
test 'generates path with timestamp placeholder for original path with tailing star with timekey' do |data|
|
|
664
|
+
timekey, placeholder, time_slice_format = data
|
|
665
|
+
# with index placeholder, without compression suffix when append disabled and compression disabled
|
|
666
|
+
assert_equal "/path/to/file.#{placeholder}_**", @i.generate_path_template('/path/to/file.*', timekey, false, nil)
|
|
667
|
+
# with index placeholder, with .gz suffix when append disabled and gzip compression enabled
|
|
668
|
+
assert_equal "/path/to/file.#{placeholder}_**.gz", @i.generate_path_template('/path/to/file.*', timekey, false, :gzip)
|
|
669
|
+
# without index placeholder, without compression suffix when append enabled and compression disabled
|
|
670
|
+
assert_equal "/path/to/file.#{placeholder}", @i.generate_path_template('/path/to/file.*', timekey, true, nil)
|
|
671
|
+
# without index placeholder, with .gz suffix when append disabled and gzip compression enabled
|
|
672
|
+
assert_equal "/path/to/file.#{placeholder}.gz", @i.generate_path_template('/path/to/file.*', timekey, true, :gzip)
|
|
673
|
+
|
|
674
|
+
# time_slice_format will used instead of computed placeholder if specified
|
|
675
|
+
assert_equal "/path/to/file.#{time_slice_format}_**", @i.generate_path_template('/path/to/file.*', timekey, false, nil, time_slice_format: time_slice_format)
|
|
676
|
+
assert_equal "/path/to/file.#{time_slice_format}_**.gz", @i.generate_path_template('/path/to/file.*', timekey, false, :gzip, time_slice_format: time_slice_format)
|
|
677
|
+
assert_equal "/path/to/file.#{time_slice_format}", @i.generate_path_template('/path/to/file.*', timekey, true, nil, time_slice_format: time_slice_format)
|
|
678
|
+
assert_equal "/path/to/file.#{time_slice_format}.gz", @i.generate_path_template('/path/to/file.*', timekey, true, :gzip, time_slice_format: time_slice_format)
|
|
679
|
+
end
|
|
680
|
+
|
|
681
|
+
data(
|
|
682
|
+
'day' => [86400 * 2, '%Y%m%d', '%Y-%m-%d'],
|
|
683
|
+
'hour' => [7200, '%Y%m%d%H', '%Y-%m-%d_%H'],
|
|
684
|
+
'minute' => [180, '%Y%m%d%H%M', '%Y-%m-%d_%H%M'],
|
|
685
|
+
)
|
|
686
|
+
test 'generates path with timestamp placeholder for original path with star and suffix with timekey' do |data|
|
|
687
|
+
timekey, placeholder, time_slice_format = data
|
|
688
|
+
# with index placeholder, without compression suffix when append disabled and compression disabled
|
|
689
|
+
assert_equal "/path/to/file.#{placeholder}_**.data", @i.generate_path_template('/path/to/file.*.data', timekey, false, nil)
|
|
690
|
+
# with index placeholder, with .gz suffix when append disabled and gzip compression enabled
|
|
691
|
+
assert_equal "/path/to/file.#{placeholder}_**.data.gz", @i.generate_path_template('/path/to/file.*.data', timekey, false, :gzip)
|
|
692
|
+
# without index placeholder, without compression suffix when append enabled and compression disabled
|
|
693
|
+
assert_equal "/path/to/file.#{placeholder}.data", @i.generate_path_template('/path/to/file.*.data', timekey, true, nil)
|
|
694
|
+
# without index placeholder, with .gz suffix when append disabled and gzip compression enabled
|
|
695
|
+
assert_equal "/path/to/file.#{placeholder}.data.gz", @i.generate_path_template('/path/to/file.*.data', timekey, true, :gzip)
|
|
696
|
+
|
|
697
|
+
# time_slice_format will used instead of computed placeholder if specified
|
|
698
|
+
assert_equal "/path/to/file.#{time_slice_format}_**.data", @i.generate_path_template('/path/to/file.*.data', timekey, false, nil, time_slice_format: time_slice_format)
|
|
699
|
+
assert_equal "/path/to/file.#{time_slice_format}_**.data.gz", @i.generate_path_template('/path/to/file.*.data', timekey, false, :gzip, time_slice_format: time_slice_format)
|
|
700
|
+
assert_equal "/path/to/file.#{time_slice_format}.data", @i.generate_path_template('/path/to/file.*.data', timekey, true, nil, time_slice_format: time_slice_format)
|
|
701
|
+
assert_equal "/path/to/file.#{time_slice_format}.data.gz", @i.generate_path_template('/path/to/file.*.data', timekey, true, :gzip, time_slice_format: time_slice_format)
|
|
702
|
+
end
|
|
703
|
+
|
|
704
|
+
test 'raise error to show it is a bug when path including * specified without timekey' do
|
|
705
|
+
assert_raise "BUG: configuration error must be raised for path including '*' without timekey" do
|
|
706
|
+
@i.generate_path_template('/path/to/file.*.log', nil, false, nil)
|
|
707
|
+
end
|
|
708
|
+
end
|
|
709
|
+
|
|
710
|
+
data(
|
|
711
|
+
'day' => [86400 * 7, '%Y%m%d', '%Y-%m-%d'],
|
|
712
|
+
'hour' => [3600 * 6, '%Y%m%d%H', '%Y-%m-%d_%H'],
|
|
713
|
+
'minute' => [60 * 15, '%Y%m%d%H%M', '%Y-%m-%d_%H%M'],
|
|
714
|
+
)
|
|
715
|
+
test 'generates path with timestamp placeholder for original path without time placeholders & star with timekey, and path_suffix configured' do |data|
|
|
716
|
+
timekey, placeholder, time_slice_format = data
|
|
717
|
+
# with index placeholder, without compression suffix when append disabled and compression disabled
|
|
718
|
+
assert_equal "/path/to/file.#{placeholder}_**.log", @i.generate_path_template('/path/to/file', timekey, false, nil, path_suffix: '.log')
|
|
719
|
+
# with index placeholder, with .gz suffix when append disabled and gzip compression enabled
|
|
720
|
+
assert_equal "/path/to/file.#{placeholder}_**.log.gz", @i.generate_path_template('/path/to/file', timekey, false, :gzip, path_suffix: '.log')
|
|
721
|
+
# without index placeholder, without compression suffix when append enabled and compression disabled
|
|
722
|
+
assert_equal "/path/to/file.#{placeholder}.log", @i.generate_path_template('/path/to/file', timekey, true, nil, path_suffix: '.log')
|
|
723
|
+
# without index placeholder, with compression suffix when append enabled and gzip compression enabled
|
|
724
|
+
assert_equal "/path/to/file.#{placeholder}.log.gz", @i.generate_path_template('/path/to/file', timekey, true, :gzip, path_suffix: '.log')
|
|
725
|
+
|
|
726
|
+
# time_slice_format will be appended always if it's specified
|
|
727
|
+
assert_equal "/path/to/file.#{time_slice_format}_**.log", @i.generate_path_template('/path/to/file', timekey, false, nil, path_suffix: '.log', time_slice_format: time_slice_format)
|
|
728
|
+
assert_equal "/path/to/file.#{time_slice_format}_**.log.gz", @i.generate_path_template('/path/to/file', timekey, false, :gzip, path_suffix: '.log', time_slice_format: time_slice_format)
|
|
729
|
+
assert_equal "/path/to/file.#{time_slice_format}.log", @i.generate_path_template('/path/to/file', timekey, true, nil, path_suffix: '.log', time_slice_format: time_slice_format)
|
|
730
|
+
assert_equal "/path/to/file.#{time_slice_format}.log.gz", @i.generate_path_template('/path/to/file', timekey, true, :gzip, path_suffix: '.log', time_slice_format: time_slice_format)
|
|
731
|
+
end
|
|
732
|
+
|
|
733
|
+
data(
|
|
734
|
+
'day' => [86400, '%Y%m%d'],
|
|
735
|
+
'hour' => [3600, '%Y%m%d%H'],
|
|
736
|
+
'minute' => [60, '%Y%m%d%H%M'],
|
|
737
|
+
)
|
|
738
|
+
test 'generates path with timestamp placeholder for original path without star with timekey, and path_suffix not configured' do |data|
|
|
739
|
+
timekey, placeholder = data
|
|
740
|
+
# with index placeholder, without compression suffix when append disabled and compression disabled
|
|
741
|
+
assert_equal "/path/to/file.#{placeholder}_**", @i.generate_path_template('/path/to/file', timekey, false, nil)
|
|
742
|
+
# with index placeholder, with .gz suffix when append disabled and gzip compression enabled
|
|
743
|
+
assert_equal "/path/to/file.#{placeholder}_**.gz", @i.generate_path_template('/path/to/file', timekey, false, :gzip)
|
|
744
|
+
# without index placeholder, without compression suffix when append enabled and compression disabled
|
|
745
|
+
assert_equal "/path/to/file.#{placeholder}", @i.generate_path_template('/path/to/file', timekey, true, nil)
|
|
746
|
+
# without index placeholder, with compression suffix when append enabled and gzip compression enabled
|
|
747
|
+
assert_equal "/path/to/file.#{placeholder}.gz", @i.generate_path_template('/path/to/file', timekey, true, :gzip)
|
|
748
|
+
end
|
|
749
|
+
|
|
750
|
+
test 'generates path without adding timestamp placeholder part if original path has enough placeholders for specified timekey' do
|
|
751
|
+
assert_equal "/path/to/file.%Y%m%d", @i.generate_path_template('/path/to/file.%Y%m%d', 86400, true, nil)
|
|
752
|
+
assert_equal "/path/to/%Y%m%d/file", @i.generate_path_template('/path/to/%Y%m%d/file', 86400, true, nil)
|
|
753
|
+
|
|
754
|
+
assert_equal "/path/to/%Y%m%d/file_**", @i.generate_path_template('/path/to/%Y%m%d/file', 86400, false, nil)
|
|
755
|
+
|
|
756
|
+
assert_raise Fluent::ConfigError.new("insufficient timestamp placeholders in path") do
|
|
757
|
+
@i.generate_path_template('/path/to/%Y%m/file', 86400, true, nil)
|
|
758
|
+
end
|
|
759
|
+
assert_raise Fluent::ConfigError.new("insufficient timestamp placeholders in path") do
|
|
760
|
+
@i.generate_path_template('/path/to/file.%Y%m%d.log', 3600, true, nil)
|
|
761
|
+
end
|
|
762
|
+
|
|
763
|
+
assert_equal "/path/to/file.%Y%m%d_%H_**.log.gz", @i.generate_path_template('/path/to/file.%Y%m%d_%H', 7200, false, :gzip, path_suffix: '.log')
|
|
764
|
+
assert_equal "/path/to/${tag}/file.%Y%m%d_%H_**.log.gz", @i.generate_path_template('/path/to/${tag}/file.%Y%m%d_%H', 7200, false, :gzip, path_suffix: '.log')
|
|
765
|
+
end
|
|
766
|
+
|
|
767
|
+
test 'generates path with specified time_slice_format appended even if path has sufficient timestamp placeholders' do
|
|
768
|
+
assert_equal "/path/to/%Y%m%d/file.%Y-%m-%d_%H_**", @i.generate_path_template('/path/to/%Y%m%d/file', 86400, false, nil, time_slice_format: '%Y-%m-%d_%H')
|
|
769
|
+
assert_equal "/path/to/%Y%m%d/file.%Y-%m-%d_%H", @i.generate_path_template('/path/to/%Y%m%d/file', 86400, true, nil, time_slice_format: '%Y-%m-%d_%H')
|
|
770
|
+
assert_equal "/path/to/%Y%m%d/file.%Y-%m-%d_%H_**.log", @i.generate_path_template('/path/to/%Y%m%d/file', 86400, false, nil, time_slice_format: '%Y-%m-%d_%H', path_suffix: '.log')
|
|
771
|
+
assert_equal "/path/to/%Y%m%d/file.%Y-%m-%d_%H.log", @i.generate_path_template('/path/to/%Y%m%d/file', 86400, true, nil, time_slice_format: '%Y-%m-%d_%H', path_suffix: '.log')
|
|
772
|
+
assert_equal "/path/to/%Y%m%d/file.%Y-%m-%d_%H.log.gz", @i.generate_path_template('/path/to/%Y%m%d/file', 86400, true, :gzip, time_slice_format: '%Y-%m-%d_%H', path_suffix: '.log')
|
|
773
|
+
end
|
|
774
|
+
|
|
775
|
+
test 'generates path without timestamp placeholder when path does not include * and timekey not specified' do
|
|
776
|
+
assert_equal '/path/to/file.log', @i.generate_path_template('/path/to/file.log', nil, true, nil)
|
|
777
|
+
assert_equal '/path/to/file.log_**', @i.generate_path_template('/path/to/file.log', nil, false, nil)
|
|
778
|
+
assert_equal '/path/to/file.${tag}.log_**', @i.generate_path_template('/path/to/file.${tag}.log', nil, false, nil)
|
|
779
|
+
assert_equal '/path/to/file.${tag}_**.log', @i.generate_path_template('/path/to/file.${tag}', nil, false, nil, path_suffix: '.log')
|
|
780
|
+
end
|
|
781
|
+
end
|
|
782
|
+
|
|
783
|
+
sub_test_case '#find_filepath_available' do
|
|
784
|
+
setup do
|
|
785
|
+
@tmp = File.join(TMP_DIR, 'find_filepath_test')
|
|
786
|
+
FileUtils.mkdir_p @tmp
|
|
787
|
+
@i = create_driver.instance
|
|
788
|
+
end
|
|
789
|
+
|
|
790
|
+
teardown do
|
|
791
|
+
FileUtils.rm_rf @tmp
|
|
792
|
+
end
|
|
793
|
+
|
|
794
|
+
test 'raise error if argument path does not include index placeholder' do
|
|
795
|
+
assert_raise "BUG: index placeholder not found in path: #{@tmp}/myfile" do
|
|
796
|
+
@i.find_filepath_available("#{@tmp}/myfile")
|
|
797
|
+
end
|
|
798
|
+
end
|
|
799
|
+
|
|
800
|
+
data(
|
|
801
|
+
'without suffix' => ['myfile_0', 'myfile_**'],
|
|
802
|
+
'with timestamp' => ['myfile_20161003_0', 'myfile_20161003_**'],
|
|
803
|
+
'with base suffix' => ['myfile_0.log', 'myfile_**.log'],
|
|
804
|
+
'with compression suffix' => ['myfile_0.log.gz', 'myfile_**.log.gz'],
|
|
805
|
+
)
|
|
806
|
+
test 'returns filepath with _0 at first' do |data|
|
|
807
|
+
expected, argument = data
|
|
808
|
+
assert_equal File.join(@tmp, expected), @i.find_filepath_available(File.join(@tmp, argument))
|
|
809
|
+
end
|
|
810
|
+
|
|
811
|
+
test 'returns filepath with index which does not exist yet' do
|
|
812
|
+
5.times do |i|
|
|
813
|
+
File.open(File.join(@tmp, "exist_#{i}.log"), 'a')
|
|
814
|
+
end
|
|
815
|
+
assert_equal File.join(@tmp, "exist_5.log"), @i.find_filepath_available(File.join(@tmp, "exist_**.log"))
|
|
816
|
+
end
|
|
817
|
+
end
|
|
818
|
+
end
|