/proc/self/cwd/source/server/options_impl.cc
Line | Count | Source (jump to first uncovered line) |
1 | | #include "source/server/options_impl.h" |
2 | | |
3 | | #include <chrono> |
4 | | #include <cstdint> |
5 | | #include <iostream> |
6 | | #include <string> |
7 | | |
8 | | #include "envoy/admin/v3/server_info.pb.h" |
9 | | |
10 | | #include "source/common/common/fmt.h" |
11 | | #include "source/common/common/logger.h" |
12 | | #include "source/common/common/macros.h" |
13 | | #include "source/common/protobuf/utility.h" |
14 | | #include "source/common/stats/tag_utility.h" |
15 | | #include "source/common/version/version.h" |
16 | | #include "source/server/options_impl_platform.h" |
17 | | |
18 | | #include "absl/strings/str_replace.h" |
19 | | #include "absl/strings/str_split.h" |
20 | | #include "absl/strings/string_view.h" |
21 | | #include "spdlog/spdlog.h" |
22 | | #include "tclap/CmdLine.h" |
23 | | |
24 | | namespace Envoy { |
25 | | namespace { |
26 | 126 | std::vector<std::string> toArgsVector(int argc, const char* const* argv) { |
27 | 126 | std::vector<std::string> args; |
28 | 126 | args.reserve(argc); |
29 | | |
30 | 252 | for (int i = 0; i < argc; ++i) { |
31 | 126 | args.emplace_back(argv[i]); |
32 | 126 | } |
33 | 126 | return args; |
34 | 126 | } |
35 | | |
36 | 0 | void throwMalformedArgExceptionOrPanic(std::string message) { |
37 | 0 | throwExceptionOrPanic(MalformedArgvException, message); |
38 | 0 | } |
39 | | |
40 | | } // namespace |
41 | | |
42 | | OptionsImpl::OptionsImpl(int argc, const char* const* argv, |
43 | | const HotRestartVersionCb& hot_restart_version_cb, |
44 | | spdlog::level::level_enum default_log_level) |
45 | 126 | : OptionsImpl(toArgsVector(argc, argv), hot_restart_version_cb, default_log_level) {} |
46 | | |
47 | | OptionsImpl::OptionsImpl(std::vector<std::string> args, |
48 | | const HotRestartVersionCb& hot_restart_version_cb, |
49 | 126 | spdlog::level::level_enum default_log_level) { |
50 | 126 | std::string log_levels_string = fmt::format("Log levels: {}", allowedLogLevels()); |
51 | 126 | log_levels_string += |
52 | 126 | fmt::format("\nDefault is [{}]", spdlog::level::level_string_views[default_log_level]); |
53 | | |
54 | 126 | const std::string component_log_level_string = |
55 | 126 | "Comma-separated list of component log levels. For example upstream:debug,config:trace"; |
56 | 126 | const std::string log_format_string = |
57 | 126 | fmt::format("Log message format in spdlog syntax " |
58 | 126 | "(see https://github.com/gabime/spdlog/wiki/3.-Custom-formatting)" |
59 | 126 | "\nDefault is \"{}\"", |
60 | 126 | Logger::Logger::DEFAULT_LOG_FORMAT); |
61 | | |
62 | | // NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.VirtualCall) |
63 | 126 | TCLAP::CmdLine cmd("envoy", ' ', VersionInfo::version()); |
64 | 126 | TCLAP::ValueArg<uint32_t> base_id( |
65 | 126 | "", "base-id", "Base ID so that multiple envoys can run on the same host if needed", false, 0, |
66 | 126 | "uint32_t", cmd); |
67 | 126 | TCLAP::SwitchArg use_dynamic_base_id( |
68 | 126 | "", "use-dynamic-base-id", |
69 | 126 | "The server chooses a base ID dynamically. Supersedes a static base ID. May not be used " |
70 | 126 | "when the restart epoch is non-zero.", |
71 | 126 | cmd, false); |
72 | 126 | TCLAP::ValueArg<std::string> base_id_path( |
73 | 126 | "", "base-id-path", "Path to which the base ID is written", false, "", "string", cmd); |
74 | 126 | TCLAP::ValueArg<uint32_t> concurrency("", "concurrency", "# of worker threads to run", false, |
75 | 126 | std::thread::hardware_concurrency(), "uint32_t", cmd); |
76 | 126 | TCLAP::ValueArg<std::string> config_path("c", "config-path", "Path to configuration file", false, |
77 | 126 | "", "string", cmd); |
78 | 126 | TCLAP::ValueArg<std::string> config_yaml( |
79 | 126 | "", "config-yaml", "Inline YAML configuration, merges with the contents of --config-path", |
80 | 126 | false, "", "string", cmd); |
81 | | |
82 | 126 | TCLAP::SwitchArg allow_unknown_fields("", "allow-unknown-fields", |
83 | 126 | "Allow unknown fields in static configuration (DEPRECATED)", |
84 | 126 | cmd, false); |
85 | 126 | TCLAP::SwitchArg allow_unknown_static_fields("", "allow-unknown-static-fields", |
86 | 126 | "Allow unknown fields in static configuration", cmd, |
87 | 126 | false); |
88 | 126 | TCLAP::SwitchArg reject_unknown_dynamic_fields("", "reject-unknown-dynamic-fields", |
89 | 126 | "Reject unknown fields in dynamic configuration", |
90 | 126 | cmd, false); |
91 | 126 | TCLAP::SwitchArg ignore_unknown_dynamic_fields("", "ignore-unknown-dynamic-fields", |
92 | 126 | "Ignore unknown fields in dynamic configuration", |
93 | 126 | cmd, false); |
94 | | |
95 | 126 | TCLAP::ValueArg<std::string> admin_address_path("", "admin-address-path", "Admin address path", |
96 | 126 | false, "", "string", cmd); |
97 | 126 | TCLAP::ValueArg<std::string> local_address_ip_version("", "local-address-ip-version", |
98 | 126 | "The local " |
99 | 126 | "IP address version (v4 or v6).", |
100 | 126 | false, "v4", "string", cmd); |
101 | 126 | TCLAP::ValueArg<std::string> log_level( |
102 | 126 | "l", "log-level", log_levels_string, false, |
103 | 126 | spdlog::level::level_string_views[default_log_level].data(), "string", cmd); |
104 | 126 | TCLAP::ValueArg<std::string> component_log_level( |
105 | 126 | "", "component-log-level", component_log_level_string, false, "", "string", cmd); |
106 | 126 | TCLAP::ValueArg<std::string> log_format("", "log-format", log_format_string, false, |
107 | 126 | Logger::Logger::DEFAULT_LOG_FORMAT, "string", cmd); |
108 | 126 | TCLAP::SwitchArg log_format_escaped("", "log-format-escaped", |
109 | 126 | "Escape c-style escape sequences in the application logs", |
110 | 126 | cmd, false); |
111 | 126 | TCLAP::SwitchArg enable_fine_grain_logging( |
112 | 126 | "", "enable-fine-grain-logging", |
113 | 126 | "Logger mode: enable file level log control (Fine-Grain Logger) or not", cmd, false); |
114 | 126 | TCLAP::ValueArg<std::string> log_path("", "log-path", "Path to logfile", false, "", "string", |
115 | 126 | cmd); |
116 | 126 | TCLAP::ValueArg<uint32_t> restart_epoch("", "restart-epoch", "Hot restart epoch #", false, 0, |
117 | 126 | "uint32_t", cmd); |
118 | 126 | TCLAP::SwitchArg hot_restart_version_option("", "hot-restart-version", |
119 | 126 | "Hot restart compatibility version", cmd); |
120 | 126 | TCLAP::ValueArg<std::string> service_cluster("", "service-cluster", "Cluster name", false, "", |
121 | 126 | "string", cmd); |
122 | 126 | TCLAP::ValueArg<std::string> service_node("", "service-node", "Node name", false, "", "string", |
123 | 126 | cmd); |
124 | 126 | TCLAP::ValueArg<std::string> service_zone("", "service-zone", "Zone name", false, "", "string", |
125 | 126 | cmd); |
126 | 126 | TCLAP::ValueArg<uint32_t> file_flush_interval_msec("", "file-flush-interval-msec", |
127 | 126 | "Interval for log flushing in msec", false, |
128 | 126 | 10000, "uint32_t", cmd); |
129 | 126 | TCLAP::ValueArg<uint32_t> drain_time_s("", "drain-time-s", |
130 | 126 | "Hot restart and LDS removal drain time in seconds", false, |
131 | 126 | 600, "uint32_t", cmd); |
132 | 126 | TCLAP::ValueArg<std::string> drain_strategy( |
133 | 126 | "", "drain-strategy", |
134 | 126 | "Hot restart drain sequence behaviour, one of 'gradual' (default) or 'immediate'.", false, |
135 | 126 | "gradual", "string", cmd); |
136 | 126 | TCLAP::ValueArg<uint32_t> parent_shutdown_time_s("", "parent-shutdown-time-s", |
137 | 126 | "Hot restart parent shutdown time in seconds", |
138 | 126 | false, 900, "uint32_t", cmd); |
139 | 126 | TCLAP::ValueArg<std::string> mode("", "mode", |
140 | 126 | "One of 'serve' (default; validate configs and then serve " |
141 | 126 | "traffic normally) or 'validate' (validate configs and exit).", |
142 | 126 | false, "serve", "string", cmd); |
143 | 126 | TCLAP::SwitchArg disable_hot_restart("", "disable-hot-restart", |
144 | 126 | "Disable hot restart functionality", cmd, false); |
145 | 126 | TCLAP::SwitchArg enable_mutex_tracing( |
146 | 126 | "", "enable-mutex-tracing", "Enable mutex contention tracing functionality", cmd, false); |
147 | 126 | TCLAP::SwitchArg cpuset_threads( |
148 | 126 | "", "cpuset-threads", "Get the default # of worker threads from cpuset size", cmd, false); |
149 | | |
150 | 126 | TCLAP::ValueArg<std::string> disable_extensions("", "disable-extensions", |
151 | 126 | "Comma-separated list of extensions to disable", |
152 | 126 | false, "", "string", cmd); |
153 | | |
154 | 126 | TCLAP::ValueArg<std::string> socket_path("", "socket-path", "Path to hot restart socket file", |
155 | 126 | false, "@envoy_domain_socket", "string", cmd); |
156 | | |
157 | 126 | TCLAP::ValueArg<std::string> socket_mode("", "socket-mode", "Socket file permission", false, |
158 | 126 | "600", "string", cmd); |
159 | 126 | TCLAP::SwitchArg enable_core_dump("", "enable-core-dump", "Enable core dumps", cmd, false); |
160 | | |
161 | 126 | TCLAP::MultiArg<std::string> stats_tag( |
162 | 126 | "", "stats-tag", |
163 | 126 | "This flag provides a universal tag for all stats generated by Envoy. The format is " |
164 | 126 | "``tag:value``. Only alphanumeric values are allowed for tag names. For tag values all " |
165 | 126 | "characters are permitted except for '.' (dot). This flag can be repeated multiple times to " |
166 | 126 | "set multiple universal tags. Multiple values for the same tag name are not allowed.", |
167 | 126 | false, "string", cmd); |
168 | | |
169 | 126 | cmd.setExceptionHandling(false); |
170 | | |
171 | 126 | std::function failure_function = [&](TCLAP::ArgException& e) { |
172 | 0 | TRY_ASSERT_MAIN_THREAD { cmd.getOutput()->failure(cmd, e); } |
173 | 0 | END_TRY |
174 | 0 | CATCH(const TCLAP::ExitException&, { |
175 | | // failure() has already written an informative message to stderr, so all that's left to do |
176 | | // is throw our own exception with the original message. |
177 | 0 | throw MalformedArgvException(e.what()); |
178 | 0 | }); |
179 | 0 | }; |
180 | | |
181 | 126 | TRY_ASSERT_MAIN_THREAD { |
182 | 126 | cmd.parse(args); |
183 | 126 | count_ = cmd.getArgList().size(); |
184 | 126 | } |
185 | 126 | END_TRY |
186 | 126 | MULTI_CATCH( |
187 | 126 | TCLAP::ArgException & e, { failure_function(e); }, |
188 | 126 | { throw NoServingException("NoServingException"); }); |
189 | | |
190 | 126 | hot_restart_disabled_ = disable_hot_restart.getValue(); |
191 | 126 | mutex_tracing_enabled_ = enable_mutex_tracing.getValue(); |
192 | 126 | core_dump_enabled_ = enable_core_dump.getValue(); |
193 | | |
194 | 126 | cpuset_threads_ = cpuset_threads.getValue(); |
195 | | |
196 | 126 | if (log_level.isSet()) { |
197 | 0 | log_level_ = parseAndValidateLogLevel(log_level.getValue()); |
198 | 126 | } else { |
199 | 126 | log_level_ = default_log_level; |
200 | 126 | } |
201 | | |
202 | 126 | log_format_ = log_format.getValue(); |
203 | 126 | log_format_set_ = log_format.isSet(); |
204 | 126 | log_format_escaped_ = log_format_escaped.getValue(); |
205 | 126 | enable_fine_grain_logging_ = enable_fine_grain_logging.getValue(); |
206 | | |
207 | 126 | parseComponentLogLevels(component_log_level.getValue()); |
208 | | |
209 | 126 | if (mode.getValue() == "serve") { |
210 | 126 | mode_ = Server::Mode::Serve; |
211 | 126 | } else if (mode.getValue() == "validate") { |
212 | 0 | mode_ = Server::Mode::Validate; |
213 | 0 | } else if (mode.getValue() == "init_only") { |
214 | 0 | mode_ = Server::Mode::InitOnly; |
215 | 0 | } else { |
216 | 0 | const std::string message = fmt::format("error: unknown mode '{}'", mode.getValue()); |
217 | 0 | throwMalformedArgExceptionOrPanic(message); |
218 | 0 | } |
219 | | |
220 | 126 | if (local_address_ip_version.getValue() == "v4") { |
221 | 126 | local_address_ip_version_ = Network::Address::IpVersion::v4; |
222 | 126 | } else if (local_address_ip_version.getValue() == "v6") { |
223 | 0 | local_address_ip_version_ = Network::Address::IpVersion::v6; |
224 | 0 | } else { |
225 | 0 | const std::string message = |
226 | 0 | fmt::format("error: unknown IP address version '{}'", local_address_ip_version.getValue()); |
227 | 0 | throwMalformedArgExceptionOrPanic(message); |
228 | 0 | } |
229 | 126 | base_id_ = base_id.getValue(); |
230 | 126 | use_dynamic_base_id_ = use_dynamic_base_id.getValue(); |
231 | 126 | base_id_path_ = base_id_path.getValue(); |
232 | 126 | restart_epoch_ = restart_epoch.getValue(); |
233 | | |
234 | 126 | if (use_dynamic_base_id_ && restart_epoch_ > 0) { |
235 | 0 | const std::string message = fmt::format( |
236 | 0 | "error: cannot use --restart-epoch={} with --use-dynamic-base-id", restart_epoch_); |
237 | 0 | throwMalformedArgExceptionOrPanic(message); |
238 | 0 | } |
239 | | |
240 | 126 | if (!concurrency.isSet() && cpuset_threads_) { |
241 | | // The 'concurrency' command line option wasn't set but the 'cpuset-threads' |
242 | | // option was set. Use the number of CPUs assigned to the process cpuset, if |
243 | | // that can be known. |
244 | 0 | concurrency_ = OptionsImplPlatform::getCpuCount(); |
245 | 126 | } else { |
246 | 126 | if (concurrency.isSet() && cpuset_threads_ && cpuset_threads.isSet()) { |
247 | 0 | ENVOY_LOG(warn, "Both --concurrency and --cpuset-threads options are set; not applying " |
248 | 0 | "--cpuset-threads."); |
249 | 0 | } |
250 | 126 | concurrency_ = std::max(1U, concurrency.getValue()); |
251 | 126 | } |
252 | | |
253 | 126 | config_path_ = config_path.getValue(); |
254 | 126 | config_yaml_ = config_yaml.getValue(); |
255 | 126 | if (allow_unknown_fields.getValue()) { |
256 | 0 | ENVOY_LOG(warn, |
257 | 0 | "--allow-unknown-fields is deprecated, use --allow-unknown-static-fields instead."); |
258 | 0 | } |
259 | 126 | allow_unknown_static_fields_ = |
260 | 126 | allow_unknown_static_fields.getValue() || allow_unknown_fields.getValue(); |
261 | 126 | reject_unknown_dynamic_fields_ = reject_unknown_dynamic_fields.getValue(); |
262 | 126 | ignore_unknown_dynamic_fields_ = ignore_unknown_dynamic_fields.getValue(); |
263 | 126 | admin_address_path_ = admin_address_path.getValue(); |
264 | 126 | log_path_ = log_path.getValue(); |
265 | 126 | service_cluster_ = service_cluster.getValue(); |
266 | 126 | service_node_ = service_node.getValue(); |
267 | 126 | service_zone_ = service_zone.getValue(); |
268 | 126 | file_flush_interval_msec_ = std::chrono::milliseconds(file_flush_interval_msec.getValue()); |
269 | 126 | drain_time_ = std::chrono::seconds(drain_time_s.getValue()); |
270 | 126 | parent_shutdown_time_ = std::chrono::seconds(parent_shutdown_time_s.getValue()); |
271 | 126 | socket_path_ = socket_path.getValue(); |
272 | | |
273 | 126 | if (socket_path_.at(0) == '@') { |
274 | 126 | socket_mode_ = 0; |
275 | 126 | } else { |
276 | 0 | uint64_t socket_mode_helper; |
277 | 0 | if (!StringUtil::atoull(socket_mode.getValue().c_str(), socket_mode_helper, 8)) { |
278 | 0 | throwExceptionOrPanic(MalformedArgvException, |
279 | 0 | fmt::format("error: invalid socket-mode '{}'", socket_mode.getValue())); |
280 | 0 | } |
281 | 0 | socket_mode_ = socket_mode_helper; |
282 | 0 | } |
283 | | |
284 | 126 | if (drain_strategy.getValue() == "immediate") { |
285 | 0 | drain_strategy_ = Server::DrainStrategy::Immediate; |
286 | 126 | } else if (drain_strategy.getValue() == "gradual") { |
287 | 126 | drain_strategy_ = Server::DrainStrategy::Gradual; |
288 | 126 | } else { |
289 | 0 | throwExceptionOrPanic(MalformedArgvException, |
290 | 0 | fmt::format("error: unknown drain-strategy '{}'", mode.getValue())); |
291 | 0 | } |
292 | | |
293 | 126 | if (hot_restart_version_option.getValue()) { |
294 | 0 | std::cerr << hot_restart_version_cb(!hot_restart_disabled_); |
295 | 0 | throwExceptionOrPanic(NoServingException, "NoServingException"); |
296 | 0 | } |
297 | | |
298 | 126 | if (!disable_extensions.getValue().empty()) { |
299 | 0 | disabled_extensions_ = absl::StrSplit(disable_extensions.getValue(), ','); |
300 | 0 | } |
301 | | |
302 | 126 | if (!stats_tag.getValue().empty()) { |
303 | 0 | for (const auto& cli_tag_pair : stats_tag.getValue()) { |
304 | |
|
305 | 0 | std::vector<absl::string_view> cli_tag_pair_tokens = |
306 | 0 | absl::StrSplit(cli_tag_pair, absl::MaxSplits(':', 1)); |
307 | 0 | if (cli_tag_pair_tokens.size() != 2) { |
308 | 0 | throwExceptionOrPanic(MalformedArgvException, |
309 | 0 | fmt::format("error: misformatted stats-tag '{}'", cli_tag_pair)); |
310 | 0 | } |
311 | | |
312 | 0 | auto name = cli_tag_pair_tokens[0]; |
313 | 0 | if (!Stats::TagUtility::isTagNameValid(name)) { |
314 | 0 | throwExceptionOrPanic( |
315 | 0 | MalformedArgvException, |
316 | 0 | fmt::format("error: misformatted stats-tag '{}' contains invalid char in '{}'", |
317 | 0 | cli_tag_pair, name)); |
318 | 0 | } |
319 | | |
320 | 0 | auto value = cli_tag_pair_tokens[1]; |
321 | 0 | if (!Stats::TagUtility::isTagValueValid(value)) { |
322 | 0 | throwExceptionOrPanic( |
323 | 0 | MalformedArgvException, |
324 | 0 | fmt::format("error: misformatted stats-tag '{}' contains invalid char in '{}'", |
325 | 0 | cli_tag_pair, value)); |
326 | 0 | } |
327 | | |
328 | 0 | stats_tags_.emplace_back(Stats::Tag{std::string(name), std::string(value)}); |
329 | 0 | } |
330 | 0 | } |
331 | 126 | } |
332 | | |
333 | 0 | spdlog::level::level_enum OptionsImpl::parseAndValidateLogLevel(absl::string_view log_level) { |
334 | 0 | if (log_level == "warn") { |
335 | 0 | return spdlog::level::level_enum::warn; |
336 | 0 | } |
337 | | |
338 | 0 | size_t level_to_use = std::numeric_limits<size_t>::max(); |
339 | 0 | for (size_t i = 0; i < ARRAY_SIZE(spdlog::level::level_string_views); i++) { |
340 | 0 | spdlog::string_view_t spd_log_level = spdlog::level::level_string_views[i]; |
341 | 0 | if (log_level == absl::string_view(spd_log_level.data(), spd_log_level.size())) { |
342 | 0 | level_to_use = i; |
343 | 0 | break; |
344 | 0 | } |
345 | 0 | } |
346 | |
|
347 | 0 | if (level_to_use == std::numeric_limits<size_t>::max()) { |
348 | 0 | logError(fmt::format("error: invalid log level specified '{}'", log_level)); |
349 | 0 | } |
350 | 0 | return static_cast<spdlog::level::level_enum>(level_to_use); |
351 | 0 | } |
352 | | |
353 | 126 | std::string OptionsImpl::allowedLogLevels() { |
354 | 126 | std::string allowed_log_levels; |
355 | 882 | for (auto level_string_view : spdlog::level::level_string_views) { |
356 | 882 | if (level_string_view == spdlog::level::to_string_view(spdlog::level::warn)) { |
357 | 126 | allowed_log_levels += fmt::format("[{}|warn]", level_string_view); |
358 | 756 | } else { |
359 | 756 | allowed_log_levels += fmt::format("[{}]", level_string_view); |
360 | 756 | } |
361 | 882 | } |
362 | 126 | return allowed_log_levels; |
363 | 126 | } |
364 | | |
365 | 126 | void OptionsImpl::parseComponentLogLevels(const std::string& component_log_levels) { |
366 | 126 | if (component_log_levels.empty()) { |
367 | 126 | return; |
368 | 126 | } |
369 | 0 | component_log_level_str_ = component_log_levels; |
370 | 0 | std::vector<std::string> log_levels = absl::StrSplit(component_log_levels, ','); |
371 | 0 | for (auto& level : log_levels) { |
372 | 0 | std::vector<std::string> log_name_level = absl::StrSplit(level, ':'); |
373 | 0 | if (log_name_level.size() != 2) { |
374 | 0 | logError(fmt::format("error: component log level not correctly specified '{}'", level)); |
375 | 0 | } |
376 | 0 | std::string log_name = log_name_level[0]; |
377 | 0 | spdlog::level::level_enum log_level = parseAndValidateLogLevel(log_name_level[1]); |
378 | 0 | Logger::Logger* logger_to_change = Logger::Registry::logger(log_name); |
379 | 0 | if (!logger_to_change) { |
380 | 0 | logError(fmt::format("error: invalid component specified '{}'", log_name)); |
381 | 0 | } |
382 | 0 | component_log_levels_.push_back(std::make_pair(log_name, log_level)); |
383 | 0 | } |
384 | 0 | } |
385 | | |
386 | 0 | uint32_t OptionsImpl::count() const { return count_; } |
387 | | |
388 | 0 | void OptionsImpl::logError(const std::string& error) { throwMalformedArgExceptionOrPanic(error); } |
389 | | |
390 | 0 | Server::CommandLineOptionsPtr OptionsImpl::toCommandLineOptions() const { |
391 | 0 | Server::CommandLineOptionsPtr command_line_options = |
392 | 0 | std::make_unique<envoy::admin::v3::CommandLineOptions>(); |
393 | 0 | command_line_options->set_base_id(baseId()); |
394 | 0 | command_line_options->set_use_dynamic_base_id(useDynamicBaseId()); |
395 | 0 | command_line_options->set_base_id_path(baseIdPath()); |
396 | 0 | command_line_options->set_concurrency(concurrency()); |
397 | 0 | command_line_options->set_config_path(configPath()); |
398 | 0 | command_line_options->set_config_yaml(configYaml()); |
399 | 0 | command_line_options->set_allow_unknown_static_fields(allow_unknown_static_fields_); |
400 | 0 | command_line_options->set_reject_unknown_dynamic_fields(reject_unknown_dynamic_fields_); |
401 | 0 | command_line_options->set_ignore_unknown_dynamic_fields(ignore_unknown_dynamic_fields_); |
402 | 0 | command_line_options->set_admin_address_path(adminAddressPath()); |
403 | 0 | command_line_options->set_component_log_level(component_log_level_str_); |
404 | 0 | command_line_options->set_log_level(spdlog::level::to_string_view(logLevel()).data(), |
405 | 0 | spdlog::level::to_string_view(logLevel()).size()); |
406 | 0 | command_line_options->set_log_format(logFormat()); |
407 | 0 | command_line_options->set_log_format_escaped(logFormatEscaped()); |
408 | 0 | command_line_options->set_enable_fine_grain_logging(enableFineGrainLogging()); |
409 | 0 | command_line_options->set_log_path(logPath()); |
410 | 0 | command_line_options->set_service_cluster(serviceClusterName()); |
411 | 0 | command_line_options->set_service_node(serviceNodeName()); |
412 | 0 | command_line_options->set_service_zone(serviceZone()); |
413 | 0 | if (mode() == Server::Mode::Serve) { |
414 | 0 | command_line_options->set_mode(envoy::admin::v3::CommandLineOptions::Serve); |
415 | 0 | } else if (mode() == Server::Mode::Validate) { |
416 | 0 | command_line_options->set_mode(envoy::admin::v3::CommandLineOptions::Validate); |
417 | 0 | } else { |
418 | 0 | command_line_options->set_mode(envoy::admin::v3::CommandLineOptions::InitOnly); |
419 | 0 | } |
420 | 0 | if (localAddressIpVersion() == Network::Address::IpVersion::v4) { |
421 | 0 | command_line_options->set_local_address_ip_version(envoy::admin::v3::CommandLineOptions::v4); |
422 | 0 | } else { |
423 | 0 | command_line_options->set_local_address_ip_version(envoy::admin::v3::CommandLineOptions::v6); |
424 | 0 | } |
425 | 0 | command_line_options->mutable_file_flush_interval()->MergeFrom( |
426 | 0 | Protobuf::util::TimeUtil::MillisecondsToDuration(fileFlushIntervalMsec().count())); |
427 | |
|
428 | 0 | command_line_options->mutable_drain_time()->MergeFrom( |
429 | 0 | Protobuf::util::TimeUtil::SecondsToDuration(drainTime().count())); |
430 | 0 | command_line_options->set_drain_strategy(drainStrategy() == Server::DrainStrategy::Immediate |
431 | 0 | ? envoy::admin::v3::CommandLineOptions::Immediate |
432 | 0 | : envoy::admin::v3::CommandLineOptions::Gradual); |
433 | 0 | command_line_options->mutable_parent_shutdown_time()->MergeFrom( |
434 | 0 | Protobuf::util::TimeUtil::SecondsToDuration(parentShutdownTime().count())); |
435 | |
|
436 | 0 | command_line_options->set_disable_hot_restart(hotRestartDisabled()); |
437 | 0 | command_line_options->set_enable_mutex_tracing(mutexTracingEnabled()); |
438 | 0 | command_line_options->set_cpuset_threads(cpusetThreadsEnabled()); |
439 | 0 | command_line_options->set_restart_epoch(restartEpoch()); |
440 | 0 | for (const auto& e : disabledExtensions()) { |
441 | 0 | command_line_options->add_disabled_extensions(e); |
442 | 0 | } |
443 | 0 | command_line_options->set_socket_path(socketPath()); |
444 | 0 | command_line_options->set_socket_mode(socketMode()); |
445 | 0 | for (const auto& tag : statsTags()) { |
446 | 0 | command_line_options->add_stats_tag(fmt::format("{}:{}", tag.name_, tag.value_)); |
447 | 0 | } |
448 | 0 | return command_line_options; |
449 | 0 | } |
450 | | |
451 | | OptionsImpl::OptionsImpl(const std::string& service_cluster, const std::string& service_node, |
452 | | const std::string& service_zone, spdlog::level::level_enum log_level) |
453 | | : log_level_(log_level), service_cluster_(service_cluster), service_node_(service_node), |
454 | 2.64k | service_zone_(service_zone) {} |
455 | | |
456 | 0 | void OptionsImpl::disableExtensions(const std::vector<std::string>& names) { |
457 | 0 | for (const auto& name : names) { |
458 | 0 | const std::vector<absl::string_view> parts = absl::StrSplit(name, absl::MaxSplits('/', 1)); |
459 | |
|
460 | 0 | if (parts.size() != 2) { |
461 | 0 | ENVOY_LOG_MISC(warn, "failed to disable invalid extension name '{}'", name); |
462 | 0 | continue; |
463 | 0 | } |
464 | | |
465 | 0 | if (Registry::FactoryCategoryRegistry::disableFactory(parts[0], parts[1])) { |
466 | 0 | ENVOY_LOG_MISC(info, "disabled extension '{}'", name); |
467 | 0 | } else { |
468 | 0 | ENVOY_LOG_MISC(warn, "failed to disable unknown extension '{}'", name); |
469 | 0 | } |
470 | 0 | } |
471 | 0 | } |
472 | | |
473 | | } // namespace Envoy |