fluentd 1.15.2-x64-mingw32 → 1.16.0-x64-mingw32

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 (66) 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 +96 -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 -64
  10. data/lib/fluent/config/yaml_parser/loader.rb +18 -1
  11. data/lib/fluent/daemon.rb +2 -4
  12. data/lib/fluent/file_wrapper.rb +137 -0
  13. data/lib/fluent/log/console_adapter.rb +66 -0
  14. data/lib/fluent/log.rb +35 -5
  15. data/lib/fluent/oj_options.rb +1 -2
  16. data/lib/fluent/plugin/base.rb +5 -7
  17. data/lib/fluent/plugin/buf_file.rb +32 -3
  18. data/lib/fluent/plugin/buf_file_single.rb +32 -3
  19. data/lib/fluent/plugin/buffer/file_chunk.rb +1 -1
  20. data/lib/fluent/plugin/buffer.rb +21 -0
  21. data/lib/fluent/plugin/in_tail.rb +1 -6
  22. data/lib/fluent/plugin/in_tcp.rb +4 -2
  23. data/lib/fluent/plugin/out_file.rb +0 -4
  24. data/lib/fluent/plugin/out_forward/ack_handler.rb +19 -4
  25. data/lib/fluent/plugin/out_forward.rb +2 -2
  26. data/lib/fluent/plugin/out_secondary_file.rb +39 -22
  27. data/lib/fluent/plugin/output.rb +49 -12
  28. data/lib/fluent/plugin_helper/http_server/server.rb +2 -1
  29. data/lib/fluent/supervisor.rb +157 -232
  30. data/lib/fluent/test/driver/base.rb +11 -5
  31. data/lib/fluent/test/driver/filter.rb +4 -0
  32. data/lib/fluent/test/startup_shutdown.rb +6 -8
  33. data/lib/fluent/version.rb +1 -1
  34. data/test/command/test_ctl.rb +1 -1
  35. data/test/command/test_fluentd.rb +168 -22
  36. data/test/command/test_plugin_config_formatter.rb +0 -1
  37. data/test/compat/test_parser.rb +5 -5
  38. data/test/config/test_system_config.rb +0 -8
  39. data/test/log/test_console_adapter.rb +110 -0
  40. data/test/plugin/out_forward/test_ack_handler.rb +39 -0
  41. data/test/plugin/test_base.rb +98 -0
  42. data/test/plugin/test_buf_file.rb +62 -23
  43. data/test/plugin/test_buf_file_single.rb +65 -0
  44. data/test/plugin/test_in_http.rb +2 -3
  45. data/test/plugin/test_in_monitor_agent.rb +2 -3
  46. data/test/plugin/test_in_tail.rb +105 -103
  47. data/test/plugin/test_in_tcp.rb +15 -0
  48. data/test/plugin/test_out_file.rb +3 -2
  49. data/test/plugin/test_out_forward.rb +14 -18
  50. data/test/plugin/test_out_http.rb +1 -0
  51. data/test/plugin/test_output.rb +269 -0
  52. data/test/plugin/test_parser_regexp.rb +1 -6
  53. data/test/plugin_helper/test_http_server_helper.rb +1 -1
  54. data/test/plugin_helper/test_server.rb +10 -5
  55. data/test/test_config.rb +57 -21
  56. data/test/{plugin/test_file_wrapper.rb → test_file_wrapper.rb} +2 -2
  57. data/test/test_formatter.rb +23 -20
  58. data/test/test_log.rb +85 -40
  59. data/test/test_supervisor.rb +300 -283
  60. metadata +15 -24
  61. data/.drone.yml +0 -35
  62. data/.github/workflows/issue-auto-closer.yml +0 -12
  63. data/.github/workflows/stale-actions.yml +0 -22
  64. data/.gitlab-ci.yml +0 -103
  65. data/lib/fluent/plugin/file_wrapper.rb +0 -131
  66. data/test/test_logger_initializer.rb +0 -46
@@ -2,12 +2,15 @@ require_relative 'helper'
2
2
  require 'fluent/event_router'
3
3
  require 'fluent/system_config'
4
4
  require 'fluent/supervisor'
5
+ require 'fluent/file_wrapper'
5
6
  require_relative 'test_plugin_classes'
