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