fluentd 1.15.3 → 1.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/linux-test.yaml +2 -2
  3. data/.github/workflows/macos-test.yaml +2 -2
  4. data/.github/workflows/windows-test.yaml +2 -2
  5. data/CHANGELOG.md +77 -0
  6. data/MAINTAINERS.md +2 -0
  7. data/README.md +0 -1
  8. data/fluentd.gemspec +2 -2
  9. data/lib/fluent/command/fluentd.rb +55 -53
  10. data/lib/fluent/daemon.rb +2 -4
  11. data/lib/fluent/log/console_adapter.rb +66 -0
  12. data/lib/fluent/log.rb +35 -5
  13. data/lib/fluent/plugin/base.rb +5 -7
  14. data/lib/fluent/plugin/buf_file.rb +32 -3
  15. data/lib/fluent/plugin/buf_file_single.rb +32 -3
  16. data/lib/fluent/plugin/buffer/file_chunk.rb +1 -1
  17. data/lib/fluent/plugin/buffer.rb +21 -0
  18. data/lib/fluent/plugin/in_tcp.rb +4 -2
  19. data/lib/fluent/plugin/out_forward/ack_handler.rb +19 -4
  20. data/lib/fluent/plugin/out_forward.rb +2 -2
  21. data/lib/fluent/plugin/out_secondary_file.rb +39 -22
  22. data/lib/fluent/plugin/output.rb +49 -12
  23. data/lib/fluent/plugin_helper/http_server/server.rb +2 -1
  24. data/lib/fluent/supervisor.rb +157 -251
  25. data/lib/fluent/test/driver/base.rb +11 -5
  26. data/lib/fluent/test/driver/filter.rb +4 -0
  27. data/lib/fluent/test/startup_shutdown.rb +6 -8
  28. data/lib/fluent/version.rb +1 -1
  29. data/test/command/test_ctl.rb +1 -1
  30. data/test/command/test_fluentd.rb +137 -6
  31. data/test/command/test_plugin_config_formatter.rb +0 -1
  32. data/test/compat/test_parser.rb +5 -5
  33. data/test/config/test_system_config.rb +0 -8
  34. data/test/log/test_console_adapter.rb +110 -0
  35. data/test/plugin/out_forward/test_ack_handler.rb +39 -0
  36. data/test/plugin/test_base.rb +98 -0
  37. data/test/plugin/test_buf_file.rb +62 -23
  38. data/test/plugin/test_buf_file_single.rb +65 -0
  39. data/test/plugin/test_in_http.rb +2 -3
  40. data/test/plugin/test_in_monitor_agent.rb +2 -3
  41. data/test/plugin/test_in_tcp.rb +15 -0
  42. data/test/plugin/test_out_forward.rb +14 -18
  43. data/test/plugin/test_out_http.rb +1 -0
  44. data/test/plugin/test_output.rb +269 -0
  45. data/test/plugin/test_parser_regexp.rb +1 -6
  46. data/test/plugin_helper/test_http_server_helper.rb +1 -1
  47. data/test/plugin_helper/test_server.rb +10 -5
  48. data/test/test_config.rb +0 -21
  49. data/test/test_formatter.rb +23 -20
  50. data/test/test_log.rb +71 -36
  51. data/test/test_supervisor.rb +277 -282
  52. metadata +12 -19
  53. data/.drone.yml +0 -35
  54. data/.gitlab-ci.yml +0 -103
  55. data/test/test_logger_initializer.rb +0 -46
@@ -10,6 +10,7 @@ require 'uri'
10
10
  require 'fileutils'
11
11
  require 'tempfile'
12
12
  require 'securerandom'
13
+ require 'pathname'
13
14
 
14
15
  if Fluent.windows?
15
16
  require 'win32/event'
@@ -29,12 +30,15 @@ class SupervisorTest < ::Test::Unit::TestCase
29
30
  end
30
31
 
31
32
  def setup
33
+ @stored_global_logger = $log
32
34
  @tmp_dir = tmp_dir
33
35
  @tmp_root_dir = File.join(@tmp_dir, 'root')
34
36
  FileUtils.mkdir_p(@tmp_dir)
37
+ @sigdump_path = "/tmp/sigdump-#{Process.pid}.log"
35
38
  end
36
39
 
37
40
  def teardown
41
+ $log = @stored_global_logger
38
42
  begin
39
43
  FileUtils.rm_rf(@tmp_dir)
40
44
  rescue Errno::EACCES
@@ -51,12 +55,11 @@ class SupervisorTest < ::Test::Unit::TestCase
51
55
 
52
56
 
53
57
  def test_system_config
54
- opts = Fluent::Supervisor.default_options
55
- sv = Fluent::Supervisor.new(opts)
58
+ sv = Fluent::Supervisor.new({})
56
59
  conf_data = <<-EOC
57
60
  <system>