6
7
 
7
8
  require 'net/http'
8
9
  require 'uri'
9
10
  require 'fileutils'
10
11
  require 'tempfile'
12
+ require 'securerandom'
13
+ require 'pathname'
11
14
 
12
15
  if Fluent.windows?
13
16
  require 'win32/event'
@@ -22,33 +25,47 @@ class SupervisorTest < ::Test::Unit::TestCase
22
25
  end
23
26
  end
24
27
 
25
- TMP_DIR = File.expand_path(File.dirname(__FILE__) + "/tmp/supervisor#{ENV['TEST_ENV_NUMBER']}")
26
- TMP_ROOT_DIR = File.join(TMP_DIR, 'root')
28
+ def tmp_dir
29
+ File.join(File.dirname(__FILE__), "tmp", "supervisor#{ENV['TEST_ENV_NUMBER']}", SecureRandom.hex(10))
30
+ end
27
31
 
28
32
  def setup
29
- FileUtils.rm_rf(TMP_DIR)
30
- FileUtils.mkdir_p(TMP_DIR)
33
+ @stored_global_logger = $log
34
+ @tmp_dir = tmp_dir
35
+ @tmp_root_dir = File.join(@tmp_dir, 'root')
36
+ FileUtils.mkdir_p(@tmp_dir)
37
+ @sigdump_path = "/tmp/sigdump-#{Process.pid}.log"
38
+ end
39
+
40
+ def teardown
41
+ $log = @stored_global_logger
42
+ begin
43
+ FileUtils.rm_rf(@tmp_dir)
44
+ rescue Errno::EACCES
45
+ # It may occur on Windows because of delete pending state due to delayed GC.
46
+ # Ruby 3.2 or later doesn't ignore Errno::EACCES:
47
+ # https://github.com/ruby/ruby/commit/983115cf3c8f75b1afbe3274f02c1529e1ce3a81
48
+ end
31
49
  end
32
50
 
33
51
  def write_config(path, data)
34
52
  FileUtils.mkdir_p(File.dirname(path))
35
- File.open(path, "w") {|f| f.write data }
53
+ Fluent::FileWrapper.open(path, "w") {|f| f.write data }
36
54
  end
37
55
 
38
56
 
39
57
  def test_system_config
40
- opts = Fluent::Supervisor.default_options
41
- sv = Fluent::Supervisor.new(opts)
58
+ sv = Fluent::Supervisor.new({})
42
59
  conf_data = <<-EOC
43
60
  <system>
44
61
  rpc_endpoint 127.0.0.1:24445
45
- suppress_repeated_stacktrace true
62
+ suppress_repeated_stacktrace false
46
63
  suppress_config_dump true
47
64
  without_source true
48
65
  enable_get_dump true
49
66
  process_name "process_name"
50
67
  log_level info
51
- root_dir #{TMP_ROOT_DIR}
68
+ root_dir #{@tmp_root_dir}
52
69
  <log>
53
70
  format json
54
71
  time_format %Y
@@ -70,13 +87,13 @@ class SupervisorTest < ::Test::Unit::TestCase
70
87
  sys_conf = sv.__send__(:build_system_config, conf)
71
88
 
72
89
  assert_equal '127.0.0.1:24445', sys_conf.rpc_endpoint
73
- assert_equal true, sys_conf.suppress_repeated_stacktrace
90
+ assert_equal false, sys_conf.suppress_repeated_stacktrace
74
91
  assert_equal true, sys_conf.suppress_config_dump
75
92
  assert_equal true, sys_conf.without_source
76
93
  assert_equal true, sys_conf.enable_get_dump
77
94
  assert_equal "process_name", sys_conf.process_name
78
95
  assert_equal 2, sys_conf.log_level
79
- assert_equal TMP_ROOT_DIR, sys_conf.root_dir
96
+ assert_equal @tmp_root_dir, sys_conf.root_dir
80
97
  assert_equal :json, sys_conf.log.format
81
98
  assert_equal '%Y', sys_conf.log.time_format
82
99
  counter_server = sys_conf.counter_server
@@ -105,8 +122,7 @@ class SupervisorTest < ::Test::Unit::TestCase
105
122
  end
