fluentd 0.14.11 → 0.14.12

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fluentd might be problematic. Click here for more details.

Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -5
  3. data/ChangeLog +54 -2
  4. data/example/in_dummy_blocks.conf +17 -0
  5. data/example/in_forward_tls.conf +14 -0
  6. data/example/in_forward_workers.conf +21 -0
  7. data/example/logevents.conf +25 -0
  8. data/example/out_forward_heartbeat_none.conf +16 -0
  9. data/example/out_forward_tls.conf +18 -0
  10. data/example/suppress_config_dump.conf +7 -0
  11. data/lib/fluent/agent.rb +3 -32
  12. data/lib/fluent/clock.rb +62 -0
  13. data/lib/fluent/command/fluentd.rb +12 -0
  14. data/lib/fluent/compat/input.rb +10 -1
  15. data/lib/fluent/compat/output.rb +40 -1
  16. data/lib/fluent/config/configure_proxy.rb +30 -7
  17. data/lib/fluent/config/section.rb +4 -0
  18. data/lib/fluent/config/types.rb +2 -2
  19. data/lib/fluent/configurable.rb +31 -5
  20. data/lib/fluent/engine.rb +61 -12
  21. data/lib/fluent/event_router.rb +6 -0
  22. data/lib/fluent/load.rb +0 -1
  23. data/lib/fluent/log.rb +118 -42
  24. data/lib/fluent/match.rb +37 -0
  25. data/lib/fluent/plugin.rb +25 -3
  26. data/lib/fluent/plugin/base.rb +4 -0
  27. data/lib/fluent/plugin/buf_file.rb +38 -14
  28. data/lib/fluent/plugin/buffer.rb +20 -20
  29. data/lib/fluent/plugin/buffer/file_chunk.rb +2 -2
  30. data/lib/fluent/plugin/compressable.rb +1 -0
  31. data/lib/fluent/plugin/filter_record_transformer.rb +3 -6
  32. data/lib/fluent/plugin/formatter_csv.rb +4 -1
  33. data/lib/fluent/plugin/formatter_hash.rb +5 -1
  34. data/lib/fluent/plugin/formatter_json.rb +10 -0
  35. data/lib/fluent/plugin/formatter_ltsv.rb +2 -1
  36. data/lib/fluent/plugin/in_dummy.rb +4 -0
  37. data/lib/fluent/plugin/in_exec.rb +4 -0
  38. data/lib/fluent/plugin/in_forward.rb +11 -3
  39. data/lib/fluent/plugin/in_gc_stat.rb +4 -0
  40. data/lib/fluent/plugin/in_http.rb +4 -0
  41. data/lib/fluent/plugin/in_monitor_agent.rb +29 -2
  42. data/lib/fluent/plugin/in_object_space.rb +4 -1
  43. data/lib/fluent/plugin/in_syslog.rb +4 -0
  44. data/lib/fluent/plugin/in_tail.rb +193 -116
  45. data/lib/fluent/plugin/in_tcp.rb +5 -1
  46. data/lib/fluent/plugin/in_udp.rb +4 -0
  47. data/lib/fluent/plugin/input.rb +4 -0
  48. data/lib/fluent/plugin/out_copy.rb +4 -0
  49. data/lib/fluent/plugin/out_exec.rb +4 -0
  50. data/lib/fluent/plugin/out_exec_filter.rb +4 -0
  51. data/lib/fluent/plugin/out_file.rb +70 -30
  52. data/lib/fluent/plugin/out_forward.rb +132 -28
  53. data/lib/fluent/plugin/out_null.rb +10 -0
  54. data/lib/fluent/plugin/out_relabel.rb +4 -0
  55. data/lib/fluent/plugin/out_roundrobin.rb +4 -0
  56. data/lib/fluent/plugin/out_secondary_file.rb +5 -0
  57. data/lib/fluent/plugin/out_stdout.rb +5 -0
  58. data/lib/fluent/plugin/output.rb +18 -9
  59. data/lib/fluent/plugin/storage_local.rb +25 -2
  60. data/lib/fluent/plugin_helper/cert_option.rb +159 -0
  61. data/lib/fluent/plugin_helper/child_process.rb +6 -6
  62. data/lib/fluent/plugin_helper/compat_parameters.rb +1 -1
  63. data/lib/fluent/plugin_helper/event_loop.rb +29 -4
  64. data/lib/fluent/plugin_helper/inject.rb +14 -1
  65. data/lib/fluent/plugin_helper/server.rb +275 -31
  66. data/lib/fluent/plugin_helper/socket.rb +144 -4
  67. data/lib/fluent/plugin_helper/socket_option.rb +2 -17
  68. data/lib/fluent/plugin_helper/storage.rb +7 -1
  69. data/lib/fluent/plugin_helper/thread.rb +16 -4
  70. data/lib/fluent/registry.rb +26 -9
  71. data/lib/fluent/root_agent.rb +7 -3
  72. data/lib/fluent/supervisor.rb +37 -15
  73. data/lib/fluent/system_config.rb +37 -10
  74. data/lib/fluent/test.rb +2 -0
  75. data/lib/fluent/test/driver/base.rb +24 -26
  76. data/lib/fluent/test/helpers.rb +21 -0
  77. data/lib/fluent/version.rb +1 -1
  78. data/test/command/test_fluentd.rb +274 -4
  79. data/test/config/test_configurable.rb +154 -0
  80. data/test/config/test_configure_proxy.rb +180 -1
  81. data/test/config/test_system_config.rb +10 -0
  82. data/test/config/test_types.rb +1 -0
  83. data/test/plugin/test_base.rb +4 -0
  84. data/test/plugin/test_buf_file.rb +241 -9
  85. data/test/plugin/test_buffer.rb +11 -11
  86. data/test/plugin/test_buffer_file_chunk.rb +6 -6
  87. data/test/plugin/test_compressable.rb +3 -0
  88. data/test/plugin/test_filter.rb +4 -0
  89. data/test/plugin/test_filter_record_transformer.rb +20 -0
  90. data/test/plugin/test_formatter_csv.rb +9 -0
  91. data/test/plugin/test_formatter_hash.rb +35 -0
  92. data/test/plugin/test_formatter_json.rb +8 -0
  93. data/test/plugin/test_formatter_ltsv.rb +7 -0
  94. data/test/plugin/test_in_dummy.rb +7 -3
  95. data/test/plugin/test_in_monitor_agent.rb +43 -5
  96. data/test/plugin/test_in_tail.rb +97 -4
  97. data/test/plugin/test_input.rb +4 -0
  98. data/test/plugin/test_out_file.rb +46 -7
  99. data/test/plugin/test_out_forward.rb +59 -7
  100. data/test/plugin/test_output.rb +10 -4
  101. data/test/plugin/test_output_as_buffered.rb +37 -25
  102. data/test/plugin/test_output_as_buffered_compress.rb +1 -1
  103. data/test/plugin/test_output_as_buffered_retries.rb +6 -6
  104. data/test/plugin/test_output_as_buffered_secondary.rb +91 -31
  105. data/test/plugin/test_storage_local.rb +40 -1
  106. data/test/plugin_helper/test_child_process.rb +29 -28
  107. data/test/plugin_helper/test_compat_parameters.rb +1 -1
  108. data/test/plugin_helper/test_inject.rb +27 -9
  109. data/test/plugin_helper/test_server.rb +822 -50
  110. data/test/plugin_helper/test_storage.rb +11 -0
  111. data/test/plugin_helper/test_timer.rb +1 -0
  112. data/test/test_clock.rb +164 -0
  113. data/test/test_log.rb +146 -15
  114. data/test/test_plugin.rb +251 -0
  115. data/test/test_supervisor.rb +65 -57
  116. data/test/test_test_drivers.rb +2 -2
  117. metadata +18 -7
  118. data/lib/fluent/process.rb +0 -504
  119. data/test/test_process.rb +0 -48