58
61
  rpc_endpoint 127.0.0.1:24445
59
- suppress_repeated_stacktrace true
62
+ suppress_repeated_stacktrace false
60
63
  suppress_config_dump true
61
64
  without_source true
62
65
  enable_get_dump true
@@ -84,7 +87,7 @@ class SupervisorTest < ::Test::Unit::TestCase
84
87
  sys_conf = sv.__send__(:build_system_config, conf)
85
88
 
86
89
  assert_equal '127.0.0.1:24445', sys_conf.rpc_endpoint
87
- assert_equal true, sys_conf.suppress_repeated_stacktrace
90
+ assert_equal false, sys_conf.suppress_repeated_stacktrace
88
91
  assert_equal true, sys_conf.suppress_config_dump
89
92
  assert_equal true, sys_conf.without_source
90
93
  assert_equal true, sys_conf.enable_get_dump
@@ -119,8 +122,7 @@ class SupervisorTest < ::Test::Unit::TestCase
119
122
  end
120
123
 
121
124
  def test_system_config
122
- opts = Fluent::Supervisor.default_options
123
- sv = Fluent::Supervisor.new(opts)
125
+ sv = Fluent::Supervisor.new({})
124
126
  conf_data = <<-EOC
125
127
  system:
126
128
  rpc_endpoint: 127.0.0.1:24445
@@ -191,26 +193,60 @@ class SupervisorTest < ::Test::Unit::TestCase
191
193
  end
192
194
  end
193
195
 
194
- def test_main_process_signal_handlers
196
+ def test_usr1_in_main_process_signal_handlers
195
197
  omit "Windows cannot handle signals" if Fluent.windows?
196
198
 
197
199
  create_info_dummy_logger
198
200
 
199
- opts = Fluent::Supervisor.default_options
200
- sv = Fluent::Supervisor.new(opts)
201
+ sv = Fluent::Supervisor.new({})
201
202
  sv.send(:install_main_process_signal_handlers)
202
203
 
203
- begin
204
- Process.kill :USR1, $$
205
- rescue
206
- end
204
+ Process.kill :USR1, Process.pid
207
205
 
208
206
  sleep 1
209
207
 
210
- info_msg = '[info]: force flushing buffered events' + "\n"
208
+ info_msg = "[info]: force flushing buffered events\n"
211
209
  assert{ $log.out.logs.first.end_with?(info_msg) }
212
210
  ensure
213
- $log.out.reset if $log && $log.out && $log.out.respond_to?(:reset)
211
+ $log.out.reset if $log&.out&.respond_to?(:reset)
212
+ end
213
+
214
+ def test_cont_in_main_process_signal_handlers
215
+ omit "Windows cannot handle signals" if Fluent.windows?
216
+
217
+ sv = Fluent::Supervisor.new({})
218
+ sv.send(:install_main_process_signal_handlers)
219
+
220
+ Process.kill :CONT, Process.pid
221
+
222
+ sleep 1
223
+
224
+ assert{ File.exist?(@sigdump_path) }
225
+ ensure
226
+ File.delete(@sigdump_path) if File.exist?(@sigdump_path)
227
+ end
228
+
229
+ def test_term_cont_in_main_process_signal_handlers
230
+ omit "Windows cannot handle signals" if Fluent.windows?
231
+
232
+ create_debug_dummy_logger
233
+
234
+ sv = Fluent::Supervisor.new({})
235
+ sv.send(:install_main_process_signal_handlers)
236
+
237
+ Process.kill :TERM, Process.pid
238
+ Process.kill :CONT, Process.pid
239
+
240
+ sleep 1
241
+
242
+ debug_msg = "[debug]: fluentd main process get SIGTERM\n"
243
+ logs = $log.out.logs
244
+ assert{ logs.any?{|log| log.include?(debug_msg) } }
245
+
246
+ assert{ not File.exist?(@sigdump_path) }
247
+ ensure
248
+ $log.out.reset if $log&.out&.respond_to?(:reset)
249
+ File.delete(@sigdump_path) if File.exist?(@sigdump_path)
214
250
  end
215
251
 
216
252
  def test_main_process_command_handlers
@@ -218,8 +254,7 @@ class SupervisorTest < ::Test::Unit::TestCase
218
254
 
219
255
  create_info_dummy_logger
220
256
 
221
- opts = Fluent::Supervisor.default_options
222
- sv = Fluent::Supervisor.new(opts)
257
+ sv = Fluent::Supervisor.new({})
223
258
  r, w = IO.pipe
224
259
  $stdin = r
225
260
  sv.send(:install_main_process_signal_handlers)
@@ -233,23 +268,21 @@ class SupervisorTest < ::Test::Unit::TestCase
233
268
 
234
269
  sleep 1
235
270
 
236
- info_msg = '[info]: force flushing buffered events' + "\n"
271
+ info_msg = "[info]: force flushing buffered events\n"
237
272
  assert{ $log.out.logs.first.end_with?(info_msg) }
