fluentd 1.16.5-x64-mingw-ucrt → 1.16.7-x64-mingw-ucrt

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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +8 -1
  3. data/CHANGELOG.md +50 -0
  4. data/README.md +0 -2
  5. data/fluentd.gemspec +9 -1
  6. data/lib/fluent/command/fluentd.rb +1 -1
  7. data/lib/fluent/config/yaml_parser/parser.rb +4 -0
  8. data/lib/fluent/plugin/out_file.rb +8 -0
  9. data/lib/fluent/plugin/parser_json.rb +4 -12
  10. data/lib/fluent/supervisor.rb +1 -1
  11. data/lib/fluent/version.rb +1 -1
  12. data/lib/fluent/winsvc.rb +28 -3
  13. data/test/command/test_cat.rb +2 -2
  14. data/test/command/test_fluentd.rb +57 -10
  15. data/test/helper.rb +27 -7
  16. data/test/plugin/in_tail/test_io_handler.rb +13 -14
  17. data/test/plugin/in_tail/test_position_file.rb +6 -7
  18. data/test/plugin/out_forward/test_ack_handler.rb +3 -3
  19. data/test/plugin/out_forward/test_socket_cache.rb +3 -3
  20. data/test/plugin/test_in_forward.rb +2 -1
  21. data/test/plugin/test_in_http.rb +1 -1
  22. data/test/plugin/test_in_monitor_agent.rb +6 -6
  23. data/test/plugin/test_in_syslog.rb +25 -18
  24. data/test/plugin/test_in_tail.rb +4 -12
  25. data/test/plugin/test_in_tcp.rb +1 -1
  26. data/test/plugin/test_in_udp.rb +16 -10
  27. data/test/plugin/test_out_exec_filter.rb +12 -7
  28. data/test/plugin/test_out_file.rb +22 -2
  29. data/test/plugin/test_out_forward.rb +2 -3
  30. data/test/plugin/test_out_stream.rb +1 -1
  31. data/test/plugin/test_parser_json.rb +31 -0
  32. data/test/plugin_helper/test_http_server_helper.rb +1 -1
  33. data/test/plugin_helper/test_server.rb +64 -41
  34. data/test/plugin_helper/test_socket.rb +1 -1
  35. data/test/test_config.rb +6 -0
  36. data/test/test_event_router.rb +2 -2
  37. metadata +37 -9
@@ -5,24 +5,24 @@ require 'fluent/plugin/in_syslog'
5
5
  class SyslogInputTest < Test::Unit::TestCase
6
6
  def setup
7
7
  Fluent::Test.setup
8
- @port = unused_port
8
+ @port = unused_port(protocol: :udp)
9
9
  end
10
10
 
11
11
  def teardown
12
12
  @port = nil
13
13
  end
14
14
 
15
- def ipv4_config
15
+ def ipv4_config(port = @port)
16
16
  %[
17
- port #{@port}
17
+ port #{port}
18
18
  bind 127.0.0.1
19
19
  tag syslog
20
20
  ]
21
21
  end
22
22
 
23
- def ipv6_config
23
+ def ipv6_config(port = @port)
24
24
  %[
25
- port #{@port}
25
+ port #{port}
26
26
  bind ::1
27
27
  tag syslog
28
28
  ]
@@ -69,7 +69,8 @@ EOS
69
69
  'Use transport and protocol' => ["protocol_type udp\n<transport tcp>\n </transport>", :udp, :tcp])
70
70
  def test_configure_protocol(param)
71
71
  conf, proto_type, transport_proto_type = *param
72
- d = create_driver([ipv4_config, conf].join("\n"))
72
+ port = unused_port(protocol: proto_type ? proto_type : transport_proto_type)
73
+ d = create_driver([ipv4_config(port), conf].join("\n"))
73
74
 
74
75
  assert_equal(d.instance.protocol_type, proto_type)
75
76
  assert_equal(d.instance.transport_config.protocol, transport_proto_type)
@@ -158,12 +159,13 @@ EOS
158
159
  end
159
160
 
160
161
  def test_msg_size_with_tcp
161
- d = create_driver([ipv4_config, "<transport tcp> \n</transport>"].join("\n"))
162
+ port = unused_port(protocol: :tcp)
163
+ d = create_driver([ipv4_config(port), "<transport tcp> \n</transport>"].join("\n"))
162
164
  tests = create_test_case
163
165
 
164
166
  d.run(expect_emits: 2) do
