fluentd 1.8.0.rc2 → 1.8.0.rc3

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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c70380cd4a9f0f78150f7332a5e484a9f9523786fabae5c1bda5761cf21617e
4
- data.tar.gz: 65e167aa06b31cc5aebce1e8d1bbb61d80e8e1ae9e1690dd58dc799f51683503
3
+ metadata.gz: 2f75be7f2480c2f0fbdddf1999dc3163b91f6bd75fb53b71ff3d7a0ee4f670af
4
+ data.tar.gz: 5089bdce54388f855748befd4234ceb945f4ef7c6aa0f2a4f1aeea21adb516da
5
5
  SHA512:
6
- metadata.gz: f19fccb4e6d84dec936215ef8388d650a5063f30e0456c9aae5f47d2d0f1b73b86f01c95fc7e3d30e939b3d72e4224fcc5c8c1d69f59a0db7fc64b239cd9f8a2
7
- data.tar.gz: dd4d743c7d1d73199c35458ba3cb09e1dd6dda5a49b2f30575d6696f573909b642b1e860687a2e6bec8575db14869cfa29039cb472eb75b00abfb944bf368e0a
6
+ metadata.gz: 6dfd02456cd7a47aaf483759b57075cc0b8c0bbe322a41c20cd6df7f9a163150af07a21201e8514b0ba097f50dc56ae7004c4116f2f4c2b5347eebde303a19a2
7
+ data.tar.gz: 1ec01c129c043f8fafee99360a3a625907cff7666f9a605093110b4b1cc57691e7fd1eba543e2003568a9aa48d714a853b2644e83d2823f5773f49615bc0d265
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: Bug Report
3
3
  about: Create a report to help us improve. If you have questions about Fluentd and plugins, please direct these to https://groups.google.com/forum/#!forum/fluentd
4
- labels: 'bug'
5
4
 
6
5
  ---
7
6
 
@@ -13,16 +13,23 @@
13
13
  https://github.com/fluent/fluentd/pull/2660
14
14
  * Relax tzinfo dependency to accept v1
15
15
  https://github.com/fluent/fluentd/pull/2673
16
- * clean up internal classes / code
16
+ * log: Deprecate top-level match for capturing fluentd logs
17
+ https://github.com/fluent/fluentd/pull/2689
18
+ * clean up internal classes / methods / code
17
19
  https://github.com/fluent/fluentd/pull/2647
18
20
  https://github.com/fluent/fluentd/pull/2648
19
21
  https://github.com/fluent/fluentd/pull/2653
20
22
  https://github.com/fluent/fluentd/pull/2654
21
23
  https://github.com/fluent/fluentd/pull/2657
22
24
  https://github.com/fluent/fluentd/pull/2667
25
+ https://github.com/fluent/fluentd/pull/2674
26
+ https://github.com/fluent/fluentd/pull/2677
27
+ https://github.com/fluent/fluentd/pull/2680
23
28
 
24
29
  ### Bug fixes
25
30
 
31
+ * Fix dry-run mode
32
+ https://github.com/fluent/fluentd/pull/2651
26
33
  * suppress warning
27
34
  https://github.com/fluent/fluentd/pull/2652
28
35
  * suppress keyword argument warning for ruby2.7
@@ -31,6 +38,12 @@
31
38
  https://github.com/fluent/fluentd/pull/2666
32
39
  * time: Properly show class names in error message
33
40
  https://github.com/fluent/fluentd/pull/2671
41
+ * Fix a potential bug that ThreadError may occur on SIGUSR1
42
+ https://github.com/fluent/fluentd/pull/2678
43
+ * server helper: Ignore ECONNREFUSED in TLS accept to avoid fluentd restart
44
+ https://github.com/fluent/fluentd/pull/2695
45
+ * server helper: Fix IPv6 dual stack mode issue for tcp socket.
46
+ https://github.com/fluent/fluentd/pull/2697
34
47
 
35
48
 
36
49
  # v1.7
@@ -62,7 +62,9 @@ module Fluent
62
62
 
63
63
  # initialize <match> and <filter> elements
