fluentd 1.12.0-x86-mingw32 → 1.13.0-x86-mingw32

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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/.deepsource.toml +13 -0
  3. data/.github/ISSUE_TEMPLATE/config.yml +2 -2
  4. data/.github/workflows/linux-test.yaml +36 -0
  5. data/.github/workflows/macos-test.yaml +30 -0
  6. data/.github/workflows/windows-test.yaml +46 -0
  7. data/.gitlab-ci.yml +41 -19
  8. data/CHANGELOG.md +164 -2
  9. data/CONTRIBUTING.md +2 -2
  10. data/MAINTAINERS.md +5 -2
  11. data/README.md +7 -4
  12. data/example/counter.conf +1 -1
  13. data/fluentd.gemspec +5 -4
  14. data/lib/fluent/command/bundler_injection.rb +1 -1
  15. data/lib/fluent/command/ca_generate.rb +6 -3
  16. data/lib/fluent/command/cat.rb +19 -4
  17. data/lib/fluent/command/fluentd.rb +5 -2
  18. data/lib/fluent/command/plugin_config_formatter.rb +16 -1
  19. data/lib/fluent/command/plugin_generator.rb +31 -1
  20. data/lib/fluent/compat/parser.rb +2 -2
  21. data/lib/fluent/config/section.rb +2 -2
  22. data/lib/fluent/config/types.rb +2 -2
  23. data/lib/fluent/event.rb +3 -13
  24. data/lib/fluent/load.rb +0 -1
  25. data/lib/fluent/log.rb +1 -0
  26. data/lib/fluent/plugin/file_wrapper.rb +49 -4
  27. data/lib/fluent/plugin/formatter_ltsv.rb +2 -2
  28. data/lib/fluent/plugin/in_http.rb +11 -1
  29. data/lib/fluent/plugin/in_monitor_agent.rb +1 -1
  30. data/lib/fluent/plugin/in_tail.rb +141 -41
  31. data/lib/fluent/plugin/in_tail/position_file.rb +15 -1
  32. data/lib/fluent/plugin/out_copy.rb +18 -5
  33. data/lib/fluent/plugin/out_exec_filter.rb +3 -3
  34. data/lib/fluent/plugin/out_forward.rb +74 -58
  35. data/lib/fluent/plugin/out_http.rb +9 -2
  36. data/lib/fluent/plugin/output.rb +11 -9
  37. data/lib/fluent/plugin/parser_csv.rb +2 -2
  38. data/lib/fluent/plugin/parser_syslog.rb +2 -2
  39. data/lib/fluent/plugin/storage_local.rb +4 -4
  40. data/lib/fluent/plugin_helper/server.rb +4 -2
  41. data/lib/fluent/plugin_helper/service_discovery.rb +39 -1
  42. data/lib/fluent/plugin_helper/service_discovery/manager.rb +11 -5
  43. data/lib/fluent/plugin_helper/socket_option.rb +2 -2
  44. data/lib/fluent/supervisor.rb +28 -5
  45. data/lib/fluent/system_config.rb +16 -1
  46. data/lib/fluent/time.rb +57 -1
  47. data/lib/fluent/version.rb +1 -1
  48. data/templates/new_gem/fluent-plugin.gemspec.erb +3 -3
  49. data/templates/plugin_config_formatter/param.md-table.erb +10 -0
  50. data/test/command/test_cat.rb +96 -0
  51. data/test/command/test_fluentd.rb +38 -0
  52. data/test/command/test_plugin_config_formatter.rb +67 -0
  53. data/test/config/test_configurable.rb +1 -1
  54. data/test/config/test_system_config.rb +46 -0
  55. data/test/plugin/in_tail/test_io_handler.rb +4 -4
  56. data/test/plugin/in_tail/test_position_file.rb +59 -5
  57. data/test/plugin/test_file_wrapper.rb +115 -0
  58. data/test/plugin/test_in_exec.rb +1 -1
  59. data/test/plugin/test_in_http.rb +15 -0
  60. data/test/plugin/test_in_tail.rb +309 -26
  61. data/test/plugin/test_out_copy.rb +87 -0
  62. data/test/plugin/test_out_forward.rb +104 -11
  63. data/test/plugin/test_out_http.rb +20 -1
  64. data/test/plugin/test_output.rb +15 -3
  65. data/test/plugin/test_output_as_buffered_backup.rb +2 -0
  66. data/test/plugin/test_parser_csv.rb +14 -0
  67. data/test/plugin/test_parser_syslog.rb +14 -0
  68. data/test/plugin/test_sd_file.rb +1 -1
  69. data/test/plugin_helper/service_discovery/test_manager.rb +1 -1
  70. data/test/plugin_helper/test_child_process.rb +5 -2
  71. data/test/plugin_helper/test_http_server_helper.rb +4 -2
  72. data/test/plugin_helper/test_server.rb +26 -7
  73. data/test/plugin_helper/test_service_discovery.rb +74 -14
  74. data/test/test_config.rb +2 -1
  75. data/test/test_event.rb +16 -0
  76. data/test/test_formatter.rb +30 -0
  77. data/test/test_output.rb +2 -2
  78. data/test/test_supervisor.rb +66 -0
  79. data/test/test_time_parser.rb +109 -0
  80. metadata +58 -31
  81. data/.travis.yml +0 -77
  82. data/appveyor.yml +0 -31
