fluentd 1.7.4-x64-mingw32 → 1.8.0-x64-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 (101) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -1
  3. data/.travis.yml +4 -0
  4. data/CHANGELOG.md +70 -0
  5. data/MAINTAINERS.md +1 -0
  6. data/example/out_forward_sd.conf +17 -0
  7. data/example/sd.yaml +8 -0
  8. data/fluentd.gemspec +1 -1
  9. data/lib/fluent/agent.rb +3 -1
  10. data/lib/fluent/command/cat.rb +1 -2
  11. data/lib/fluent/command/fluentd.rb +16 -8
  12. data/lib/fluent/compat/call_super_mixin.rb +9 -0
  13. data/lib/fluent/compat/exec_util.rb +1 -1
  14. data/lib/fluent/config/configure_proxy.rb +4 -4
  15. data/lib/fluent/config/element.rb +28 -15
  16. data/lib/fluent/config/error.rb +6 -0
  17. data/lib/fluent/config/literal_parser.rb +24 -2
  18. data/lib/fluent/config/section.rb +43 -6
  19. data/lib/fluent/config/types.rb +98 -26
  20. data/lib/fluent/configurable.rb +2 -2
  21. data/lib/fluent/counter/base_socket.rb +2 -4
  22. data/lib/fluent/engine.rb +41 -122
  23. data/lib/fluent/event.rb +5 -7
  24. data/lib/fluent/fluent_log_event_router.rb +141 -0
  25. data/lib/fluent/msgpack_factory.rb +19 -2
  26. data/lib/fluent/plugin.rb +10 -1
  27. data/lib/fluent/plugin/base.rb +2 -2
  28. data/lib/fluent/plugin/buf_file.rb +11 -7
  29. data/lib/fluent/plugin/buf_file_single.rb +8 -5
  30. data/lib/fluent/plugin/buffer/chunk.rb +1 -1
  31. data/lib/fluent/plugin/buffer/file_chunk.rb +4 -6
  32. data/lib/fluent/plugin/buffer/file_single_chunk.rb +3 -5
  33. data/lib/fluent/plugin/formatter_csv.rb +23 -1
  34. data/lib/fluent/plugin/formatter_stdout.rb +1 -1
  35. data/lib/fluent/plugin/in_forward.rb +1 -1
  36. data/lib/fluent/plugin/in_monitor_agent.rb +4 -2
  37. data/lib/fluent/plugin/in_tail.rb +6 -0
  38. data/lib/fluent/plugin/in_unix.rb +1 -1
  39. data/lib/fluent/plugin/out_forward.rb +77 -28
  40. data/lib/fluent/plugin/out_forward/ack_handler.rb +1 -1
  41. data/lib/fluent/plugin/out_forward/load_balancer.rb +5 -2
  42. data/lib/fluent/plugin/out_stream.rb +1 -1
  43. data/lib/fluent/plugin/output.rb +11 -3
  44. data/lib/fluent/plugin/parser.rb +1 -0
  45. data/lib/fluent/plugin/sd_file.rb +155 -0
  46. data/lib/fluent/plugin/sd_static.rb +58 -0
  47. data/lib/fluent/plugin/service_discovery.rb +80 -0
  48. data/lib/fluent/plugin_helper.rb +1 -0
  49. data/lib/fluent/plugin_helper/child_process.rb +3 -3
  50. data/lib/fluent/plugin_helper/compat_parameters.rb +11 -1
  51. data/lib/fluent/plugin_helper/extract.rb +1 -1
  52. data/lib/fluent/plugin_helper/inject.rb +1 -1
  53. data/lib/fluent/plugin_helper/record_accessor.rb +10 -19
  54. data/lib/fluent/plugin_helper/server.rb +8 -4
  55. data/lib/fluent/plugin_helper/service_discovery.rb +80 -0
  56. data/lib/fluent/plugin_helper/service_discovery/manager.rb +132 -0
  57. data/lib/fluent/plugin_helper/service_discovery/round_robin_balancer.rb +43 -0
  58. data/lib/fluent/plugin_id.rb +7 -0
  59. data/lib/fluent/root_agent.rb +7 -9
  60. data/lib/fluent/supervisor.rb +192 -211
  61. data/lib/fluent/system_config.rb +26 -52
  62. data/lib/fluent/test/driver/base_owned.rb +15 -2
  63. data/lib/fluent/time.rb +8 -6
  64. data/lib/fluent/version.rb +1 -1
  65. data/test/command/test_fluentd.rb +12 -7
  66. data/test/config/test_configurable.rb +154 -0
  67. data/test/config/test_element.rb +18 -0
  68. data/test/config/test_literal_parser.rb +4 -0
  69. data/test/config/test_system_config.rb +48 -91
  70. data/test/config/test_types.rb +293 -120
  71. data/test/counter/test_client.rb +8 -4
  72. data/test/plugin/data/sd_file/config +11 -0
  73. data/test/plugin/data/sd_file/config.json +17 -0
  74. data/test/plugin/data/sd_file/config.yaml +11 -0
  75. data/test/plugin/data/sd_file/config.yml +11 -0
  76. data/test/plugin/data/sd_file/invalid_config.yml +7 -0
  77. data/test/plugin/out_forward/test_handshake_protocol.rb +2 -2
  78. data/test/plugin/out_forward/test_load_balancer.rb +1 -1
  79. data/test/plugin/out_forward/test_socket_cache.rb +2 -2
  80. data/test/plugin/test_buf_file.rb +40 -0
  81. data/test/plugin/test_buf_file_single.rb +32 -0
  82. data/test/plugin/test_buffer_file_chunk.rb +0 -11
  83. data/test/plugin/test_buffer_file_single_chunk.rb +0 -10
  84. data/test/plugin/test_formatter_csv.rb +9 -0
  85. data/test/plugin/test_in_forward.rb +9 -9
  86. data/test/plugin/test_in_monitor_agent.rb +37 -10
  87. data/test/plugin/test_in_unix.rb +5 -5
  88. data/test/plugin/test_out_forward.rb +45 -1
  89. data/test/plugin/test_out_stdout.rb +36 -1
  90. data/test/plugin/test_out_stream.rb +3 -3
  91. data/test/plugin/test_output.rb +25 -1
  92. data/test/plugin/test_sd_file.rb +211 -0
  93. data/test/plugin_helper/service_discovery/test_manager.rb +93 -0
  94. data/test/plugin_helper/service_discovery/test_round_robin_balancer.rb +21 -0
  95. data/test/plugin_helper/test_server.rb +13 -0
  96. data/test/plugin_helper/test_service_discovery.rb +72 -0
  97. data/test/test_event.rb +15 -15
  98. data/test/test_fluent_log_event_router.rb +99 -0
  99. data/test/test_logger_initializer.rb +26 -0
  100. data/test/test_supervisor.rb +30 -59
  101. metadata +43 -6
