Skip to content

Commit b1329d3

Browse files
committed
system_config: support built-in config files
Currently @include directive supports to reuse configuration files, but no way to apply specific configuration files by default (without specifying to). In the previous versions, if you want to manage multiple configuration files, you must use @include directive explicitly. In this commit, add an option to specify the directory (e.g. /etc/fluent/conf.d) which stores additional configuration files. If there are such files under specified directory, they are loaded by default without @include directive. If you want to disable this feature, set empty string for config_include_dir "". Signed-off-by: Kentaro Hayashi <[email protected]>
1 parent 3a6826a commit b1329d3

File tree

5 files changed

+145
-1
lines changed

5 files changed

+145
-1
lines changed

lib/fluent/config/element.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ def add_element(name, arg = '')
7171
e
7272
end
7373

74+
def merge_elements(elements)
75+
@elements.concat(elements)
76+
end
77+
7478
def inspect
7579
attrs = super
7680
"name:#{@name}, arg:#{@arg}, " + attrs + ", " + @elements.inspect

lib/fluent/env.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ module Fluent
2424
DEFAULT_PLUGIN_DIR = ENV['FLUENT_PLUGIN'] || '/etc/fluent/plugin'
2525
DEFAULT_SOCKET_PATH = ENV['FLUENT_SOCKET'] || '/var/run/fluent/fluent.sock'
2626
DEFAULT_BACKUP_DIR = ENV['FLUENT_BACKUP_DIR'] || '/tmp/fluent'
27+
DEFAULT_CONFIG_DIR = ENV['FLUENT_CONF_DIR'] || '/etc/fluent/conf.d'
2728
DEFAULT_OJ_OPTIONS = Fluent::OjOptions.load_env
2829
DEFAULT_DIR_PERMISSION = 0755
2930
DEFAULT_FILE_PERMISSION = 0644

lib/fluent/supervisor.rb

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
require 'fileutils'
1818
require 'open3'
1919
require 'pathname'
20+
require 'find'
2021

2122
require 'fluent/config'
2223
require 'fluent/counter'
@@ -806,6 +807,53 @@ def configure(supervisor: false)
806807

807808
$log.info :supervisor, 'parsing config file is succeeded', path: @config_path
808809

810+
# merge additional configuration
811+
config_type = if File.extname(@config_path) == '.yaml' || File.extname(@config_path) == '.yml'
812+
:yaml
813+
else
814+
nil
815+
end
816+
if @system_config.config_include_dir&.empty?
817+
$log.warn :supervisor, 'default configuration include directory was disabled'
818+
else
819+
begin
820+
Find.find(@system_config.config_include_dir) do |path|
821+
next if path == @system_config.config_include_dir
822+
if config_type == :yaml
823+
if File.extname(path) != '.yaml' && File.extname(path) != '.yml'
824+
$log.warn :supervisor, 'skip loading configuration file', path: path
825+
next
826+
end
827+
$log.info :supervisor, 'loading additional configuration file', path: path
828+
# wrap additional YAML configuration to make it parsed correctly
829+
buffer = "config:\n"
830+
buffer << File.readlines(path).collect do |line|
831+
" " + line.chomp
832+
end.join("\n")
833+
Tempfile.open do |file|
834+
file.puts(buffer)
835+
file.rewind
836+
elements = Fluent::Config::YamlParser.parse(file.path).elements
837+
@conf.merge_elements(elements)
838+
end
839+
else
840+
if File.extname(path) == '.yaml' || File.extname(path) == '.yml'
841+
$log.warn :supervisor, 'skip loading configuration file', path: path
842+
next
843+
end
844+
$log.info :supervisor, 'loading additional configuration file', path: path
845+
elements = Fluent::Config.build(config_path: path,
846+
encoding: @conf_encoding,
847+
use_v1_config: @use_v1_config,
848+
type: config_type).elements
849+
@conf.merge_elements(elements)
850+
end
851+
end
852+
rescue Errno::ENOENT
853+
$log.warn :supervisor, 'no default configuration include directory was disabled', path: @system_config.config_include_dir
854+
end
855+
end
856+
809857
@libs.each do |lib|
810858
require lib
811859
end

lib/fluent/system_config.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ class SystemConfig
2828
:without_source, :with_source_only, :rpc_endpoint, :enable_get_dump, :process_name,
2929
:file_permission, :dir_permission, :counter_server, :counter_client,
3030
:strict_config_value, :enable_msgpack_time_support, :disable_shared_socket,
31-
:metrics, :enable_input_metrics, :enable_size_metrics, :enable_jit, :source_only_buffer
31+
:metrics, :enable_input_metrics, :enable_size_metrics, :enable_jit, :source_only_buffer,
32+
:config_include_dir
3233
]
3334

