aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/zenserver.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2026-03-15 20:42:36 +0100
committerStefan Boberg <[email protected]>2026-03-15 20:42:36 +0100
commit9c724efbf6b38466a9b6bfde37236369f1e85cb8 (patch)
tree214e1ec00c5bfca0704ce52789017ade734fd054 /src/zenserver/zenserver.cpp
parentreduced WaitForThreads time to see how it behaves with explicit thread pools (diff)
parentadd buildid updates to oplog and builds test scripts (#838) (diff)
downloadzen-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.cpp132
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