@@ -0,0 +1,43 @@
1
+ #
2
+ # Fluentd
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ module Fluent
18
+ module PluginHelper
19
+ module ServiceDiscovery
20
+ class RoundRobinBalancer
21
+ def initialize
22
+ @services = []
23
+ @mutex = Mutex.new
24
+ end
25
+
26
+ def rebalance(services)
27
+ @mutex.synchronize do
28
+ @services = services
29
+ end
30
+ end
31
+
32
+ def select_service
33
+ s = @mutex.synchronize do
34
+ s = @services.shift
35
+ @services.push(s)
36
+ s
37
+ end
38
+ yield(s)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -23,6 +23,7 @@ module Fluent
23
23
  def initialize
24
24
  super
25
25
  @_plugin_root_dir = nil
26
+ @id = nil
26
27
  end
27
28
 
28
29
  def configure(conf)
@@ -76,5 +77,11 @@ module Fluent
76
77
  @_plugin_root_dir = dir.freeze
77
78
  dir
78
79
  end
80
+
81
+ def stop
82
+ @@configured_ids.delete(@id)
83
+
84
+ super
85
+ end
79
86
  end
80
87
  end
@@ -89,7 +89,7 @@ module Fluent
89
89
  raise Fluent::ConfigError, "worker id #{target_worker_id} specified by <worker> directive is not allowed. Available worker id is between 0 and #{(Fluent::Engine.system_config.workers - 1)}"
90
90
  end
91
91
  available_worker_ids.delete(target_worker_id) if available_worker_ids.include?(target_worker_id)
92
- if used_worker_ids.include?(target_worker_id) && !Fluent::Engine.dry_run_mode
92
+ if used_worker_ids.include?(target_worker_id)
93
93
  raise Fluent::ConfigError, "specified worker_id<#{worker_id}> collisions is detected on <worker> directive. Available worker id(s): #{available_worker_ids}"
94
94
  end
95
95
  used_worker_ids << target_worker_id
@@ -100,9 +100,6 @@ module Fluent
100
100
  end
101
101
  end
102
102
 
103
- # On dry_run mode, all worker sections have to be configured on supervisor (recognized as worker_id = 0).
104
- target_worker_ids = [0] if Fluent::Engine.dry_run_mode
105
-
106
103
  unless target_worker_ids.empty?
107
104
  e.set_target_worker_ids(target_worker_ids.uniq)
108
105
  end
