diff options
| author | Stefan Boberg <[email protected]> | 2026-03-15 20:42:36 +0100 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2026-03-15 20:42:36 +0100 |
| commit | 9c724efbf6b38466a9b6bfde37236369f1e85cb8 (patch) | |
| tree | 214e1ec00c5bfca0704ce52789017ade734fd054 /src/zenserver/zenserver.cpp | |
| parent | reduced WaitForThreads time to see how it behaves with explicit thread pools (diff) | |
| parent | add buildid updates to oplog and builds test scripts (#838) (diff) | |
| download | zen-9c724efbf6b38466a9b6bfde37236369f1e85cb8.tar.xz zen-9c724efbf6b38466a9b6bfde37236369f1e85cb8.zip | |
Merge remote-tracking branch 'origin/main' into sb/threadpool
Diffstat (limited to 'src/zenserver/zenserver.cpp')
| -rw-r--r-- | src/zenserver/zenserver.cpp | 132 |
1 files changed, 117 insertions, 15 deletions
diff --git a/src/zenserver/zenserver.cpp b/src/zenserver/zenserver.cpp index 5fd35d9b4..519176ffe 100644 --- a/src/zenserver/zenserver.cpp +++ b/src/zenserver/zenserver.cpp @@ -23,9 +23,11 @@ #include <zencore/timer.h> #include <zencore/trace.h> #include <zencore/workthreadpool.h> +#include <zenhttp/httpclient.h> #include <zenhttp/httpserver.h> #include <zenhttp/security/passwordsecurityfilter.h> #include <zentelemetry/otlptrace.h> +#include <zenutil/authutils.h> #include <zenutil/service.h> #include <zenutil/workerpools.h> #include <zenutil/zenserverprocess.h> @@ -46,6 +48,20 @@ ZEN_THIRD_PARTY_INCLUDES_END ////////////////////////////////////////////////////////////////////////// +#ifndef ZEN_WITH_COMPUTE_SERVICES +# define ZEN_WITH_COMPUTE_SERVICES 0 +#endif + +#ifndef ZEN_WITH_HORDE +# define ZEN_WITH_HORDE 0 +#endif + +#ifndef ZEN_WITH_NOMAD +# define ZEN_WITH_NOMAD 0 +#endif + +////////////////////////////////////////////////////////////////////////// + #include "config/config.h" #include "diag/logging.h" @@ -85,6 +101,7 @@ ZenServerBase::Initialize(const ZenServerConfig& ServerOptions, ZenServerState:: ZEN_MEMSCOPE(GetZenserverTag()); m_IsPowerCycle = ServerOptions.IsPowerCycle; + m_NoNetwork = ServerOptions.HttpConfig.NoNetwork; const std::string MutexName = fmt::format("zen_{}", ServerOptions.BasePort); @@ -131,6 +148,14 @@ ZenServerBase::Initialize(const ZenServerConfig& ServerOptions, ZenServerState:: EnqueueSigIntTimer(); + // Configure HTTP client back-end + + const std::string HttpClientBackend = ToLower(ServerOptions.HttpClient.Backend); + zen::SetDefaultHttpClientBackend(HttpClientBackend); + ZEN_INFO("Using '{}' as HTTP client backend", HttpClientBackend); + + // Initialize HTTP server + m_Http = CreateHttpServer(ServerOptions.HttpConfig); int EffectiveBasePort = m_Http->Initialize(ServerOptions.BasePort, ServerOptions.DataDir); if (EffectiveBasePort == 0) @@ -155,6 +180,7 @@ ZenServerBase::Initialize(const ZenServerConfig& ServerOptions, ZenServerState:: m_StatusService.RegisterHandler("status", *this); m_Http->RegisterService(m_StatusService); + m_Http->RegisterService(m_StatsService); m_StatsReporter.Initialize(ServerOptions.StatsConfig); if (ServerOptions.StatsConfig.Enabled) @@ -162,10 +188,37 @@ ZenServerBase::Initialize(const ZenServerConfig& ServerOptions, ZenServerState:: EnqueueStatsReportingTimer(); } - m_HealthService.SetHealthInfo({.DataRoot = ServerOptions.DataDir, - .AbsLogPath = ServerOptions.LoggingConfig.AbsLogFile, - .HttpServerClass = std::string(ServerOptions.HttpConfig.ServerClass), - .BuildVersion = std::string(ZEN_CFG_VERSION_BUILD_STRING_FULL)}); + // clang-format off + HealthServiceInfo HealthInfo { + .DataRoot = ServerOptions.DataDir, + .AbsLogPath = ServerOptions.LoggingConfig.AbsLogFile, + .HttpServerClass = std::string(ServerOptions.HttpConfig.ServerClass), + .BuildVersion = std::string(ZEN_CFG_VERSION_BUILD_STRING_FULL), + .Port = EffectiveBasePort, + .Pid = GetCurrentProcessId(), + .IsDedicated = ServerOptions.IsDedicated, + .StartTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>( + std::chrono::system_clock::now().time_since_epoch()).count(), + .BuildOptions = { + {"ZEN_ADDRESS_SANITIZER", ZEN_ADDRESS_SANITIZER != 0}, + {"ZEN_USE_SENTRY", ZEN_USE_SENTRY != 0}, + {"ZEN_WITH_TESTS", ZEN_WITH_TESTS != 0}, + {"ZEN_USE_MIMALLOC", ZEN_USE_MIMALLOC != 0}, + {"ZEN_USE_RPMALLOC", ZEN_USE_RPMALLOC != 0}, + {"ZEN_WITH_HTTPSYS", ZEN_WITH_HTTPSYS != 0}, + {"ZEN_WITH_MEMTRACK", ZEN_WITH_MEMTRACK != 0}, + {"ZEN_WITH_TRACE", ZEN_WITH_TRACE != 0}, + {"ZEN_WITH_COMPUTE_SERVICES", ZEN_WITH_COMPUTE_SERVICES != 0}, + {"ZEN_WITH_HORDE", ZEN_WITH_HORDE != 0}, + {"ZEN_WITH_NOMAD", ZEN_WITH_NOMAD != 0}, + }, + .RuntimeConfig = BuildSettingsList(ServerOptions), + }; + // clang-format on + + HealthInfo.RuntimeConfig.emplace(HealthInfo.RuntimeConfig.begin() + 2, "EffectivePort"sv, fmt::to_string(EffectiveBasePort)); + + m_HealthService.SetHealthInfo(std::move(HealthInfo)); LogSettingsSummary(ServerOptions); @@ -175,12 +228,23 @@ ZenServerBase::Initialize(const ZenServerConfig& ServerOptions, ZenServerState:: void ZenServerBase::Finalize() { + m_StatsService.RegisterHandler("http", *m_Http); + + m_Http->SetDefaultRedirect("/dashboard/"); + // Register health service last so if we return "OK" for health it means all services have been properly initialized m_Http->RegisterService(m_HealthService); } void +ZenServerBase::ShutdownServices() +{ + m_StatsService.UnregisterHandler("http", *m_Http); + m_StatsService.Shutdown(); +} + +void ZenServerBase::GetBuildOptions(StringBuilderBase& OutOptions, char Separator) const { ZEN_MEMSCOPE(GetZenserverTag()); @@ -386,22 +450,26 @@ ZenServerBase::CheckSigInt() void ZenServerBase::HandleStatusRequest(HttpServerRequest& Request) { + auto Metrics = m_MetricsTracker.Query(); + CbObjectWriter Cbo; Cbo << "ok" << true; Cbo << "state" << ToString(m_CurrentState); + Cbo << "hostname" << GetMachineName(); + Cbo << "cpuUsagePercent" << Metrics.CpuUsagePercent; + Cbo << "serverMode" << std::string_view(m_ServerMode); Request.WriteResponse(HttpResponseCode::OK, Cbo.Save()); } -void -ZenServerBase::LogSettingsSummary(const ZenServerConfig& ServerConfig) +std::vector<std::pair<std::string_view, std::string>> +ZenServerBase::BuildSettingsList(const ZenServerConfig& ServerConfig) { // clang-format off - std::list<std::pair<std::string_view, std::string>> Settings = { - {"DataDir"sv, fmt::format("{}", ServerConfig.DataDir)}, - {"AbsLogFile"sv, fmt::format("{}", ServerConfig.LoggingConfig.AbsLogFile)}, + std::vector<std::pair<std::string_view, std::string>> Settings = { {"SystemRootDir"sv, fmt::format("{}", ServerConfig.SystemRootDir)}, {"ContentDir"sv, fmt::format("{}", ServerConfig.ContentDir)}, {"BasePort"sv, fmt::to_string(ServerConfig.BasePort)}, + {"CoreLimit"sv, fmt::to_string(ServerConfig.CoreLimit)}, {"IsDebug"sv, fmt::to_string(ServerConfig.IsDebug)}, {"IsCleanStart"sv, fmt::to_string(ServerConfig.IsCleanStart)}, {"IsPowerCycle"sv, fmt::to_string(ServerConfig.IsPowerCycle)}, @@ -409,9 +477,6 @@ ZenServerBase::LogSettingsSummary(const ZenServerConfig& ServerConfig) {"Detach"sv, fmt::to_string(ServerConfig.Detach)}, {"NoConsoleOutput"sv, fmt::to_string(ServerConfig.LoggingConfig.NoConsoleOutput)}, {"QuietConsole"sv, fmt::to_string(ServerConfig.LoggingConfig.QuietConsole)}, - {"CoreLimit"sv, fmt::to_string(ServerConfig.CoreLimit)}, - {"IsDedicated"sv, fmt::to_string(ServerConfig.IsDedicated)}, - {"ShouldCrash"sv, fmt::to_string(ServerConfig.ShouldCrash)}, {"ChildId"sv, ServerConfig.ChildId}, {"LogId"sv, ServerConfig.LoggingConfig.LogId}, {"Sentry DSN"sv, ServerConfig.SentryConfig.Dsn.empty() ? "not set" : ServerConfig.SentryConfig.Dsn}, @@ -423,10 +488,28 @@ ZenServerBase::LogSettingsSummary(const ZenServerConfig& ServerConfig) if (ServerConfig.StatsConfig.Enabled) { - Settings.emplace_back("Statsd Host", ServerConfig.StatsConfig.StatsdHost); - Settings.emplace_back("Statsd Port", fmt::to_string(ServerConfig.StatsConfig.StatsdPort)); + Settings.emplace_back("Statsd Host"sv, ServerConfig.StatsConfig.StatsdHost); + Settings.emplace_back("Statsd Port"sv, fmt::to_string(ServerConfig.StatsConfig.StatsdPort)); } + return Settings; +} + +void +ZenServerBase::LogSettingsSummary(const ZenServerConfig& ServerConfig) +{ + auto Settings = BuildSettingsList(ServerConfig); + + // Log-only entries not needed in RuntimeConfig + // clang-format off + Settings.insert(Settings.begin(), { + {"DataDir"sv, fmt::format("{}", ServerConfig.DataDir)}, + {"AbsLogFile"sv, fmt::format("{}", ServerConfig.LoggingConfig.AbsLogFile)}, + }); + // clang-format on + Settings.emplace_back("IsDedicated"sv, fmt::to_string(ServerConfig.IsDedicated)); + Settings.emplace_back("ShouldCrash"sv, fmt::to_string(ServerConfig.ShouldCrash)); + size_t MaxWidth = 0; for (const auto& Setting : Settings) { @@ -643,6 +726,20 @@ ZenServerMain::Run() Entry = ServerState.Register(m_ServerOptions.BasePort); + // Publish per-instance extended info (e.g. UDS path) via a small shared memory + // section keyed by SessionId so clients can discover it during Snapshot() enumeration. + { + InstanceInfoData InstanceData; + InstanceData.UnixSocketPath = m_ServerOptions.HttpConfig.UnixSocketPath; + m_InstanceInfo.Create(GetSessionId(), InstanceData); + Entry->SignalHasInstanceInfo(); + } + + if (m_ServerOptions.HttpConfig.NoNetwork) + { + Entry->SignalNoNetwork(); + } + if (m_ServerOptions.OwnerPid) { // We are adding a sponsor process to our own entry, can't wait for pick since the code is not run until later @@ -674,6 +771,10 @@ ZenServerMain::Run() RequestApplicationExit(1); } +#if ZEN_USE_SENTRY + Sentry.Close(); +#endif + ShutdownServerLogging(); ReportServiceStatus(ServiceStatus::Stopped); @@ -699,7 +800,8 @@ ZenServerMain::MakeLockData(bool IsReady) .EffectiveListenPort = gsl::narrow<uint16_t>(m_ServerOptions.BasePort), .Ready = IsReady, .DataDir = m_ServerOptions.DataDir, - .ExecutablePath = GetRunningExecutablePath()}); + .ExecutablePath = GetRunningExecutablePath(), + .UnixSocketPath = m_ServerOptions.HttpConfig.UnixSocketPath}); }; } // namespace zen |