64
64
  conf.elements('filter', 'match').each { |e|
65
- next if e.for_another_worker?
65
+ if !Fluent::Engine.supervisor_mode && e.for_another_worker?
66
+ next
67
+ end
66
68
  pattern = e.arg.empty? ? '**' : e.arg
67
69
  type = e['@type']
68
70
  raise ConfigError, "Missing '@type' parameter on <#{e.name}> directive" unless type
@@ -309,7 +309,6 @@ end
309
309
 
310
310
  exit 0 if early_exit
311
311
 
312
- require 'fluent/supervisor'
313
312
  if opts[:supervise]
314
313
  if Fluent.windows?
315
314
  if opts[:log_path] && opts[:log_path] != "-"
@@ -321,11 +320,16 @@ if opts[:supervise]
321
320
  end
322
321
  end
323
322
  end
324
- Fluent::Supervisor.new(opts).run_supervisor
323
+
324
+ supervisor = Fluent::Supervisor.new(opts)
325
+ supervisor.configure(supervisor: true)
326
+ supervisor.run_supervisor(dry_run: opts[:dry_run])
325
327
  else
326
328
  if opts[:standalone_worker] && opts[:workers] && opts[:workers] > 1
327
329
  puts "Error: multi workers is not supported with --no-supervisor"
328
330
  exit 2
329
331
  end
330
- Fluent::Supervisor.new(opts).run_worker
332
+ worker = Fluent::Supervisor.new(opts)
333
+ worker.configure
334
+ worker.run_worker
331
335
  end
@@ -41,16 +41,16 @@ module Fluent
41
41
  @fluent_log_event_router = nil
42
42
  @system_config = SystemConfig.new
43
43
 
44
- @dry_run_mode = false
44
+ @supervisor_mode = false
45
45
  end
46
46
 
47
47
  MAINLOOP_SLEEP_INTERVAL = 0.3
48
48
 
49
- attr_reader :root_agent, :system_config
50
- attr_accessor :dry_run_mode
49
+ attr_reader :root_agent, :system_config, :supervisor_mode
51
50
 
52
- def init(system_config)
51
+ def init(system_config, supervisor_mode: false)
53
52
  @system_config = system_config
53
+ @supervisor_mode = supervisor_mode
54
54
 
55
55
  @suppress_config_dump = system_config.suppress_config_dump unless system_config.suppress_config_dump.nil?
56
56
  @without_source = system_config.without_source unless system_config.without_source.nil?
@@ -75,34 +75,29 @@ module Fluent
75
75
  end
76
76
  end
77
77
 
78
- def run_configure(conf)
78
+ def run_configure(conf, dry_run: false)
79
79
  configure(conf)
80
- conf.check_not_fetched { |key, e|
80
+ conf.check_not_fetched do |key, e|
81
81
  parent_name, plugin_name = e.unused_in
82
- if parent_name
83
- message = if plugin_name
84
- "section <#{e.name}> is not used in <#{parent_name}> of #{plugin_name} plugin"
85
- else
86
- "section <#{e.name}> is not used in <#{parent_name}>"
87
- end
88
- if e.for_every_workers?
89
- $log.warn :worker0, message
90
- elsif e.for_this_worker?
91
- $log.warn message
92
- end
93
- next
82
+ message = if parent_name && plugin_name
83
+ "section <#{e.name}> is not used in <#{parent_name}> of #{plugin_name} plugin"
84
+ elsif parent_name
85
+ "section <#{e.name}> is not used in <#{parent_name}>"
86
+ elsif e.name != 'system' && !(@without_source && e.name == 'source')
87
+ "parameter '#{key}' in #{e.to_s.strip} is not used."
88
+ else
89
+ nil
90
+ end
91
+ next if message.nil?
92
+
93
+ if dry_run && @supervisor_mode
94
+ $log.warn :supervisor, message
95
+ elsif e.for_every_workers?
96
+ $log.warn :worker0, message
97
+ elsif e.for_this_worker?
98
+ $log.warn message
94
99
  end
95
- unless e.name == 'system'
96
- unless @without_source && e.name == 'source'
97
- message = "parameter '#{key}' in #{e.to_s.strip} is not used."
98
- if e.for_every_workers?
99
- $log.warn :worker0, message
100
- elsif e.for_this_worker?
101
- $log.warn message
102
- end
103
- end
104
- end
105
- }
100
+ end
106
101
  end
107
102
 
108
103
  def configure(conf)
@@ -120,6 +115,7 @@ module Fluent
120
115
  end
121
116
 
122
117
  def add_plugin_dir(dir)
118
+ $log.warn('Deprecated method: this method is going to be deleted. Use Fluent::Plugin.add_plugin_dir')
123
119
  Plugin.add_plugin_dir(dir)
124
120
  end
125
121
 
@@ -181,6 +177,10 @@ module Fluent
181
177
  end
182
178
 
183
179
  def worker_id
180
+ if @supervisor_mode
181
+ return -1
182
+ end
183
+
184
184
  return @_worker_id if @_worker_id
185
185
  # if ENV doesn't have SERVERENGINE_WORKER_ID, it is a worker under --no-supervisor or in tests
186
186
  # so it's (almost) a single worker, worker_id=0
@@ -51,19 +51,23 @@ module Fluent
51
51
 
52
52
  unmatched_tags = Fluent::Log.event_tags.select { |t| !log_event_router.match?(t) }
53
53
  unless unmatched_tags.empty?
54
- $log.warn "match for some tags of log events are not defined (to be ignored)", tags: unmatched_tags
54
+ $log.warn "match for some tags of log events are not defined in @FLUENT_LOG label (to be ignored)", tags: unmatched_tags
55
55
  end
56
56
 
57
57
  rescue ArgumentError # ArgumentError "#{label_name} label not found"
58
58
  # use default event router if <label @FLUENT_LOG> is missing in configuration
59
59
  root_log_event_router = root_agent.event_router
60
-
61
- if Fluent::Log.event_tags.any? { |t| root_log_event_router.match?(t) }
60
+ event_tags = Fluent::Log.event_tags
61
+ if event_tags.any? { |t| root_log_event_router.match?(t) }
62
62
  log_event_router = root_log_event_router
63
63
 
64
- unmatched_tags = Fluent::Log.event_tags.select { |t| !log_event_router.match?(t) }
65
- unless unmatched_tags.empty?
66
- $log.warn "match for some tags of log events are not defined (to be ignored)", tags: unmatched_tags
64
+ unmatched_tags = event_tags.select { |t| !log_event_router.match?(t) }
65
+ if unmatched_tags.empty?
66
+ $log.warn "define <match fluent.**> to capture fluentd logs in top level is deprecated. Use <label @FLUENT_LOG> instead"
67
+ else
68
+ matched_sections = (event_tags - unmatched_tags).map { |tag| "<match #{tag}>" }.join(', ')
69
+ $log.warn "define #{matched_sections} to capture fluentd logs in top level is deprecated. Use <label @FLUENT_LOG> instead"
70
+ $log.warn "match for some tags of log events are not defined in top level (to be ignored)", tags: unmatched_tags
67
71
  end
68
72
  end
69
73
  end
@@ -52,7 +52,7 @@ module Fluent
52
52
  end
53
53
 
54
54
  def configure(conf)
55
- if conf.respond_to?(:for_this_worker?) && conf.for_this_worker?
55
+ if Fluent::Engine.supervisor_mode || (conf.respond_to?(:for_this_worker?) && conf.for_this_worker?)
56
56
  workers = if conf.target_worker_ids && !conf.target_worker_ids.empty?
57
57
  conf.target_worker_ids.size
58
58
  else
@@ -175,12 +175,8 @@ module Fluent
175
175
 
176
176
  def generate_chunk(metadata)
177
177
  # FileChunk generates real path with unique_id
178
- if @file_permission
179
- chunk = Fluent::Plugin::Buffer::FileChunk.new(metadata, @path, :create, perm: @file_permission, compress: @compress)
180
- else
181
- chunk = Fluent::Plugin::Buffer::FileChunk.new(metadata, @path, :create, compress: @compress)
182
- end
183
-
178
+ perm = @file_permission || system_config.file_permission
179
+ chunk = Fluent::Plugin::Buffer::FileChunk.new(metadata, @path, :create, perm: perm, compress: @compress)
184
180
  log.debug "Created new chunk", chunk_id: dump_unique_id_hex(chunk.unique_id), metadata: metadata
185
181
 
186
182
  return chunk
@@ -195,11 +195,8 @@ module Fluent
195
195
 
196
196
  def generate_chunk(metadata)
197
197
  # FileChunk generates real path with unique_id
198
- if @file_permission
199
- chunk = Fluent::Plugin::Buffer::FileSingleChunk.new(metadata, @path, :create, @key_in_path, perm: @file_permission, compress: @compress)
200
- else
201
- chunk = Fluent::Plugin::Buffer::FileSingleChunk.new(metadata, @path, :create, @key_in_path, compress: @compress)
202
- end
198
+ perm = @file_permission || system_config.file_permission
199
+ chunk = Fluent::Plugin::Buffer::FileSingleChunk.new(metadata, @path, :create, @key_in_path, perm: perm, compress: @compress)
203
200
 
204
201
  log.debug "Created new chunk", chunk_id: dump_unique_id_hex(chunk.unique_id), metadata: metadata
205
202
 
@@ -37,14 +37,13 @@ module Fluent
37
37
  # path_prefix: path prefix string, ended with '.'
38
38
  # path_suffix: path suffix string, like '.log' (or any other user specified)
39
39
 
40
- include SystemConfig::Mixin
41
-
42
40
  FILE_PERMISSION = 0644
43
41
 
44
42
  attr_reader :path, :permission
45
43
 
46
- def initialize(metadata, path, mode, perm: system_config.file_permission || FILE_PERMISSION, compress: :text)
44
+ def initialize(metadata, path, mode, perm: nil, compress: :text)
47
45
  super(metadata, compress: compress)
46
+ perm ||= FILE_PERMISSION
48
47
  @permission = perm.is_a?(String) ? perm.to_i(8) : perm
49
48
  @bytesize = @size = @adding_bytes = @adding_size = 0
50
49
  @meta = nil
@@ -29,8 +29,6 @@ module Fluent
29
29
  ## buffer chunk path : /path/to/directory/fsb.key.b513b61c9791029c2513b61c9791029c2.buf
30
30
  ## state: b/q - 'b'(on stage), 'q'(enqueued)
31
31
 
32
- include SystemConfig::Mixin
33
-
34
32
  PATH_EXT = 'buf'
35
33
  PATH_SUFFIX = ".#{PATH_EXT}"
36
34
  PATH_REGEXP = /\.(b|q)([0-9a-f]+)\.#{PATH_EXT}*\Z/n # //n switch means explicit 'ASCII-8BIT' pattern
@@ -38,9 +36,10 @@ module Fluent
38
36
 
39
37
  attr_reader :path, :permission
40
38
 
41
- def initialize(metadata, path, mode, key, perm: system_config.file_permission || FILE_PERMISSION, compress: :text)
39
+ def initialize(metadata, path, mode, key, perm: FILE_PERMISSION, compress: :text)
42
40
  super(metadata, compress: compress)
43
41
  @key = key
42
+ perm ||= FILE_PERMISSION
44
43
  @permission = perm.is_a?(String) ? perm.to_i(8) : perm
45
44
  @bytesize = @size = @adding_bytes = @adding_size = 0
46
45
 
@@ -355,7 +355,11 @@ module Fluent
355
355
  sock = if shared
356
356
  server_socket_manager_client.listen_tcp(bind, port)
357
357
  else
358
- TCPServer.new(bind, port) # this method call can create sockets for AF_INET6
358
+ # TCPServer.new doesn't set IPV6_V6ONLY flag, so use Addrinfo class instead.
359
+ # backlog will be set by the caller, we don't need to set backlog here
360
+ tsock = Addrinfo.tcp(bind, port).listen
361
+ tsock.autoclose = false
362
+ TCPServer.for_fd(tsock.fileno)
359
363
  end
360
364
  # close-on-exec is set by default in Ruby 2.0 or later (, and it's unavailable on Windows)
361
365
  sock.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK) # nonblock
