fluentd 1.8.0.rc3 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

@@ -74,7 +74,7 @@ module Fluent
74
74
  Fluent::Config::SectionGenerator.generate(proxy, conf, nil, nil)
75
75
  end
76
76
 
77
- def configure(conf)
77
+ def configure(conf, strict_config_value=false)
78
78
  @config = conf
79
79
 
80
80
  logger = if self.respond_to?(:log)
@@ -91,7 +91,7 @@ module Fluent
91
91
 
92
92
  # In the nested section, can't get plugin class through proxies so get plugin class here
93
93
  plugin_class = Fluent::Plugin.lookup_type_from_class(proxy.name.to_s)
94
- root = Fluent::Config::SectionGenerator.generate(proxy, conf, logger, plugin_class)
94
+ root = Fluent::Config::SectionGenerator.generate(proxy, conf, logger, plugin_class, [], strict_config_value)
95
95
  @config_root_section = root
96
96
 
97
97
  root.instance_eval{ @params.keys }.each do |param_name|
@@ -103,9 +103,9 @@ module Fluent
103
103
  def configure(conf)
104
104
  @root_agent.configure(conf)
105
105
 
106
- @fleunt_log_event_router = FluentLogEventRouter.build(@root_agent)
106
+ @fluent_log_event_router = FluentLogEventRouter.build(@root_agent)
107
107
 
108
- if @fleunt_log_event_router.emittable?
108
+ if @fluent_log_event_router.emittable?
109
109
  $log.enable_event(true)
110
110
  end
111
111
 
@@ -145,7 +145,7 @@ module Fluent
145
145
  $log.info "starting fluentd worker", pid: Process.pid, ppid: Process.ppid, worker: worker_id
146
146
  start
147
147
 
148
- @fleunt_log_event_router.start
148
+ @fluent_log_event_router.start
149
149
 
150
150
  $log.info "fluentd worker is now running", worker: worker_id
151
151
  sleep MAINLOOP_SLEEP_INTERVAL until @engine_stopped
@@ -159,12 +159,12 @@ module Fluent
159
159
 
160
160
  unless @log_event_verbose
161
161
  $log.enable_event(false)
162
- @fleunt_log_event_router.graceful_stop
162
+ @fluent_log_event_router.graceful_stop
163
163
  end
164
164
  $log.info "shutting down fluentd worker", worker: worker_id
165
165
  shutdown
166
166
 
167
- @fleunt_log_event_router.stop
167
+ @fluent_log_event_router.stop
168
168
  end
169
169
 
170
170
  def stop
@@ -173,7 +173,7 @@ module Fluent
173
173
  end
174
174
 
175
175
  def push_log_event(tag, time, record)
176
- @fleunt_log_event_router.emit_event([tag, time, record])
176
+ @fluent_log_event_router.emit_event([tag, time, record])
177
177
  end
178
178
 
179
179
  def worker_id
@@ -60,7 +60,7 @@ module Fluent
60
60
  end
61
61
  system_config_override(workers: workers)
62
62
  end
63
- super
63
+ super(conf, system_config.strict_config_value)
64
64
  @_state ||= State.new(false, false, false, false, false, false, false, false, false)
65
65
  @_state.configure = true
66
66
  self
@@ -28,7 +28,7 @@ module Fluent
28
28
  def configure(conf)
29
29
  super
30
30
 
31
- @time_formatter = Strftime.new(TIME_FORMAT)
31
+ @time_formatter = Strftime.new(@time_format || TIME_FORMAT)
32
32
  @sub_formatter = Plugin.new_formatter(@output_type, parent: self.owner)
33
33
  @sub_formatter.configure(conf)
34
34
  end
@@ -64,7 +64,8 @@ module Fluent::Plugin
64
64
  def config_ltsv(_req)
65
65
  obj = {
66
66
  'pid' => Process.pid,
67
- 'ppid' => Process.ppid
67
+ 'ppid' => Process.ppid,
68
+ 'version' => Fluent::VERSION,
68
69
  }.merge(@agent.fluentd_opts)
69
70
 
70
71
  render_ltsv([obj])
@@ -73,7 +74,8 @@ module Fluent::Plugin
73
74
  def config_json(req)
74
75
  obj = {
75
76
  'pid' => Process.pid,
76
- 'ppid' => Process.ppid
77
+ 'ppid' => Process.ppid,
78
+ 'version' => Fluent::VERSION,
77
79
  }.merge(@agent.fluentd_opts)
78
80
  opts = build_option(req)
79
81
 
@@ -406,16 +406,16 @@ module Fluent::Plugin
406
406
  def statistics
407
407
  stats = super
408
408
  services = discovery_manager.services
409
- healty_nodes_count = 0
409
+ healthy_nodes_count = 0
410
410
  registed_nodes_count = services.size
411
411
  services.each do |s|
