in source/server/server.cc [198:350]
void InstanceImpl::initialize(Options& options,
Network::Address::InstanceConstSharedPtr local_address,
ComponentFactory& component_factory) {
ENVOY_LOG(info, "initializing epoch {} (hot restart version={})", options.restartEpoch(),
restarter_.version());
ENVOY_LOG(info, "statically linked extensions:");
ENVOY_LOG(info, " access_loggers: {}",
Registry::FactoryRegistry<Configuration::AccessLogInstanceFactory>::allFactoryNames());
ENVOY_LOG(
info, " filters.http: {}",
Registry::FactoryRegistry<Configuration::NamedHttpFilterConfigFactory>::allFactoryNames());
ENVOY_LOG(info, " filters.listener: {}",
Registry::FactoryRegistry<
Configuration::NamedListenerFilterConfigFactory>::allFactoryNames());
ENVOY_LOG(
info, " filters.network: {}",
Registry::FactoryRegistry<Configuration::NamedNetworkFilterConfigFactory>::allFactoryNames());
ENVOY_LOG(info, " stat_sinks: {}",
Registry::FactoryRegistry<Configuration::StatsSinkFactory>::allFactoryNames());
ENVOY_LOG(info, " tracers: {}",
Registry::FactoryRegistry<Configuration::TracerFactory>::allFactoryNames());
ENVOY_LOG(info, " transport_sockets.downstream: {}",
Registry::FactoryRegistry<
Configuration::DownstreamTransportSocketConfigFactory>::allFactoryNames());
ENVOY_LOG(info, " transport_sockets.upstream: {}",
Registry::FactoryRegistry<
Configuration::UpstreamTransportSocketConfigFactory>::allFactoryNames());
// Handle configuration that needs to take place prior to the main configuration load.
InstanceUtil::loadBootstrapConfig(bootstrap_, options);
bootstrap_config_update_time_ = time_system_.systemTime();
// Needs to happen as early as possible in the instantiation to preempt the objects that require
// stats.
stats_store_.setTagProducer(Config::Utility::createTagProducer(bootstrap_));
stats_store_.setStatsMatcher(Config::Utility::createStatsMatcher(bootstrap_));
const std::string server_stats_prefix = "server.";
server_stats_ = std::make_unique<ServerStats>(
ServerStats{ALL_SERVER_STATS(POOL_COUNTER_PREFIX(stats_store_, server_stats_prefix),
POOL_GAUGE_PREFIX(stats_store_, server_stats_prefix))});
server_stats_->concurrency_.set(options_.concurrency());
server_stats_->hot_restart_epoch_.set(options_.restartEpoch());
assert_action_registration_ = Assert::setDebugAssertionFailureRecordAction(
[this]() { server_stats_->debug_assertion_failures_.inc(); });
failHealthcheck(false);
uint64_t version_int;
if (!StringUtil::atoul(VersionInfo::revision().substr(0, 6).c_str(), version_int, 16)) {
throw EnvoyException("compiled GIT SHA is invalid. Invalid build.");
}
server_stats_->version_.set(version_int);
bootstrap_.mutable_node()->set_build_version(VersionInfo::version());
local_info_ = std::make_unique<LocalInfo::LocalInfoImpl>(
bootstrap_.node(), local_address, options.serviceZone(), options.serviceClusterName(),
options.serviceNodeName());
Configuration::InitialImpl initial_config(bootstrap_);
HotRestart::ShutdownParentAdminInfo info;
info.original_start_time_ = original_start_time_;
restarter_.shutdownParentAdmin(info);
original_start_time_ = info.original_start_time_;
admin_ = std::make_unique<AdminImpl>(initial_config.admin().profilePath(), *this);
if (initial_config.admin().address()) {
if (initial_config.admin().accessLogPath().empty()) {
throw EnvoyException("An admin access log path is required for a listening server.");
}
ENVOY_LOG(info, "admin address: {}", initial_config.admin().address()->asString());
admin_->startHttpListener(initial_config.admin().accessLogPath(), options.adminAddressPath(),
initial_config.admin().address(),
stats_store_.createScope("listener.admin."));
} else {
ENVOY_LOG(warn, "No admin address given, so no admin HTTP server started.");
}
config_tracker_entry_ =
admin_->getConfigTracker().add("bootstrap", [this] { return dumpBootstrapConfig(); });
if (initial_config.admin().address()) {
admin_->addListenerToHandler(handler_.get());
}
loadServerFlags(initial_config.flagsPath());
// Initialize the overload manager early so other modules can register for actions.
overload_manager_ = std::make_unique<OverloadManagerImpl>(dispatcher(), stats(), threadLocal(),
bootstrap_.overload_manager());
// Workers get created first so they register for thread local updates.
listener_manager_ = std::make_unique<ListenerManagerImpl>(*this, listener_component_factory_,
worker_factory_, time_system_);
// The main thread is also registered for thread local updates so that code that does not care
// whether it runs on the main thread or on workers can still use TLS.
thread_local_.registerThread(*dispatcher_, true);
// We can now initialize stats for threading.
stats_store_.initializeThreading(*dispatcher_, thread_local_);
// Runtime gets initialized before the main configuration since during main configuration
// load things may grab a reference to the loader for later use.
runtime_loader_ = component_factory.createRuntime(*this, initial_config);
// Once we have runtime we can initialize the SSL context manager.
ssl_context_manager_ = std::make_unique<Ssl::ContextManagerImpl>(time_system_);
cluster_manager_factory_ = std::make_unique<Upstream::ProdClusterManagerFactory>(
runtime(), stats(), threadLocal(), random(), dnsResolver(), sslContextManager(), dispatcher(),
localInfo(), secretManager(), api(), http_context_);
// Now the configuration gets parsed. The configuration may start setting
// thread local data per above. See MainImpl::initialize() for why ConfigImpl
// is constructed as part of the InstanceImpl and then populated once
// cluster_manager_factory_ is available.
config_.initialize(bootstrap_, *this, *cluster_manager_factory_);
http_context_.setTracer(config_.httpTracer());
// Instruct the listener manager to create the LDS provider if needed. This must be done later
// because various items do not yet exist when the listener manager is created.
if (bootstrap_.dynamic_resources().has_lds_config()) {
listener_manager_->createLdsApi(bootstrap_.dynamic_resources().lds_config());
}
if (bootstrap_.has_hds_config()) {
const auto& hds_config = bootstrap_.hds_config();
async_client_manager_ = std::make_unique<Grpc::AsyncClientManagerImpl>(
clusterManager(), thread_local_, time_system_, api());
hds_delegate_ = std::make_unique<Upstream::HdsDelegate>(
bootstrap_.node(), stats(),
Config::Utility::factoryForGrpcApiConfigSource(*async_client_manager_, hds_config, stats())
->create(),
dispatcher(), runtime(), stats(), sslContextManager(), random(), info_factory_,
access_log_manager_, clusterManager(), localInfo());
}
for (Stats::SinkPtr& sink : config_.statsSinks()) {
stats_store_.addSink(*sink);
}
// Some of the stat sinks may need dispatcher support so don't flush until the main loop starts.
// Just setup the timer.
stat_flush_timer_ = dispatcher_->createTimer([this]() -> void { flushStats(); });
stat_flush_timer_->enableTimer(config_.statsFlushInterval());
// GuardDog (deadlock detection) object and thread setup before workers are
// started and before our own run() loop runs.
guard_dog_ = std::make_unique<Server::GuardDogImpl>(stats_store_, config_, time_system_, api());
}