Skip to content

Commit 8e9f46a

Browse files
authored
Merge pull request #4064 from daipom/fix-override-systemconfig
Fix problem that some system configs are not reflected
2 parents 6c649d1 + e58fd66 commit 8e9f46a

File tree

5 files changed

+152
-103
lines changed

5 files changed

+152
-103
lines changed

lib/fluent/command/fluentd.rb

Lines changed: 55 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -26,205 +26,206 @@
2626
op = OptionParser.new
2727
op.version = Fluent::VERSION
2828

29-
opts = Fluent::Supervisor.default_options
29+
default_opts = Fluent::Supervisor.default_options
30+
cmd_opts = {}
3031

3132
op.on('-s', "--setup [DIR=#{File.dirname(Fluent::DEFAULT_CONFIG_PATH)}]", "install sample configuration file to the directory") {|s|
32-
opts[:setup_path] = s || File.dirname(Fluent::DEFAULT_CONFIG_PATH)
33+
cmd_opts[:setup_path] = s || File.dirname(Fluent::DEFAULT_CONFIG_PATH)
3334
}
3435

3536
op.on('-c', '--config PATH', "config file path (default: #{Fluent::DEFAULT_CONFIG_PATH})") {|s|
36-
opts[:config_path] = s
37+
cmd_opts[:config_path] = s
3738
}
3839

3940
op.on('--dry-run', "Check fluentd setup is correct or not", TrueClass) {|b|
40-
opts[:dry_run] = b
41+
cmd_opts[:dry_run] = b
4142
}
4243

4344
op.on('--show-plugin-config=PLUGIN', "[DEPRECATED] Show PLUGIN configuration and exit(ex: input:dummy)") {|plugin|
44-
opts[:show_plugin_config] = plugin
45+
cmd_opts[:show_plugin_config] = plugin
4546
}
4647

4748
op.on('-p', '--plugin DIR', "add plugin directory") {|s|
48-
opts[:plugin_dirs] << s
49+
(cmd_opts[:plugin_dirs] ||= []) << s
4950
}
5051

5152
op.on('-I PATH', "add library path") {|s|
5253
$LOAD_PATH << s
5354
}
5455

5556
op.on('-r NAME', "load library") {|s|
56-
opts[:libs] << s
57+
(cmd_opts[:libs] ||= []) << s
5758
}
5859

5960
op.on('-d', '--daemon PIDFILE', "daemonize fluent process") {|s|
60-
opts[:daemonize] = s
61+
cmd_opts[:daemonize] = s
6162
}
6263

6364
op.on('--under-supervisor', "run fluent worker under supervisor (this option is NOT for users)") {
64-
opts[:supervise] = false
65+
cmd_opts[:supervise] = false
6566
}
6667

6768
op.on('--no-supervisor', "run fluent worker without supervisor") {
68-
opts[:supervise] = false
69-
opts[:standalone_worker] = true
69+
cmd_opts[:supervise] = false
70+
cmd_opts[:standalone_worker] = true
7071
}
7172

7273
op.on('--workers NUM', "specify the number of workers under supervisor") { |i|
73-
opts[:workers] = i.to_i
74+
cmd_opts[:workers] = i.to_i
7475
}
7576

7677
op.on('--user USER', "change user") {|s|
77-
opts[:chuser] = s
78+
cmd_opts[:chuser] = s
7879
}
7980

8081
op.on('--group GROUP', "change group") {|s|
81-
opts[:chgroup] = s
82+
cmd_opts[:chgroup] = s
8283
}
8384

8485
op.on('--umask UMASK', "change umask") {|s|
85-
opts[:chumask] = s
86+
cmd_opts[:chumask] = s
8687
}
8788

8889
op.on('-o', '--log PATH', "log file path") {|s|
89-
opts[:log_path] = s
90+
cmd_opts[:log_path] = s
9091
}
9192

9293
op.on('--log-rotate-age AGE', 'generations to keep rotated log files') {|age|
9394
if Fluent::Log::LOG_ROTATE_AGE.include?(age)
94-
opts[:log_rotate_age] = age
95+
cmd_opts[:log_rotate_age] = age
9596
else
9697
begin
97-
opts[:log_rotate_age] = Integer(age)
98+
cmd_opts[:log_rotate_age] = Integer(age)
9899
rescue TypeError, ArgumentError
99100
usage "log-rotate-age should be #{ROTATE_AGE.join(', ')} or a number"
100101
end
101102
end
102103
}
103104