412
412
  if s.available?
413
- healty_nodes_count += 1
413
+ healthy_nodes_count += 1
414
414
  end
415
415
  end
416
416
 
417
417
  stats.merge(
418
- 'healty_nodes_count' => healty_nodes_count,
418
+ 'healthy_nodes_count' => healthy_nodes_count,
419
419
  'registered_nodes_count' => registed_nodes_count,
420
420
  )
421
421
  end
@@ -40,7 +40,7 @@ module Fluent
40
40
  helpers_internal :thread, :retry_state
41
41
 
42
42
  CHUNK_KEY_PATTERN = /^[-_.@a-zA-Z0-9]+$/
43
- CHUNK_KEY_PLACEHOLDER_PATTERN = /\$\{[-_.@$a-zA-Z0-9]+\}/
43
+ CHUNK_KEY_PLACEHOLDER_PATTERN = /\$\{([-_.@$a-zA-Z0-9]+)\}/
44
44
  CHUNK_TAG_PLACEHOLDER_PATTERN = /\$\{(tag(?:\[-?\d+\])?)\}/
45
45
  CHUNK_ID_PLACEHOLDER_PATTERN = /\$\{chunk_id\}/
46
46
 
@@ -707,7 +707,7 @@ module Fluent
707
707
  end
708
708
 
709
709
  def get_placeholders_keys(str)
710
- str.scan(CHUNK_KEY_PLACEHOLDER_PATTERN).map{|ph| ph[2..-2]}.reject{|s| (s == "tag") || (s == 'chunk_id') }.sort
710
+ str.scan(CHUNK_KEY_PLACEHOLDER_PATTERN).map(&:first).reject{|s| (s == "tag") || (s == 'chunk_id') }.sort
711
711
  end
712
712
 
713
713
  # TODO: optimize this code
@@ -759,11 +759,19 @@ module Fluent
759
759
  @chunk_keys.each do |key|
760
760
  hash["${#{key}}"] = metadata.variables[key.to_sym]
761
761
  end
762
- rvalue = rvalue.gsub(CHUNK_KEY_PLACEHOLDER_PATTERN, hash)
762
+
763
+ rvalue = rvalue.gsub(CHUNK_KEY_PLACEHOLDER_PATTERN) do |matched|
764
+ hash.fetch(matched) do
765
+ log.warn "chunk key placeholder '#{matched[2..-2]}' not replaced. template:#{str}"
766
+ ''
767
+ end
768
+ end
763
769
  end
770
+
764
771
  if rvalue =~ CHUNK_KEY_PLACEHOLDER_PATTERN
765
772
  log.warn "chunk key placeholder '#{$1}' not replaced. template:#{str}"
766
773
  end
774
+
767
775
  rvalue.sub(CHUNK_ID_PLACEHOLDER_PATTERN) {
768
776
  if chunk_passed
769
777
  dump_unique_id_hex(chunk.unique_id)
@@ -194,7 +194,9 @@ module Fluent
194
194
  hash['time_type'] = 'unixtime'
195
195
  end
196
196
  if conf.has_key?('localtime') || conf.has_key?('utc')
197
- if conf.has_key?('localtime') && conf.has_key?('utc')
197
+ utc = to_bool(conf['utc'])
198
+ localtime = to_bool(conf['localtime'])
199
+ if conf.has_key?('localtime') && conf.has_key?('utc') && !(localtime ^ utc)
198
200
  raise Fluent::ConfigError, "both of utc and localtime are specified, use only one of them"
199
201
  elsif conf.has_key?('localtime')
200
202
  hash['localtime'] = Fluent::Config.bool_value(conf['localtime'])
@@ -217,6 +219,14 @@ module Fluent
217
219
  conf
218
220
  end
219
221
 
222
+ def to_bool(v)
223
+ if v.is_a?(FalseClass) || v == 'false' || v.nil?
224
+ false
225
+ else
226
+ true
227
+ end
228
+ end
229
+
220
230
  def compat_parameters_extract(conf)
221
231
  return unless conf.elements('extract').empty?
222
232
  return if EXTRACT_PARAMS.keys.all?{|k| !conf.has_key?(k) } && !conf.has_key?('format')
@@ -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,
@@ -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,
@@ -572,6 +554,10 @@ module Fluent
572
554
  show_plugin_config
573
555
  end
574
556
 
557
+ if @inline_config == '-'
558
+ @inline_config = STDIN.read
559
+ end
560
+
575
561
  @conf = read_config
576
562
  @system_config = build_system_config(@conf)
577
563
 
@@ -638,11 +624,15 @@ module Fluent
638
624
  'use_v1_config' => @use_v1_config,
639
625
  'conf_encoding' => @conf_encoding,
640
626
  'signame' => @signame,
627
+ 'fluentd_conf' => @conf.to_s,
641
628
 
642
629
  'workers' => @system_config.workers,
643
630
  'root_dir' => @system_config.root_dir,
644
631
  'log_level' => @system_config.log_level,
645
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,
646
636
  }
