Coverage Report

Created: 2023-11-12 09:30

/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