@@ -22,23 +22,24 @@ module Fluent
22
22
  include Configurable
23
23
 
24
24
  SYSTEM_CONFIG_PARAMETERS = [
25
- :root_dir, :log_level,
25
+ :workers, :root_dir, :log_level,
26
26
  :suppress_repeated_stacktrace, :emit_error_log_interval, :suppress_config_dump,
27
+ :log_event_verbose,
27
28
  :without_source, :rpc_endpoint, :enable_get_dump, :process_name,
28
29
  :file_permission, :dir_permission,
29
30
  ]
30
31
 
31
- config_param :root_dir, :string, default: nil
32
- config_param :log_level, default: nil do |level|
33
- Log.str_to_level(level)
34
- end
32
+ config_param :workers, :integer, default: 1
33
+ config_param :root_dir, :string, default: nil
34
+ config_param :log_level, :enum, list: [:trace, :debug, :info, :warn, :error, :fatal], default: nil
35
35
  config_param :suppress_repeated_stacktrace, :bool, default: nil
36
- config_param :emit_error_log_interval, :time, default: nil
36
+ config_param :emit_error_log_interval, :time, default: nil
37
37
  config_param :suppress_config_dump, :bool, default: nil
38
- config_param :without_source, :bool, default: nil
39
- config_param :rpc_endpoint, :string, default: nil
38
+ config_param :log_event_verbose, :bool, default: nil
39
+ config_param :without_source, :bool, default: nil
40
+ config_param :rpc_endpoint, :string, default: nil
40
41
  config_param :enable_get_dump, :bool, default: nil