106
123
 
107
124
  def test_system_config
108
- opts = Fluent::Supervisor.default_options
109
- sv = Fluent::Supervisor.new(opts)
125
+ sv = Fluent::Supervisor.new({})
110
126
  conf_data = <<-EOC
111
127
  system:
112
128
  rpc_endpoint: 127.0.0.1:24445
@@ -116,7 +132,7 @@ class SupervisorTest < ::Test::Unit::TestCase
116
132
  enable_get_dump: true
117
133
  process_name: "process_name"
118
134
  log_level: info
119
- root_dir: !fluent/s "#{TMP_ROOT_DIR}"
135
+ root_dir: !fluent/s "#{@tmp_root_dir}"
120
136
  log:
121
137
  format: json
122
138
  time_format: "%Y"
@@ -144,7 +160,7 @@ class SupervisorTest < ::Test::Unit::TestCase
144
160
  true,
145
161
  "process_name",
146
162
  2,
147
- TMP_ROOT_DIR,
163
+ @tmp_root_dir,
148
164
  :json,
149
165
  '%Y',
150
166
  '127.0.0.1',
@@ -177,26 +193,60 @@ class SupervisorTest < ::Test::Unit::TestCase
177
193
  end
178
194
  end
179
195
 
180
- def test_main_process_signal_handlers
196
+ def test_usr1_in_main_process_signal_handlers
181
197
  omit "Windows cannot handle signals" if Fluent.windows?
182
198
 
183
199
  create_info_dummy_logger
184
200
 
185
- opts = Fluent::Supervisor.default_options
186
- sv = Fluent::Supervisor.new(opts)
201
+ sv = Fluent::Supervisor.new({})
187
202
  sv.send(:install_main_process_signal_handlers)
188
203
 
189
- begin
190
- Process.kill :USR1, $$
191
- rescue
192
- end
204
+ Process.kill :USR1, Process.pid
193
205
 
194
206
  sleep 1
195
207
 
196
- info_msg = '[info]: force flushing buffered events' + "\n"
208
+ info_msg = "[info]: force flushing buffered events\n"
197
209
  assert{ $log.out.logs.first.end_with?(info_msg) }
198
210
  ensure
199
- $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)
200
250
  end
201
251
 
202
252
  def test_main_process_command_handlers
@@ -204,8 +254,7 @@ class SupervisorTest < ::Test::Unit::TestCase
204
254
 
205
255
  create_info_dummy_logger
206
256
 
207
- opts = Fluent::Supervisor.default_options
208
- sv = Fluent::Supervisor.new(opts)
257
+ sv = Fluent::Supervisor.new({})
209
258
  r, w = IO.pipe
210
259
  $stdin = r
211
260
  sv.send(:install_main_process_signal_handlers)
@@ -219,23 +268,21 @@ class SupervisorTest < ::Test::Unit::TestCase
219
268
 
220
269
  sleep 1
221
270
 
222
- info_msg = '[info]: force flushing buffered events' + "\n"
271
+ info_msg = "[info]: force flushing buffered events\n"
223
272
  assert{ $log.out.logs.first.end_with?(info_msg) }
224
273
  ensure
225
- $log.out.reset if $log && $log.out && $log.out.respond_to?(:reset)
274
+ $log.out.reset if $log&.out&.respond_to?(:reset)
226
275
  end
227
276
 
228
- def test_supervisor_signal_handler
277
+ def test_usr1_in_supervisor_signal_handler
229
278
  omit "Windows cannot handle signals" if Fluent.windows?
230
279
 
231
280
  create_debug_dummy_logger
232
281
 
233
282
  server = DummyServer.new
234
283
  server.install_supervisor_signal_handlers
235
- begin
236
- Process.kill :USR1, $$
237
- rescue
238
- end
284
+
285
+ Process.kill :USR1, Process.pid
239
286
 
240
287
  sleep 1
241
288
 
@@ -243,12 +290,43 @@ class SupervisorTest < ::Test::Unit::TestCase
243
290
  logs = $log.out.logs
244
291
  assert{ logs.any?{|log| log.include?(debug_msg) } }
245
292
  ensure
246
- $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)
247
323
  end
248
324
 
249
325
  def test_windows_shutdown_event