238
273
  ensure
239
- $log.out.reset if $log && $log.out && $log.out.respond_to?(:reset)
274
+ $log.out.reset if $log&.out&.respond_to?(:reset)
240
275
  end
241
276
 
242
- def test_supervisor_signal_handler
277
+ def test_usr1_in_supervisor_signal_handler
243
278
  omit "Windows cannot handle signals" if Fluent.windows?
244
279
 
245
280
  create_debug_dummy_logger
246
281
 
247
282
  server = DummyServer.new
248
283
  server.install_supervisor_signal_handlers
249
- begin
250
- Process.kill :USR1, $$
251
- rescue
252
- end
284
+
285
+ Process.kill :USR1, Process.pid
253
286
 
254
287
  sleep 1
255
288
 
@@ -257,12 +290,43 @@ class SupervisorTest < ::Test::Unit::TestCase
257
290
  logs = $log.out.logs
258
291
  assert{ logs.any?{|log| log.include?(debug_msg) } }
259
292
  ensure
260
- $log.out.reset if $log && $log.out && $log.out.respond_to?(:reset)
293
+ $log.out.reset if $log&.out&.respond_to?(:reset)
294
+ end
295
+
296
+ def test_cont_in_supervisor_signal_handler
297
+ omit "Windows cannot handle signals" if Fluent.windows?
298
+
299
+ server = DummyServer.new
300
+ server.install_supervisor_signal_handlers
301
+
302
+ Process.kill :CONT, Process.pid
303
+
304
+ sleep 1
305
+
306
+ assert{ File.exist?(@sigdump_path) }
307
+ ensure
308
+ File.delete(@sigdump_path) if File.exist?(@sigdump_path)
309
+ end
310
+
311
+ def test_term_cont_in_supervisor_signal_handler
312
+ omit "Windows cannot handle signals" if Fluent.windows?
313
+
314
+ server = DummyServer.new
315
+ server.install_supervisor_signal_handlers
316
+
317
+ Process.kill :TERM, Process.pid
318
+ Process.kill :CONT, Process.pid
319
+
320
+ assert{ not File.exist?(@sigdump_path) }
321
+ ensure
322
+ File.delete(@sigdump_path) if File.exist?(@sigdump_path)
261
323
  end
262
324
 
263
325
  def test_windows_shutdown_event
264
326
  omit "Only for Windows platform" unless Fluent.windows?
265
327
 
328
+ create_debug_dummy_logger
329
+
266
330
  server = DummyServer.new
267
331
  def server.config
268
332
  {:signame => "TestFluentdEvent"}
@@ -285,7 +349,7 @@ class SupervisorTest < ::Test::Unit::TestCase
285
349
  logs = $log.out.logs
286
350
  assert{ logs.any?{|log| log.include?(debug_msg) } }
287
351
  ensure
288
- $log.out.reset if $log && $log.out && $log.out.respond_to?(:reset)
352
+ $log.out.reset if $log&.out&.respond_to?(:reset)
289
353
  end
290
354
 
291
355
  def test_supervisor_event_handler
@@ -311,15 +375,14 @@ class SupervisorTest < ::Test::Unit::TestCase
311
375
  logs = $log.out.logs
312
376
  assert{ logs.any?{|log| log.include?(debug_msg) } }
313
377
  ensure
314
- $log.out.reset if $log && $log.out && $log.out.respond_to?(:reset)
378
+ $log.out.reset if $log&.out&.respond_to?(:reset)
315
379
  end
316
380
 
317
- data("Normal", {raw_path: "C:\\Windows\\Temp\\sigdump.log", expected: "C:\\Windows\\Temp\\sigdump-#{$$}.log"})
318
- data("UNIX style", {raw_path: "/Windows/Temp/sigdump.log", expected: "/Windows/Temp/sigdump-#{$$}.log"})
319
- data("No extension", {raw_path: "C:\\Windows\\Temp\\sigdump", expected: "C:\\Windows\\Temp\\sigdump-#{$$}"})
320
- data("Multi-extension", {raw_path: "C:\\Windows\\Temp\\sig.dump.bk", expected: "C:\\Windows\\Temp\\sig.dump-#{$$}.bk"})
381
+ data("Normal", {raw_path: "C:\\Windows\\Temp\\sigdump.log", expected: "C:\\Windows\\Temp\\sigdump-#{Process.pid}.log"})
382
+ data("UNIX style", {raw_path: "/Windows/Temp/sigdump.log", expected: "/Windows/Temp/sigdump-#{Process.pid}.log"})
383
+ data("No extension", {raw_path: "C:\\Windows\\Temp\\sigdump", expected: "C:\\Windows\\Temp\\sigdump-#{Process.pid}"})
384
+ data("Multi-extension", {raw_path: "C:\\Windows\\Temp\\sig.dump.bk", expected: "C:\\Windows\\Temp\\sig.dump-#{Process.pid}.bk"})
321
385
  def test_fluentsigdump_get_path_with_pid(data)