41
- config_param :process_name, default: nil
42
+ config_param :process_name, :string, default: nil
42
43
  config_param :file_permission, default: nil do |v|
43
44
  v.to_i(8)
44
45
  end
@@ -74,6 +75,12 @@ module Fluent
74
75
  configure(conf)
75
76
  end
76
77
 
78
+ def configure(conf)
79
+ super
80
+
81
+ @log_level = Log.str_to_level(@log_level.to_s) if @log_level
82
+ end
83
+
77
84
  def dup
78
85
  s = SystemConfig.new
79
86
  SYSTEM_CONFIG_PARAMETERS.each do |param|
@@ -82,11 +89,31 @@ module Fluent
82
89
  s
83
90
  end
84
91
 
92
+ def attach(supervisor)
93
+ system = self
94
+ supervisor.instance_eval {
95
+ SYSTEM_CONFIG_PARAMETERS.each do |param|
96
+ case param
97
+ when :rpc_endpoint, :enable_get_dump, :process_name, :file_permission, :dir_permission
98
+ next # doesn't exist in command line options
99
+ when :emit_error_log_interval
100
+ system.emit_error_log_interval = @suppress_interval if @suppress_interval
101
+ else
102
+ next unless instance_variable_defined?("@#{param}")
103
+ supervisor_value = instance_variable_get("@#{param}")
104
+ next if supervisor_value.nil? # it's not configured by command line options
105
+
106
+ system.send("#{param}=", supervisor_value)
107
+ end
108
+ end
109
+ }
110
+ end
111
+
85
112
  def apply(supervisor)
86
113
  system = self