250
326
  omit "Only for Windows platform" unless Fluent.windows?
251
327
 
328
+ create_debug_dummy_logger
329
+
252
330
  server = DummyServer.new
253
331
  def server.config
254
332
  {:signame => "TestFluentdEvent"}
@@ -271,7 +349,7 @@ class SupervisorTest < ::Test::Unit::TestCase
271
349
  logs = $log.out.logs
272
350
  assert{ logs.any?{|log| log.include?(debug_msg) } }
273
351
  ensure
274
- $log.out.reset if $log && $log.out && $log.out.respond_to?(:reset)
352
+ $log.out.reset if $log&.out&.respond_to?(:reset)
275
353
  end
276
354
 
277
355
  def test_supervisor_event_handler
@@ -297,15 +375,14 @@ class SupervisorTest < ::Test::Unit::TestCase
297
375
  logs = $log.out.logs
298
376
  assert{ logs.any?{|log| log.include?(debug_msg) } }
299
377
  ensure
300
- $log.out.reset if $log && $log.out && $log.out.respond_to?(:reset)
378
+ $log.out.reset if $log&.out&.respond_to?(:reset)
301
379
  end
302
380
 
303
- data("Normal", {raw_path: "C:\\Windows\\Temp\\sigdump.log", expected: "C:\\Windows\\Temp\\sigdump-#{$$}.log"})
304
- data("UNIX style", {raw_path: "/Windows/Temp/sigdump.log", expected: "/Windows/Temp/sigdump-#{$$}.log"})
305
- data("No extension", {raw_path: "C:\\Windows\\Temp\\sigdump", expected: "C:\\Windows\\Temp\\sigdump-#{$$}"})
306
- 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"})
307
385
  def test_fluentsigdump_get_path_with_pid(data)
308
- p data
309
386
  path = Fluent::FluentSigdump.get_path_with_pid(data[:raw_path])
310
387
  assert_equal(data[:expected], path)
311
388
  end
@@ -354,8 +431,7 @@ class SupervisorTest < ::Test::Unit::TestCase
354
431
 
355
432
  create_info_dummy_logger
356
433
 
357
- opts = Fluent::Supervisor.default_options
358
- sv = Fluent::Supervisor.new(opts)
434
+ sv = Fluent::Supervisor.new({})
359
435
  conf_data = <<-EOC
360
436
  <system>
361
437
  rpc_endpoint "#{bindaddr}:24447"
@@ -372,7 +448,7 @@ class SupervisorTest < ::Test::Unit::TestCase
372
448
 
373
449
  sv.send(:install_main_process_signal_handlers)
374
450
  response = Net::HTTP.get(URI.parse("http://#{localhost}:24447/api/plugins.flushBuffers"))
375
- info_msg = '[info]: force flushing buffered events' + "\n"
451
+ info_msg = "[info]: force flushing buffered events\n"
376
452
 
377
453
  server.stop_rpc_server
378
454
 
@@ -391,8 +467,7 @@ class SupervisorTest < ::Test::Unit::TestCase
391
467
  def test_invalid_rpc_endpoint(data)
392
468
  endpoint = data[0]
393
469
 
394
- opts = Fluent::Supervisor.default_options
395
- sv = Fluent::Supervisor.new(opts)
470
+ sv = Fluent::Supervisor.new({})
396
471
  conf_data = <<-EOC
397
472
  <system>
398
473
  rpc_endpoint "#{endpoint}"
@@ -420,8 +495,7 @@ class SupervisorTest < ::Test::Unit::TestCase
420
495
 
421
496
  create_info_dummy_logger
422
497
 
423
- opts = Fluent::Supervisor.default_options
424
- sv = Fluent::Supervisor.new(opts)
498
+ sv = Fluent::Supervisor.new({})
425
499
  conf_data = <<-EOC
426
500
  <system>
427
501
  rpc_endpoint "#{bindaddr}:24447"
@@ -448,36 +522,17 @@ class SupervisorTest < ::Test::Unit::TestCase
448
522
  assert_equal('{"ok":true}', response)
449
523
  end
450
524
 