@@ -159,9 +159,9 @@ module Fluent::Plugin
159
159
  @added_prefix_string = @add_prefix + '.'
160
160
  end
161
161
 
162
- @respawns = if @child_respawn.nil? or @child_respawn == 'none' or @child_respawn == '0'
162
+ @respawns = if @child_respawn.nil? || (@child_respawn == 'none') || (@child_respawn == '0')
163
163
  0
164
- elsif @child_respawn == 'inf' or @child_respawn == '-1'
164
+ elsif (@child_respawn == 'inf') || (@child_respawn == '-1')
165
165
  -1
166
166
  elsif @child_respawn =~ /^\d+$/
167
167
  @child_respawn.to_i
@@ -251,7 +251,7 @@ module Fluent::Plugin
251
251
 
252
252
  def tag_remove_prefix(tag)
253
253
  if @remove_prefix
254
- if (tag[0, @removed_length] == @removed_prefix_string and tag.length > @removed_length) or tag == @removed_prefix_string
254
+ if ((tag[0, @removed_length] == @removed_prefix_string) && (tag.length > @removed_length)) || (tag == @removed_prefix_string)
255
255
  tag = tag[@removed_length..-1] || ''
256
256
  end
257
257
  end
@@ -166,6 +166,7 @@ module Fluent::Plugin
166
166
 
167
167
  @usock = nil
168
168
  @keep_alive_watcher_interval = 5 # TODO
169
+ @suspend_flush = false
169
170
  end
170
171
 
171
172
  def configure(conf)
@@ -226,31 +227,14 @@ module Fluent::Plugin
226
227
  socket_cache: socket_cache,
227
228
  )
228
229
 