@@ -113,9 +110,6 @@ module Fluent
113
110
  raise Fluent::ConfigError, "worker id #{target_worker_id} specified by <worker> directive is not allowed. Available worker id is between 0 and #{(Fluent::Engine.system_config.workers - 1)}"
114
111
  end
115
112
 
116
- ## On dry_run mode, all worker sections have to be configured on supervisor (recognized as worker_id = 0).
117
- target_worker_id = 0 if Fluent::Engine.dry_run_mode
118
-
119
113
  e.elements.each do |elem|
120
114
  unless ['source', 'match', 'filter', 'label'].include?(elem.name)
121
115
  raise Fluent::ConfigError, "<worker> section cannot have <#{elem.name}> directive"
@@ -132,7 +126,9 @@ module Fluent
132
126
  # initialize <label> elements before configuring all plugins to avoid 'label not found' in input, filter and output.
133
127
  label_configs = {}
134
128
  conf.elements(name: 'label').each { |e|
135
- next if e.for_another_worker?
129
+ if !Fluent::Engine.supervisor_mode && e.for_another_worker?
130
+ next
131
+ end
136
132
  name = e.arg
137
133
  raise ConfigError, "Missing symbol argument on <label> directive" if name.empty?
138
134
 
@@ -154,7 +150,9 @@ module Fluent
154
150
  log.info :worker0, "'--without-source' is applied. Ignore <source> sections"
155
151
  else
156
152
  conf.elements(name: 'source').each { |e|
157
- next if e.for_another_worker?
153
+ if !Fluent::Engine.supervisor_mode && e.for_another_worker?
154
+ next
155
+ end
158
156
  type = e['@type']
159
157
  raise ConfigError, "Missing '@type' parameter on <source> directive" unless type
160
158
  add_source(type, e)
@@ -25,6 +25,7 @@ require 'fluent/log'
25
25
  require 'fluent/plugin'
26
26
  require 'fluent/rpc'
27
27
  require 'fluent/system_config'
28
+ require 'fluent/msgpack_factory'
28
29
  require 'serverengine'
29
30
 
30
31
  if Fluent.windows?
@@ -41,7 +42,6 @@ end
41
42
  module Fluent
42
43
  module ServerModule
43
44
  def before_run
44
- @start_time = Time.now
45
45
  @rpc_server = nil
46
46
  @counter = nil
47
47
 
@@ -121,7 +121,7 @@ module Fluent
121
121
  }
122
122
 
123
123
  @rpc_server.mount_proc('/api/config.getDump') { |req, res|
124
- $log.debug "fluentd RPC got /api/config.dump request"
124
+ $log.debug "fluentd RPC got /api/config.getDump request"
125
125
  $log.info "get dump in-memory config via HTTP"
126
126
  res.body = supervisor_get_dump_config_handler
127
127
  [nil, nil, res]
@@ -182,9 +182,9 @@ module Fluent
182
182
  if log = config[:logger_initializer]
183
183
  # Creating new thread due to mutex can't lock
184
184
  # in main thread during trap context
185
- Thread.new {
185
+ Thread.new do
186
186
  log.reopen!
187
- }.run
187
+ end
188
188
  end
189
189
 
190
190
  if config[:worker_pid]
@@ -210,11 +210,11 @@ module Fluent
210
210
  end
211
211
 
212
212
  def supervisor_dump_config_handler
213
- $log.info config[:fluentd_conf].to_s
213
+ $log.info config[:fluentd_conf]
214
214
  end
215
215
 
216
216
  def supervisor_get_dump_config_handler
217
- {conf: config[:fluentd_conf].to_s}
217
+ {conf: config[:fluentd_conf]}
218
218
  end
219
219
  end
220
220
 
@@ -234,7 +234,6 @@ module Fluent
234
234
 
235
235
  class Supervisor
236
236
  def self.load_config(path, params = {})
237
-
238
237
  pre_loadtime = 0
239
238
  pre_loadtime = params['pre_loadtime'].to_i if params['pre_loadtime']
240
239
  pre_config_mtime = nil
@@ -246,23 +245,6 @@ module Fluent
246
245
  return params['pre_conf']
247
246
  end
248
247
 
249
- config_fname = File.basename(path)
250
- config_basedir = File.dirname(path)
251
- # Assume fluent.conf encoding is UTF-8
252
- config_data = File.open(path, "r:#{params['conf_encoding']}:utf-8") {|f| f.read }
253
- inline_config = params['inline_config']
254
- if inline_config == '-'
255
- config_data << "\n" << STDIN.read
256
- elsif inline_config
257
- config_data << "\n" << inline_config.gsub("\\n","\n")
258
- end
259
- fluentd_conf = Fluent::Config.parse(config_data, config_fname, config_basedir, params['use_v1_config'])
260
- system_config = SystemConfig.create(fluentd_conf)
261
-
262
- # these params must NOT be configured via system config here.
263
- # these may be overridden by command line params.
264
- workers = params['workers']
265
- root_dir = params['root_dir']
266
248
  log_level = params['log_level']
267
249
  suppress_repeated_stacktrace = params['suppress_repeated_stacktrace']
268
250
 
@@ -271,9 +253,6 @@ module Fluent
271
253
  chgroup = params['chgroup']
272
254
  log_rotate_age = params['log_rotate_age']
273
255
  log_rotate_size = params['log_rotate_size']
274
- rpc_endpoint = system_config.rpc_endpoint
275
- enable_get_dump = system_config.enable_get_dump
276
- counter_server = system_config.counter_server
277
256
 
278
257
  log_opts = {suppress_repeated_stacktrace: suppress_repeated_stacktrace}
279
258
  logger_initializer = Supervisor::LoggerInitializer.new(
@@ -290,43 +269,41 @@ module Fluent
290
269
  # ServerEngine's "daemonize" option is boolean, and path of pid file is brought by "pid_path"
291
270
  pid_path = params['daemonize']
292
271
  daemonize = !!params['daemonize']
293
- main_cmd = params['main_cmd']
294
- signame = params['signame']
295
272
 
296
273
  se_config = {
297
- worker_type: 'spawn',
298
- workers: workers,
299
- log_stdin: false,
300
- log_stdout: false,
301
- log_stderr: false,
302
- enable_heartbeat: true,
303
- auto_heartbeat: false,
304
- unrecoverable_exit_codes: [2],
305
- stop_immediately_at_unrecoverable_exit: true,
306
- root_dir: root_dir,
307
- logger: logger,
308
- log: logger.out,
309
- log_path: log_path,
310
- log_level: log_level,
311
- logger_initializer: logger_initializer,
312
- chuser: chuser,
313
- chgroup: chgroup,
314
- chumask: 0,
315
- suppress_repeated_stacktrace: suppress_repeated_stacktrace,
316
- daemonize: daemonize,
317
- rpc_endpoint: rpc_endpoint,
318
- counter_server: counter_server,
319
- enable_get_dump: enable_get_dump,
320
- windows_daemon_cmdline: [ServerEngine.ruby_bin_path,
321
- File.join(File.dirname(__FILE__), 'daemon.rb'),
322
- ServerModule.name,
323
- WorkerModule.name,
324
- path,
325
- JSON.dump(params)],
326
- command_sender: command_sender,
327
- fluentd_conf: fluentd_conf,
328
- main_cmd: main_cmd,
329
- signame: signame,
274
+ worker_type: 'spawn',
275
+ workers: params['workers'],
276
+ log_stdin: false,
277
+ log_stdout: false,
278
+ log_stderr: false,
279
+ enable_heartbeat: true,
280
+ auto_heartbeat: false,
281
+ unrecoverable_exit_codes: [2],
282
+ stop_immediately_at_unrecoverable_exit: true,
283
+ root_dir: params['root_dir'],
284
+ logger: logger,
285
+ log: logger.out,
286
+ log_path: log_path,
287
+ log_level: log_level,
288
+ logger_initializer: logger_initializer,
289
+ chuser: chuser,
290
+ chgroup: chgroup,
291
+ chumask: 0,
292
+ suppress_repeated_stacktrace: suppress_repeated_stacktrace,
293
+ daemonize: daemonize,
294
+ rpc_endpoint: params['rpc_endpoint'],
295
+ counter_server: params['counter_server'],
296
+ enable_get_dump: params['enable_get_dump'],
297
+ windows_daemon_cmdline: [ServerEngine.ruby_bin_path,
298
+ File.join(File.dirname(__FILE__), 'daemon.rb'),
299
+ ServerModule.name,
300
+ WorkerModule.name,
301
+ path,
302
+ JSON.dump(params)],
303
+ command_sender: command_sender,
304
+ fluentd_conf: params['fluentd_conf'],
305
+ main_cmd: params['main_cmd'],
306
+ signame: params['signame'],
330
307
  }
331
308
  if daemonize
332
309
  se_config[:pid_path] = pid_path
@@ -339,7 +316,7 @@ module Fluent
339
316
  pre_params['pre_conf'] = nil
340
317
  params['pre_conf'][:windows_daemon_cmdline][5] = JSON.dump(pre_params)
341
318
 
342
- return se_config
319
+ se_config
343
320
  end
344
321
 
345
322
  class LoggerInitializer
@@ -364,6 +341,10 @@ module Fluent
364
341
  @opts[:worker_id] = worker_id
365
342
 
366
343
  if @path && @path != "-"
344
+ unless File.exist?(@path)
345
+ FileUtils.mkdir_p(File.dirname(@path))
346
+ end
347
+
367
348
  @logdev = if @log_rotate_age || @log_rotate_size
368
349
  Fluent::LogDeviceIO.new(Fluent.windows? ?
369
350
  worker_id_suffixed_path(worker_id, @path) : @path,
@@ -400,9 +381,9 @@ module Fluent
400
381
  self
401
382
  end
402
383
 
403
- def apply_options(opts)
404
- $log.format = opts[:format] if opts[:format]
405
- $log.time_format = opts[:time_format] if opts[:time_format]
384
+ def apply_options(format: nil, time_format: nil)
385
+ $log.format = format if format
386
+ $log.time_format = time_format if time_format
406
387
  end
407
388
 
408
389
  def level=(level)
@@ -427,6 +408,7 @@ module Fluent
427
408
  suppress_repeated_stacktrace: true,
428
409
  without_source: nil,
429
410
  use_v1_config: true,
411
+ strict_config_value: nil,
430
412
  supervise: true,
431
413
  standalone_worker: false,
432
414
  signame: nil,
@@ -444,72 +426,75 @@ module Fluent
444
426
 
445
427
  def initialize(opt)
446
428
  @daemonize = opt[:daemonize]
447
- @supervise = opt[:supervise]
448
429
  @standalone_worker= opt[:standalone_worker]
449
430
  @config_path = opt[:config_path]
450
431
  @inline_config = opt[:inline_config]
451
432
  @use_v1_config = opt[:use_v1_config]
452
433
  @conf_encoding = opt[:conf_encoding]
453
434
  @log_path = opt[:log_path]
454
- @dry_run = opt[:dry_run]
455
435
  @show_plugin_config = opt[:show_plugin_config]
456
436
  @libs = opt[:libs]
457
437
  @plugin_dirs = opt[:plugin_dirs]
458
438
  @chgroup = opt[:chgroup]
459
439
  @chuser = opt[:chuser]
460
- @rpc_server = nil
461
- @process_name = nil
462
440
 
463
- @workers = opt[:workers]
464
- @root_dir = opt[:root_dir]
465
- @log_level = opt[:log_level]
466
441
  @log_rotate_age = opt[:log_rotate_age]
467
442
  @log_rotate_size = opt[:log_rotate_size]
468
- @suppress_interval = opt[:suppress_interval]
469
- @suppress_config_dump = opt[:suppress_config_dump]
470
- @log_event_verbose = opt[:log_event_verbose]
471
- @without_source = opt[:without_source]
472
443
  @signame = opt[:signame]
473
444
 
474
- @suppress_repeated_stacktrace = opt[:suppress_repeated_stacktrace]
475
- log_opts = {suppress_repeated_stacktrace: @suppress_repeated_stacktrace}
445
+ @cl_opt = opt
446
+ @conf = nil
447
+
448
+ log_opts = { suppress_repeated_stacktrace: opt[:suppress_repeated_stacktrace] }
476
449
  @log = LoggerInitializer.new(
477
- @log_path, @log_level, @chuser, @chgroup, log_opts,
450
+ @log_path, opt[:log_level], @chuser, @chgroup, log_opts,
478
451
  log_rotate_age: @log_rotate_age,
479
452
  log_rotate_size: @log_rotate_size
480
453
  )
481
454
  @finished = false
482
455
  end
483
456
 
484
- def run_supervisor
485
- @log.init(:supervisor, 0)
486
- show_plugin_config if @show_plugin_config
487
- read_config
488
- set_system_config
489
- @log.apply_options(format: @system_config.log.format, time_format: @system_config.log.time_format)
490
-
491
- $log.info :supervisor, "parsing config file is succeeded", path: @config_path
457
+ def run_supervisor(dry_run: false)
458
+ if dry_run
459
+ $log.info "starting fluentd-#{Fluent::VERSION} as dry run mode", ruby: RUBY_VERSION
460
+ end
492
461
 
493
- if @workers < 1
494
- raise Fluent::ConfigError, "invalid number of workers (must be > 0):#{@workers}"
462
+ if @system_config.workers < 1
463
+ raise Fluent::ConfigError, "invalid number of workers (must be > 0):#{@system_config.workers}"
495
464
  end
496
465
 
497
- if @root_dir
498
- if File.exist?(@root_dir)
499
- unless Dir.exist?(@root_dir)
500
- raise Fluent::InvalidRootDirectory, "non directory entry exists:#{@root_dir}"
466
+ root_dir = @system_config.root_dir
467
+ if root_dir
468
+ if File.exist?(root_dir)
469
+ unless Dir.exist?(root_dir)
470
+ raise Fluent::InvalidRootDirectory, "non directory entry exists:#{root_dir}"
501
471
  end
502
472
  else
503
473
  begin
504
- FileUtils.mkdir_p(@root_dir)
474
+ FileUtils.mkdir_p(root_dir)
505
475
  rescue => e
506
- raise Fluent::InvalidRootDirectory, "failed to create root directory:#{@root_dir}, #{e.inspect}"
476
+ raise Fluent::InvalidRootDirectory, "failed to create root directory:#{root_dir}, #{e.inspect}"
507
477
  end
508
478
  end
509
479
  end
510
480
 
511
- dry_run_cmd if @dry_run
512
- supervise
481
+ begin
482
+ ServerEngine::Privilege.change(@chuser, @chgroup)
483
+ MessagePackFactory.init
484
+ Fluent::Engine.init(@system_config, supervisor_mode: true)
485
+ Fluent::Engine.run_configure(@conf, dry_run: dry_run)
486
+ rescue Fluent::ConfigError => e
487
+ $log.error 'config error', file: @config_path, error: e
488
+ $log.debug_backtrace
489
+ exit!(1)
490
+ end
491
+
492
+ if dry_run
493
+ $log.info 'finsihed dry run mode'
494
+ exit 0
495
+ else
496
+ supervise
497
+ end
513
498
  end
514
499
 
515
500
  def options
@@ -518,7 +503,7 @@ module Fluent
518
503
  'pid_file' => @daemonize,
519
504
  'plugin_dirs' => @plugin_dirs,
520
505
  'log_path' => @log_path,
521
- 'root_dir' => @root_dir,
506
+ 'root_dir' => @system_config.root_dir,
522
507
  }
523
508
  end
524
509
 
@@ -528,22 +513,11 @@ module Fluent
528
513
  rescue Exception
529
514
  # ignore LoadError and others (related with signals): it may raise these errors in Windows
530
515
  end
531
- worker_id = ENV['SERVERENGINE_WORKER_ID'].to_i
532
- process_type = case
533
- when @standalone_worker then :standalone
534
- when worker_id == 0 then :worker0
535
- else :workers
536
- end
537
- @log.init(process_type, worker_id)
538
- show_plugin_config if @show_plugin_config
539
- read_config
540
- set_system_config
541
- @log.apply_options(format: @system_config.log.format, time_format: @system_config.log.time_format)
542
516
 
543
- Process.setproctitle("worker:#{@process_name}") if @process_name
517
+ Process.setproctitle("worker:#{@system_config.process_name}") if @process_name
544
518
 
545
- if @standalone_worker && @workers != 1
546
- raise Fluent::ConfigError, "invalid number of workers (must be 1 or unspecified) with --no-supervisor: #{@workers}"
519
+ if @standalone_worker && @system_config.workers != 1
520
+ raise Fluent::ConfigError, "invalid number of workers (must be 1 or unspecified) with --no-supervisor: #{@system_config.workers}"
547
521
  end
548
522
 
549
523
  install_main_process_signal_handlers
@@ -553,15 +527,64 @@ module Fluent
553
527
 
554
528
  main_process do
555
529
  create_socket_manager if @standalone_worker
556
- change_privilege if @standalone_worker
557
- init_engine
558
- run_configure
559
- run_engine
530
+ ServerEngine::Privilege.change(@chuser, @chgroup) if @standalone_worker
531
+ MessagePackFactory.init
532
+ Fluent::Engine.init(@system_config)
533
+ Fluent::Engine.run_configure(@conf)
534
+ Fluent::Engine.run
560
535
  self.class.cleanup_resources if @standalone_worker
561
536
  exit 0
562
537
  end
563
538
  end
564
539
 
540
+ def configure(supervisor: false)
541
+ if supervisor
542
+ @log.init(:supervisor, 0)
543
+ else
544
+ worker_id = ENV['SERVERENGINE_WORKER_ID'].to_i
545
+ process_type = case
546
+ when @standalone_worker then :standalone
547
+ when worker_id == 0 then :worker0
548
+ else :workers
549
+ end
550
+ @log.init(process_type, worker_id)
551
+ end
552
+
553
+ if @show_plugin_config
554
+ show_plugin_config
555
+ end
556
+
557
+ if @inline_config == '-'
558
+ @inline_config = STDIN.read
559
+ end
560
+
561
+ @conf = read_config
562
+ @system_config = build_system_config(@conf)
563
+
564
+ @log.level = @system_config.log_level
565
+ @log.apply_options(format: @system_config.log.format, time_format: @system_config.log.time_format)
566
+
567
+ $log.info :supervisor, 'parsing config file is succeeded', path: @config_path
568
+
569
+ @libs.each do |lib|
570
+ require lib
571
+ end
572
+
573
+ @plugin_dirs.each do |dir|
574
+ if Dir.exist?(dir)
575
+ dir = File.expand_path(dir)
576
+ Fluent::Plugin.add_plugin_dir(dir)
577
+ end
578
+ end
579
+
580
+ if supervisor
581
+ # plugins / configuration dumps
582
+ Gem::Specification.find_all.select { |x| x.name =~ /^fluent(d|-(plugin|mixin)-.*)$/ }.each do |spec|
583
+ $log.info("gem '#{spec.name}' version '#{spec.version}'")
584
+ end
585
+ end
586
+ end
587
+
565
588
  private
566
589
 
567
590
  def create_socket_manager
@@ -570,32 +593,6 @@ module Fluent
570
593
  ENV['SERVERENGINE_SOCKETMANAGER_PATH'] = socket_manager_path.to_s
571
594
  end
572
595
 
573
- def dry_run_cmd
574
- $log.info "starting fluentd-#{Fluent::VERSION} as dry run mode", ruby: RUBY_VERSION
575
- @system_config.suppress_config_dump = true
576
- dry_run
577
- exit 0
578
- rescue => e
579
- $log.error "dry run failed: #{e}"
580
- exit 1
581
- end
582
-
583
- ## Set Engine's dry_run_mode true to override all target_id of worker sections
584
- def dry_run
585
- begin
586
- Fluent::Engine.dry_run_mode = true
587
- change_privilege
588
- init_engine
589
- run_configure
590
- rescue Fluent::ConfigError => e
591
- $log.error "config error", file: @config_path, error: e
592
- $log.debug_backtrace
593
- exit!(1)
594
- ensure
595
- Fluent::Engine.dry_run_mode = false
596
- end
597
- end
598
-
599
596
  def show_plugin_config
600
597
  name, type = @show_plugin_config.split(":") # input:tail
601
598
  $log.info "show_plugin_config option is deprecated. Use fluent-plugin-config-format --format=txt #{name} #{type}"
@@ -603,10 +600,7 @@ module Fluent
603
600
  end
604
601
 
605
602
  def supervise
606
- # Make dumpable conf, which is set corresponding_proxies for all elements in all worker sections
607
- dry_run
608
-
609
- Process.setproctitle("supervisor:#{@process_name}") if @process_name
603
+ Process.setproctitle("supervisor:#{@system_config.process_name}") if @system_config.process_name
610
604
  $log.info "starting fluentd-#{Fluent::VERSION}", pid: Process.pid, ruby: RUBY_VERSION
611
605
 
612
606
  rubyopt = ENV["RUBYOPT"]
@@ -618,24 +612,28 @@ module Fluent
618
612
 
619
613
  $log.info "spawn command to main: ", cmdline: fluentd_spawn_cmd
620
614
 
621
- params = {}
622
- params['main_cmd'] = fluentd_spawn_cmd
623
- params['daemonize'] = @daemonize
624
- params['inline_config'] = @inline_config
625
- params['log_path'] = @log_path
626
- params['log_rotate_age'] = @log_rotate_age
627
- params['log_rotate_size'] = @log_rotate_size
628
- params['chuser'] = @chuser
629
- params['chgroup'] = @chgroup
630
- params['use_v1_config'] = @use_v1_config
631
- params['conf_encoding'] = @conf_encoding
632
-
633
- # system config parameters
634
- params['workers'] = @workers
635
- params['root_dir'] = @root_dir
636
- params['log_level'] = @log_level
637
- params['suppress_repeated_stacktrace'] = @suppress_repeated_stacktrace
638
- params['signame'] = @signame
615
+ params = {
616
+ 'main_cmd' => fluentd_spawn_cmd,
617
+ 'daemonize' => @daemonize,
618
+ 'inline_config' => @inline_config,
619
+ 'log_path' => @log_path,
620
+ 'log_rotate_age' => @log_rotate_age,
621
+ 'log_rotate_size' => @log_rotate_size,
622
+ 'chuser' => @chuser,
623
+ 'chgroup' => @chgroup,
624
+ 'use_v1_config' => @use_v1_config,
625
+ 'conf_encoding' => @conf_encoding,
626
+ 'signame' => @signame,
627
+ 'fluentd_conf' => @conf.to_s,
628
+
629
+ 'workers' => @system_config.workers,
630
+ 'root_dir' => @system_config.root_dir,
631
+ 'log_level' => @system_config.log_level,
632
+ 'suppress_repeated_stacktrace' => @system_config.suppress_repeated_stacktrace,
633
+ 'rpc_endpoint' => @system_config.rpc_endpoint,
634
+ 'enable_get_dump' => @system_config.enable_get_dump,
635
+ 'counter_server' => @system_config.counter_server,
636
+ }
639
637
 
640
638
  se = ServerEngine.create(ServerModule, WorkerModule){
641
639
  Fluent::Supervisor.load_config(@config_path, params)
@@ -702,7 +700,7 @@ module Fluent
702
700
  def flush_buffer
703
701
  # Creating new thread due to mutex can't lock
704
702
  # in main thread during trap context
705
- Thread.new {
703
+ Thread.new do
706
704
  begin
707
705
  $log.debug "fluentd main process get SIGUSR1"
708
706
  $log.info "force flushing buffered events"
@@ -712,7 +710,7 @@ module Fluent
712
710
  rescue Exception => e
713
711
  $log.warn "flushing thread error: #{e}"
714
712
  end
715
- }.run
713
+ end
716
714
  end
717
715
 
718
716
  def logging_with_console_output
@@ -720,18 +718,18 @@ module Fluent
720
718
  unless @log.stdout?
721
719
  logger = ServerEngine::DaemonLogger.new(STDOUT)
722
720
  log = Fluent::Log.new(logger)
723
- log.level = @log_level
721
+ log.level = @system_config.log_level
724
722
  console = log.enable_debug
725
723
  yield console
726
724
  end
727
725
  end
728
726
 
729
727
  def main_process(&block)
730
- if @process_name
731
- if @workers > 1
732
- Process.setproctitle("worker:#{@process_name}#{ENV['SERVERENGINE_WORKER_ID']}")
728
+ if @system_config.process_name
729
+ if @system_config.workers > 1
730
+ Process.setproctitle("worker:#{@system_config.process_name}#{ENV['SERVERENGINE_WORKER_ID']}")
733
731
  else
734
- Process.setproctitle("worker:#{@process_name}")
732
+ Process.setproctitle("worker:#{@system_config.process_name}")
735
733
  end
736
734
  end
737
735
 
@@ -772,48 +770,31 @@ module Fluent
772
770
  end
773
771
 
774
772
  def read_config
775
- @config_fname = File.basename(@config_path)
776
- @config_basedir = File.dirname(@config_path)
777
- @config_data = File.open(@config_path, "r:#{@conf_encoding}:utf-8") {|f| f.read }
778
- if @inline_config == '-'
779
- @config_data << "\n" << STDIN.read
780
- elsif @inline_config
781
- @config_data << "\n" << @inline_config.gsub("\\n","\n")
773
+ config_fname = File.basename(@config_path)
774
+ config_basedir = File.dirname(@config_path)
775
+ config_data = File.open(@config_path, "r:#{@conf_encoding}:utf-8") {|f| f.read }
776
+ if @inline_config
777
+ config_data << "\n" << @inline_config.gsub("\\n", "\n")
782
778
  end
783
- @conf = Fluent::Config.parse(@config_data, @config_fname, @config_basedir, @use_v1_config)
784
- end
785
-
786
- def set_system_config
787
- @system_config = SystemConfig.create(@conf) # @conf is set in read_config
788
- @system_config.attach(self)
789
- @system_config.apply(self)
790
- end
791
-
792
- def change_privilege
793
- ServerEngine::Privilege.change(@chuser, @chgroup)
794
- end
795
-
796
- def init_engine
797
- Fluent::Engine.init(@system_config)
798
-
799
- @libs.each {|lib|
800
- require lib
801
- }
779
+ Fluent::Config.parse(config_data, config_fname, config_basedir, @use_v1_config)
780
+ end
781
+
782
+ def build_system_config(conf)
783
+ system_config = SystemConfig.create(conf, @cl_opt[:strict_config_value])
784
+ opt = {}
785
+ Fluent::SystemConfig::SYSTEM_CONFIG_PARAMETERS.each do |param|
786
+ if @cl_opt.key?(param) && !@cl_opt[param].nil?
787
+ if param == :log_level && @cl_opt[:log_level] == Fluent::Log::LEVEL_INFO
788
+ # info level can't be specified via command line option.
789
+ # log_level is info here, it is default value and <system>'s log_level should be applied if exists.
790
+ next
791
+ end
802
792
 
803
- @plugin_dirs.each {|dir|
804
- if Dir.exist?(dir)
805
- dir = File.expand_path(dir)
806
- Fluent::Engine.add_plugin_dir(dir)
793
+ opt[param] = @cl_opt[param]
807
794
  end
808
- }
809
- end
810
-
811
- def run_configure
812
- Fluent::Engine.run_configure(@conf)
813
- end
814
-
815
- def run_engine
816
- Fluent::Engine.run
795
+ end
796
+ system_config.overwrite_variables(opt)
797
+ system_config
817
798
  end
818
799
  end
819
800
  end