Coverage Report

Created: 2024-09-19 09:45

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