322
- p data
323
386
  path = Fluent::FluentSigdump.get_path_with_pid(data[:raw_path])
324
387
  assert_equal(data[:expected], path)
325
388
  end
@@ -368,8 +431,7 @@ class SupervisorTest < ::Test::Unit::TestCase
368
431
 
369
432
  create_info_dummy_logger
370
433
 
371
- opts = Fluent::Supervisor.default_options
372
- sv = Fluent::Supervisor.new(opts)
434
+ sv = Fluent::Supervisor.new({})
373
435
  conf_data = <<-EOC
374
436
  <system>
375
437
  rpc_endpoint "#{bindaddr}:24447"
@@ -386,7 +448,7 @@ class SupervisorTest < ::Test::Unit::TestCase
386
448
 
387
449
  sv.send(:install_main_process_signal_handlers)
388
450
  response = Net::HTTP.get(URI.parse("http://#{localhost}:24447/api/plugins.flushBuffers"))
389
- info_msg = '[info]: force flushing buffered events' + "\n"
451
+ info_msg = "[info]: force flushing buffered events\n"
390
452
 
391
453
  server.stop_rpc_server
392
454
 
@@ -405,8 +467,7 @@ class SupervisorTest < ::Test::Unit::TestCase
405
467
  def test_invalid_rpc_endpoint(data)
406
468
  endpoint = data[0]
407
469
 
408
- opts = Fluent::Supervisor.default_options
409
- sv = Fluent::Supervisor.new(opts)
470
+ sv = Fluent::Supervisor.new({})
410
471
  conf_data = <<-EOC
411
472
  <system>
412
473
  rpc_endpoint "#{endpoint}"
@@ -434,8 +495,7 @@ class SupervisorTest < ::Test::Unit::TestCase
434
495
 
435
496
  create_info_dummy_logger
436
497
 
437
- opts = Fluent::Supervisor.default_options
438
- sv = Fluent::Supervisor.new(opts)
498
+ sv = Fluent::Supervisor.new({})
439
499
  conf_data = <<-EOC
440
500
  <system>
441
501
  rpc_endpoint "#{bindaddr}:24447"
@@ -462,36 +522,17 @@ class SupervisorTest < ::Test::Unit::TestCase
462
522
  assert_equal('{"ok":true}', response)
463
523
  end
464
524
 
465
- def test_load_config
466
- tmp_dir = "#{@tmp_dir}/dir/test_load_config.conf"
467
- conf_info_str = %[
468
- <system>
469
- log_level info
470
- </system>
471
- ]
472
- conf_debug_str = %[
473
- <system>
474
- log_level debug
475
- </system>
476
- ]
477
- now = Time.now
478
- Timecop.freeze(now)
479
-
480
- write_config tmp_dir, conf_info_str
481
-
525
+ def test_serverengine_config
482
526
  params = {}
483
527
  params['workers'] = 1
528
+ params['fluentd_conf_path'] = "fluentd.conf"
484
529
  params['use_v1_config'] = true
485
- params['log_path'] = 'test/tmp/supervisor/log'
486
- params['suppress_repeated_stacktrace'] = true
487
- params['log_level'] = Fluent::Log::LEVEL_INFO
488
530
  params['conf_encoding'] = 'utf-8'
489
- load_config_proc = Proc.new { Fluent::Supervisor.load_config(tmp_dir, params) }
531
+ params['log_level'] = Fluent::Log::LEVEL_INFO
532
+ load_config_proc = Proc.new { Fluent::Supervisor.serverengine_config(params) }
490
533
 
491
- # first call
492
534
  se_config = load_config_proc.call
493
535
  assert_equal Fluent::Log::LEVEL_INFO, se_config[:log_level]
494
- assert_equal true, se_config[:suppress_repeated_stacktrace]
495
536
  assert_equal 'spawn', se_config[:worker_type]
496
537
  assert_equal 1, se_config[:workers]
497
538
  assert_equal false, se_config[:log_stdin]
@@ -499,99 +540,23 @@ class SupervisorTest < ::Test::Unit::TestCase
499
540
  assert_equal false, se_config[:log_stderr]
500
541
  assert_equal true, se_config[:enable_heartbeat]
501
542
  assert_equal false, se_config[:auto_heartbeat]
543
+ assert_equal "fluentd.conf", se_config[:config_path]
502
544
  assert_equal false, se_config[:daemonize]
503
545
  assert_nil se_config[:pid_path]