165
167
  tests.each {|test|
166
- TCPSocket.open('127.0.0.1', @port) do |s|
168
+ TCPSocket.open('127.0.0.1', port) do |s|
167
169
  s.send(test['msg'], 0)
168
170
  end
169
171
  }
@@ -189,11 +191,12 @@ EOS
189
191
  end
190
192
 
191
193
  def test_msg_size_with_same_tcp_connection
192
- d = create_driver([ipv4_config, "<transport tcp> \n</transport>"].join("\n"))
194
+ port = unused_port(protocol: :tcp)
195
+ d = create_driver([ipv4_config(port), "<transport tcp> \n</transport>"].join("\n"))
193
196
  tests = create_test_case
194
197
 
195
198
  d.run(expect_emits: 2) do
196
- TCPSocket.open('127.0.0.1', @port) do |s|
199
+ TCPSocket.open('127.0.0.1', port) do |s|
197
200
  tests.each {|test|
198
201
  s.send(test['msg'], 0)
199
202
  }
@@ -347,12 +350,13 @@ EOS
347
350
 
348
351
  sub_test_case 'octet counting frame' do
349
352
  def test_msg_size_with_tcp
350
- d = create_driver([ipv4_config, "<transport tcp> \n</transport>", 'frame_type octet_count'].join("\n"))
353
+ port = unused_port(protocol: :tcp)
354
+ d = create_driver([ipv4_config(port), "<transport tcp> \n</transport>", 'frame_type octet_count'].join("\n"))
351
355
  tests = create_test_case
352
356
 
353
357
  d.run(expect_emits: 2) do
354
358
  tests.each {|test|
355
- TCPSocket.open('127.0.0.1', @port) do |s|
359
+ TCPSocket.open('127.0.0.1', port) do |s|
356
360
  s.send(test['msg'], 0)
357
361
  end
358
362
  }
@@ -363,11 +367,12 @@ EOS
363
367
  end
364
368
 
365
369
  def test_msg_size_with_same_tcp_connection
366
- d = create_driver([ipv4_config, "<transport tcp> \n</transport>", 'frame_type octet_count'].join("\n"))
370
+ port = unused_port(protocol: :tcp)
371
+ d = create_driver([ipv4_config(port), "<transport tcp> \n</transport>", 'frame_type octet_count'].join("\n"))
367
372
  tests = create_test_case
368
373
 
369
374
  d.run(expect_emits: 2) do
370
- TCPSocket.open('127.0.0.1', @port) do |s|
375
+ TCPSocket.open('127.0.0.1', port) do |s|
371
376
  tests.each {|test|
372
377
  s.send(test['msg'], 0)
373
378
  }
@@ -469,7 +474,8 @@ EOS
469
474
  end
470
475
 
471
476
  def test_send_keepalive_packet_is_disabled_by_default