229
- configs = []
230
-
231
- # rewrite for using server as sd_static
232
- conf.elements(name: 'server').each do |s|
233
- s.name = 'service'
234
- end
235
-
236
- unless conf.elements(name: 'service').empty?
237
- # To copy `services` element only
238
- new_elem = Fluent::Config::Element.new('static_service_discovery', {}, {}, conf.elements(name: 'service'))
239
- configs << { type: :static, conf: new_elem }
240
- end
241
-
242
- conf.elements(name: 'service_discovery').each_with_index do |c, i|
243
- configs << { type: @service_discovery[i][:@type], conf: c }
244
- end
245
-
246
- service_discovery_create_manager(
230
+ service_discovery_configure(
247
231
  :out_forward_service_discovery_watcher,
248
- configurations: configs,
232
+ static_default_service_directive: 'server',
249
233
  load_balancer: LoadBalancer.new(log),
250
234
  custom_build_method: method(:build_node),
251
235
  )
252
236
 
253
- discovery_manager.services.each do |server|
237
+ service_discovery_services.each do |server|
254
238
  # it's only for test
255
239
  @nodes << server
256
240
  unless @heartbeat_type == :none
@@ -272,7 +256,7 @@ module Fluent::Plugin
272
256
  end
273
257
  end
274
258
 
275
- if discovery_manager.services.empty?
259
+ if service_discovery_services.empty?
276
260
  raise Fluent::ConfigError, "forward output plugin requires at least one node is required. Add <server> or <service_discovery>"
277
261
  end
278
262
 
@@ -291,30 +275,33 @@ module Fluent::Plugin
291
275
  @require_ack_response
292
276
  end
293
277
 
278
+ def overwrite_delayed_commit_timeout
279
+ # Output#start sets @delayed_commit_timeout by @buffer_config.delayed_commit_timeout
280
+ # But it should be overwritten by ack_response_timeout to rollback chunks after timeout
281
+ if @delayed_commit_timeout != @ack_response_timeout
282
+ log.info "delayed_commit_timeout is overwritten by ack_response_timeout"
283
+ @delayed_commit_timeout = @ack_response_timeout + 2 # minimum ack_reader IO.select interval is 1s
284
+ end
285
+ end
286
+
294
287
  def start
295
288
  super
296
289
 
297
290
  unless @heartbeat_type == :none
298
291
  if @heartbeat_type == :udp
299
- @usock = socket_create_udp(discovery_manager.services.first.host, discovery_manager.services.first.port, nonblock: true)
292
+ @usock = socket_create_udp(service_discovery_services.first.host, service_discovery_services.first.port, nonblock: true)
300
293
  server_create_udp(:out_forward_heartbeat_receiver, 0, socket: @usock, max_bytes: @read_length, &method(:on_udp_heatbeat_response_recv))
301
294
  end
302
295
  timer_execute(:out_forward_heartbeat_request, @heartbeat_interval, &method(:on_heartbeat_timer))
303
296
  end
304
297
 
305
298
  if @require_ack_response
306
- # Output#start sets @delayed_commit_timeout by @buffer_config.delayed_commit_timeout
307
- # But it should be overwritten by ack_response_timeout to rollback chunks after timeout
308
- if @delayed_commit_timeout != @ack_response_timeout
309
- log.info "delayed_commit_timeout is overwritten by ack_response_timeout"
310
- @delayed_commit_timeout = @ack_response_timeout + 2 # minimum ack_reader IO.select interval is 1s
311
- end
312
-
299
+ overwrite_delayed_commit_timeout
313
300
  thread_create(:out_forward_receiving_ack, &method(:ack_reader))
314
301
  end
315
302
 
316
303
  if @verify_connection_at_startup
317
- discovery_manager.services.each do |node|
304
+ service_discovery_services.each do |node|
318
305
  begin
319
306
  node.verify_connection
320
307
  rescue StandardError => e
@@ -346,11 +333,31 @@ module Fluent::Plugin
346
333
  end
347
334
  end
348
335
 
336
+ def before_shutdown
337
+ super
338
+ @suspend_flush = true
339
+ end
340
+
341
+ def after_shutdown
342
+ last_ack if @require_ack_response
343
+ super
344
+ end
345
+
346
+ def try_flush
347
+ return if @require_ack_response && @suspend_flush
348
+ super
349
+ end
350
+
351
+ def last_ack
352
+ overwrite_delayed_commit_timeout
353
+ ack_check(ack_select_interval)
354
+ end
355
+
349
356
  def write(chunk)
350
357
  return if chunk.empty?
351
358
  tag = chunk.metadata.tag
352
359
 
353
- discovery_manager.select_service { |node| node.send_data(tag, chunk) }
360
+ service_discovery_select_service { |node| node.send_data(tag, chunk) }
354
361
  end
355
362
 
356
363
  def try_write(chunk)
@@ -360,7 +367,8 @@ module Fluent::Plugin
360
367
  return
361
368
  end
362
369
  tag = chunk.metadata.tag
363
- discovery_manager.select_service { |node| node.send_data(tag, chunk) }
370
+ service_discovery_select_service { |node| node.send_data(tag, chunk) }
371
+ last_ack if @require_ack_response && @suspend_flush
364
372
  end
365
373
 
366
374
  def create_transfer_socket(host, port, hostname, &block)
@@ -409,7 +417,7 @@ module Fluent::Plugin
409
417
 
410
418
  def statistics
411
419
  stats = super
412
- services = discovery_manager.services
420
+ services = service_discovery_services
413
421
  healthy_nodes_count = 0
414
422
  registed_nodes_count = services.size
415
423
  services.each do |s|
@@ -446,7 +454,7 @@ module Fluent::Plugin
446
454
 
447
455
  def on_heartbeat_timer
448
456
  need_rebuild = false
449
- discovery_manager.services.each do |n|
457
+ service_discovery_services.each do |n|
450
458
  begin
451
459
  log.trace "sending heartbeat", host: n.host, port: n.port, heartbeat_type: @heartbeat_type
452
460
  n.usock = @usock if @usock
@@ -461,16 +469,16 @@ module Fluent::Plugin
461
469
  end
462
470
 
463
471
  if need_rebuild
464
- discovery_manager.rebalance
472
+ service_discovery_rebalance
465
473
  end
466
474
  end
467
475
 
468
476
  def on_udp_heatbeat_response_recv(data, sock)
469
477
  sockaddr = Socket.pack_sockaddr_in(sock.remote_port, sock.remote_host)
470
- if node = discovery_manager.services.find { |n| n.sockaddr == sockaddr }
478
+ if node = service_discovery_services.find { |n| n.sockaddr == sockaddr }
471
479
  # log.trace "heartbeat arrived", name: node.name, host: node.host, port: node.port
472
480
  if node.heartbeat
473
- discovery_manager.rebalance
481
+ service_discovery_rebalance
474
482
  end
475
483
  else
476
484
  log.warn("Unknown heartbeat response received from #{sock.remote_host}:#{sock.remote_port}. It may service out")
@@ -481,31 +489,39 @@ module Fluent::Plugin
481
489
  @connection_manager.purge_obsolete_socks
482
490
  end
483
491
 
492
+ def ack_select_interval
493
+ if @delayed_commit_timeout > 3
494
+ 1
495
+ else
496
+ @delayed_commit_timeout / 3.0
497
+ end
498
+ end
499
+
484
500
  def ack_reader
485
- select_interval = if @delayed_commit_timeout > 3
486
- 1
487
- else
488
- @delayed_commit_timeout / 3.0
489
- end
501
+ select_interval = ack_select_interval
490
502
 
491
503
  while thread_current_running?
492
- @ack_handler.collect_response(select_interval) do |chunk_id, node, sock, result|
493
- @connection_manager.close(sock)
494
-
495
- case result
496
- when AckHandler::Result::SUCCESS
497
- commit_write(chunk_id)
498
- when AckHandler::Result::FAILED
499
- node.disable!
500
- rollback_write(chunk_id, update_retry: false)
501
- when AckHandler::Result::CHUNKID_UNMATCHED
502
- rollback_write(chunk_id, update_retry: false)
503
- else
504
- log.warn("BUG: invalid status #{result} #{chunk_id}")
504
+ ack_check(select_interval)
505
+ end
506
+ end
505
507
 
506
- if chunk_id
507
- rollback_write(chunk_id, update_retry: false)
508
- end
508
+ def ack_check(select_interval)
509
+ @ack_handler.collect_response(select_interval) do |chunk_id, node, sock, result|
510
+ @connection_manager.close(sock)
511
+
512
+ case result
513
+ when AckHandler::Result::SUCCESS
514
+ commit_write(chunk_id)
515
+ when AckHandler::Result::FAILED
516
+ node.disable!
517
+ rollback_write(chunk_id, update_retry: false)
518
+ when AckHandler::Result::CHUNKID_UNMATCHED
519
+ rollback_write(chunk_id, update_retry: false)
520
+ else
521
+ log.warn("BUG: invalid status #{result} #{chunk_id}")
522
+
523
+ if chunk_id
524
+ rollback_write(chunk_id, update_retry: false)
509
525
  end
510
526
  end
511
527
  end
@@ -51,6 +51,8 @@ module Fluent::Plugin
51
51
  config_param :json_array, :bool, default: false
52
52
  desc 'Additional headers for HTTP request'
53
53
  config_param :headers, :hash, default: nil
54
+ desc 'Additional placeholder based headers for HTTP request'
55
+ config_param :headers_from_placeholders, :hash, default: nil
54
56
 
55
57
  desc 'The connection open timeout in seconds'
56
58
  config_param :open_timeout, :integer, default: nil
@@ -213,12 +215,17 @@ module Fluent::Plugin
213
215
  URI.parse(endpoint)
214
216
  end
215
217
 
216
- def set_headers(req)
218
+ def set_headers(req, chunk)
217
219
  if @headers
218
220
  @headers.each do |k, v|
219
221
  req[k] = v
220
222
  end
221
223
  end
224
+ if @headers_from_placeholders
225
+ @headers_from_placeholders.each do |k, v|
226
+ req[k] = extract_placeholders(v, chunk)
227
+ end
228
+ end
222
229
  req['Content-Type'] = @content_type
223
230
  end
224
231
 
@@ -232,7 +239,7 @@ module Fluent::Plugin
232
239
  if @auth
233
240
  req.basic_auth(@auth.username, @auth.password)
234
241
  end
235
- set_headers(req)
242
+ set_headers(req, chunk)
236
243
  req.body = @json_array ? "[#{chunk.read.chop}]" : chunk.read
237
244
  req
238
245
  end
@@ -754,7 +754,17 @@ module Fluent
754
754
  log.warn "tag placeholder '#{$1}' not replaced. tag:#{metadata.tag}, template:#{str}"
755
755
  end
756
756
  end
757
- # ${a_chunk_key}, ...
757
+
758
+ # First we replace ${chunk_id} with chunk.unique_id (hexlified).
759
+ rvalue = rvalue.sub(CHUNK_ID_PLACEHOLDER_PATTERN) {
760
+ if chunk_passed
761
+ dump_unique_id_hex(chunk.unique_id)
762
+ else
763
+ log.warn "${chunk_id} is not allowed in this plugin. Pass Chunk instead of metadata in extract_placeholders's 2nd argument"
764
+ end
765
+ }
766
+
767
+ # Then, replace other ${chunk_key}s.
758
768
  if !@chunk_keys.empty? && metadata.variables
759
769
  hash = {'${tag}' => '${tag}'} # not to erase this wrongly
760
770
  @chunk_keys.each do |key|
@@ -769,14 +779,6 @@ module Fluent
769
779
  end
770
780
  end
771
781
 
772
- rvalue = rvalue.sub(CHUNK_ID_PLACEHOLDER_PATTERN) {
773
- if chunk_passed
774
- dump_unique_id_hex(chunk.unique_id)
775
- else
776
- log.warn "${chunk_id} is not allowed in this plugin. Pass Chunk instead of metadata in extract_placeholders's 2nd argument"
777
- end
778
- }
779
-
780
782
  if rvalue =~ CHUNK_KEY_PLACEHOLDER_PATTERN
781
783
  log.warn "chunk key placeholder '#{$1}' not replaced. template:#{str}"
782
784
  end
@@ -28,13 +28,13 @@ module Fluent
28
28
  desc 'The delimiter character (or string) of CSV values'
29
29
  config_param :delimiter, :string, default: ','
30
30
  desc 'The parser type used to parse CSV line'
31
- config_param :parser_type, :enum, list: [:normal, :fast], default: :normal
31
+ config_param :parser_engine, :enum, list: [:normal, :fast], default: :normal, alias: :parser_type
32
32
 
33
33
  def configure(conf)
34
34
  super
35
35
 
36
36
 
37
- if @parser_type == :fast
37
+ if @parser_engine == :fast
38
38
  @quote_char = '"'
39
39
  @escape_pattern = Regexp.compile(@quote_char * 2)
40
40
 
@@ -56,7 +56,7 @@ module Fluent
56
56
  desc 'Specify time format for event time for rfc5424 protocol'
57
57
  config_param :rfc5424_time_format, :string, default: "%Y-%m-%dT%H:%M:%S.%L%z"
58
58
  desc 'The parser type used to parse syslog message'
59
- config_param :parser_type, :enum, list: [:regexp, :string], default: :regexp
59
+ config_param :parser_engine, :enum, list: [:regexp, :string], default: :regexp, alias: :parser_type
60
60
  desc 'support colonless ident in string parser'
61
61
  config_param :support_colonless_ident, :bool, default: true
62
62
 
@@ -79,7 +79,7 @@ module Fluent
79
79
  def configure(conf)
80
80
  super
81
81
 
82
- @regexp_parser = @parser_type == :regexp
82
+ @regexp_parser = @parser_engine == :regexp
83
83
  @regexp = case @message_format
84
84
  when :rfc3164
85
85
  if @regexp_parser
@@ -87,7 +87,7 @@ module Fluent
87
87
  if File.exist?(@path)
88
88
  raise Fluent::ConfigError, "Plugin storage path '#{@path}' is not readable/writable" unless File.readable?(@path) && File.writable?(@path)
89
89
  begin
90
- data = open(@path, 'r:utf-8') { |io| io.read }
90
+ data = File.open(@path, 'r:utf-8') { |io| io.read }
91
91
  if data.empty?
92
92
  log.warn "detect empty plugin storage file during startup. Ignored: #{@path}"
93
93
  return
@@ -115,7 +115,7 @@ module Fluent
115
115
  return if @on_memory
116
116
  return unless File.exist?(@path)
117
117
  begin
118
- json_string = open(@path, 'r:utf-8'){ |io| io.read }
118
+ json_string = File.open(@path, 'r:utf-8'){ |io| io.read }
119
119
  json = Yajl::Parser.parse(json_string)
120
120
  unless json.is_a?(Hash)
121
121
  log.error "broken content for plugin storage (Hash required: ignored)", type: json.class
@@ -130,10 +130,10 @@ module Fluent
130
130
 
131
131
  def save
132
132
  return if @on_memory
133
- tmp_path = @path + '.tmp'
133
+ tmp_path = @path + '.tmp.' + Fluent::UniqueId.hex(Fluent::UniqueId.generate)
134
134
  begin
135
135
  json_string = Yajl::Encoder.encode(@store, pretty: @pretty_print)
136
- open(tmp_path, 'w:utf-8', @mode) { |io| io.write json_string; io.fsync }
136
+ File.open(tmp_path, 'w:utf-8', @mode) { |io| io.write json_string; io.fsync }
137
137
  File.rename(tmp_path, @path)
138
138
  rescue => e
139
139
  log.error "failed to save data for plugin storage to file", path: @path, tmp: tmp_path, error: e
@@ -709,11 +709,13 @@ module Fluent
709
709
  return true
710
710
  end
711
711
  rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::ECONNREFUSED, Errno::EHOSTUNREACH => e
712
- @log.trace "unexpected error before accepting TLS connection", error: e
712
+ @log.trace "unexpected error before accepting TLS connection",
713
+ host: @_handler_socket.peeraddr[3], port: @_handler_socket.peeraddr[1], error: e
713
714
  close rescue nil
714
715
  rescue OpenSSL::SSL::SSLError => e
715
716
  # Use same log level as on_readable
716
- @log.warn "unexpected error before accepting TLS connection by OpenSSL", error: e
717
+ @log.warn "unexpected error before accepting TLS connection by OpenSSL",
718
+ host: @_handler_socket.peeraddr[3], port: @_handler_socket.peeraddr[1], error: e
717
719
  close rescue nil
718
720
  end
719
721
 
@@ -22,10 +22,19 @@ module Fluent
22
22
  module ServiceDiscovery
23
23
  include Fluent::PluginHelper::Timer
24
24
 
25
+ # For the compatibility with older versions without `param_name: :service_discovery_configs`
26
+ attr_reader :service_discovery
27
+
25
28
  def self.included(mod)
26
29
  mod.include ServiceDiscoveryParams
27
30
  end
28
31
 
32
+ def configure(conf)
33
+ super
34
+ # For the compatibility with older versions without `param_name: :service_discovery_configs`
35
+ @service_discovery = @service_discovery_configs
36
+ end
37
+
29
38
  def start
30
39
  unless @discovery_manager
31
40
  log.warn('There is no discovery_manager. skip start them')
@@ -52,6 +61,35 @@ module Fluent
52
61
 
53
62
  private
54
63
 
64
+ # @param title [Symbol] the thread name. this value should be unique.
65
+ # @param static_default_service_directive [String] the directive name of each service when "static" service discovery is enabled in default
66
+ # @param load_balancer [Object] object which has two methods #rebalance and #select_service
67
+ # @param custom_build_method [Proc]
68
+ def service_discovery_configure(title, static_default_service_directive: nil, load_balancer: nil, custom_build_method: nil, interval: 3)
69
+ configs = @service_discovery_configs.map(&:corresponding_config_element)
70
+ if static_default_service_directive
71
+ configs.prepend Fluent::Config::Element.new(
72
+ 'service_discovery',
73
+ '',
74
+ {'@type' => 'static'},
75
+ @config.elements(name: static_default_service_directive.to_s).map{|e| Fluent::Config::Element.new('service', e.arg, e.dup, e.elements, e.unused) }
76
+ )
77
+ end
78
+ service_discovery_create_manager(title, configurations: configs, load_balancer: load_balancer, custom_build_method: custom_build_method, interval: interval)
79
+ end
80
+
81
+ def service_discovery_select_service(&block)
82
+ @discovery_manager.select_service(&block)
83
+ end
84
+
85
+ def service_discovery_services
86
+ @discovery_manager.services
87
+ end
88
+
89
+ def service_discovery_rebalance
90
+ @discovery_manager.rebalance
91
+ end
92
+
55
93
  # @param title [Symbol] the thread name. this value should be unique.
56
94
  # @param configurations [Hash] hash which must has discivery_service type and its configuration like `{ type: :static, conf: <Fluent::Config::Element> }`
57
95
  # @param load_balancer [Object] object which has two methods #rebalance and #select_service
@@ -78,7 +116,7 @@ module Fluent
78
116
  module ServiceDiscoveryParams
79
117
  include Fluent::Configurable
80
118
 
81
- config_section :service_discovery do
119
+ config_section :service_discovery, multi: true, param_name: :service_discovery_configs do
82
120
  config_param :@type, :string
83
121
  end
84
122
  end