504
-
505
- # second call immediately(reuse config)
506
- se_config = load_config_proc.call
507
- pre_config_mtime = se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
508
- pre_loadtime = se_config[:windows_daemon_cmdline][5]['pre_loadtime']
509
- assert_nil pre_config_mtime
510
- assert_nil pre_loadtime
511
-
512
- Timecop.freeze(now + 5)
513
-
514
- # third call after 5 seconds(don't reuse config)
515
- se_config = load_config_proc.call
516
- pre_config_mtime = se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
517
- pre_loadtime = se_config[:windows_daemon_cmdline][5]['pre_loadtime']
518
- assert_not_nil pre_config_mtime
519
- assert_not_nil pre_loadtime
520
-
521
- # forth call immediately(reuse config)
522
- se_config = load_config_proc.call
523
- # test that pre_config_mtime and pre_loadtime are not changed from previous one because reused pre_config
524
- assert_equal pre_config_mtime, se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
525
- assert_equal pre_loadtime, se_config[:windows_daemon_cmdline][5]['pre_loadtime']
526
-
527
- write_config tmp_dir, conf_debug_str
528
-
529
- # fifth call after changed conf file(don't reuse config)
530
- se_config = load_config_proc.call
531
- assert_equal Fluent::Log::LEVEL_INFO, se_config[:log_level]
532
- ensure
533
- Timecop.return
534
546
  end
535
547
 
536
- def test_load_config_for_logger
537
- tmp_dir = "#{@tmp_dir}/dir/test_load_config_log.conf"
538
- conf_info_str = %[
539
- <system>
540
- <log>
541
- format json
542
- time_format %FT%T.%L%z
543
- </log>
544
- </system>
545
- ]
546
- write_config tmp_dir, conf_info_str
547
- params = {
548
- 'use_v1_config' => true,
549
- 'conf_encoding' => 'utf8',
550
- 'log_level' => Fluent::Log::LEVEL_INFO,
551
- 'log_path' => 'test/tmp/supervisor/log',
552
-
553
- 'workers' => 1,
554
- 'log_format' => :json,
555
- 'log_time_format' => '%FT%T.%L%z',
556
- }
557
-
558
- r = Fluent::Supervisor.load_config(tmp_dir, params)
559
- assert_equal :json, r[:logger].format
560
- assert_equal '%FT%T.%L%z', r[:logger].time_format
561
- end
562
-
563
- def test_load_config_for_daemonize
564
- tmp_dir = "#{@tmp_dir}/dir/test_load_config.conf"
565
- conf_info_str = %[
566
- <system>
567
- log_level info
568
- </system>
569
- ]
570
- conf_debug_str = %[
571
- <system>
572
- log_level debug
573
- </system>
574
- ]
575
-
576
- now = Time.now
577
- Timecop.freeze(now)
578
-
579
- write_config tmp_dir, conf_info_str
580
-
548
+ def test_serverengine_config_for_daemonize
581
549
  params = {}
582
550
  params['workers'] = 1
551
+ params['fluentd_conf_path'] = "fluentd.conf"
583
552
  params['use_v1_config'] = true
584
- params['log_path'] = 'test/tmp/supervisor/log'
585
- params['suppress_repeated_stacktrace'] = true
553
+ params['conf_encoding'] = 'utf-8'
586
554
  params['log_level'] = Fluent::Log::LEVEL_INFO
587
555
  params['daemonize'] = './fluentd.pid'
588
- params['conf_encoding'] = 'utf-8'
589
- load_config_proc = Proc.new { Fluent::Supervisor.load_config(tmp_dir, params) }
556
+ load_config_proc = Proc.new { Fluent::Supervisor.serverengine_config(params) }
590
557
 
591
- # first call
592
558
  se_config = load_config_proc.call
593
559
  assert_equal Fluent::Log::LEVEL_INFO, se_config[:log_level]
594
- assert_equal true, se_config[:suppress_repeated_stacktrace]
595
560
  assert_equal 'spawn', se_config[:worker_type]
596
561
  assert_equal 1, se_config[:workers]
597
562
  assert_equal false, se_config[:log_stdin]
@@ -599,161 +564,199 @@ class SupervisorTest < ::Test::Unit::TestCase
599
564
  assert_equal false, se_config[:log_stderr]
600
565
  assert_equal true, se_config[:enable_heartbeat]
601
566
  assert_equal false, se_config[:auto_heartbeat]
567
+ assert_equal "fluentd.conf", se_config[:config_path]
602
568
  assert_equal true, se_config[:daemonize]
603
569
  assert_equal './fluentd.pid', se_config[:pid_path]
570
+ end
604
571
 