@@ -722,7 +726,7 @@ module Fluent
722
726
 
723
727
  return true
724
728
  end
725
- rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ETIMEDOUT, OpenSSL::SSL::SSLError => e
729
+ rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::ECONNREFUSED, OpenSSL::SSL::SSLError => e
726
730
  @log.trace "unexpected error before accepting TLS connection", error: e
727
731
  close rescue nil
728
732
  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)
@@ -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]
@@ -400,9 +400,9 @@ module Fluent
400
400
  self
401
401
  end
402
402
 
403
- def apply_options(opts)
404
- $log.format = opts[:format] if opts[:format]
405
- $log.time_format = opts[:time_format] if opts[:time_format]
403
+ def apply_options(format: nil, time_format: nil)
404
+ $log.format = format if format
405
+ $log.time_format = time_format if time_format
406
406
  end
407
407
 
408
408
  def level=(level)
@@ -444,71 +444,75 @@ module Fluent
444
444
 
445
445
  def initialize(opt)
446
446
  @daemonize = opt[:daemonize]
447
- @supervise = opt[:supervise]
448
447
  @standalone_worker= opt[:standalone_worker]
449
448
  @config_path = opt[:config_path]
450
449
  @inline_config = opt[:inline_config]
451
450
  @use_v1_config = opt[:use_v1_config]