451
- def test_load_config
452
- tmp_dir = "#{TMP_DIR}/dir/test_load_config.conf"
453
- conf_info_str = %[
454
- <system>
455
- log_level info
456
- </system>
457
- ]
458
- conf_debug_str = %[
459
- <system>
460
- log_level debug
461
- </system>
462
- ]
463
- now = Time.now
464
- Timecop.freeze(now)
465
-
466
- write_config tmp_dir, conf_info_str
467
-
525
+ def test_serverengine_config
468
526
  params = {}
469
527
  params['workers'] = 1
528
+ params['fluentd_conf_path'] = "fluentd.conf"
470
529
  params['use_v1_config'] = true
471
- params['log_path'] = 'test/tmp/supervisor/log'
472
- params['suppress_repeated_stacktrace'] = true
473
- params['log_level'] = Fluent::Log::LEVEL_INFO
474
530
  params['conf_encoding'] = 'utf-8'
475
- 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) }
476
533
 
477
- # first call
478
534
  se_config = load_config_proc.call
479
535
  assert_equal Fluent::Log::LEVEL_INFO, se_config[:log_level]
480
- assert_equal true, se_config[:suppress_repeated_stacktrace]
481
536
  assert_equal 'spawn', se_config[:worker_type]
482
537
  assert_equal 1, se_config[:workers]
483
538
  assert_equal false, se_config[:log_stdin]
@@ -485,99 +540,23 @@ class SupervisorTest < ::Test::Unit::TestCase
485
540
  assert_equal false, se_config[:log_stderr]
486
541
  assert_equal true, se_config[:enable_heartbeat]
487
542
  assert_equal false, se_config[:auto_heartbeat]
543
+ assert_equal "fluentd.conf", se_config[:config_path]
488
544
  assert_equal false, se_config[:daemonize]
489
545
  assert_nil se_config[:pid_path]
490
-
491
- # second call immediately(reuse config)
492
- se_config = load_config_proc.call
493
- pre_config_mtime = se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
494
- pre_loadtime = se_config[:windows_daemon_cmdline][5]['pre_loadtime']
495
- assert_nil pre_config_mtime
496
- assert_nil pre_loadtime
497
-
498
- Timecop.freeze(now + 5)
499
-
500
- # third call after 5 seconds(don't reuse config)
501
- se_config = load_config_proc.call
502
- pre_config_mtime = se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
503
- pre_loadtime = se_config[:windows_daemon_cmdline][5]['pre_loadtime']
504
- assert_not_nil pre_config_mtime
505
- assert_not_nil pre_loadtime
506
-
507
- # forth call immediately(reuse config)
508
- se_config = load_config_proc.call
509
- # test that pre_config_mtime and pre_loadtime are not changed from previous one because reused pre_config
510
- assert_equal pre_config_mtime, se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
511
- assert_equal pre_loadtime, se_config[:windows_daemon_cmdline][5]['pre_loadtime']
512
-
513
- write_config tmp_dir, conf_debug_str
514
-
515
- # fifth call after changed conf file(don't reuse config)
516
- se_config = load_config_proc.call
517
- assert_equal Fluent::Log::LEVEL_INFO, se_config[:log_level]
518
- ensure
519
- Timecop.return
520
- end
521
-
522
- def test_load_config_for_logger
523
- tmp_dir = "#{TMP_DIR}/dir/test_load_config_log.conf"
524
- conf_info_str = %[
525
- <system>
526
- <log>
527
- format json
528
- time_format %FT%T.%L%z
529
- </log>
530
- </system>
531
- ]
532
- write_config tmp_dir, conf_info_str
533
- params = {
534
- 'use_v1_config' => true,
535
- 'conf_encoding' => 'utf8',
536
- 'log_level' => Fluent::Log::LEVEL_INFO,
537
- 'log_path' => 'test/tmp/supervisor/log',
538
-
539
- 'workers' => 1,
540
- 'log_format' => :json,
541
- 'log_time_format' => '%FT%T.%L%z',
542
- }
543
-
544
- r = Fluent::Supervisor.load_config(tmp_dir, params)
545
- assert_equal :json, r[:logger].format
546
- assert_equal '%FT%T.%L%z', r[:logger].time_format
547
546
  end
548
547
 