605
- # second call immediately(reuse config)
606
- se_config = load_config_proc.call
607
- pre_config_mtime = se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
608
- pre_loadtime = se_config[:windows_daemon_cmdline][5]['pre_loadtime']
609
- assert_nil pre_config_mtime
610
- assert_nil pre_loadtime
611
-
612
- Timecop.freeze(now + 5)
613
-
614
- # third call after 6 seconds(don't reuse config)
615
- se_config = load_config_proc.call
616
- pre_config_mtime = se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
617
- pre_loadtime = se_config[:windows_daemon_cmdline][5]['pre_loadtime']
618
- assert_not_nil pre_config_mtime
619
- assert_not_nil pre_loadtime
620
-
621
- # forth call immediately(reuse config)
622
- se_config = load_config_proc.call
623
- # test that pre_config_mtime and pre_loadtime are not changed from previous one because reused pre_config
624
- assert_equal pre_config_mtime, se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
625
- assert_equal pre_loadtime, se_config[:windows_daemon_cmdline][5]['pre_loadtime']
572
+ sub_test_case "init logger" do
573
+ data(supervisor: true)
574
+ data(worker: false)
575
+ def test_init_for_logger(supervisor)
576
+ tmp_conf_path = "#{@tmp_dir}/dir/test_init_for_logger.conf"
577
+ conf_info_str = <<~EOC
578
+ <system>
579
+ log_level warn # To suppress logs
580
+ suppress_repeated_stacktrace false
581
+ ignore_repeated_log_interval 10s
582
+ ignore_same_log_interval 20s
583
+ <log>
584
+ format json
585
+ time_format %FT%T.%L%z
586
+ </log>
587
+ </system>
588
+ EOC
589
+ write_config tmp_conf_path, conf_info_str
626
590
 
627
- write_config tmp_dir, conf_debug_str
591
+ s = Fluent::Supervisor.new({config_path: tmp_conf_path})
592
+ s.configure(supervisor: supervisor)
628
593
 
629
- # fifth call after changed conf file(don't reuse config)
630
- se_config = load_config_proc.call
631
- assert_equal Fluent::Log::LEVEL_INFO, se_config[:log_level]
632
- ensure
633
- Timecop.return
634
- end
594
+ assert_equal :json, $log.format
595
+ assert_equal '%FT%T.%L%z', $log.time_format
596
+ assert_equal false, $log.suppress_repeated_stacktrace
597
+ assert_equal 10, $log.ignore_repeated_log_interval
598
+ assert_equal 20, $log.ignore_same_log_interval
599
+ end
635
600
 
636
- def test_logger
637
- opts = Fluent::Supervisor.default_options
638
- sv = Fluent::Supervisor.new(opts)
639
- log = sv.instance_variable_get(:@log)
640
- log.init(:standalone, 0)
641
- logger = $log.instance_variable_get(:@logger)
601
+ data(
602
+ daily_age: 'daily',
603
+ weekly_age: 'weekly',
604
+ monthly_age: 'monthly',
605
+ integer_age: 2,
606
+ )
607
+ def test_logger_with_rotate_age_and_rotate_size(rotate_age)
608
+ config_path = "#{@tmp_dir}/empty.conf"
609
+ write_config config_path, ""
610
+
611
+ sv = Fluent::Supervisor.new(
612
+ config_path: config_path,
613
+ log_path: "#{@tmp_dir}/test",
614
+ log_rotate_age: rotate_age,
615
+ log_rotate_size: 10,
616
+ )
617
+ sv.__send__(:setup_global_logger)
618
+
619
+ assert_equal Fluent::LogDeviceIO, $log.out.class
620
+ assert_equal rotate_age, $log.out.instance_variable_get(:@shift_age)
621
+ assert_equal 10, $log.out.instance_variable_get(:@shift_size)
622
+ end
642
623
 
643
- assert_equal Fluent::Log::LEVEL_INFO, $log.level
624
+ sub_test_case "system log rotation" do
625
+ def parse_text(text)
626
+ basepath = File.expand_path(File.dirname(__FILE__) + '/../../')
627
+ Fluent::Config.parse(text, '(test)', basepath, true).elements.find { |e| e.name == 'system' }
628
+ end
644
629
 
645
- # test that DamonLogger#level= overwrites Fluent.log#level
646
- logger.level = 'debug'
647
- assert_equal Fluent::Log::LEVEL_DEBUG, $log.level
630
+ def test_override_default_log_rotate
631
+ Tempfile.open do |file|
632
+ config = parse_text(<<-EOS)
633
+ <system>
634
+ <log>
635
+ rotate_age 3
636
+ rotate_size 300
637
+ </log>
638
+ </system>
639
+ EOS
640
+ file.puts(config)
641
+ file.flush
642
+ sv = Fluent::Supervisor.new({log_path: "#{@tmp_dir}/test.log", config_path: file.path})
643
+
644
+ sv.__send__(:setup_global_logger)
645
+ logger = $log.instance_variable_get(:@logger)
646
+
647
+ assert_equal Fluent::LogDeviceIO, $log.out.class
648
+ assert_equal 3, $log.out.instance_variable_get(:@shift_age)
649
+ assert_equal 300, $log.out.instance_variable_get(:@shift_size)
650
+ end
651
+ end
648
652
 