452
451
  @conf_encoding = opt[:conf_encoding]
453
452
  @log_path = opt[:log_path]
454
- @dry_run = opt[:dry_run]
455
453
  @show_plugin_config = opt[:show_plugin_config]
456
454
  @libs = opt[:libs]
457
455
  @plugin_dirs = opt[:plugin_dirs]
458
456
  @chgroup = opt[:chgroup]
459
457
  @chuser = opt[:chuser]
460
- @process_name = nil
461
458
 
462
- @workers = opt[:workers]
463
- @root_dir = opt[:root_dir]
464
- @log_level = opt[:log_level]
465
459
  @log_rotate_age = opt[:log_rotate_age]
466
460
  @log_rotate_size = opt[:log_rotate_size]
467
- @suppress_interval = opt[:suppress_interval]
468
- @suppress_config_dump = opt[:suppress_config_dump]
469
- @log_event_verbose = opt[:log_event_verbose]
470
- @without_source = opt[:without_source]
471
461
  @signame = opt[:signame]
472
462
 
473
- @suppress_repeated_stacktrace = opt[:suppress_repeated_stacktrace]
474
- log_opts = {suppress_repeated_stacktrace: @suppress_repeated_stacktrace}
463
+ @cl_opt = opt
464
+ @conf = nil
465
+
466
+ log_opts = { suppress_repeated_stacktrace: opt[:suppress_repeated_stacktrace] }
475
467
  @log = LoggerInitializer.new(
476
- @log_path, @log_level, @chuser, @chgroup, log_opts,
468
+ @log_path, opt[:log_level], @chuser, @chgroup, log_opts,
477
469
  log_rotate_age: @log_rotate_age,
478
470
  log_rotate_size: @log_rotate_size
479
471
  )
