Skip to content

Commit b2d896b

Browse files
committed
config: fix duplicate config file loading in config_include_dir
Signed-off-by: Shizuo Fujita <fujita@clear-code.com>
1 parent a22ce7f commit b2d896b

File tree

5 files changed

+35
-17
lines changed

5 files changed

+35
-17
lines changed

lib/fluent/config.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ module Config
2626
# @param additional_config [String] config which is added to last of config body
2727
# @param use_v1_config [Bool] config is formatted with v1 or not
2828
# @return [Fluent::Config]
29-
def self.build(config_path:, encoding: 'utf-8', additional_config: nil, use_v1_config: true, type: nil)
29+
def self.build(config_path:, encoding: 'utf-8', additional_config: nil, use_v1_config: true, type: nil, on_parsed_file: nil)
3030
if type == :guess
3131
config_file_ext = File.extname(config_path)
3232
if config_file_ext == '.yaml' || config_file_ext == '.yml'
@@ -35,7 +35,7 @@ def self.build(config_path:, encoding: 'utf-8', additional_config: nil, use_v1_c
3535
end
3636

3737
if type == :yaml || type == :yml
38-
return Fluent::Config::YamlParser.parse(config_path)
38+
return Fluent::Config::YamlParser.parse(config_path, on_parsed_file: on_parsed_file)
3939
end
4040

4141
config_fname = File.basename(config_path)
@@ -49,10 +49,10 @@ def self.build(config_path:, encoding: 'utf-8', additional_config: nil, use_v1_c
4949
s
5050
end
5151

52-
Fluent::Config.parse(config_data, config_fname, config_basedir, use_v1_config)
52+
Fluent::Config.parse(config_data, config_fname, config_basedir, use_v1_config, on_parsed_file: on_parsed_file)
5353
end
5454

55-
def self.parse(str, fname, basepath = Dir.pwd, v1_config = nil, syntax: :v1)
55+
def self.parse(str, fname, basepath = Dir.pwd, v1_config = nil, syntax: :v1, on_parsed_file: nil)
5656
parser = if fname =~ /\.rb$/ || syntax == :ruby
5757
:ruby
5858
elsif v1_config.nil?
@@ -68,7 +68,7 @@ def self.parse(str, fname, basepath = Dir.pwd, v1_config = nil, syntax: :v1)
6868
case parser
6969
when :v1
7070
require 'fluent/config/v1_parser'
71-
V1Parser.parse(str, fname, basepath, Kernel.binding)
71+
V1Parser.parse(str, fname, basepath, Kernel.binding, on_parsed_file: on_parsed_file)
7272
when :v0
7373
# TODO: show deprecated message in v1
7474
require 'fluent/config/parser'

lib/fluent/config/v1_parser.rb

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,18 @@ module Config
2727
class V1Parser < LiteralParser
2828
ELEMENT_NAME = /[a-zA-Z0-9_]+/
2929

30-
def self.parse(data, fname, basepath = Dir.pwd, eval_context = nil)
30+
def self.parse(data, fname, basepath = Dir.pwd, eval_context = nil, on_parsed_file: nil)
3131
ss = StringScanner.new(data)
32-
ps = V1Parser.new(ss, basepath, fname, eval_context)
32+
ps = V1Parser.new(ss, basepath, fname, eval_context, on_parsed_file: on_parsed_file)
3333
ps.parse!
3434
end
3535

36-
def initialize(strscan, include_basepath, fname, eval_context)
36+
def initialize(strscan, include_basepath, fname, eval_context, on_parsed_file: nil)
3737
super(strscan, eval_context)
3838
@include_basepath = include_basepath
3939
@fname = fname
4040
@logger = defined?($log) ? $log : nil
41+
@on_parsed_file = on_parsed_file
4142
end
4243

4344
def parse!
@@ -138,6 +139,8 @@ def parse_element(root_element, elem_name, attrs = {}, elems = [])
138139
end
139140
end
140141

142+
@on_parsed_file&.call(File.join(@include_basepath, @fname)) if root_element
143+
141144
return attrs, elems
142145
end
143146

@@ -166,7 +169,7 @@ def eval_include(attrs, elems, uri)
166169
data = File.read(entry)
167170
data.force_encoding('UTF-8')
168171
ss = StringScanner.new(data)
169-
V1Parser.new(ss, basepath, fname, @eval_context).parse_element(true, nil, attrs, elems)
172+
V1Parser.new(ss, basepath, fname, @eval_context, on_parsed_file: @on_parsed_file).parse_element(true, nil, attrs, elems)
170173
}
171174
else
172175
require 'open-uri'
@@ -175,7 +178,7 @@ def eval_include(attrs, elems, uri)
175178
data = u.open { |f| f.read }
176179
data.force_encoding('UTF-8')
177180
ss = StringScanner.new(data)
178-
V1Parser.new(ss, basepath, fname, @eval_context).parse_element(true, nil, attrs, elems)
181+
V1Parser.new(ss, basepath, fname, @eval_context, on_parsed_file: @on_parsed_file).parse_element(true, nil, attrs, elems)
179182
end
180183
rescue SystemCallError => e
181184
cpe = ConfigParseError.new("include error #{uri} - #{e}")

lib/fluent/config/yaml_parser.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
module Fluent
2222
module Config
2323
module YamlParser
24-
def self.parse(path)
24+
def self.parse(path, on_parsed_file: nil)
2525
context = Kernel.binding
2626

2727
unless context.respond_to?(:use_nil)
@@ -48,7 +48,7 @@ def self.parse(path)
4848
end
4949
end
5050

51-
s = Fluent::Config::YamlParser::Loader.new(context).load(Pathname.new(path))
51+
s = Fluent::Config::YamlParser::Loader.new(context, on_parsed_file: on_parsed_file).load(Pathname.new(path))
5252
Fluent::Config::YamlParser::Parser.new(s).build.to_element
5353
end
5454
end

lib/fluent/config/yaml_parser/loader.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ class Loader
3030
FLUENT_STR_TAG = 'tag:fluent/s'.freeze
3131
SHOVEL = '<<'.freeze
3232

33-
def initialize(context = Kernel.binding)
33+
def initialize(context = Kernel.binding, on_parsed_file: nil)
3434
@context = context
3535
@current_path = nil
36+
@on_parsed_file = on_parsed_file
3637
end
3738

3839
# @param [String] path
@@ -55,9 +56,13 @@ def load(path)
5556
Fluent::Config::YamlParser::FluentValue::StringValue.new(val, @context)
5657
end
5758

58-
path.open do |f|
59+
config = path.open do |f|
5960
visitor.accept(Psych.parse(f))
6061
end
62+
63+
@on_parsed_file&.call(path.to_s)
64+
65+
config
6166
end
6267

6368
def eval_include(path, parent)

lib/fluent/supervisor.rb

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
require 'open3'
1919
require 'pathname'
2020
require 'find'
21+
require 'set'
2122

2223
require 'fluent/config'
2324
require 'fluent/counter'
@@ -796,18 +797,20 @@ def configure(supervisor: false)
796797
$log.warn('the value "-" for `inline_config` is deprecated. See https://github.com/fluent/fluentd/issues/2711')
797798
@inline_config = STDIN.read
798799
end
800+
parsed_files = Set.new
799801
@conf = Fluent::Config.build(
800802
config_path: @config_path,
801803
encoding: @conf_encoding,
802804
additional_config: @inline_config,
803805
use_v1_config: @use_v1_config,
804806
type: @config_file_type,
807+
on_parsed_file: ->(path) { parsed_files << path },
805808
)
806809
@system_config = build_system_config(@conf)
807810

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

810-
build_additional_configurations do |additional_conf|
813+
build_additional_configurations(parsed_files) do |additional_conf|
811814
@conf += additional_conf
812815
end
813816

@@ -1088,15 +1091,17 @@ def reload_config
10881091
$log.debug('worker got SIGUSR2')
10891092

10901093
begin
1094+
parsed_files = Set.new
10911095
conf = Fluent::Config.build(
10921096
config_path: @config_path,
10931097
encoding: @conf_encoding,
10941098
additional_config: @inline_config,
10951099
use_v1_config: @use_v1_config,
10961100
type: @config_file_type,
1101+
on_parsed_file: ->(path) { parsed_files << path },
10971102
)
10981103

1099-
build_additional_configurations do |additional_conf|
1104+
build_additional_configurations(parsed_files) do |additional_conf|
11001105
conf += additional_conf
11011106
end
11021107

@@ -1206,7 +1211,7 @@ def build_system_config(conf)
12061211
system_config
12071212
end
12081213

1209-
def build_additional_configurations
1214+
def build_additional_configurations(parsed_files)
12101215
if @system_config.config_include_dir&.empty?
12111216
$log.info :supervisor, 'configuration include directory is disabled'
12121217
return
@@ -1218,6 +1223,11 @@ def build_additional_configurations
12181223
next unless supported_suffixes.include?(File.extname(path))
12191224
# NOTE: both types of normal config (.conf) and YAML will be loaded.
12201225
# Thus, it does not care whether @config_path is .conf or .yml.
1226+
if parsed_files.include?(path)
1227+
$log.info :supervisor, 'skip auto loading, it was already loaded', path: path
1228+
next
1229+
end
1230+
12211231
$log.info :supervisor, 'loading additional configuration file', path: path
12221232
yield Fluent::Config.build(config_path: path,
12231233
encoding: @conf_encoding,

0 commit comments

Comments
 (0)