472
- d = create_driver(ipv4_config + %[
477
+ port = unused_port(protocol: :tcp)
478
+ d = create_driver(ipv4_config(port) + %[
473
479
  <transport tcp>
474
480
  </transport>
475
481
  protocol tcp
@@ -479,19 +485,20 @@ EOS
479
485
 
480
486
  def test_send_keepalive_packet_can_be_enabled
481
487
  addr = "127.0.0.1"
482
- d = create_driver(ipv4_config + %[
488
+ port = unused_port(protocol: :tcp)
489
+ d = create_driver(ipv4_config(port) + %[
483
490
  <transport tcp>
484
491
  </transport>
485
492
  send_keepalive_packet true
486
493
  ])
487
494
  assert_true d.instance.send_keepalive_packet
488
495
  mock.proxy(d.instance).server_create_connection(
489
- :in_syslog_tcp_server, @port,
496
+ :in_syslog_tcp_server, port,
490
497
  bind: addr,
491
498
  resolve_name: nil,
492
499
  send_keepalive_packet: true)
493
500
  d.run do
494
- TCPSocket.open(addr, @port)
501
+ TCPSocket.open(addr, port)
495
502
  end
496
503
  end
497
504
 
@@ -3172,9 +3172,7 @@ class TailInputTest < Test::Unit::TestCase
3172
3172
  Fluent::FileWrapper.open("#{@tmp_dir}/tail.txt0", "ab") {|f| f.puts "file3 log2"}
3173
3173
  end
3174
3174
 
3175
- inode_0 = tail_watchers[0]&.ino
3176
- inode_1 = tail_watchers[1]&.ino
3177
- inode_2 = tail_watchers[2]&.ino
3175
+ pos_file_inode = tail_watchers[2].pe.read_inode
3178
3176
  record_values = d.events.collect { |event| event[2]["message"] }.sort
3179
3177
  position_entries = []
3180
3178
  Fluent::FileWrapper.open("#{@tmp_dir}/tail.pos", "r") do |f|
@@ -3188,17 +3186,15 @@ class TailInputTest < Test::Unit::TestCase
3188
3186
  {
3189
3187
  record_values: ["file1 log1", "file1 log2", "file2 log1", "file2 log2", "file3 log1", "file3 log2"],
3190
3188
  tail_watcher_paths: ["#{@tmp_dir}/tail.txt0", "#{@tmp_dir}/tail.txt0", "#{@tmp_dir}/tail.txt0"],
3191
- tail_watcher_inodes: [inode_0, inode_1, inode_2],
3192
3189
  tail_watcher_io_handler_opened_statuses: [false, false, false],
3193
3190
  position_entries: [
3194
3191
  # The recorded path is old, but it is no problem. The path is not used when using follow_inodes.
3195
- ["#{@tmp_dir}/tail.txt0", "0000000000000016", inode_2],
3192
+ ["#{@tmp_dir}/tail.txt0", "0000000000000016", pos_file_inode],
3196
3193
  ],
3197
3194
  },
3198
3195
  {
3199
3196
  record_values: record_values,
3200
3197
  tail_watcher_paths: tail_watchers.collect { |tw| tw.path },
3201
- tail_watcher_inodes: tail_watchers.collect { |tw| tw.ino },
3202
3198
  tail_watcher_io_handler_opened_statuses: tail_watchers.collect { |tw| tw.instance_variable_get(:@io_handler)&.opened? || false },
3203
3199
  position_entries: position_entries
3204
3200
  },
@@ -3253,9 +3249,7 @@ class TailInputTest < Test::Unit::TestCase
3253
3249
  sleep 4
3254
3250
  end
3255
3251
 
3256
- inode_0 = tail_watchers[0]&.ino
3257
- inode_1 = tail_watchers[1]&.ino
3258
- inode_2 = tail_watchers[2]&.ino
3252
+ pos_file_inode = tail_watchers[2].pe.read_inode
3259
3253
  record_values = d.events.collect { |event| event[2]["message"] }.sort
3260
3254
  position_entries = []
3261
3255
  Fluent::FileWrapper.open("#{@tmp_dir}/tail.pos", "r") do |f|
@@ -3269,16 +3263,14 @@ class TailInputTest < Test::Unit::TestCase
3269
3263
  {
3270
3264
  record_values: ["file1 log1", "file1 log2", "file2 log1", "file2 log2", "file3 log1", "file3 log2"],
3271
3265
  tail_watcher_paths: ["#{@tmp_dir}/tail.txt0", "#{@tmp_dir}/tail.txt0", "#{@tmp_dir}/tail.txt0"],
3272
- tail_watcher_inodes: [inode_0, inode_1, inode_2],
3273
3266
  tail_watcher_io_handler_opened_statuses: [false, false, false],
3274
3267
  position_entries: [
3275
- ["#{@tmp_dir}/tail.txt0", "0000000000000016", inode_2],
3268
+ ["#{@tmp_dir}/tail.txt0", "0000000000000016", pos_file_inode],
3276
3269
  ],
3277
3270
  },
3278
3271
  {
3279
3272
  record_values: record_values,
3280
3273
  tail_watcher_paths: tail_watchers.collect { |tw| tw.path },
3281
- tail_watcher_inodes: tail_watchers.collect { |tw| tw.ino },
3282
3274
  tail_watcher_io_handler_opened_statuses: tail_watchers.collect { |tw| tw.instance_variable_get(:@io_handler)&.opened? || false },
3283
3275
  position_entries: position_entries
3284
3276
  },
@@ -5,7 +5,7 @@ require 'fluent/plugin/in_tcp'
5
5
  class TcpInputTest < Test::Unit::TestCase
6
6
  def setup
7
7
  Fluent::Test.setup
8
- @port = unused_port
8
+ @port = unused_port(protocol: :tcp)
9
9
  end
10
10
 
11
11
  def teardown
@@ -5,7 +5,7 @@ require 'fluent/plugin/in_udp'
5
5
  class UdpInputTest < Test::Unit::TestCase
6
6
  def setup
7
7
  Fluent::Test.setup
8
- @port = unused_port
8
+ @port = unused_port(protocol: :udp)
9
9
  end
10
10
 
11
11
  def teardown
@@ -268,25 +268,31 @@ class UdpInputTest < Test::Unit::TestCase
268
268
 
269
269
  test 'message_length_limit' do
270
270
  message_length_limit = 32
271
+
272
+ if Fluent.windows?
273
+ expected_records = ["0" * 30, "4" * 30]
274
+ else
275
+ expected_records = 1.upto(3).collect do |i|
276
+ "#{i}" * message_length_limit
277
+ end
278
+ expected_records.prepend("0" * 30)
279
+ expected_records.append("4" * 30)
280
+ end
281
+
271
282
  d = create_driver(base_config + %!
272
283
  format none
273
284
  message_length_limit #{message_length_limit}
274
285
  !)
275
- d.run(expect_records: 3) do
286
+ d.run(expect_records: expected_records.size, timeout: 5) do
276
287
  create_udp_socket('127.0.0.1', @port) do |u|
277
- 3.times do |i|
288
+ u.send("0" * 30 + "\n", 0)
289
+ 1.upto(3) do |i|
278
290
  u.send("#{i}" * 40 + "\n", 0)
279
291
  end
292
+ u.send("4" * 30 + "\n", 0)
280
293
  end
281
294
  end
282
295
 
283
- if Fluent.windows?
284
- expected_records = []
285
- else
286
- expected_records = 3.times.collect do |i|
287
- "#{i}" * message_length_limit
288
- end
289
- end
290
296
  actual_records = d.events.collect do |event|
291
297
  event[2]["message"]
292
298
  end
@@ -500,10 +500,18 @@ class ExecFilterOutputTest < Test::Unit::TestCase
500
500
  d = create_driver(conf)
501
501
  time = event_time('2011-01-02 13:14:15')
502
502
 
503
- d.run(default_tag: 'test', expect_emits: 1, timeout: 10, start: true, shutdown: false){ d.feed(time, {"k1" => 0}) }
504
- d.run(default_tag: 'test', expect_emits: 1, timeout: 10, start: false, shutdown: false){ d.feed(time, {"k1" => 1}) }
505
- d.run(default_tag: 'test', expect_emits: 1, timeout: 10, start: false, shutdown: false){ d.feed(time, {"k1" => 2}) }
506
- d.run(default_tag: 'test', expect_emits: 1, timeout: 10, start: false, shutdown: false){ d.feed(time, {"k1" => 3}) }
503
+ d.run(default_tag: 'test', expect_emits: 4) do
504
+ d.feed(time, {"k1" => 0})
505
+ d.flush
506
+ sleep 0.5
507
+ d.feed(time, {"k1" => 1})
508
+ d.flush
509
+ sleep 0.5
510
+ d.feed(time, {"k1" => 2})
511
+ d.flush
512
+ sleep 0.5
513
+ d.feed(time, {"k1" => 3})
514
+ end
507
515
 
508
516
  assert_equal "2011-01-02 13:14:15\ttest\t0\n", d.formatted[0]
509
517
  assert_equal "2011-01-02 13:14:15\ttest\t1\n", d.formatted[1]
@@ -524,9 +532,6 @@ class ExecFilterOutputTest < Test::Unit::TestCase
524
532
  assert_equal pid_list[1], events[1][2]['child_pid']
525
533
  assert_equal pid_list[0], events[2][2]['child_pid']
526
534
  assert_equal pid_list[1], events[3][2]['child_pid']
527
-
528
- ensure
529
- d.run(start: false, shutdown: true)
530
535
  end
531
536
 
532
537
  # child process exits per 3 lines
@@ -130,7 +130,7 @@ class FileOutputTest < Test::Unit::TestCase
130
130
  'path' => "#{TMP_DIR}/${tag}/${type}/conf_test.%Y%m%d.%H%M.log",
131
131
  'add_path_suffix' => 'false',
132
132
  'append' => "true",
133
- 'symlink_path' => "#{TMP_DIR}/conf_test.current.log",
133
+ 'symlink_path' => "#{TMP_DIR}/${tag}/conf_test.current.log",
134
134
  'compress' => 'gzip',
135
135
  'recompress' => 'true',
136
136
  }, [
@@ -183,6 +183,26 @@ class FileOutputTest < Test::Unit::TestCase
183
183
  Fluent::Test::Driver::Output.new(Fluent::Plugin::NullOutput).configure(conf)
184
184
  end
185
185
  end
186
+
187
+ test 'warning for symlink_path not including correct placeholders corresponding to chunk keys' do
188
+ omit "Windows doesn't support symlink" if Fluent.windows?
189
+ conf = config_element('match', '**', {
190
+ 'path' => "#{TMP_DIR}/${tag}/${key1}/${key2}/conf_test.%Y%m%d.%H%M.log",
191
+ 'symlink_path' => "#{TMP_DIR}/conf_test.current.log",
192
+ }, [
193
+ config_element('buffer', 'time,tag,key1,key2', {
194
+ '@type' => 'file',
195
+ 'timekey' => '1d',
196
+ 'path' => "#{TMP_DIR}/buf_conf_test",
197
+ }),
198
+ ])
199
+ assert_nothing_raised do
200
+ d = create_driver(conf)
201
+ assert do
202
+ d.logs.count { |log| log.include?("multiple chunks are competing for a single symlink_path") } == 2
203
+ end
204
+ end
205
+ end
186
206
  end
187
207
 
188
208
  sub_test_case 'fully configured output' do
@@ -314,7 +334,7 @@ class FileOutputTest < Test::Unit::TestCase
314
334
  assert_equal r5, d.formatted[4]
315
335
 
316
336
  read_gunzip = ->(path){
317
- File.open(path){ |fio|
337
+ File.open(path, 'rb'){ |fio|
318
338
  Zlib::GzipReader.new(StringIO.new(fio.read)).read
319
339
  }
320
340
  }
@@ -12,7 +12,8 @@ class ForwardOutputTest < Test::Unit::TestCase
12
12
  FileUtils.rm_rf(TMP_DIR)
13
13
  FileUtils.mkdir_p(TMP_DIR)
14
14
  @d = nil
15
- @target_port = unused_port
15
+ # forward plugin uses TCP and UDP sockets on the same port number
16
+ @target_port = unused_port(protocol: :all)
16
17
  end
17
18
 
18
19
  def teardown
@@ -610,7 +611,6 @@ EOL
610
611
 
611
612
  @d = d = create_driver(config + %[
612
613
  require_ack_response true
613
- ack_response_timeout 1s
614
614
  <buffer tag>
615
615
  flush_mode immediate
616
616
  retry_type periodic
@@ -658,7 +658,6 @@ EOL
658
658
 
659
659
  @d = d = create_driver(config + %[
660
660
  require_ack_response true
661
- ack_response_timeout 10s
662
661
  <buffer tag>
663
662
  flush_mode immediate
664
663
  retry_type periodic
@@ -54,7 +54,7 @@ class TcpOutputTest < Test::Unit::TestCase
54
54
 
55
55
  def setup
56
56
  super
57
- @port = unused_port
57
+ @port = unused_port(protocol: :tcp)
58
58
  end
59
59
 
60
60
  def teardown
@@ -8,6 +8,37 @@ class JsonParserTest < ::Test::Unit::TestCase
8
8
  @parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::JSONParser)
9
9
  end
10
10
 
11
+ sub_test_case "configure_json_parser" do
12
+ data("oj", [:oj, [Oj.method(:load), Oj::ParseError]])
13
+ data("json", [:json, [JSON.method(:load), JSON::ParserError]])
14
+ data("yajl", [:yajl, [Yajl.method(:load), Yajl::ParseError]])
15
+ def test_return_each_loader((input, expected_return))
16
+ result = @parser.instance.configure_json_parser(input)
17
+ assert_equal expected_return, result
18
+ end
19
+
20
+ def test_raise_exception_for_unknown_input
21
+ assert_raise RuntimeError do
22
+ @parser.instance.configure_json_parser(:unknown)
23
+ end
24
+ end
25
+
26
+ def test_fall_back_oj_to_yajl_if_oj_not_available
27
+ stub(Fluent::OjOptions).available? { false }
28
+
29
+ result = @parser.instance.configure_json_parser(:oj)
30
+
31
+ assert_equal [Yajl.method(:load), Yajl::ParseError], result
32
+ logs = @parser.logs.collect do |log|
33
+ log.gsub(/\A\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [-+]\d{4} /, "")
34
+ end
35
+ assert_equal(
36
+ ["[info]: Oj is not installed, and failing back to Yajl for json parser\n"],
37
+ logs
38
+ )
39
+ end
40
+ end
41
+
11
42
  data('oj' => 'oj', 'yajl' => 'yajl')
12
43
  def test_parse(data)
13
44
  @parser.configure('json_parser' => data)
@@ -14,7 +14,7 @@ class HttpHelperTest < Test::Unit::TestCase
14
14
  CERT_CA_DIR = File.expand_path(File.dirname(__FILE__) + '/data/cert/with_ca')
15
15
 
16
16
  def setup
17
- @port = unused_port
17
+ @port = unused_port(protocol: :tcp)
18
18
  end
19
19
 
20
20
  def teardown