480
472
  @finished = false
481
473
  end
482
474
 
483
- def run_supervisor
484
- @log.init(:supervisor, 0)
485
- show_plugin_config if @show_plugin_config
486
- read_config
487
- set_system_config
488
- @log.apply_options(format: @system_config.log.format, time_format: @system_config.log.time_format)
489
-
490
- $log.info :supervisor, "parsing config file is succeeded", path: @config_path
475
+ def run_supervisor(dry_run: false)
476
+ if dry_run
477
+ $log.info "starting fluentd-#{Fluent::VERSION} as dry run mode", ruby: RUBY_VERSION
478
+ end
491
479
 
492
- if @workers < 1
493
- raise Fluent::ConfigError, "invalid number of workers (must be > 0):#{@workers}"
480
+ if @system_config.workers < 1
481
+ raise Fluent::ConfigError, "invalid number of workers (must be > 0):#{@system_config.workers}"
494
482
  end
495
483
 
496
- if @root_dir
497
- if File.exist?(@root_dir)
498
- unless Dir.exist?(@root_dir)
499
- raise Fluent::InvalidRootDirectory, "non directory entry exists:#{@root_dir}"
484
+ root_dir = @system_config.root_dir
485
+ if root_dir
486
+ if File.exist?(root_dir)
487
+ unless Dir.exist?(root_dir)
488
+ raise Fluent::InvalidRootDirectory, "non directory entry exists:#{root_dir}"
500
489
  end
501
490
  else
502
491
  begin