3435
config_param :workers, :integer, default: 1
@@ -58,6 +59,7 @@ class SystemConfig
5859
config_param :dir_permission, default: nil do |v|
5960
v.to_i(8)
6061
end
62+
config_param :config_include_dir, default: ENV["FLUENT_CONF_DIR"] || '/etc/fluent/conf.d'
6163
config_section :log, required: false, init: true, multi: false do
6264
config_param :path, :string, default: nil
6365
config_param :format, :enum, list: [:text, :json], default: :text

test/command/test_fluentd.rb

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1536,4 +1536,93 @@ def send_end(port)
15361536
end_thread&.kill
15371537
end
15381538
end
1539+
1540+
sub_test_case "test additional configuration directory" do
1541+
setup do
1542+
omit "Not supported on Windows" if Fluent.windows?
1543+
FileUtils.mkdir_p(File.join(@tmp_dir, "conf.d"))
1544+
end
1545+
1546+
test "disable additional configuration directory" do
1547+
conf = <<CONF
1548+
<system>
1549+
config_include_dir ""
1550+
</system>
1551+
CONF
1552+
conf_path = create_conf_file('disabled_config_include_dir.conf', conf)
1553+
assert_log_matches(create_cmdline(conf_path),
1554+
"[warn]: default configuration include directory was disabled")
1555+
end
1556+
1557+
data("test with relative conf.d case" => true,
1558+
"test with full path conf.d case" => false)
1559+
test "additional configuration file (conf.d/child.conf) was loaded" do |relative|
1560+
conf_dir = relative ? "conf.d" : "#{@tmp_dir}/conf.d"
1561+
conf = <<CONF
1562+
<system>
1563+
config_include_dir #{conf_dir}
1564+
</system>
1565+
CONF
1566+
conf_path = create_conf_file('parent.conf', conf)
1567+
create_conf_file('conf.d/child.conf', "")
1568+
assert_log_matches(create_cmdline(conf_path),
1569+
"[info]: loading additional configuration file path=\"#{conf_dir}/child.conf\"")
1570+
end
1571+
1572+
test "skip loading different YAML configuration" do
1573+
conf = <<CONF
1574+
<system>
1575+
config_include_dir #{@tmp_dir}/conf.d
1576+
</system>
1577+
CONF
1578+
conf_path = create_conf_file('parent.conf', conf)
1579+
FileUtils.mkdir_p(File.join(@tmp_dir, "conf.d"))
1580+
create_conf_file('conf.d/child.yml', "")
1581+
assert_log_matches(create_cmdline(conf_path),
1582+
"[warn]: skip loading configuration file path=\"#{@tmp_dir}/conf.d/child.yml\"")
1583+
end
1584+
end
1585+
1586+
sub_test_case "test additional configuration directory (YAML)" do
1587+
setup do
1588+
omit "Not supported on Windows" if Fluent.windows?
1589+
FileUtils.mkdir_p(File.join(@tmp_dir, "conf.d"))
1590+
end
1591+
1592+
test "disable additional configuration directory" do
1593+
conf = <<CONF
1594+
system:
1595+
config_include_dir: ""
1596+
CONF
1597+
conf_path = create_conf_file('disabled_config_include_dir.yml', conf)
1598+
assert_log_matches(create_cmdline(conf_path),
1599+
"[warn]: default configuration include directory was disabled")
1600+
end
1601+
1602+
data("test with relative conf.d case" => true,
1603+
"test with full path conf.d case" => false)
1604+
test "additional relative configuration file (conf.d/child.yml) was loaded" do |relative|
1605+
conf_dir = relative ? "conf.d" : "#{@tmp_dir}/conf.d"
1606+
conf = <<CONF
1607+
system:
1608+
config_include_dir: #{conf_dir}
1609+
CONF
1610+
conf_path = create_conf_file('parent.yml', conf)
1611+
create_conf_file('conf.d/child.yml', "")
1612+
assert_log_matches(create_cmdline(conf_path),
1613+
"[info]: loading additional configuration file path=\"#{conf_dir}/child.yml\"")
1614+
end
1615+
1616+
test "skip loading different V1 conf configuration" do
1617+
conf = <<CONF
1618+
system:
1619+
config_include_dir: #{@tmp_dir}/conf.d
1620+
CONF
1621+
conf_path = create_conf_file('parent.yml', conf)
1622+
create_conf_file('conf.d/child.conf', "")
1623+
assert_log_matches(create_cmdline(conf_path),
1624+
"[warn]: skip loading configuration file path=\"#{@tmp_dir}/conf.d/child.conf\"")
1625+
end
1626+
1627+
end
15391628
end

0 commit comments

Comments
 (0)