87
114
  supervisor.instance_eval {
88
115
  SYSTEM_CONFIG_PARAMETERS.each do |param|
89
- param_value = system.send(param)
116
+ param_value = system.__send__(param)
90
117
  next if param_value.nil?
91
118
 
92
119
  case param
@@ -36,6 +36,8 @@ module Fluent
36
36
  end
37
37
 
38
38
  def self.setup
39
+ ENV['SERVERENGINE_WORKER_ID'] = '0'
40
+
39
41
  $log = dummy_logger
40
42
 
41
43
  Fluent.__send__(:remove_const, :Engine)
@@ -17,6 +17,7 @@
17
17
  require 'fluent/config'
18
18
  require 'fluent/config/element'
19
19
  require 'fluent/log'
20
+ require 'fluent/clock'
20
21
 
21
22
  require 'serverengine/socket_manager'
22
23
  require 'fileutils'
@@ -48,8 +49,6 @@ module Fluent
48
49
 
49
50
  @logs = []
50
51
 
51
- @test_clock_id = Process::CLOCK_MONOTONIC_RAW rescue Process::CLOCK_MONOTONIC
52
-
53
52
  @run_post_conditions = []
54
53
  @run_breaking_conditions = []
55
54
  @broken = false
@@ -77,8 +76,8 @@ module Fluent
77
76
  instance_start if start
78
77
 
79
78
  timeout ||= DEFAULT_TIMEOUT
80
- stop_at = Process.clock_gettime(@test_clock_id) + timeout
81
- @run_breaking_conditions << ->(){ Process.clock_gettime(@test_clock_id) >= stop_at }
79
+ stop_at = Fluent::Clock.now + timeout
80
+ @run_breaking_conditions << ->(){ Fluent::Clock.now >= stop_at }
82
81
 
83
82
  if !block_given? && @run_post_conditions.empty? && @run_breaking_conditions.empty?
84
83
  raise ArgumentError, "no stop conditions nor block specified"
@@ -139,38 +138,37 @@ module Fluent
139
138
  def instance_shutdown
140
139
  instance_hook_before_stopped
141
140
 
142
- unless @instance.stopped?
143
- @instance.stop rescue nil
144
- end
145
- unless @instance.before_shutdown?
146
- @instance.before_shutdown rescue nil
147
- end
148
- unless @instance.shutdown?
149
- @instance.shutdown rescue nil
141
+ show_errors_if_exists = ->(label, block){
142
+ begin
143
+ block.call
144
+ rescue => e
145
+ puts "unexpected error while #{label}, #{e.class}:#{e.message}"
146
+ e.backtrace.each do |bt|
147
+ puts "\t#{bt}"
148
+ end
149
+ end
150
+ }
151
+
152
+ show_errors_if_exists.call(:stop, ->(){ @instance.stop unless @instance.stopped? })
153
+ show_errors_if_exists.call(:before_shutdown, ->(){ @instance.before_shutdown unless @instance.before_shutdown? })
154
+ show_errors_if_exists.call(:shutdown, ->(){ @instance.shutdown unless @instance.shutdown? })
155
+ show_errors_if_exists.call(:after_shutdown, ->(){ @instance.after_shutdown unless @instance.after_shutdown? })
156
+
157
+ if @instance.respond_to?(:server_wait_until_stop)
158
+ @instance.server_wait_until_stop
150
159
  end
151
160
 
152
161
  if @instance.respond_to?(:event_loop_wait_until_stop)
153
162
  @instance.event_loop_wait_until_stop
154
163
  end
155
164
 
156
- unless @instance.after_shutdown?
157
- @instance.after_shutdown rescue nil
158
- end
159
- unless @instance.closed?
160
- @instance.close rescue nil
161
- end
165
+ show_errors_if_exists.call(:close, ->(){ @instance.close unless @instance.closed? })
162
166
 
163
167
  if @instance.respond_to?(:thread_wait_until_stop)
164
168
  @instance.thread_wait_until_stop
165
169
  end
166
170
 
167
- if @instance.respond_to?(:server_wait_until_stop)
168
- @instance.server_wait_until_stop
169
- end
170
-
171
- unless @instance.terminated?
172
- @instance.terminate rescue nil
173
- end
171
+ show_errors_if_exists.call(:terminate, ->(){ @instance.terminate unless @instance.terminated? })
174
172
 
175
173
  if @socket_manager_server
176
174
  @socket_manager_server.close
@@ -195,7 +193,7 @@ module Fluent
195
193
 
196
194
  return_value = nil
197
195
  begin
198
- Timeout.timeout(timeout * 1.1) do |sec|
196
+ Timeout.timeout(timeout * 2) do |sec|
199
197
  return_value = block.call if block_given?
200
198
  end
201
199
  rescue Timeout::Error
@@ -57,6 +57,27 @@ EOT
57
57
  ENV['TZ'] = oldtz
58
58
  end
59
59
 
60
+ def with_worker_config(root_dir: nil, workers: nil, worker_id: nil, &block)
61
+ if workers
62
+ if worker_id
63
+ if worker_id >= workers
64
+ raise "worker_id must be between 0 and (workers - 1)"
65
+ end
66
+ else
67
+ worker_id = 0
68
+ end
69
+ end
70
+
71
+ opts = {}
72
+ opts['root_dir'] = root_dir if root_dir
73
+ opts['workers'] = workers if workers
74
+
75
+ ENV['SERVERENGINE_WORKER_ID'] = worker_id.to_s
76
+ Fluent::SystemConfig.overwrite_system_config(opts, &block)
77
+ ensure
78
+ ENV.delete('SERVERENGINE_WORKER_ID')
79
+ end
80
+
60
81
  def time2str(time, localtime: false, format: nil)
61
82
  if format
62
83
  if localtime
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Fluent
18
18
 
19
- VERSION = '0.14.11'
19
+ VERSION = '0.14.12'
20
20
 
21
21
  end
@@ -81,7 +81,7 @@ class TestFluentdCommand < ::Test::Unit::TestCase
81
81
  null_stream.close rescue nil
82
82
  end
83
83
 
84
- def assert_log_matches(cmdline, *pattern_list, timeout: 10)
84
+ def assert_log_matches(cmdline, *pattern_list, patterns_not_match: [], timeout: 10)
85
85
  matched = false
86
86
  assert_error_msg = "matched correctly"
87
87
  stdio_buf = ""
@@ -118,6 +118,18 @@ class TestFluentdCommand < ::Test::Unit::TestCase
118
118
  assert_error_msg = "unexpected error in launching fluentd: #{e.inspect}\n" + stdio_buf
119
119
  end
120
120
  assert matched, assert_error_msg
121
+
122
+ unless patterns_not_match.empty?
123
+ lines = stdio_buf.split("\n")
124
+ patterns_not_match.each do |ptn|
125
+ matched_wrongly = if ptn.is_a? Regexp
126
+ lines.any?{|line| ptn.match(line) }
127
+ else
128
+ lines.any?{|line| line.include?(ptn) }
129
+ end
130
+ assert_false matched_wrongly, "pattern exists in logs wrongly:\n" + stdio_buf
131
+ end
132
+ end
121
133
  end
122
134
 
123
135
  def assert_fluentd_fails_to_start(cmdline, *pattern_list, timeout: 10)
@@ -187,7 +199,7 @@ CONF
187
199
  conf_path = create_conf_file('valid.conf', conf)
188
200
  assert File.exist?(conf_path)
189
201
 
190
- assert_log_matches(create_cmdline(conf_path), "fluentd worker is now running", 'worker="0"')
202
+ assert_log_matches(create_cmdline(conf_path), "fluentd worker is now running", 'worker=0')
191
203
  end
192
204
  end
193
205
 
@@ -220,14 +232,14 @@ CONF
220
232
  conf_path = create_conf_file('existing_root_dir.conf', @conf)
221
233
  assert Dir.exist?(@root_path)
222
234
 
223
- assert_log_matches(create_cmdline(conf_path), "fluentd worker is now running", 'worker="0"')
235
+ assert_log_matches(create_cmdline(conf_path), "fluentd worker is now running", 'worker=0')
224
236
  end
225
237
 
226
238
  test 'creates the specified root directory if missing' do
227
239
  conf_path = create_conf_file('missing_root_dir.conf', @conf)
228
240
  assert_false Dir.exist?(@root_path)
229
241
 
230
- assert_log_matches(create_cmdline(conf_path), "fluentd worker is now running", 'worker="0"')
242
+ assert_log_matches(create_cmdline(conf_path), "fluentd worker is now running", 'worker=0')
231
243
  assert Dir.exist?(@root_path)
232
244
  end
233
245
 
@@ -244,6 +256,135 @@ CONF
244
256
  end
245
257
  end
246
258
 
259
+ sub_test_case 'configured to route log events to plugins' do
260
+ setup do
261
+ @basic_conf = <<CONF
262
+ <source>
263
+ @type dummy
264
+ @id dummy
265
+ tag dummy
266
+ dummy {"message": "yay!"}
267
+ </source>
268
+ <match dummy>
269
+ @type null
270
+ @id blackhole
271
+ </match>
272
+ CONF
273
+ end
274
+
275
+ test 'by top level <match fluent.*> section' do
276
+ conf = @basic_conf + <<CONF
277
+ <match fluent.**>
278
+ @type stdout
279
+ </match>
280
+ CONF
281
+ conf_path = create_conf_file('logevent_1.conf', conf)
282
+ assert_log_matches(
283
+ create_cmdline(conf_path),
284
+ "fluentd worker is now running",
285
+ 'fluent.info: {"worker":0,"message":"fluentd worker is now running worker=0"}',
286
+ patterns_not_match: ['[warn]: some tags for log events are not defined (to be ignored) tags=["fluent.trace", "fluent.debug"]'],
287
+ )
288
+ end
289
+
290
+ test 'by top level <match> section with warning for missing log levels (and warnings for each log event records)' do
291
+ conf = @basic_conf + <<CONF
292
+ <match fluent.warn fluent.error fluent.fatal>
293
+ @type stdout
294
+ </match>
295
+ CONF
296
+ conf_path = create_conf_file('logevent_2.conf', conf)
297
+ assert_log_matches(
298
+ create_cmdline(conf_path),
299
+ "fluentd worker is now running",
300
+ '[warn]: match for some tags of log events are not defined (to be ignored) tags=["fluent.trace", "fluent.debug", "fluent.info"]',
301
+ '[warn]: #0 no patterns matched tag="fluent.info"',
302
+ )
303
+ end
304
+
305
+ test 'by <label @FLUENT_LOG> section' do
306
+ conf = @basic_conf + <<CONF
307
+ <label @FLUENT_LOG>
308
+ <match **>
309
+ @type stdout
310
+ </match>
311
+ </label>
312
+ CONF
313
+ conf_path = create_conf_file('logevent_3.conf', conf)
314
+ assert_log_matches(
315
+ create_cmdline(conf_path),
316
+ "fluentd worker is now running",
317
+ 'fluent.info: {"worker":0,"message":"fluentd worker is now running worker=0"}',
318
+ patterns_not_match: ['[warn]: some tags for log events are not defined (to be ignored)'],
319
+ )
320
+ end
321
+
322
+ test 'by <label> section with warning for missing log levels' do
323
+ conf = @basic_conf + <<CONF
324
+ <label @FLUENT_LOG>
325
+ <match fluent.{trace,debug}>
326
+ @type null
327
+ </match>
328
+ <match fluent.warn fluent.error>
329
+ @type stdout
330
+ </match>
331
+ </label>
332
+ CONF
333
+ conf_path = create_conf_file('logevent_4.conf', conf)
334
+ assert_log_matches(
335
+ create_cmdline(conf_path),
336
+ "fluentd worker is now running",
337
+ '[warn]: match for some tags of log events are not defined (to be ignored) tags=["fluent.info", "fluent.fatal"]',
338
+ patterns_not_match: ['[warn]: no patterns matched tag="fluent.info"'],
339
+ )
340
+ end
341
+ end
342
+
343
+ sub_test_case 'configured to suppress configration dump' do
344
+ setup do
345
+ @basic_conf = <<CONF
346
+ <source>
347
+ @type dummy
348
+ @id dummy
349
+ @label @dummydata
350
+ tag dummy
351
+ dummy {"message": "yay!"}
352
+ </source>
353
+ <label @dummydata>
354
+ <match dummy>
355
+ @type null
356
+ @id blackhole
357
+ </match>
358
+ </label>
359
+ CONF
360
+ end
361
+
362
+ test 'configured by system config' do
363
+ conf = <<SYSTEM + @basic_conf
364
+ <system>
365
+ suppress_config_dump
366
+ </system>
367
+ SYSTEM
368
+ conf_path = create_conf_file('suppress_conf_dump_1.conf', conf)
369
+ assert_log_matches(create_cmdline(conf_path), "fluentd worker is now running", patterns_not_match: ["tag dummy"])
370
+ end
371
+
372
+ test 'configured by command line option' do
373
+ conf_path = create_conf_file('suppress_conf_dump_2.conf', @basic_conf)
374
+ assert_log_matches(create_cmdline(conf_path, '--suppress-config-dump'), "fluentd worker is now running", patterns_not_match: ["tag dummy"])
375
+ end
376
+
377
+ test 'configured as false by system config, but overridden as true by command line option' do
378
+ conf = <<SYSTEM + @basic_conf
379
+ <system>
380
+ suppress_config_dump false
381
+ </system>
382
+ SYSTEM
383
+ conf_path = create_conf_file('suppress_conf_dump_3.conf', conf)
384
+ assert_log_matches(create_cmdline(conf_path, '--suppress-config-dump'), "fluentd worker is now running", patterns_not_match: ["tag dummy"])
385
+ end
386
+ end
387
+
247
388
  sub_test_case 'configuration with wrong plugin type' do
248
389
  test 'failed to start' do
249
390
  conf = <<CONF
@@ -345,4 +486,133 @@ CONF
345
486
  )