647
637
 
648
638
  se = ServerEngine.create(ServerModule, WorkerModule){
@@ -783,20 +773,18 @@ module Fluent
783
773
  config_fname = File.basename(@config_path)
784
774
  config_basedir = File.dirname(@config_path)
785
775
  config_data = File.open(@config_path, "r:#{@conf_encoding}:utf-8") {|f| f.read }
786
- if @inline_config == '-'
787
- config_data << "\n" << STDIN.read
788
- elsif @inline_config
789
- config_data << "\n" << @inline_config.gsub("\\n","\n")
776
+ if @inline_config
777
+ config_data << "\n" << @inline_config.gsub("\\n", "\n")
790
778
  end
791
779
  Fluent::Config.parse(config_data, config_fname, config_basedir, @use_v1_config)
792
780
  end
793
781
 
794
782
  def build_system_config(conf)
795
- system_config = SystemConfig.create(conf)
783
+ system_config = SystemConfig.create(conf, @cl_opt[:strict_config_value])
796
784
  opt = {}
797
785
  Fluent::SystemConfig::SYSTEM_CONFIG_PARAMETERS.each do |param|
798
786
  if @cl_opt.key?(param) && !@cl_opt[param].nil?
799
- if param == :log_level && opt[:log_level] == Fluent::Log::LEVEL_INFO
787
+ if param == :log_level && @cl_opt[:log_level] == Fluent::Log::LEVEL_INFO
800
788
  # info level can't be specified via command line option.
801
789
  # log_level is info here, it is default value and <system>'s log_level should be applied if exists.
802
790
  next
@@ -27,11 +27,12 @@ module Fluent
27
27
  :log_event_verbose,
28
28
  :without_source, :rpc_endpoint, :enable_get_dump, :process_name,
29
29
  :file_permission, :dir_permission, :counter_server, :counter_client,
30
+ :strict_config_value
30
31
  ]
31
32
 
32
33
  config_param :workers, :integer, default: 1
33
34
  config_param :root_dir, :string, default: nil
34
- config_param :log_level, :enum, list: [:trace, :debug, :info, :warn, :error, :fatal], default: nil
35
+ config_param :log_level, :enum, list: [:trace, :debug, :info, :warn, :error, :fatal], default: 'info'
35
36
  config_param :suppress_repeated_stacktrace, :bool, default: nil
36
37
  config_param :emit_error_log_interval, :time, default: nil
37
38
  config_param :suppress_config_dump, :bool, default: nil
@@ -40,6 +41,7 @@ module Fluent
40
41
  config_param :rpc_endpoint, :string, default: nil
41
42
  config_param :enable_get_dump, :bool, default: nil
42
43
  config_param :process_name, :string, default: nil
44
+ config_param :strict_config_value, :bool, default: nil
43
45
  config_param :file_permission, default: nil do |v|
44
46
  v.to_i(8)
45
47
  end
@@ -73,12 +75,12 @@ module Fluent
73
75
  config_param :timeout, :time, default: nil
74
76
  end
75
77
 
76
- def self.create(conf)
78
+ def self.create(conf, strict_config_value=false)
77
79
  systems = conf.elements(name: 'system')
78
80
  return SystemConfig.new if systems.empty?
79
81
  raise Fluent::ConfigError, "<system> is duplicated. <system> should be only one" if systems.size > 1
80
82
 
81
- SystemConfig.new(systems.first)
83
+ SystemConfig.new(systems.first, strict_config_value)
82
84
  end
83
85
 
84
86
  def self.blank_system_config
@@ -95,14 +97,26 @@ module Fluent
95
97
  end
96
98
  end
97
99
 
98
- def initialize(conf=nil)
100
+ def initialize(conf=nil, strict_config_value=false)
99
101
  super()
100
102
  conf ||= SystemConfig.blank_system_config
101
- configure(conf)
103
+ configure(conf, strict_config_value)
102
104
  end
103
105
 
104
- def configure(conf)
105
- super
106
+ def configure(conf, strict_config_value=false)
107
+ strict = strict_config_value
108
+ if !strict && conf && conf.has_key?("strict_config_value")
109
+ strict = Fluent::Config.bool_value(conf["strict_config_value"])
110
+ end
111
+
112
+ begin
113
+ super(conf, strict)
114
+ rescue ConfigError => e
115
+ $log.error "config error in:\n#{conf}"
116
+ $log.error 'config error', error: e
117
+ $log.debug_backtrace
118
+ exit!(1)
119
+ end
106
120
 
107
121
  @log_level = Log.str_to_level(@log_level.to_s) if @log_level
108
122
  end