503
- FileUtils.mkdir_p(@root_dir)
492
+ FileUtils.mkdir_p(root_dir)
504
493
  rescue => e
505
- raise Fluent::InvalidRootDirectory, "failed to create root directory:#{@root_dir}, #{e.inspect}"
494
+ raise Fluent::InvalidRootDirectory, "failed to create root directory:#{root_dir}, #{e.inspect}"
506
495
  end
507
496
  end
508
497
  end
509
498
 
510
- dry_run_cmd if @dry_run
511
- supervise
499
+ begin
500
+ ServerEngine::Privilege.change(@chuser, @chgroup)
501
+ MessagePackFactory.init
502
+ Fluent::Engine.init(@system_config, supervisor_mode: true)
503
+ Fluent::Engine.run_configure(@conf, dry_run: dry_run)
504
+ rescue Fluent::ConfigError => e
505
+ $log.error 'config error', file: @config_path, error: e
506
+ $log.debug_backtrace
507
+ exit!(1)
508
+ end
509
+
510
+ if dry_run
511
+ $log.info 'finsihed dry run mode'
512
+ exit 0
513
+ else
514
+ supervise
515
+ end
512
516
  end
513
517
 
514
518
  def options
@@ -517,7 +521,7 @@ module Fluent
517
521
  'pid_file' => @daemonize,
518
522
  'plugin_dirs' => @plugin_dirs,
519
523
  'log_path' => @log_path,
520
- 'root_dir' => @root_dir,
524
+ 'root_dir' => @system_config.root_dir,
521
525
  }
522
526
  end
523
527
 
@@ -527,22 +531,11 @@ module Fluent
527
531
  rescue Exception
528
532
  # ignore LoadError and others (related with signals): it may raise these errors in Windows
529
533
  end
530
- worker_id = ENV['SERVERENGINE_WORKER_ID'].to_i
531
- process_type = case
532
- when @standalone_worker then :standalone
533
- when worker_id == 0 then :worker0
534
- else :workers
535
- end
536
- @log.init(process_type, worker_id)
537
- show_plugin_config if @show_plugin_config
538
- read_config
539
- set_system_config
540
- @log.apply_options(format: @system_config.log.format, time_format: @system_config.log.time_format)
541
534
 
542
- Process.setproctitle("worker:#{@process_name}") if @process_name
535
+ Process.setproctitle("worker:#{@system_config.process_name}") if @process_name
543
536
 
544
- if @standalone_worker && @workers != 1
545
- raise Fluent::ConfigError, "invalid number of workers (must be 1 or unspecified) with --no-supervisor: #{@workers}"
537
+ if @standalone_worker && @system_config.workers != 1
538
+ raise Fluent::ConfigError, "invalid number of workers (must be 1 or unspecified) with --no-supervisor: #{@system_config.workers}"
546
539
  end
547
540
 
548
541
  install_main_process_signal_handlers
@@ -552,16 +545,60 @@ module Fluent
552
545
 
553
546
  main_process do
554
547
  create_socket_manager if @standalone_worker
555
- change_privilege if @standalone_worker
548
+ ServerEngine::Privilege.change(@chuser, @chgroup) if @standalone_worker
556
549
  MessagePackFactory.init
557
- init_engine
558
- run_configure
559
- run_engine
550
+ Fluent::Engine.init(@system_config)
551
+ Fluent::Engine.run_configure(@conf)
552
+ Fluent::Engine.run
560
553
  self.class.cleanup_resources if @standalone_worker
561
554
  exit 0
562
555
  end
563
556
  end
564
557
 