549
- def test_load_config_for_daemonize
550
- tmp_dir = "#{TMP_DIR}/dir/test_load_config.conf"
551
- conf_info_str = %[
552
- <system>
553
- log_level info
554
- </system>
555
- ]
556
- conf_debug_str = %[
557
- <system>
558
- log_level debug
559
- </system>
560
- ]
561
-
562
- now = Time.now
563
- Timecop.freeze(now)
564
-
565
- write_config tmp_dir, conf_info_str
566
-
548
+ def test_serverengine_config_for_daemonize
567
549
  params = {}
568
550
  params['workers'] = 1
551
+ params['fluentd_conf_path'] = "fluentd.conf"
569
552
  params['use_v1_config'] = true
570
- params['log_path'] = 'test/tmp/supervisor/log'
571
- params['suppress_repeated_stacktrace'] = true
553
+ params['conf_encoding'] = 'utf-8'
572
554
  params['log_level'] = Fluent::Log::LEVEL_INFO
573
555
  params['daemonize'] = './fluentd.pid'
574
- params['conf_encoding'] = 'utf-8'
575
- load_config_proc = Proc.new { Fluent::Supervisor.load_config(tmp_dir, params) }
556
+ load_config_proc = Proc.new { Fluent::Supervisor.serverengine_config(params) }
576
557
 
577
- # first call
578
558
  se_config = load_config_proc.call
579
559
  assert_equal Fluent::Log::LEVEL_INFO, se_config[:log_level]
580
- assert_equal true, se_config[:suppress_repeated_stacktrace]
581
560
  assert_equal 'spawn', se_config[:worker_type]
582
561
  assert_equal 1, se_config[:workers]
583
562
  assert_equal false, se_config[:log_stdin]
@@ -585,161 +564,199 @@ class SupervisorTest < ::Test::Unit::TestCase
585
564
  assert_equal false, se_config[:log_stderr]
586
565
  assert_equal true, se_config[:enable_heartbeat]
587
566
  assert_equal false, se_config[:auto_heartbeat]
567
+ assert_equal "fluentd.conf", se_config[:config_path]
588
568
  assert_equal true, se_config[:daemonize]
589
569
  assert_equal './fluentd.pid', se_config[:pid_path]
570
+ end
590
571
 
591
- # second call immediately(reuse config)
592
- se_config = load_config_proc.call
593
- pre_config_mtime = se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
594
- pre_loadtime = se_config[:windows_daemon_cmdline][5]['pre_loadtime']
595
- assert_nil pre_config_mtime
596
- assert_nil pre_loadtime
597
-
598
- Timecop.freeze(now + 5)
599
-
600
- # third call after 6 seconds(don't reuse config)
601
- se_config = load_config_proc.call
602
- pre_config_mtime = se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
603
- pre_loadtime = se_config[:windows_daemon_cmdline][5]['pre_loadtime']
604
- assert_not_nil pre_config_mtime
605
- assert_not_nil pre_loadtime
606
-
607
- # forth call immediately(reuse config)
608
- se_config = load_config_proc.call
609
- # test that pre_config_mtime and pre_loadtime are not changed from previous one because reused pre_config
610
- assert_equal pre_config_mtime, se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
611
- 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
612
590
 
613
- write_config tmp_dir, conf_debug_str
591
+ s = Fluent::Supervisor.new({config_path: tmp_conf_path})
592
+ s.configure(supervisor: supervisor)
614
593
 
615
- # fifth call after changed conf file(don't reuse config)
616
- se_config = load_config_proc.call
617
- assert_equal Fluent::Log::LEVEL_INFO, se_config[:log_level]
618
- ensure
619
- Timecop.return
620
- 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
621
600
 
622
- def test_logger
623
- opts = Fluent::Supervisor.default_options
624
- sv = Fluent::Supervisor.new(opts)
625
- log = sv.instance_variable_get(:@log)
626
- log.init(:standalone, 0)
627
- 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
628
623
 
629
- 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
630
629
 
631
- # test that DamonLogger#level= overwrites Fluent.log#level
632
- logger.level = 'debug'
633
- 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
634
652
 
635
- assert_equal 5, logger.instance_variable_get(:@rotate_age)
636
- assert_equal 1048576, logger.instance_variable_get(:@rotate_size)
637
- 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
638
674
 