649
- assert_equal 5, logger.instance_variable_get(:@rotate_age)
650
- assert_equal 1048576, logger.instance_variable_get(:@rotate_size)
651
- end
653
+ def test_override_default_log_rotate_with_yaml_config
654
+ Tempfile.open do |file|
655
+ config = <<-EOS
656
+ system:
657
+ log:
658
+ rotate_age: 3
659
+ rotate_size: 300
660
+ EOS
661
+ file.puts(config)
662
+ file.flush
663
+ sv = Fluent::Supervisor.new({log_path: "#{@tmp_dir}/test.log", config_path: file.path, config_file_type: :yaml})
664
+
665
+ sv.__send__(:setup_global_logger)
666
+ logger = $log.instance_variable_get(:@logger)
667
+
668
+ assert_equal Fluent::LogDeviceIO, $log.out.class
669
+ assert_equal 3, $log.out.instance_variable_get(:@shift_age)
670
+ assert_equal 300, $log.out.instance_variable_get(:@shift_size)
671
+ end
672
+ end
673
+ end
652
674
 
653
- data(
654
- daily_age: 'daily',
655
- weekly_age: 'weekly',
656
- monthly_age: 'monthly',
657
- integer_age: 2,
658
- )
659
- def test_logger_with_rotate_age_and_rotate_size(rotate_age)
660
- opts = Fluent::Supervisor.default_options.merge(
661
- log_path: "#{@tmp_dir}/test", log_rotate_age: rotate_age, log_rotate_size: 10
662
- )
663
- sv = Fluent::Supervisor.new(opts)
664
- log = sv.instance_variable_get(:@log)
665
- log.init(:standalone, 0)
675
+ def test_log_level_affects
676
+ sv = Fluent::Supervisor.new({})
666
677
 
667
- assert_equal Fluent::LogDeviceIO, $log.out.class
668
- assert_equal rotate_age, $log.out.instance_variable_get(:@shift_age)
669
- assert_equal 10, $log.out.instance_variable_get(:@shift_size)
670
- end
678
+ c = Fluent::Config::Element.new('system', '', { 'log_level' => 'error' }, [])
679
+ stub(Fluent::Config).build { config_element('ROOT', '', {}, [c]) }
671
680
 
672
- sub_test_case "system log rotation" do
673
- def parse_text(text)
674
- basepath = File.expand_path(File.dirname(__FILE__) + '/../../')
675
- Fluent::Config.parse(text, '(test)', basepath, true).elements.find { |e| e.name == 'system' }
681
+ sv.configure
682
+ assert_equal Fluent::Log::LEVEL_ERROR, $log.level
676
683
  end
677
684
 
678
- def test_override_default_log_rotate
679
- Tempfile.open do |file|
680
- config = parse_text(<<-EOS)
681
- <system>
682
- <log>
683
- rotate_age 3
684
- rotate_size 300
685
- </log>
686
- </system>
687
- EOS
688
- file.puts(config)
689
- file.flush
690
- opts = Fluent::Supervisor.default_options.merge(
691
- log_path: "#{@tmp_dir}/test.log", config_path: file.path
692
- )
693
- sv = Fluent::Supervisor.new(opts)
694
-
695
- log = sv.instance_variable_get(:@log)
696
- log.init(:standalone, 0)
697
- logger = $log.instance_variable_get(:@logger)
698
-
699
- assert_equal([3, 300],
700
- [logger.instance_variable_get(:@rotate_age),
701
- logger.instance_variable_get(:@rotate_size)])
685
+ data(supervisor: true)
686
+ data(worker: false)
687
+ def test_log_path(supervisor)
688
+ log_path = Pathname(@tmp_dir) + "fluentd.log"
689
+ config_path = Pathname(@tmp_dir) + "fluentd.conf"
690
+ write_config config_path.to_s, ""
691
+
692
+ s = Fluent::Supervisor.new(config_path: config_path.to_s, log_path: log_path.to_s)
693
+ assert_rr do
694
+ mock.proxy(File).chmod(0o777, log_path.parent.to_s).never
695
+ s.__send__(:setup_global_logger, supervisor: supervisor)
702
696
  end
703
- end
704
697
 
705
- def test_override_default_log_rotate_with_yaml_config
706
- Tempfile.open do |file|
707
- config = <<-EOS
708
- system:
709
- log:
710
- rotate_age: 3
711
- rotate_size: 300
712
- EOS
713
- file.puts(config)
714
- file.flush
715
- opts = Fluent::Supervisor.default_options.merge(
716
- log_path: "#{@tmp_dir}/test.log", config_path: file.path, config_file_type: :yaml,
717
- )
718
- sv = Fluent::Supervisor.new(opts)
719
-
720
- log = sv.instance_variable_get(:@log)
721
- log.init(:standalone, 0)
722
- logger = $log.instance_variable_get(:@logger)
723
-
724
- assert_equal([3, 300],
725
- [logger.instance_variable_get(:@rotate_age),
726
- logger.instance_variable_get(:@rotate_size)])
727
- end
698
+ assert { log_path.parent.exist? }
699
+ ensure
700
+ $log.out.close
728
701
  end