558
+ def configure(supervisor: false)
559
+ if supervisor
560
+ @log.init(:supervisor, 0)
561
+ else
562
+ worker_id = ENV['SERVERENGINE_WORKER_ID'].to_i
563
+ process_type = case
564
+ when @standalone_worker then :standalone
565
+ when worker_id == 0 then :worker0
566
+ else :workers
567
+ end
568
+ @log.init(process_type, worker_id)
569
+ end
570
+
571
+ if @show_plugin_config
572
+ show_plugin_config
573
+ end
574
+
575
+ @conf = read_config
576
+ @system_config = build_system_config(@conf)
577
+
578
+ @log.level = @system_config.log_level
579
+ @log.apply_options(format: @system_config.log.format, time_format: @system_config.log.time_format)
580
+
581
+ $log.info :supervisor, 'parsing config file is succeeded', path: @config_path
582
+
583
+ @libs.each do |lib|
584
+ require lib
585
+ end
586
+
587
+ @plugin_dirs.each do |dir|
588
+ if Dir.exist?(dir)
589
+ dir = File.expand_path(dir)
590
+ Fluent::Plugin.add_plugin_dir(dir)
591
+ end
592
+ end
593
+
594
+ if supervisor
595
+ # plugins / configuration dumps
596
+ Gem::Specification.find_all.select { |x| x.name =~ /^fluent(d|-(plugin|mixin)-.*)$/ }.each do |spec|
597
+ $log.info("gem '#{spec.name}' version '#{spec.version}'")
598
+ end
599
+ end
600
+ end
601
+
565
602
  private
566
603
 
567
604
  def create_socket_manager
@@ -570,33 +607,6 @@ module Fluent
570
607
  ENV['SERVERENGINE_SOCKETMANAGER_PATH'] = socket_manager_path.to_s
571
608
  end
572
609
 
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
- MessagePackFactory.init
589
- init_engine(supervisor: true)
590
- run_configure
591
- rescue Fluent::ConfigError => e
592
- $log.error "config error", file: @config_path, error: e
593
- $log.debug_backtrace
594
- exit!(1)
595
- ensure
596
- Fluent::Engine.dry_run_mode = false
597
- end
598
- end
599
-
600
610
  def show_plugin_config
601
611
  name, type = @show_plugin_config.split(":") # input:tail
602
612
  $log.info "show_plugin_config option is deprecated. Use fluent-plugin-config-format --format=txt #{name} #{type}"
@@ -604,10 +614,7 @@ module Fluent
604
614
  end
605
615
 
606
616
  def supervise
607
- # Make dumpable conf, which is set corresponding_proxies for all elements in all worker sections
608
- dry_run
609
-
610
- Process.setproctitle("supervisor:#{@process_name}") if @process_name
617
+ Process.setproctitle("supervisor:#{@system_config.process_name}") if @system_config.process_name
611
618
  $log.info "starting fluentd-#{Fluent::VERSION}", pid: Process.pid, ruby: RUBY_VERSION
612
619
 
613
620
  rubyopt = ENV["RUBYOPT"]
@@ -619,24 +626,24 @@ module Fluent
619
626
 
620
627
  $log.info "spawn command to main: ", cmdline: fluentd_spawn_cmd
621
628
 
622
- params = {}
623
- params['main_cmd'] = fluentd_spawn_cmd
624
- params['daemonize'] = @daemonize
625
- params['inline_config'] = @inline_config
626
- params['log_path'] = @log_path
627
- params['log_rotate_age'] = @log_rotate_age
628
- params['log_rotate_size'] = @log_rotate_size
629
- params['chuser'] = @chuser
630
- params['chgroup'] = @chgroup
631
- params['use_v1_config'] = @use_v1_config
632
- params['conf_encoding'] = @conf_encoding
633
-
634
- # system config parameters
635
- params['workers'] = @workers
636
- params['root_dir'] = @root_dir
637
- params['log_level'] = @log_level
638
- params['suppress_repeated_stacktrace'] = @suppress_repeated_stacktrace
639
- params['signame'] = @signame
629
+ params = {
630
+ 'main_cmd' => fluentd_spawn_cmd,
631
+ 'daemonize' => @daemonize,
632
+ 'inline_config' => @inline_config,
633
+ 'log_path' => @log_path,
634
+ 'log_rotate_age' => @log_rotate_age,
635
+ 'log_rotate_size' => @log_rotate_size,
636
+ 'chuser' => @chuser,
637
+ 'chgroup' => @chgroup,
638
+ 'use_v1_config' => @use_v1_config,
639
+ 'conf_encoding' => @conf_encoding,
640
+ 'signame' => @signame,
641
+
642
+ 'workers' => @system_config.workers,
643
+ 'root_dir' => @system_config.root_dir,
644
+ 'log_level' => @system_config.log_level,
645
+ 'suppress_repeated_stacktrace' => @system_config.suppress_repeated_stacktrace,
646
+ }
640
647
 