104105
op.on('--log-rotate-size BYTES', 'sets the byte size to rotate log files') {|s|
105-
opts[:log_rotate_size] = s.to_i
106+
cmd_opts[:log_rotate_size] = s.to_i
106107
}
107108

108109
op.on('--log-event-verbose', 'enable log events during process startup/shutdown') {|b|
109-
opts[:log_event_verbose] = b
110+
cmd_opts[:log_event_verbose] = b
110111
}
111112

112113
op.on('-i', '--inline-config CONFIG_STRING', "inline config which is appended to the config file on-the-fly") {|s|
113-
opts[:inline_config] = s
114+
cmd_opts[:inline_config] = s
114115
}
115116

116117
op.on('--emit-error-log-interval SECONDS', "suppress interval seconds of emit error logs") {|s|
117-
opts[:suppress_interval] = s.to_i
118+
cmd_opts[:suppress_interval] = s.to_i
118119
}
119120

120121
op.on('--suppress-repeated-stacktrace [VALUE]', "suppress repeated stacktrace", TrueClass) {|b|
121122
b = true if b.nil?
122-
opts[:suppress_repeated_stacktrace] = b
123+
cmd_opts[:suppress_repeated_stacktrace] = b
123124
}
124125

125126
op.on('--without-source', "invoke a fluentd without input plugins", TrueClass) {|b|
126-
opts[:without_source] = b
127+
cmd_opts[:without_source] = b
127128
}
128129

129130
op.on('--config-file-type VALU', 'guessing file type of fluentd configuration. yaml/yml or guess') { |s|
130131
if (s == 'yaml') || (s == 'yml')
131-
opts[:config_file_type] = s.to_sym
132+
cmd_opts[:config_file_type] = s.to_sym
132133
elsif (s == 'guess')
133-
opts[:config_file_type] = s.to_sym
134+
cmd_opts[:config_file_type] = s.to_sym
134135
else
135136
usage '--config-file-type accepts yaml/yml or guess'
136137
end
137138
}
138139

139140
op.on('--use-v1-config', "Use v1 configuration format (default)", TrueClass) {|b|
140-
opts[:use_v1_config] = b
141+
cmd_opts[:use_v1_config] = b
141142
}
142143

143144
op.on('--use-v0-config', "Use v0 configuration format", TrueClass) {|b|
144-
opts[:use_v1_config] = !b
145+
cmd_opts[:use_v1_config] = !b
145146
}
146147

147148
op.on('--strict-config-value', "Parse config values strictly", TrueClass) {|b|
148-
opts[:strict_config_value] = b
149+
cmd_opts[:strict_config_value] = b
149150
}
150151

151152
op.on('--enable-input-metrics', "Enable input plugin metrics on fluentd", TrueClass) {|b|
152-
opts[:enable_input_metrics] = b
153+
cmd_opts[:enable_input_metrics] = b
153154
}
154155

155156
op.on('--enable-size-metrics', "Enable plugin record size metrics on fluentd", TrueClass) {|b|
156-
opts[:enable_size_metrics] = b
157+
cmd_opts[:enable_size_metrics] = b
157158
}
158159

159160
op.on('-v', '--verbose', "increase verbose level (-v: debug, -vv: trace)", TrueClass) {|b|
160-
if b
161-
opts[:log_level] = [opts[:log_level] - 1, Fluent::Log::LEVEL_TRACE].max
162-
end
161+
return unless b
162+
cur_level = cmd_opts.fetch(:log_level, default_opts[:log_level])
163+
cmd_opts[:log_level] = [cur_level - 1, Fluent::Log::LEVEL_TRACE].max
163164
}
164165

165166
op.on('-q', '--quiet', "decrease verbose level (-q: warn, -qq: error)", TrueClass) {|b|
166-
if b
167-
opts[:log_level] = [opts[:log_level] + 1, Fluent::Log::LEVEL_ERROR].min
168-
end
167+
return unless b
168+
cur_level = cmd_opts.fetch(:log_level, default_opts[:log_level])
169+
cmd_opts[:log_level] = [cur_level + 1, Fluent::Log::LEVEL_TRACE].max
169170
}
170171

171172
op.on('--suppress-config-dump', "suppress config dumping when fluentd starts", TrueClass) {|b|
172-
opts[:suppress_config_dump] = b
173+
cmd_opts[:suppress_config_dump] = b
173174
}
174175

