fluentd 0.14.13-x64-mingw32 → 0.14.17-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fluentd might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +4 -5
- data/ChangeLog +106 -0
- data/MAINTAINERS.md +5 -0
- data/README.md +25 -0
- data/example/worker_section.conf +36 -0
- data/fluentd.gemspec +1 -1
- data/lib/fluent/agent.rb +5 -2
- data/lib/fluent/command/binlog_reader.rb +1 -0
- data/lib/fluent/command/fluentd.rb +28 -12
- data/lib/fluent/command/plugin_config_formatter.rb +0 -1
- data/lib/fluent/command/plugin_generator.rb +1 -1
- data/lib/fluent/compat/detach_process_mixin.rb +8 -0
- data/lib/fluent/compat/input.rb +0 -10
- data/lib/fluent/compat/output.rb +0 -10
- data/lib/fluent/config/element.rb +22 -0
- data/lib/fluent/config/literal_parser.rb +2 -0
- data/lib/fluent/config/types.rb +2 -2
- data/lib/fluent/engine.rb +27 -10
- data/lib/fluent/env.rb +3 -3
- data/lib/fluent/log.rb +4 -1
- data/lib/fluent/plugin/base.rb +3 -0
- data/lib/fluent/plugin/filter.rb +2 -2
- data/lib/fluent/plugin/filter_parser.rb +17 -6
- data/lib/fluent/plugin/in_forward.rb +1 -1
- data/lib/fluent/plugin/in_http.rb +4 -0
- data/lib/fluent/plugin/in_monitor_agent.rb +8 -3
- data/lib/fluent/plugin/in_syslog.rb +3 -2
- data/lib/fluent/plugin/in_tail.rb +14 -3
- data/lib/fluent/plugin/in_udp.rb +6 -2
- data/lib/fluent/plugin/out_file.rb +5 -0
- data/lib/fluent/plugin/out_forward.rb +5 -2
- data/lib/fluent/plugin/output.rb +13 -8
- data/lib/fluent/plugin/parser_apache2.rb +1 -1
- data/lib/fluent/plugin/parser_syslog.rb +40 -1
- data/lib/fluent/plugin_helper/cert_option.rb +2 -2
- data/lib/fluent/plugin_helper/compat_parameters.rb +1 -1
- data/lib/fluent/plugin_helper/storage.rb +1 -1
- data/lib/fluent/root_agent.rb +36 -4
- data/lib/fluent/supervisor.rb +37 -6
- data/lib/fluent/system_config.rb +7 -0
- data/lib/fluent/time.rb +1 -0
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +25 -11
- data/test/command/test_fluentd.rb +253 -4
- data/test/config/test_element.rb +63 -0
- data/test/config/test_literal_parser.rb +1 -1
- data/test/config/test_system_config.rb +36 -6
- data/test/config/test_types.rb +19 -0
- data/test/plugin/test_filter_parser.rb +35 -0
- data/test/plugin/test_in_http.rb +58 -4
- data/test/plugin/test_in_monitor_agent.rb +90 -9
- data/test/plugin/test_in_tail.rb +16 -0
- data/test/plugin/test_in_udp.rb +11 -1
- data/test/plugin/test_out_file.rb +9 -0
- data/test/plugin/test_out_forward.rb +45 -0
- data/test/plugin/test_output.rb +15 -15
- data/test/plugin/test_output_as_buffered.rb +30 -2
- data/test/plugin/test_parser_apache2.rb +8 -0
- data/test/plugin/test_parser_syslog.rb +176 -0
- data/test/plugin_helper/test_server.rb +37 -31
- data/test/plugin_helper/test_storage.rb +9 -0
- data/test/test_log.rb +6 -0
- data/test/test_plugin_classes.rb +50 -0
- data/test/test_root_agent.rb +245 -14
- data/test/test_time_parser.rb +12 -0
- metadata +13 -5
@@ -662,4 +662,39 @@ class ParserFilterTest < Test::Unit::TestCase
|
|
662
662
|
end
|
663
663
|
end
|
664
664
|
end
|
665
|
+
|
666
|
+
class EmitInvalidRecordToErrorTest < self
|
667
|
+
def test_pattern_is_mismached_with_emit_invalid_record_to_error
|
668
|
+
d = create_driver(CONFIG_UNMATCHED_PATTERN_LOG + "emit_invalid_record_to_error false")
|
669
|
+
flexmock(d.instance.router).should_receive(:emit_error_event).never
|
670
|
+
assert_nothing_raised {
|
671
|
+
d.run do
|
672
|
+
d.feed(@tag, Fluent::EventTime.now.to_i, {'message' => INVALID_MESSAGE})
|
673
|
+
end
|
674
|
+
}
|
675
|
+
assert_equal 0, d.filtered.length
|
676
|
+
end
|
677
|
+
|
678
|
+
def test_parser_error_with_emit_invalid_record_to_error
|
679
|
+
d = create_driver(CONFIG_INVALID_TIME_VALUE + "emit_invalid_record_to_error false")
|
680
|
+
flexmock(d.instance.router).should_receive(:emit_error_event).never
|
681
|
+
assert_nothing_raised {
|
682
|
+
d.run do
|
683
|
+
d.feed(@tag, Fluent::EventTime.now.to_i, {'data' => '{"time":[], "f1":"v1"}'})
|
684
|
+
end
|
685
|
+
}
|
686
|
+
assert_equal 0, d.filtered.length
|
687
|
+
end
|
688
|
+
|
689
|
+
def test_key_not_exist_with_emit_invalid_record_to_error
|
690
|
+
d = create_driver(CONFIG_NOT_IGNORE + "emit_invalid_record_to_error false")
|
691
|
+
flexmock(d.instance.router).should_receive(:emit_error_event).never
|
692
|
+
assert_nothing_raised {
|
693
|
+
d.run do
|
694
|
+
d.feed(@tag, Fluent::EventTime.now.to_i, {'foo' => 'bar'})
|
695
|
+
end
|
696
|
+
}
|
697
|
+
assert_equal 0, d.filtered.length
|
698
|
+
end
|
699
|
+
end
|
665
700
|
end
|
data/test/plugin/test_in_http.rb
CHANGED
@@ -215,14 +215,14 @@ class HttpInputTest < Test::Unit::TestCase
|
|
215
215
|
def test_multi_json_with_add_remote_addr_given_x_forwarded_for
|
216
216
|
d = create_driver(CONFIG + "add_remote_addr true")
|
217
217
|
|
218
|
+
tag = "tag1"
|
218
219
|
time = event_time("2011-01-02 13:14:15 UTC")
|
219
220
|
time_i = time.to_i
|
220
221
|
records = [{"a"=>1},{"a"=>2}]
|
221
222
|
events = [
|
222
|
-
[
|
223
|
-
[
|
223
|
+
[tag, time, {"REMOTE_ADDR"=>"129.78.138.66", "a"=>1}],
|
224
|
+
[tag, time, {"REMOTE_ADDR"=>"129.78.138.66", "a"=>2}],
|
224
225
|
]
|
225
|
-
tag = "tag1"
|
226
226
|
res_codes = []
|
227
227
|
|
228
228
|
d.run(expect_records: 2, timeout: 5) do
|
@@ -235,6 +235,37 @@ class HttpInputTest < Test::Unit::TestCase
|
|
235
235
|
assert_equal_event_time time, d.events[1][1]
|
236
236
|
end
|
237
237
|
|
238
|
+
def test_add_remote_addr_given_multi_x_forwarded_for
|
239
|
+
d = create_driver(CONFIG + "add_remote_addr true")
|
240
|
+
|
241
|
+
tag = "tag1"
|
242
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
243
|
+
time_i = time.to_i
|
244
|
+
record = {"a" => 1}
|
245
|
+
event = ["tag1", time, {"REMOTE_ADDR" => "129.78.138.66", "a" => 1}]
|
246
|
+
res_code = nil
|
247
|
+
|
248
|
+
d.run(expect_records: 1, timeout: 5) do
|
249
|
+
res = post("/#{tag}", {"json" => record.to_json, "time" => time_i.to_s}) { |http, req|
|
250
|
+
# net/http can't send multiple headers so overwrite it.
|
251
|
+
def req.each_capitalized
|
252
|
+
block_given? or return enum_for(__method__) { @header.size }
|
253
|
+
@header.each do |k, vs|
|
254
|
+
vs.each { |v|
|
255
|
+
yield capitalize(k), v
|
256
|
+
}
|
257
|
+
end
|
258
|
+
end
|
259
|
+
req.add_field("X-Forwarded-For", "129.78.138.66, 127.0.0.1")
|
260
|
+
req.add_field("X-Forwarded-For", "8.8.8.8")
|
261
|
+
}
|
262
|
+
res_code = res.code
|
263
|
+
end
|
264
|
+
assert_equal "200", res_code
|
265
|
+
assert_equal event, d.events.first
|
266
|
+
assert_equal_event_time time, d.events.first[1]
|
267
|
+
end
|
268
|
+
|
238
269
|
def test_multi_json_with_add_http_headers
|
239
270
|
d = create_driver(CONFIG + "add_http_headers true")
|
240
271
|
time = event_time("2011-01-02 13:14:15 UTC")
|
@@ -313,6 +344,28 @@ class HttpInputTest < Test::Unit::TestCase
|
|
313
344
|
assert_equal_event_time time, d.events[1][1]
|
314
345
|
end
|
315
346
|
|
347
|
+
def test_application_msgpack
|
348
|
+
d = create_driver
|
349
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
350
|
+
time_i = time.to_i
|
351
|
+
events = [
|
352
|
+
["tag1", time, {"a"=>1}],
|
353
|
+
["tag2", time, {"a"=>2}],
|
354
|
+
]
|
355
|
+
res_codes = []
|
356
|
+
|
357
|
+
d.run(expect_records: 2) do
|
358
|
+
events.each do |tag, t, record|
|
359
|
+
res = post("/#{tag}?time=#{time_i.to_s}", record.to_msgpack, {"Content-Type"=>"application/msgpack"})
|
360
|
+
res_codes << res.code
|
361
|
+
end
|
362
|
+
end
|
363
|
+
assert_equal ["200", "200"], res_codes
|
364
|
+
assert_equal events, d.events
|
365
|
+
assert_equal_event_time time, d.events[0][1]
|
366
|
+
assert_equal_event_time time, d.events[1][1]
|
367
|
+
end
|
368
|
+
|
316
369
|
def test_msgpack
|
317
370
|
d = create_driver
|
318
371
|
time = event_time("2011-01-02 13:14:15 UTC")
|
@@ -543,9 +596,10 @@ class HttpInputTest < Test::Unit::TestCase
|
|
543
596
|
assert_equal $test_in_http_connection_object_ids[0], $test_in_http_connection_object_ids[1]
|
544
597
|
end
|
545
598
|
|
546
|
-
def post(path, params, header = {})
|
599
|
+
def post(path, params, header = {}, &block)
|
547
600
|
http = Net::HTTP.new("127.0.0.1", PORT)
|
548
601
|
req = Net::HTTP::Post.new(path, header)
|
602
|
+
block.call(http, req) if block
|
549
603
|
if params.is_a?(String)
|
550
604
|
unless header.has_key?('Content-Type')
|
551
605
|
header['Content-Type'] = 'application/octet-stream'
|
@@ -204,10 +204,9 @@ EOC
|
|
204
204
|
unless header.has_key?('Content-Type')
|
205
205
|
header['Content-Type'] = 'application/octet-stream'
|
206
206
|
end
|
207
|
-
|
207
|
+
Net::HTTP.start(url.host, url.port) {|http|
|
208
208
|
http.request(req)
|
209
209
|
}
|
210
|
-
res.body
|
211
210
|
end
|
212
211
|
|
213
212
|
sub_test_case "servlets" do
|
@@ -268,7 +267,7 @@ plugin_id:test_in\tplugin_category:input\ttype:test_in\toutput_plugin:false\tret
|
|
268
267
|
expected_test_filter_response = "\
|
269
268
|
plugin_id:test_filter\tplugin_category:filter\ttype:test_filter\toutput_plugin:false\tretry_count:"
|
270
269
|
|
271
|
-
response = get("http://127.0.0.1:#{@port}/api/plugins")
|
270
|
+
response = get("http://127.0.0.1:#{@port}/api/plugins").body
|
272
271
|
test_in = response.split("\n")[0]
|
273
272
|
test_filter = response.split("\n")[3]
|
274
273
|
assert_equal(expected_test_in_response, test_in)
|
@@ -306,7 +305,7 @@ plugin_id:test_filter\tplugin_category:filter\ttype:test_filter\toutput_plugin:f
|
|
306
305
|
}
|
307
306
|
expected_null_response.merge!("config" => {"@id" => "null", "@type" => "null"}) if with_config
|
308
307
|
expected_null_response.merge!("retry" => {}) if with_retry
|
309
|
-
response = JSON.parse(get("http://127.0.0.1:#{@port}/api/plugins.json"))
|
308
|
+
response = JSON.parse(get("http://127.0.0.1:#{@port}/api/plugins.json").body)
|
310
309
|
test_in_response = response["plugins"][0]
|
311
310
|
null_response = response["plugins"][5]
|
312
311
|
assert_equal(expected_test_in_response, test_in_response)
|
@@ -343,7 +342,7 @@ plugin_id:test_filter\tplugin_category:filter\ttype:test_filter\toutput_plugin:f
|
|
343
342
|
}
|
344
343
|
expected_null_response.merge!("config" => {"@id" => "null", "@type" => "null"}) if with_config
|
345
344
|
expected_null_response.merge!("retry" => {}) if with_retry
|
346
|
-
response = JSON.parse(get("http://127.0.0.1:#{@port}/api/plugins.json#{query_param}"))
|
345
|
+
response = JSON.parse(get("http://127.0.0.1:#{@port}/api/plugins.json#{query_param}").body)
|
347
346
|
test_in_response = response["plugins"][0]
|
348
347
|
null_response = response["plugins"][5]
|
349
348
|
assert_equal(expected_test_in_response, test_in_response)
|
@@ -376,7 +375,7 @@ plugin_id:test_filter\tplugin_category:filter\ttype:test_filter\toutput_plugin:f
|
|
376
375
|
"type" => "null",
|
377
376
|
"instance_variables" => {"id" => "null", "num_errors" => 0}
|
378
377
|
}
|
379
|
-
response = JSON.parse(get("http://127.0.0.1:#{@port}/api/plugins.json?with_config=no&with_retry=no&with_ivars=id,num_errors"))
|
378
|
+
response = JSON.parse(get("http://127.0.0.1:#{@port}/api/plugins.json?with_config=no&with_retry=no&with_ivars=id,num_errors").body)
|
380
379
|
test_in_response = response["plugins"][0]
|
381
380
|
null_response = response["plugins"][5]
|
382
381
|
assert_equal(expected_test_in_response, test_in_response)
|
@@ -394,7 +393,7 @@ plugin_id:test_filter\tplugin_category:filter\ttype:test_filter\toutput_plugin:f
|
|
394
393
|
expected_response_regex = /pid:\d+\tppid:\d+\tconfig_path:\/etc\/fluent\/fluent.conf\tpid_file:\tplugin_dirs:\[\"\/etc\/fluent\/plugin\"\]\tlog_path:/
|
395
394
|
|
396
395
|
assert_match(expected_response_regex,
|
397
|
-
get("http://127.0.0.1:#{@port}/api/config"))
|
396
|
+
get("http://127.0.0.1:#{@port}/api/config").body)
|
398
397
|
end
|
399
398
|
|
400
399
|
test "/api/config.json" do
|
@@ -405,7 +404,7 @@ plugin_id:test_filter\tplugin_category:filter\ttype:test_filter\toutput_plugin:f
|
|
405
404
|
tag monitor
|
406
405
|
")
|
407
406
|
d.instance.start
|
408
|
-
res = JSON.parse(get("http://127.0.0.1:#{@port}/api/config.json"))
|
407
|
+
res = JSON.parse(get("http://127.0.0.1:#{@port}/api/config.json").body)
|
409
408
|
assert_equal("/etc/fluent/fluent.conf", res["config_path"])
|
410
409
|
assert_nil(res["pid_file"])
|
411
410
|
assert_equal(["/etc/fluent/plugin"], res["plugin_dirs"])
|
@@ -474,7 +473,7 @@ plugin_id:test_filter\tplugin_category:filter\ttype:test_filter\toutput_plugin:f
|
|
474
473
|
output.submit_flush_once
|
475
474
|
sleep 0.1 until output.buffer.queued?
|
476
475
|
end
|
477
|
-
response = JSON.parse(get("http://127.0.0.1:#{@port}/api/plugins.json"))
|
476
|
+
response = JSON.parse(get("http://127.0.0.1:#{@port}/api/plugins.json").body)
|
478
477
|
test_out_fail_write_response = response["plugins"][1]
|
479
478
|
# remove dynamic keys
|
480
479
|
response_retry_count = test_out_fail_write_response.delete("retry_count")
|
@@ -486,4 +485,86 @@ plugin_id:test_filter\tplugin_category:filter\ttype:test_filter\toutput_plugin:f
|
|
486
485
|
assert{ response_retry_count == response_retry["steps"] + 1 }
|
487
486
|
end
|
488
487
|
end
|
488
|
+
|
489
|
+
sub_test_case "check the port number of http server" do
|
490
|
+
test "on single worker environment" do
|
491
|
+
port = unused_port
|
492
|
+
d = create_driver("
|
493
|
+
@type monitor_agent
|
494
|
+
bind '127.0.0.1'
|
495
|
+
port #{port}
|
496
|
+
")
|
497
|
+
d.instance.start
|
498
|
+
assert_equal("200", get("http://127.0.0.1:#{port}/api/plugins").code)
|
499
|
+
end
|
500
|
+
|
501
|
+
test "worker_id = 2 on multi worker environment" do
|
502
|
+
port = unused_port
|
503
|
+
Fluent::SystemConfig.overwrite_system_config('workers' => 4) do
|
504
|
+
d = Fluent::Test::Driver::Input.new(Fluent::Plugin::MonitorAgentInput)
|
505
|
+
d.instance.instance_eval{ @_fluentd_worker_id = 2 }
|
506
|
+
d.configure("
|
507
|
+
@type monitor_agent
|
508
|
+
bind '127.0.0.1'
|
509
|
+
port #{port - 2}
|
510
|
+
")
|
511
|
+
d.instance.start
|
512
|
+
end
|
513
|
+
assert_equal("200", get("http://127.0.0.1:#{port}/api/plugins").code)
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
sub_test_case "check NoMethodError does not happen" do
|
518
|
+
class FluentTestBufferVariableOutput < ::Fluent::Plugin::Output
|
519
|
+
::Fluent::Plugin.register_output('test_out_buffer_variable', self)
|
520
|
+
def configure(conf)
|
521
|
+
super
|
522
|
+
@buffer = []
|
523
|
+
end
|
524
|
+
|
525
|
+
def write(chunk)
|
526
|
+
end
|
527
|
+
end
|
528
|
+
class FluentTestBufferVariableFilter < ::Fluent::Plugin::Filter
|
529
|
+
::Fluent::Plugin.register_filter("test_filter_buffer_variable", self)
|
530
|
+
def initialize
|
531
|
+
super
|
532
|
+
@buffer = {}
|
533
|
+
end
|
534
|
+
def filter(tag, time, record)
|
535
|
+
record
|
536
|
+
end
|
537
|
+
end
|
538
|
+
|
539
|
+
setup do
|
540
|
+
conf = <<-EOC
|
541
|
+
<match **>
|
542
|
+
@type test_out_buffer_variable
|
543
|
+
@id test_out_buffer_variable
|
544
|
+
</match>
|
545
|
+
<filter **>
|
546
|
+
@type test_filter_buffer_variable
|
547
|
+
@id test_filter_buffer_variable
|
548
|
+
</filter>
|
549
|
+
EOC
|
550
|
+
@ra = Fluent::RootAgent.new(log: $log)
|
551
|
+
stub(Fluent::Engine).root_agent { @ra }
|
552
|
+
@ra = configure_ra(@ra, conf)
|
553
|
+
end
|
554
|
+
|
555
|
+
test "plugins have a variable named buffer does not throws NoMethodError" do
|
556
|
+
port = unused_port
|
557
|
+
d = create_driver("
|
558
|
+
@type monitor_agent
|
559
|
+
bind '127.0.0.1'
|
560
|
+
port #{port}
|
561
|
+
include_config no
|
562
|
+
")
|
563
|
+
d.instance.start
|
564
|
+
|
565
|
+
assert_equal("200", get("http://127.0.0.1:#{port}/api/plugins.json").code)
|
566
|
+
assert{ d.logs.none?{|log| log.include?("NoMethodError") } }
|
567
|
+
assert_equal(false, d.instance.instance_variable_get(:@first_warn))
|
568
|
+
end
|
569
|
+
end
|
489
570
|
end
|
data/test/plugin/test_in_tail.rb
CHANGED
@@ -72,6 +72,7 @@ class TailInputTest < Test::Unit::TestCase
|
|
72
72
|
assert_equal 2, d.instance.rotate_wait
|
73
73
|
assert_equal "#{TMP_DIR}/tail.pos", d.instance.pos_file
|
74
74
|
assert_equal 1000, d.instance.read_lines_limit
|
75
|
+
assert_equal false, d.instance.ignore_repeated_permission_error
|
75
76
|
end
|
76
77
|
|
77
78
|
data("empty" => config_element,
|
@@ -1198,4 +1199,19 @@ class TailInputTest < Test::Unit::TestCase
|
|
1198
1199
|
assert_equal expected_files, plugin.expand_paths.sort
|
1199
1200
|
end
|
1200
1201
|
end
|
1202
|
+
|
1203
|
+
def test_skip_refresh_on_startup
|
1204
|
+
FileUtils.touch("#{TMP_DIR}/tail.txt")
|
1205
|
+
config = config_element('', '', {
|
1206
|
+
'format' => 'none',
|
1207
|
+
'refresh_interval' => 1,
|
1208
|
+
'skip_refresh_on_startup' => true
|
1209
|
+
})
|
1210
|
+
d = create_driver(config)
|
1211
|
+
d.run(shutdown: false) {}
|
1212
|
+
assert_equal 0, d.instance.instance_variable_get(:@tails).keys.size
|
1213
|
+
# detect a file at first execution of in_tail_refresh_watchers timer
|
1214
|
+
waiting(5) { sleep 0.1 until d.instance.instance_variable_get(:@tails).keys.size == 1 }
|
1215
|
+
d.instance_shutdown
|
1216
|
+
end
|
1201
1217
|
end
|
data/test/plugin/test_in_udp.rb
CHANGED
@@ -54,7 +54,7 @@ class UdpInputTest < Test::Unit::TestCase
|
|
54
54
|
d = create_driver(conf)
|
55
55
|
assert_equal PORT, d.instance.port
|
56
56
|
assert_equal bind, d.instance.bind
|
57
|
-
assert_equal 4096, d.instance.
|
57
|
+
assert_equal 4096, d.instance.message_length_limit
|
58
58
|
end
|
59
59
|
|
60
60
|
data(
|
@@ -86,6 +86,16 @@ class UdpInputTest < Test::Unit::TestCase
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
+
data(
|
90
|
+
'message_length_limit' => 'message_length_limit 2048',
|
91
|
+
'body_size_limit' => 'body_size_limit 2048'
|
92
|
+
)
|
93
|
+
test 'message_length_limit/body_size_limit compatibility' do |param|
|
94
|
+
|
95
|
+
d = create_driver(CONFIG + param)
|
96
|
+
assert_equal 2048, d.instance.message_length_limit
|
97
|
+
end
|
98
|
+
|
89
99
|
data(
|
90
100
|
'none' => {
|
91
101
|
'format' => 'none',
|
@@ -20,6 +20,9 @@ class FileOutputTest < Test::Unit::TestCase
|
|
20
20
|
path #{TMP_DIR}/out_file_test
|
21
21
|
compress gz
|
22
22
|
utc
|
23
|
+
<buffer>
|
24
|
+
timekey_use_utc true
|
25
|
+
</buffer>
|
23
26
|
]
|
24
27
|
|
25
28
|
def create_driver(conf = CONFIG, opts = {})
|
@@ -405,6 +408,9 @@ class FileOutputTest < Test::Unit::TestCase
|
|
405
408
|
path #{TMP_DIR_WITH_SYSTEM}/out_file_test
|
406
409
|
compress gz
|
407
410
|
utc
|
411
|
+
<buffer>
|
412
|
+
timekey_use_utc true
|
413
|
+
</buffer>
|
408
414
|
<system>
|
409
415
|
file_permission #{OVERRIDE_FILE_PERMISSION}
|
410
416
|
dir_permission #{OVERRIDE_DIR_PERMISSION}
|
@@ -527,6 +533,9 @@ class FileOutputTest < Test::Unit::TestCase
|
|
527
533
|
compress gz
|
528
534
|
utc
|
529
535
|
append true
|
536
|
+
<buffer>
|
537
|
+
timekey_use_utc true
|
538
|
+
</buffer>
|
530
539
|
]
|
531
540
|
d.run(default_tag: 'test'){
|
532
541
|
d.feed(time, {"a"=>1})
|
@@ -430,6 +430,51 @@ EOL
|
|
430
430
|
assert_empty d.instance.exceptions
|
431
431
|
end
|
432
432
|
|
433
|
+
data('ack true' => true,
|
434
|
+
'ack false' => false)
|
435
|
+
test 'TLS transport and ack parameter combination' do |ack|
|
436
|
+
omit "TLS and 'ack false' always fails on AppVeyor. Need to debug" if Fluent.windows? && !ack
|
437
|
+
|
438
|
+
input_conf = TARGET_CONFIG + %[
|
439
|
+
<transport tls>
|
440
|
+
insecure true
|
441
|
+
</transport>
|
442
|
+
]
|
443
|
+
target_input_driver = create_target_input_driver(conf: input_conf)
|
444
|
+
|
445
|
+
output_conf = %[
|
446
|
+
send_timeout 5
|
447
|
+
require_ack_response #{ack}
|
448
|
+
transport tls
|
449
|
+
tls_insecure_mode true
|
450
|
+
<server>
|
451
|
+
host #{TARGET_HOST}
|
452
|
+
port #{TARGET_PORT}
|
453
|
+
</server>
|
454
|
+
<buffer>
|
455
|
+
#flush_mode immediate
|
456
|
+
flush_interval 0s
|
457
|
+
flush_at_shutdown false # suppress errors in d.instance_shutdown
|
458
|
+
</buffer>
|
459
|
+
]
|
460
|
+
@d = d = create_driver(output_conf)
|
461
|
+
|
462
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
463
|
+
records = [{"a" => 1}, {"a" => 2}]
|
464
|
+
target_input_driver.run(expect_records: 2, timeout: 3) do
|
465
|
+
d.run(default_tag: 'test', wait_flush_completion: false, shutdown: false) do
|
466
|
+
records.each do |record|
|
467
|
+
d.feed(time, record)
|
468
|
+
end
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
events = target_input_driver.events
|
473
|
+
assert{ events != [] }
|
474
|
+
assert_equal(['test', time, records[0]], events[0])
|
475
|
+
assert_equal(['test', time, records[1]], events[1])
|
476
|
+
end
|
477
|
+
|
433
478
|
test 'a destination node not supporting responses by just ignoring' do
|
434
479
|
target_input_driver = create_target_input_driver(response_stub: ->(_option) { nil }, disconnect: false)
|
435
480
|
|
data/test/plugin/test_output.rb
CHANGED
@@ -315,7 +315,7 @@ class OutputTest < Test::Unit::TestCase
|
|
315
315
|
validators = @i.placeholder_validators(:path, "/my/path/file.%Y-%m-%d.log")
|
316
316
|
assert_equal 1, validators.size
|
317
317
|
assert_equal 1, validators.select(&:time?).size
|
318
|
-
assert_raise Fluent::ConfigError.new("Parameter 'path' has timestamp placeholders, but chunk key 'time' is not configured") do
|
318
|
+
assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.%Y-%m-%d.log' has timestamp placeholders, but chunk key 'time' is not configured") do
|
319
319
|
validators.first.validate!
|
320
320
|
end
|
321
321
|
end
|
@@ -325,7 +325,7 @@ class OutputTest < Test::Unit::TestCase
|
|
325
325
|
validators = @i.placeholder_validators(:path, "/my/path/to/file.log")
|
326
326
|
assert_equal 1, validators.size
|
327
327
|
assert_equal 1, validators.select(&:time?).size
|
328
|
-
assert_raise Fluent::ConfigError.new("Parameter 'path' doesn't have timestamp placeholders for timekey 30") do
|
328
|
+
assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/to/file.log' doesn't have timestamp placeholders for timekey 30") do
|
329
329
|
validators.first.validate!
|
330
330
|
end
|
331
331
|
end
|
@@ -335,7 +335,7 @@ class OutputTest < Test::Unit::TestCase
|
|
335
335
|
validators = @i.placeholder_validators(:path, "/my/path/${tag}/file.log")
|
336
336
|
assert_equal 1, validators.size
|
337
337
|
assert_equal 1, validators.select(&:tag?).size
|
338
|
-
assert_raise Fluent::ConfigError.new("Parameter 'path' has tag placeholders, but chunk key 'tag' is not configured") do
|
338
|
+
assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/${tag}/file.log' has tag placeholders, but chunk key 'tag' is not configured") do
|
339
339
|
validators.first.validate!
|
340
340
|
end
|
341
341
|
end
|
@@ -345,7 +345,7 @@ class OutputTest < Test::Unit::TestCase
|
|
345
345
|
validators = @i.placeholder_validators(:path, "/my/path/file.log")
|
346
346
|
assert_equal 1, validators.size
|
347
347
|
assert_equal 1, validators.select(&:tag?).size
|
348
|
-
assert_raise Fluent::ConfigError.new("Parameter 'path' doesn't have tag placeholder") do
|
348
|
+
assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.log' doesn't have tag placeholder") do
|
349
349
|
validators.first.validate!
|
350
350
|
end
|
351
351
|
end
|
@@ -355,7 +355,7 @@ class OutputTest < Test::Unit::TestCase
|
|
355
355
|
validators = @i.placeholder_validators(:path, "/my/path/${username}/file.${group}.log")
|
356
356
|
assert_equal 1, validators.size
|
357
357
|
assert_equal 1, validators.select(&:keys?).size
|
358
|
-
assert_raise Fluent::ConfigError.new("Parameter 'path' has placeholders, but chunk keys doesn't have keys group,username") do
|
358
|
+
assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/${username}/file.${group}.log' has placeholders, but chunk keys doesn't have keys group,username") do
|
359
359
|
validators.first.validate!
|
360
360
|
end
|
361
361
|
end
|
@@ -365,7 +365,7 @@ class OutputTest < Test::Unit::TestCase
|
|
365
365
|
validators = @i.placeholder_validators(:path, "/my/path/file.log")
|
366
366
|
assert_equal 1, validators.size
|
367
367
|
assert_equal 1, validators.select(&:keys?).size
|
368
|
-
assert_raise Fluent::ConfigError.new("Parameter 'path' doesn't have enough placeholders for keys group,username") do
|
368
|
+
assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.log' doesn't have enough placeholders for keys group,username") do
|
369
369
|
validators.first.validate!
|
370
370
|
end
|
371
371
|
end
|
@@ -374,14 +374,14 @@ class OutputTest < Test::Unit::TestCase
|
|
374
374
|
sub_test_case '#placeholder_validate!' do
|
375
375
|
test 'raises configuration error for a templace when timestamp placeholders exist but time key is missing' do
|
376
376
|
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
|
377
|
-
assert_raise Fluent::ConfigError.new("Parameter 'path' has timestamp placeholders, but chunk key 'time' is not configured") do
|
377
|
+
assert_raise Fluent::ConfigError.new("Parameter 'path: /path/without/timestamp/file.%Y%m%d-%H%M.log' has timestamp placeholders, but chunk key 'time' is not configured") do
|
378
378
|
@i.placeholder_validate!(:path, "/path/without/timestamp/file.%Y%m%d-%H%M.log")
|
379
379
|
end
|
380
380
|
end
|
381
381
|
|
382
382
|
test 'raises configuration error for a template without timestamp placeholders when timekey is configured' do
|
383
383
|
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'time', {"timekey" => 180})]))
|
384
|
-
assert_raise Fluent::ConfigError.new("Parameter 'path' doesn't have timestamp placeholders for timekey 180") do
|
384
|
+
assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.log' doesn't have timestamp placeholders for timekey 180") do
|
385
385
|
@i.placeholder_validate!(:path, "/my/path/file.log")
|
386
386
|
end
|
387
387
|
assert_nothing_raised do
|
@@ -391,7 +391,7 @@ class OutputTest < Test::Unit::TestCase
|
|
391
391
|
|
392
392
|
test 'raises configuration error for a template with timestamp placeholders when plugin is configured more fine timekey' do
|
393
393
|
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'time', {"timekey" => 180})]))
|
394
|
-
assert_raise Fluent::ConfigError.new("Parameter 'path' doesn't have timestamp placeholder for hour('%H') for timekey 180") do
|
394
|
+
assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.%Y%m%d_%H.log' doesn't have timestamp placeholder for hour('%H') for timekey 180") do
|
395
395
|
@i.placeholder_validate!(:path, "/my/path/file.%Y%m%d_%H.log")
|
396
396
|
end
|
397
397
|
assert_nothing_raised do
|
@@ -401,14 +401,14 @@ class OutputTest < Test::Unit::TestCase
|
|
401
401
|
|
402
402
|
test 'raises configuration error for a template when tag placeholders exist but tag key is missing' do
|
403
403
|
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
|
404
|
-
assert_raise Fluent::ConfigError.new("Parameter 'path' has tag placeholders, but chunk key 'tag' is not configured") do
|
404
|
+
assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/${tag}/file.${tag[2]}.log' has tag placeholders, but chunk key 'tag' is not configured") do
|
405
405
|
@i.placeholder_validate!(:path, "/my/path/${tag}/file.${tag[2]}.log")
|
406
406
|
end
|
407
407
|
end
|
408
408
|
|
409
409
|
test 'raises configuration error for a template without tag placeholders when tagkey is configured' do
|
410
410
|
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'tag')]))
|
411
|
-
assert_raise Fluent::ConfigError.new("Parameter 'path' doesn't have tag placeholder") do
|
411
|
+
assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.log' doesn't have tag placeholder") do
|
412
412
|
@i.placeholder_validate!(:path, "/my/path/file.log")
|
413
413
|
end
|
414
414
|
assert_nothing_raised do
|
@@ -418,14 +418,14 @@ class OutputTest < Test::Unit::TestCase
|
|
418
418
|
|
419
419
|
test 'raises configuration error for a template when variable key placeholders exist but chunk keys are missing' do
|
420
420
|
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
|
421
|
-
assert_raise Fluent::ConfigError.new("Parameter 'path' has placeholders, but chunk keys doesn't have keys service,username") do
|
421
|
+
assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/${service}/file.${username}.log' has placeholders, but chunk keys doesn't have keys service,username") do
|
422
422
|
@i.placeholder_validate!(:path, "/my/path/${service}/file.${username}.log")
|
423
423
|
end
|
424
424
|
end
|
425
425
|
|
426
426
|
test 'raises configuration error for a template without variable key placeholders when chunk keys are configured' do
|
427
427
|
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'username,service')]))
|
428
|
-
assert_raise Fluent::ConfigError.new("Parameter 'path' doesn't have enough placeholders for keys service,username") do
|
428
|
+
assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.log' doesn't have enough placeholders for keys service,username") do
|
429
429
|
@i.placeholder_validate!(:path, "/my/path/file.log")
|
430
430
|
end
|
431
431
|
assert_nothing_raised do
|
@@ -435,10 +435,10 @@ class OutputTest < Test::Unit::TestCase
|
|
435
435
|
|
436
436
|
test 'raise configuration error for a template and configuration with keys mismatch' do
|
437
437
|
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'username,service')]))
|
438
|
-
assert_raise Fluent::ConfigError.new("Parameter 'path' doesn't have enough placeholders for keys service") do
|
438
|
+
assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.${username}.log' doesn't have enough placeholders for keys service") do
|
439
439
|
@i.placeholder_validate!(:path, "/my/path/file.${username}.log")
|
440
440
|
end
|
441
|
-
assert_raise Fluent::ConfigError.new("Parameter 'path' doesn't have enough placeholders for keys username") do
|
441
|
+
assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/${service}/file.log' doesn't have enough placeholders for keys username") do
|
442
442
|
@i.placeholder_validate!(:path, "/my/path/${service}/file.log")
|
443
443
|
end
|
444
444
|
assert_nothing_raised do
|