641
648
  se = ServerEngine.create(ServerModule, WorkerModule){
642
649
  Fluent::Supervisor.load_config(@config_path, params)
@@ -703,7 +710,7 @@ module Fluent
703
710
  def flush_buffer
704
711
  # Creating new thread due to mutex can't lock
705
712
  # in main thread during trap context
706
- Thread.new {
713
+ Thread.new do
707
714
  begin
708
715
  $log.debug "fluentd main process get SIGUSR1"
709
716
  $log.info "force flushing buffered events"
@@ -713,7 +720,7 @@ module Fluent
713
720
  rescue Exception => e
714
721
  $log.warn "flushing thread error: #{e}"
715
722
  end
716
- }.run
723
+ end
717
724
  end
718
725
 
719
726
  def logging_with_console_output
@@ -721,18 +728,18 @@ module Fluent
721
728
  unless @log.stdout?
722
729
  logger = ServerEngine::DaemonLogger.new(STDOUT)
723
730
  log = Fluent::Log.new(logger)
724
- log.level = @log_level
731
+ log.level = @system_config.log_level
725
732
  console = log.enable_debug
726
733
  yield console
727
734
  end
728
735
  end
729
736
 
730
737
  def main_process(&block)
731
- if @process_name
732
- if @workers > 1
733
- Process.setproctitle("worker:#{@process_name}#{ENV['SERVERENGINE_WORKER_ID']}")
738
+ if @system_config.process_name
739
+ if @system_config.workers > 1
740
+ Process.setproctitle("worker:#{@system_config.process_name}#{ENV['SERVERENGINE_WORKER_ID']}")
734
741
  else
735
- Process.setproctitle("worker:#{@process_name}")
742
+ Process.setproctitle("worker:#{@system_config.process_name}")
736
743
  end
737
744
  end
738
745
 
@@ -781,47 +788,25 @@ module Fluent
781
788
  elsif @inline_config
782
789
  config_data << "\n" << @inline_config.gsub("\\n","\n")
783
790
  end
784
- @conf = Fluent::Config.parse(config_data, config_fname, config_basedir, @use_v1_config)
785
- end
786
-
787
- def set_system_config
788
- @system_config = SystemConfig.create(@conf) # @conf is set in read_config
789
- @system_config.attach(self)
790
- @system_config.apply(self)
791
+ Fluent::Config.parse(config_data, config_fname, config_basedir, @use_v1_config)
791
792
  end
792
793
 
793
- def change_privilege
794
- ServerEngine::Privilege.change(@chuser, @chgroup)
795
- end
796
-
797
- def init_engine(supervisor: false)
798
- Fluent::Engine.init(@system_config)
799
-
800
- @libs.each {|lib|
801
- require lib
802
- }
803
-
804
- @plugin_dirs.each {|dir|
805
- if Dir.exist?(dir)
806
- dir = File.expand_path(dir)
807
- Fluent::Engine.add_plugin_dir(dir)
808
- end
809
- }
794
+ def build_system_config(conf)
795
+ system_config = SystemConfig.create(conf)
796
+ opt = {}
797
+ Fluent::SystemConfig::SYSTEM_CONFIG_PARAMETERS.each do |param|
798
+ if @cl_opt.key?(param) && !@cl_opt[param].nil?
799
+ if param == :log_level && opt[:log_level] == Fluent::Log::LEVEL_INFO
800
+ # info level can't be specified via command line option.
801
+ # log_level is info here, it is default value and <system>'s log_level should be applied if exists.
802
+ next
803
+ end
810
804
 
811
- if supervisor
812
- # plugins / configuration dumps
813
- Gem::Specification.find_all.select { |x| x.name =~ /^fluent(d|-(plugin|mixin)-.*)$/ }.each do |spec|
814
- $log.info("gem '#{spec.name}' version '#{spec.version}'")
805
+ opt[param] = @cl_opt[param]
815
806
  end
816
807
  end
817
- end
818
-
819
- def run_configure
820
- Fluent::Engine.run_configure(@conf)
821
- end
822
-
823
- def run_engine
824
- Fluent::Engine.run
808
+ system_config.overwrite_variables(opt)
809
+ system_config
825
810
  end
826
811
  end
827
812
  end