diff --git a/lib/fluent/command/fluentd.rb b/lib/fluent/command/fluentd.rb
index e66285bf81..2f08689b07 100644
--- a/lib/fluent/command/fluentd.rb
+++ b/lib/fluent/command/fluentd.rb
@@ -85,9 +85,8 @@
opts[:log_path] = s
}
-ROTATE_AGE = %w(daily weekly monthly)
op.on('--log-rotate-age AGE', 'generations to keep rotated log files') {|age|
- if ROTATE_AGE.include?(age)
+ if Fluent::Log::LOG_ROTATE_AGE.include?(age)
opts[:log_rotate_age] = age
else
begin
diff --git a/lib/fluent/log.rb b/lib/fluent/log.rb
index 4c096a615e..201b2d88a6 100644
--- a/lib/fluent/log.rb
+++ b/lib/fluent/log.rb
@@ -49,6 +49,7 @@ module TTYColor
LOG_TYPE_DEFAULT = :default # show logs in all supervisor/workers, with worker id in workers (default)
LOG_TYPES = [LOG_TYPE_SUPERVISOR, LOG_TYPE_WORKER0, LOG_TYPE_DEFAULT].freeze
+ LOG_ROTATE_AGE = %w(daily weekly monthly)
def self.str_to_level(log_level_str)
case log_level_str.downcase
diff --git a/lib/fluent/supervisor.rb b/lib/fluent/supervisor.rb
index 86cb9f3556..8cc9df021d 100644
--- a/lib/fluent/supervisor.rb
+++ b/lib/fluent/supervisor.rb
@@ -518,6 +518,8 @@ def init(process_type, worker_id)
dl_opts = {}
# subtract 1 to match serverengine daemon logger side logging severity.
dl_opts[:log_level] = @level - 1
+ dl_opts[:log_rotate_age] = @log_rotate_age if @log_rotate_age
+ dl_opts[:log_rotate_size] = @log_rotate_size if @log_rotate_size
logger = ServerEngine::DaemonLogger.new(@logdev, dl_opts)
$log = Fluent::Log.new(logger, @opts)
$log.enable_color(false) if @path
@@ -606,6 +608,19 @@ def initialize(opt)
@cl_opt = opt
@conf = nil
+ # parse configuration immediately to initialize logger in early stage
+ if @config_path and File.exist?(@config_path)
+ @conf = Fluent::Config.build(config_path: @config_path,
+ encoding: @conf_encoding ? @conf_encoding : 'utf-8',
+ additional_config: @inline_config ? @inline_config : nil,
+ use_v1_config: !!@use_v1_config)
+ @system_config = build_system_config(@conf)
+ if @system_config.log
+ @log_rotate_age ||= @system_config.log.rotate_age
+ @log_rotate_size ||= @system_config.log.rotate_size
+ end
+ @conf = nil
+ end
log_opts = {suppress_repeated_stacktrace: opt[:suppress_repeated_stacktrace], ignore_repeated_log_interval: opt[:ignore_repeated_log_interval],
ignore_same_log_interval: opt[:ignore_same_log_interval]}
diff --git a/lib/fluent/system_config.rb b/lib/fluent/system_config.rb
index 041ecaeea9..b322b4bb60 100644
--- a/lib/fluent/system_config.rb
+++ b/lib/fluent/system_config.rb
@@ -55,6 +55,20 @@ class SystemConfig
config_section :log, required: false, init: true, multi: false do
config_param :format, :enum, list: [:text, :json], default: :text
config_param :time_format, :string, default: '%Y-%m-%d %H:%M:%S %z'
+ config_param :rotate_age, default: nil do |v|
+ if Fluent::Log::LOG_ROTATE_AGE.include?(v)
+ v.to_sym
+ else
+ begin
+ Integer(v)
+ rescue ArgumentError => e
+ raise Fluent::ConfigError, e.message
+ else
+ v.to_i
+ end
+ end
+ end
+ config_param :rotate_size, :size, default: nil
end
config_section :counter_server, multi: false do
diff --git a/test/config/test_system_config.rb b/test/config/test_system_config.rb
index 675311ab3b..0e992fa310 100644
--- a/test/config/test_system_config.rb
+++ b/test/config/test_system_config.rb
@@ -143,5 +143,51 @@ def parse_text(text)
sc.overwrite_variables(**s.for_system_config)
assert_equal(level, sc.log_level)
end
+
+ sub_test_case "log rotation" do
+ data('daily' => "daily",
+ 'weekly' => 'weekly',
+ 'monthly' => 'monthly')
+ test "symbols for rotate_age" do |age|
+ conf = parse_text(<<-EOS)
+
+
+ rotate_age #{age}
+
+
+ EOS
+ sc = Fluent::SystemConfig.new(conf)
+ assert_equal(age.to_sym, sc.log.rotate_age)
+ end
+
+ test "numeric number for rotate age" do
+ conf = parse_text(<<-EOS)
+
+
+ rotate_age 3
+
+
+ EOS
+ s = FakeSupervisor.new
+ sc = Fluent::SystemConfig.new(conf)
+ assert_equal(3, sc.log.rotate_age)
+ end
+
+ data(h: ['100', 100],
+ k: ['1k', 1024],
+ m: ['1m', 1024 * 1024],
+ g: ['1g', 1024 * 1024 * 1024])
+ test "numeric and SI prefix for rotate_size" do |(label, size)|
+ conf = parse_text(<<-EOS)
+
+
+ rotate_size #{label}
+
+
+ EOS
+ sc = Fluent::SystemConfig.new(conf)
+ assert_equal(size, sc.log.rotate_size)
+ end
+ end
end
end
diff --git a/test/test_config.rb b/test/test_config.rb
index 1efb79edd2..e9d1005647 100644
--- a/test/test_config.rb
+++ b/test/test_config.rb
@@ -160,7 +160,8 @@ def test_inline
prepare_config
opts = {
:config_path => "#{TMP_DIR}/config_test_1.conf",
- :inline_config => "\n type http\n port 2222\n "
+ :inline_config => "\n type http\n port 2222\n ",
+ :use_v1_config => false
}
assert_nothing_raised do
Fluent::Supervisor.new(opts)
diff --git a/test/test_supervisor.rb b/test/test_supervisor.rb
index 26025f5810..cea498e2b4 100644
--- a/test/test_supervisor.rb
+++ b/test/test_supervisor.rb
@@ -7,6 +7,7 @@
require 'net/http'
require 'uri'
require 'fileutils'
+require 'tempfile'
if Fluent.windows?
require 'win32/event'
@@ -489,6 +490,40 @@ def test_logger_with_rotate_age_and_rotate_size(rotate_age)
assert_equal 10, $log.out.instance_variable_get(:@shift_size)
end
+ sub_test_case "system log rotation" do
+ def parse_text(text)
+ basepath = File.expand_path(File.dirname(__FILE__) + '/../../')
+ Fluent::Config.parse(text, '(test)', basepath, true).elements.find { |e| e.name == 'system' }
+ end
+
+ def test_override_default_log_rotate
+ Tempfile.open do |file|
+ config = parse_text(<<-EOS)
+
+
+ rotate_age 3
+ rotate_size 300
+
+
+ EOS
+ file.puts(config)
+ file.flush
+ opts = Fluent::Supervisor.default_options.merge(
+ log_path: "#{TMP_DIR}/test.log", config_path: file.path
+ )
+ sv = Fluent::Supervisor.new(opts)
+
+ log = sv.instance_variable_get(:@log)
+ log.init(:standalone, 0)
+ logger = $log.instance_variable_get(:@logger)
+
+ assert_equal([3, 300],
+ [logger.instance_variable_get(:@rotate_age),
+ logger.instance_variable_get(:@rotate_size)])
+ end
+ end
+ end
+
def test_inline_config
omit 'this feature is deprecated. see https://github.com/fluent/fluentd/issues/2711'