639
- data(
640
- daily_age: 'daily',
641
- weekly_age: 'weekly',
642
- monthly_age: 'monthly',
643
- integer_age: 2,
644
- )
645
- def test_logger_with_rotate_age_and_rotate_size(rotate_age)
646
- opts = Fluent::Supervisor.default_options.merge(
647
- log_path: "#{TMP_DIR}/test", log_rotate_age: rotate_age, log_rotate_size: 10
648
- )
649
- sv = Fluent::Supervisor.new(opts)
650
- log = sv.instance_variable_get(:@log)
651
- log.init(:standalone, 0)
675
+ def test_log_level_affects
676
+ sv = Fluent::Supervisor.new({})
652
677
 
653
- assert_equal Fluent::LogDeviceIO, $log.out.class
654
- assert_equal rotate_age, $log.out.instance_variable_get(:@shift_age)
655
- assert_equal 10, $log.out.instance_variable_get(:@shift_size)
656
- end
678
+ c = Fluent::Config::Element.new('system', '', { 'log_level' => 'error' }, [])
679
+ stub(Fluent::Config).build { config_element('ROOT', '', {}, [c]) }
657
680
 
658
- sub_test_case "system log rotation" do
659
- def parse_text(text)
660
- basepath = File.expand_path(File.dirname(__FILE__) + '/../../')
661
- 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
662
683
  end
663
684
 
664
- def test_override_default_log_rotate
665
- Tempfile.open do |file|
666
- config = parse_text(<<-EOS)
667
- <system>
668
- <log>
669
- rotate_age 3
670
- rotate_size 300
671
- </log>
672
- </system>
673
- EOS
674
- file.puts(config)
675
- file.flush
676
- opts = Fluent::Supervisor.default_options.merge(
677
- log_path: "#{TMP_DIR}/test.log", config_path: file.path
678
- )
679
- sv = Fluent::Supervisor.new(opts)
680
-
681
- log = sv.instance_variable_get(:@log)
682
- log.init(:standalone, 0)
683
- logger = $log.instance_variable_get(:@logger)
684
-
685
- assert_equal([3, 300],
686
- [logger.instance_variable_get(:@rotate_age),
687
- 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)
688
696
  end
689
- end
690
697
 
691
- def test_override_default_log_rotate_with_yaml_config
692
- Tempfile.open do |file|
693
- config = <<-EOS
694
- system:
695
- log:
696
- rotate_age: 3
697
- rotate_size: 300
698
- EOS
699
- file.puts(config)
700
- file.flush
701
- opts = Fluent::Supervisor.default_options.merge(
702
- log_path: "#{TMP_DIR}/test.log", config_path: file.path, config_file_type: :yaml,
703
- )
704
- sv = Fluent::Supervisor.new(opts)
705
-
706
- log = sv.instance_variable_get(:@log)
707
- log.init(:standalone, 0)
708
- logger = $log.instance_variable_get(:@logger)
709
-
710
- assert_equal([3, 300],
711
- [logger.instance_variable_get(:@rotate_age),
712
- logger.instance_variable_get(:@rotate_size)])
713
- end
698
+ assert { log_path.parent.exist? }
699
+ ensure
700
+ $log.out.close
714
701
  end
715
- end
716
702
 
717
- def test_inline_config
718
- 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
719
722
 
720
- opts = Fluent::Supervisor.default_options
721
- opts[:inline_config] = '-'
722
- sv = Fluent::Supervisor.new(opts)
723
- 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
724
728
 
725
- inline_config = '<match *>\n@type stdout\n</match>'
726
- stub(STDIN).read { inline_config }
727
- stub(Fluent::Config).build # to skip
728
- 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
729
742
 
730
- sv.configure
731
- assert_equal inline_config, sv.instance_variable_get(:@inline_config)
732
- 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
733
746
 
734
- def test_log_level_affects
735
- opts = Fluent::Supervisor.default_options
736
- 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
737
750
 
738
- c = Fluent::Config::Element.new('system', '', { 'log_level' => 'error' }, [])
739
- 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
740
755
 
741
- sv.configure
742
- 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
743
760
  end
744
761
 
745
762
  def test_enable_shared_socket