fluentd 1.15.2-x86-mingw32 → 1.16.1-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.yaml +1 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.yaml +1 -0
  4. data/.github/workflows/linux-test.yaml +2 -2
  5. data/.github/workflows/macos-test.yaml +2 -2
  6. data/.github/workflows/stale-actions.yml +11 -9
  7. data/.github/workflows/windows-test.yaml +2 -2
  8. data/CHANGELOG.md +133 -0
  9. data/CONTRIBUTING.md +1 -1
  10. data/MAINTAINERS.md +5 -3
  11. data/README.md +0 -1
  12. data/SECURITY.md +5 -9
  13. data/fluentd.gemspec +2 -2
  14. data/lib/fluent/command/fluentd.rb +55 -64
  15. data/lib/fluent/config/yaml_parser/loader.rb +18 -1
  16. data/lib/fluent/daemon.rb +2 -4
  17. data/lib/fluent/event.rb +2 -2
  18. data/lib/fluent/file_wrapper.rb +137 -0
  19. data/lib/fluent/log/console_adapter.rb +66 -0
  20. data/lib/fluent/log.rb +35 -5
  21. data/lib/fluent/oj_options.rb +1 -2
  22. data/lib/fluent/plugin/base.rb +5 -7
  23. data/lib/fluent/plugin/buf_file.rb +32 -3
  24. data/lib/fluent/plugin/buf_file_single.rb +32 -3
  25. data/lib/fluent/plugin/buffer/file_chunk.rb +1 -1
  26. data/lib/fluent/plugin/buffer.rb +21 -0
  27. data/lib/fluent/plugin/in_tail.rb +1 -6
  28. data/lib/fluent/plugin/in_tcp.rb +47 -2
  29. data/lib/fluent/plugin/out_file.rb +0 -4
  30. data/lib/fluent/plugin/out_forward/ack_handler.rb +19 -4
  31. data/lib/fluent/plugin/out_forward.rb +2 -2
  32. data/lib/fluent/plugin/out_secondary_file.rb +39 -22
  33. data/lib/fluent/plugin/output.rb +49 -12
  34. data/lib/fluent/plugin_helper/http_server/server.rb +2 -1
  35. data/lib/fluent/plugin_helper/server.rb +8 -0
  36. data/lib/fluent/supervisor.rb +157 -232
  37. data/lib/fluent/test/driver/base.rb +11 -5
  38. data/lib/fluent/test/driver/filter.rb +4 -0
  39. data/lib/fluent/test/startup_shutdown.rb +6 -8
  40. data/lib/fluent/version.rb +1 -1
  41. data/templates/new_gem/test/helper.rb.erb +0 -1
  42. data/test/command/test_ctl.rb +1 -1
  43. data/test/command/test_fluentd.rb +168 -22
  44. data/test/command/test_plugin_config_formatter.rb +0 -1
  45. data/test/compat/test_parser.rb +5 -5
  46. data/test/config/test_system_config.rb +0 -8
  47. data/test/log/test_console_adapter.rb +110 -0
  48. data/test/plugin/out_forward/test_ack_handler.rb +39 -0
  49. data/test/plugin/test_base.rb +98 -0
  50. data/test/plugin/test_buf_file.rb +62 -23
  51. data/test/plugin/test_buf_file_single.rb +65 -0
  52. data/test/plugin/test_in_http.rb +2 -3
  53. data/test/plugin/test_in_monitor_agent.rb +2 -3
  54. data/test/plugin/test_in_tail.rb +105 -103
  55. data/test/plugin/test_in_tcp.rb +87 -2
  56. data/test/plugin/test_in_udp.rb +28 -0
  57. data/test/plugin/test_out_file.rb +3 -2
  58. data/test/plugin/test_out_forward.rb +14 -18
  59. data/test/plugin/test_out_http.rb +1 -0
  60. data/test/plugin/test_output.rb +269 -0
  61. data/test/plugin/test_output_as_buffered_compress.rb +32 -18
  62. data/test/plugin/test_parser_regexp.rb +1 -6
  63. data/test/plugin_helper/test_http_server_helper.rb +1 -1
  64. data/test/plugin_helper/test_server.rb +59 -5
  65. data/test/test_config.rb +57 -21
  66. data/test/{plugin/test_file_wrapper.rb → test_file_wrapper.rb} +2 -2
  67. data/test/test_formatter.rb +23 -20
  68. data/test/test_log.rb +85 -40
  69. data/test/test_supervisor.rb +300 -283
  70. metadata +15 -23
  71. data/.drone.yml +0 -35
  72. data/.github/workflows/issue-auto-closer.yml +0 -12
  73. data/.gitlab-ci.yml +0 -103
  74. data/lib/fluent/plugin/file_wrapper.rb +0 -131
  75. 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