729
- end
730
702
 
731
- def test_inline_config
732
- omit 'this feature is deprecated. see https://github.com/fluent/fluentd/issues/2711'
703
+ data(supervisor: true)
704
+ data(worker: false)
705
+ def test_dir_permission(supervisor)
706
+ omit "NTFS doesn't support UNIX like permissions" if Fluent.windows?
707
+
708
+ log_path = Pathname(@tmp_dir) + "fluentd.log"
709
+ config_path = Pathname(@tmp_dir) + "fluentd.conf"
710
+ conf = <<~EOC
711
+ <system>
712
+ dir_permission 0o777
713
+ </system>
714
+ EOC
715
+ write_config config_path.to_s, conf
716
+
717
+ s = Fluent::Supervisor.new(config_path: config_path.to_s, log_path: log_path.to_s)
718
+ assert_rr do
719
+ mock.proxy(File).chmod(0o777, log_path.parent.to_s).once
720
+ s.__send__(:setup_global_logger, supervisor: supervisor)
721
+ end
733
722
 
734
- opts = Fluent::Supervisor.default_options
735
- opts[:inline_config] = '-'
736
- sv = Fluent::Supervisor.new(opts)
737
- assert_equal '-', sv.instance_variable_get(:@inline_config)
723
+ assert { log_path.parent.exist? }
724
+ assert { (File.stat(log_path.parent).mode & 0xFFF) == 0o777 }
725
+ ensure
726
+ $log.out.close
727
+ end
738
728
 
739
- inline_config = '<match *>\n@type stdout\n</match>'
740
- stub(STDIN).read { inline_config }
741
- stub(Fluent::Config).build # to skip
742
- stub(sv).build_system_config { Fluent::SystemConfig.new } # to skip
729
+ def test_files_for_each_process_with_rotate_on_windows
730
+ omit "Only for Windows." unless Fluent.windows?
731
+
732
+ log_path = Pathname(@tmp_dir) + "log" + "fluentd.log"
733
+ config_path = Pathname(@tmp_dir) + "fluentd.conf"
734
+ conf = <<~EOC
735
+ <system>
736
+ <log>
737
+ rotate_age 5
738
+ </log>
739
+ </system>
740
+ EOC
741
+ write_config config_path.to_s, conf
743
742
 
744
- sv.configure
745
- assert_equal inline_config, sv.instance_variable_get(:@inline_config)
746
- end
743
+ s = Fluent::Supervisor.new(config_path: config_path.to_s, log_path: log_path.to_s)
744
+ s.__send__(:setup_global_logger, supervisor: true)
745
+ $log.out.close
747
746
 
748
- def test_log_level_affects
749
- opts = Fluent::Supervisor.default_options
750
- sv = Fluent::Supervisor.new(opts)
747
+ s = Fluent::Supervisor.new(config_path: config_path.to_s, log_path: log_path.to_s)
748
+ s.__send__(:setup_global_logger, supervisor: false)
749
+ $log.out.close
751
750
 
752
- c = Fluent::Config::Element.new('system', '', { 'log_level' => 'error' }, [])
753
- stub(Fluent::Config).build { config_element('ROOT', '', {}, [c]) }
751
+ ENV["SERVERENGINE_WORKER_ID"] = "1"
752
+ s = Fluent::Supervisor.new(config_path: config_path.to_s, log_path: log_path.to_s)
753
+ s.__send__(:setup_global_logger, supervisor: false)
754
+ $log.out.close
754
755
 
755
- sv.configure
756
- assert_equal Fluent::Log::LEVEL_ERROR, $log.level
756
+ assert { log_path.parent.entries.size == 5 } # [".", "..", "logfile.log", ...]
757
+ ensure
758
+ ENV.delete("SERVERENGINE_WORKER_ID")
759
+ end
757
760
  end
758
761
 
759
762
  def test_enable_shared_socket
@@ -787,14 +790,6 @@ class SupervisorTest < ::Test::Unit::TestCase
787
790
  end
788
791
  end
789
792
 
790
- def test_per_process_path
791
- path = Fluent::Supervisor::LoggerInitializer.per_process_path("C:/tmp/test.log", :supervisor, 0)
792
- assert_equal(path, "C:/tmp/test-supervisor-0.log")
793
-
794
- path = Fluent::Supervisor::LoggerInitializer.per_process_path("C:/tmp/test.log", :worker, 1)
795
- assert_equal(path, "C:/tmp/test-1.log")
796
- end
797
-
798
793
  def create_debug_dummy_logger
799
794
  dl_opts = {}
800
795
  dl_opts[:log_level] = ServerEngine::DaemonLogger::DEBUG