175176
op.on('-g', '--gemfile GEMFILE', "Gemfile path") {|s|
176-
opts[:gemfile] = s
177+
cmd_opts[:gemfile] = s
177178
}
178179

179180
op.on('-G', '--gem-path GEM_INSTALL_PATH', "Gemfile install path (default: $(dirname $gemfile)/vendor/bundle)") {|s|
180-
opts[:gem_install_path] = s
181+
cmd_opts[:gem_install_path] = s
181182
}
182183

183184
op.on('--conf-encoding ENCODING', "specify configuration file encoding") { |s|
184-
opts[:conf_encoding] = s
185+
cmd_opts[:conf_encoding] = s
185186
}
186187

187188
op.on('--disable-shared-socket', "Don't open shared socket for multiple workers") { |b|
188-
opts[:disable_shared_socket] = b
189+
cmd_opts[:disable_shared_socket] = b
189190
}
190191

191192
if Fluent.windows?
192-
opts.merge!(
193+
cmd_opts.merge!(
193194
:winsvc_name => 'fluentdwinsvc',
194195
:winsvc_display_name => 'Fluentd Windows Service',
195196
:winsvc_desc => 'Fluentd is an event collector system.',
196197
)
197198

198199
op.on('-x', '--signame INTSIGNAME', "an object name which is used for Windows Service signal (Windows only)") {|s|
199-
opts[:signame] = s
200+
cmd_opts[:signame] = s
200201
}
201202

202203
op.on('--reg-winsvc MODE', "install/uninstall as Windows Service. (i: install, u: uninstall) (Windows only)") {|s|
203-
opts[:regwinsvc] = s
204+
cmd_opts[:regwinsvc] = s
204205
}
205206

206207
op.on('--[no-]reg-winsvc-auto-start', "Automatically start the Windows Service at boot. (only effective with '--reg-winsvc i') (Windows only)") {|s|
207-
opts[:regwinsvcautostart] = s
208+
cmd_opts[:regwinsvcautostart] = s
208209
}
209210

210211
op.on('--[no-]reg-winsvc-delay-start', "Automatically start the Windows Service at boot with delay. (only effective with '--reg-winsvc i' and '--reg-winsvc-auto-start') (Windows only)") {|s|
211-
opts[:regwinsvcdelaystart] = s
212+
cmd_opts[:regwinsvcdelaystart] = s
212213
}
213214

214215
op.on('--reg-winsvc-fluentdopt OPTION', "specify fluentd option parameters for Windows Service. (Windows only)") {|s|
215-
opts[:fluentdopt] = s
216+
cmd_opts[:fluentdopt] = s
216217
}
217218

218219
op.on('--winsvc-name NAME', "The Windows Service name to run as (Windows only)") {|s|
219-
opts[:winsvc_name] = s
220+
cmd_opts[:winsvc_name] = s
220221
}
221222

222223
op.on('--winsvc-display-name DISPLAY_NAME', "The Windows Service display name (Windows only)") {|s|
223-
opts[:winsvc_display_name] = s
224+
cmd_opts[:winsvc_display_name] = s
224225
}
225226

226227
op.on('--winsvc-desc DESC', "The Windows Service description (Windows only)") {|s|
227-
opts[:winsvc_desc] = s
228+
cmd_opts[:winsvc_desc] = s
228229
}
229230
end
230231

@@ -247,6 +248,7 @@
247248
usage $!.to_s
248249
end
249250

251+
opts = default_opts.merge(cmd_opts)
250252

251253
##
252254
## Bundler injection
@@ -345,15 +347,15 @@
345347
exit 0 if early_exit
346348

347349
if opts[:supervise]
348-
supervisor = Fluent::Supervisor.new(opts)
350+
supervisor = Fluent::Supervisor.new(cmd_opts)
349351
supervisor.configure(supervisor: true)
350352
supervisor.run_supervisor(dry_run: opts[:dry_run])
351353
else
352354
if opts[:standalone_worker] && opts[:workers] && opts[:workers] > 1
353355
puts "Error: multi workers is not supported with --no-supervisor"
354356
exit 2
355357
end
356-
worker = Fluent::Supervisor.new(opts)
358+
worker = Fluent::Supervisor.new(cmd_opts)
357359
worker.configure
358360

359361
if opts[:daemonize] && opts[:standalone_worker]

lib/fluent/supervisor.rb

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,10 @@ def self.cleanup_resources
656656
end
657657
end
658658

659-
def initialize(opt)
659+
def initialize(cl_opt)
660+
@cl_opt = cl_opt
661+
opt = self.class.default_options.merge(cl_opt)
662+
660663
@config_file_type = opt[:config_file_type]
661664
@daemonize = opt[:daemonize]
662665
@standalone_worker= opt[:standalone_worker]
@@ -676,7 +679,6 @@ def initialize(opt)
676679
@log_rotate_size = opt[:log_rotate_size]
677680
@signame = opt[:signame]
678681

679-
@cl_opt = opt
680682
@conf = nil
681683
# parse configuration immediately to initialize logger in early stage
682684
if @config_path and File.exist?(@config_path)
@@ -1098,15 +1100,10 @@ def main_process(&block)
10981100

10991101
def build_system_config(conf)
11001102
system_config = SystemConfig.create(conf, @cl_opt[:strict_config_value])
1103+
# Prefer the options explicitly specified in the command line
11011104
opt = {}
11021105
Fluent::SystemConfig::SYSTEM_CONFIG_PARAMETERS.each do |param|
11031106
if @cl_opt.key?(param) && !@cl_opt[param].nil?
1104-
if param == :log_level && @cl_opt[:log_level] == Fluent::Log::LEVEL_INFO
1105-
# info level can't be specified via command line option.
1106-
# log_level is info here, it is default value and <system>'s log_level should be applied if exists.
1107-
next
1108-
end
1109-
11101107
opt[param] = @cl_opt[param]
11111108
end
11121109
end

test/command/test_fluentd.rb

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,4 +1165,77 @@ def multi_workers_ready?; true; end
11651165
"shared socket for multiple workers is disabled",)
11661166
end
11671167
end
1168+
1169+
sub_test_case 'log_level by command line option' do
1170+
test 'info' do
1171+
conf = ""
1172+
conf_path = create_conf_file('empty.conf', conf)
1173+
assert File.exist?(conf_path)
1174+
assert_log_matches(create_cmdline(conf_path),
1175+
"[info]",
1176+
patterns_not_match: ["[debug]"])
1177+
end
1178+
1179+
test 'debug' do
1180+
conf = ""
1181+
conf_path = create_conf_file('empty.conf', conf)
1182+
assert File.exist?(conf_path)
1183+
assert_log_matches(create_cmdline(conf_path, "-v"),
1184+
"[debug]",
1185+
patterns_not_match: ["[trace]"])
1186+
end
1187+
1188+
test 'trace' do
1189+
conf = <<CONF
1190+
<source>
1191+
@type sample
1192+
tag test
1193+
</source>
1194+
CONF
1195+
conf_path = create_conf_file('sample.conf', conf)
1196+
assert File.exist?(conf_path)
1197+
assert_log_matches(create_cmdline(conf_path, "-vv"),
1198+
"[trace]",)
1199+
end
1200+
1201+
test 'warn' do
1202+
conf = <<CONF
1203+
<source>
1204+
@type sample
1205+
tag test
1206+
</source>
1207+
CONF
1208+
conf_path = create_conf_file('sample.conf', conf)
1209+
assert File.exist?(conf_path)
1210+
assert_log_matches(create_cmdline(conf_path, "-q"),
1211+
"[warn]",
1212+
patterns_not_match: ["[info]"])
1213+
end
1214+
1215+
test 'error' do
1216+
conf = <<CONF
1217+
<source>
1218+
@type plugin_not_found
1219+
tag test
1220+
</source>
1221+
CONF
1222+
conf_path = create_conf_file('plugin_not_found.conf', conf)
1223+
assert File.exist?(conf_path)
1224+
assert_log_matches(create_cmdline(conf_path, "-qq"),
1225+
"[error]",
1226+
patterns_not_match: ["[warn]"])
1227+
end
1228+
1229+
test 'system config one should not be overwritten when cmd line one is not specified' do
1230+
conf = <<CONF
1231+
<system>
1232+
log_level debug
1233+
</system>
1234+
CONF
1235+
conf_path = create_conf_file('debug.conf', conf)
1236+
assert File.exist?(conf_path)
1237+
assert_log_matches(create_cmdline(conf_path),
1238+
"[debug]")
1239+
end
1240+
end
11681241
end

0 commit comments

Comments
 (0)