346
487
  end
347
488
  end
489
+
490
+ sub_test_case 'configured to run 2 workers' do
491
+ setup do
492
+ @root_path = File.join(TMP_DIR, "rootpath")
493
+ FileUtils.rm_rf(@root_path)
494
+ FileUtils.mkdir_p(@root_path)
495
+ end
496
+
497
+ test 'success to start the number of workers specified in configuration' do
498
+ conf = <<CONF
499
+ <system>
500
+ workers 2
501
+ root_dir #{@root_path}
502
+ </system>
503
+ <source>
504
+ @type dummy
505
+ @id dummy
506
+ @label @dummydata
507
+ tag dummy
508
+ dummy {"message": "yay!"}
509
+ </source>
510
+ <label @dummydata>
511
+ <match dummy>
512
+ @type null
513
+ @id blackhole
514
+ </match>
515
+ </label>
516
+ CONF
517
+ conf_path = create_conf_file('workers1.conf', conf)
518
+ assert Dir.exist?(@root_path)
519
+
520
+ assert_log_matches(
521
+ create_cmdline(conf_path),
522
+ "#0 fluentd worker is now running worker=0",
523
+ "#1 fluentd worker is now running worker=1"
524
+ )
525
+ end
526
+
527
+ test 'success to start the number of workers specified by command line option' do
528
+ conf = <<CONF
529
+ <system>
530
+ root_dir #{@root_path}
531
+ </system>
532
+ <source>
533
+ @type dummy
534
+ @id dummy
535
+ @label @dummydata
536
+ tag dummy
537
+ dummy {"message": "yay!"}
538
+ </source>
539
+ <label @dummydata>
540
+ <match dummy>
541
+ @type null
542
+ @id blackhole
543
+ </match>
544
+ </label>
545
+ CONF
546
+ conf_path = create_conf_file('workers2.conf', conf)
547
+ assert_log_matches(
548
+ create_cmdline(conf_path, '--workers', '2'),
549
+ "#0 fluentd worker is now running worker=0",
550
+ "#1 fluentd worker is now running worker=1"
551
+ )
552
+ end
553
+
554
+ test 'failed to start workers when configured plugins do not support multi worker configuration' do
555
+ script = "require 'fluent/plugin/input'\n"
556
+ script << "module Fluent::Plugin\n"
557
+ script << " class SingleInput < Input\n"
558
+ script << " Fluent::Plugin.register_input('single', self)\n"
559
+ script << " def multi_workers_ready?\n"
560
+ script << " false\n"
561
+ script << " end\n"
562
+ script << " end\n"
563
+ script << "end\n"
564
+ plugin_path = create_plugin_file('in_single.rb', script)
565
+
566
+ conf = <<CONF
567
+ <system>
568
+ workers 2
569
+ </system>
570
+ <source>
571
+ @type single
572
+ @id single
573
+ @label @dummydata
574
+ </source>
575
+ <label @dummydata>
576
+ <match dummy>
577
+ @type null
578
+ @id blackhole
579
+ </match>
580
+ </label>
581
+ CONF
582
+ conf_path = create_conf_file('workers_invalid1.conf', conf)
583
+ assert_fluentd_fails_to_start(
584
+ create_cmdline(conf_path, "-p", File.dirname(plugin_path)),
585
+ "Plugin 'single' does not support multi workers configuration (Fluent::Plugin::SingleInput)",
586
+ )
587
+ end
588
+
589
+ test 'failed to start workers when file buffer is configured in non-workers way' do
590
+ conf = <<CONF
591
+ <system>
592
+ workers 2
593
+ </system>
594
+ <source>
595
+ @type single
596
+ @id single
597
+ @label @dummydata
598
+ </source>
599
+ <label @dummydata>
600
+ <match dummy>
601
+ @type null
602
+ @id blackhole
603
+ <buffer>
604
+ @type file
605
+ path #{File.join(@root_path, "buf", "file.*.log")}
606
+ </buffer>
607
+ </match>
608
+ </label>
609
+ CONF
610
+ conf_path = create_conf_file('workers_invalid2.conf', conf)
611
+ assert_fluentd_fails_to_start(
612
+ create_cmdline(conf_path),
613
+ "[blackhole] file buffer with multi workers should be configured to use directory 'path', or system root_dir and plugin id",
614
+ "config error file=\"#{conf_path}\" error_class=Fluent::ConfigError error=\"Plugin 'file' does not support multi workers configuration (Fluent::Plugin::FileBuffer)\"",
615
+ )
616
+ end
617
+ end
348
618
  end