diff options
| author | Stefan Boberg <[email protected]> | 2026-01-19 15:47:59 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2026-01-19 15:47:59 +0100 |
| commit | 975babca65c6e118db268c6335a4ecbf7c2a9744 (patch) | |
| tree | 08c9ad8a58a7a2393ab10b26666d5fd29d44bd63 /src | |
| parent | ZenServerProcess API changes (#719) (diff) | |
| download | zen-975babca65c6e118db268c6335a4ecbf7c2a9744.tar.xz zen-975babca65c6e118db268c6335a4ecbf7c2a9744.zip | |
zenserver API changes, some other minor changes (#720)
* add system metrics output to top command
* removed unnecessary xmake directives
* file system API/comment tweaks
* fixed out-of-range access in httpserver test
* updated ZenServer base API to allow customization by mode
Diffstat (limited to 'src')
| -rw-r--r-- | src/zen/cmds/top_cmd.cpp | 42 | ||||
| -rw-r--r-- | src/zen/xmake.lua | 2 | ||||
| -rw-r--r-- | src/zencore/include/zencore/filesystem.h | 15 | ||||
| -rw-r--r-- | src/zenhttp/httpserver.cpp | 2 | ||||
| -rw-r--r-- | src/zenserver/main.cpp | 54 | ||||
| -rw-r--r-- | src/zenserver/storage/zenstorageserver.cpp | 15 | ||||
| -rw-r--r-- | src/zenserver/storage/zenstorageserver.h | 3 | ||||
| -rw-r--r-- | src/zenserver/zenserver.cpp | 77 | ||||
| -rw-r--r-- | src/zenserver/zenserver.h | 5 |
9 files changed, 186 insertions, 29 deletions
diff --git a/src/zen/cmds/top_cmd.cpp b/src/zen/cmds/top_cmd.cpp index 0e44dbbec..f674db6cd 100644 --- a/src/zen/cmds/top_cmd.cpp +++ b/src/zen/cmds/top_cmd.cpp @@ -4,6 +4,7 @@ #include <zencore/fmtutils.h> #include <zencore/logging.h> +#include <zencore/system.h> #include <zencore/uid.h> #include <zenutil/zenserverprocess.h> @@ -24,6 +25,47 @@ TopCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { ZEN_UNUSED(GlobalOptions, argc, argv); + SystemMetrics Metrics = GetSystemMetrics(); + + struct SystemMetric + { + const char* Name; + uint64_t Value; + } MetricValues[] = { + {"Cpus", Metrics.CpuCount}, + {"Cores", Metrics.CoreCount}, + {"LPs", Metrics.LogicalProcessorCount}, + {"SysMemMiB", Metrics.SystemMemoryMiB}, + {"AvailSysMemMiB", Metrics.AvailSystemMemoryMiB}, + {"VirtMemMiB", Metrics.VirtualMemoryMiB}, + {"AvailVirtMemMiB", Metrics.AvailVirtualMemoryMiB}, + {"PageFileMiB", Metrics.PageFileMiB}, + {"AvailPageFileMiB", Metrics.AvailPageFileMiB}, + }; + + std::vector<size_t> ColumnWidths; + for (const SystemMetric& Metric : MetricValues) + { + size_t NameLen = strlen(Metric.Name); + size_t ValueLen = fmt::formatted_size("{}", Metric.Value); + ColumnWidths.push_back(std::max(NameLen, ValueLen)); + } + + ExtendableStringBuilder<128> Header; + for (size_t i = 0; i < sizeof(MetricValues) / sizeof(MetricValues[0]); ++i) + { + Header << fmt::format("{:<{}} ", MetricValues[i].Name, ColumnWidths[i]); + } + ZEN_CONSOLE("{}", Header); + + // Print values with same adaptive widths + ExtendableStringBuilder<128> Values; + for (size_t i = 0; i < sizeof(MetricValues) / sizeof(MetricValues[0]); ++i) + { + Values << fmt::format("{:>{}} ", MetricValues[i].Value, ColumnWidths[i]); + } + ZEN_CONSOLE("{}\n", Values); + ZenServerState State; if (!State.InitializeReadOnly()) { diff --git a/src/zen/xmake.lua b/src/zen/xmake.lua index 55d073a86..ab094fef3 100644 --- a/src/zen/xmake.lua +++ b/src/zen/xmake.lua @@ -19,8 +19,6 @@ target("zen") add_files("zen.rc") add_ldflags("/subsystem:console,5.02") add_ldflags("/LTCG") - add_links("crypt32", "wldap32", "Ws2_32", "Shlwapi") - add_links("dbghelp", "winhttp", "version") -- for Sentry end if is_plat("macosx") then diff --git a/src/zencore/include/zencore/filesystem.h b/src/zencore/include/zencore/filesystem.h index e3eafb875..f28863679 100644 --- a/src/zencore/include/zencore/filesystem.h +++ b/src/zencore/include/zencore/filesystem.h @@ -8,8 +8,14 @@ #include <zencore/iobuffer.h> #include <zencore/string.h> +ZEN_THIRD_PARTY_INCLUDES_START #include <filesystem> #include <functional> +ZEN_THIRD_PARTY_INCLUDES_END + +#if ZEN_PLATFORM_WINDOWS +# undef CopyFile +#endif namespace zen { @@ -28,7 +34,7 @@ bool DeleteDirectories(const std::filesystem::path& Path, std::error_code& Ec); /** Ensure directory exists. - Will also create any required parent direCleanDirectoryctories + Will also create any required parent directories */ bool CreateDirectories(const std::filesystem::path& Path); @@ -149,8 +155,15 @@ struct FileContents std::error_code ErrorCode; IoBuffer Flatten(); + + explicit operator bool() const { return !ErrorCode; } }; +/** Read all of standard input into a FileContents structure + * + * Note that this will block until end-of-file is reached on standard input + * which could be a very bad idea in some contexts. + */ FileContents ReadStdIn(); /** Prepare file for reading diff --git a/src/zenhttp/httpserver.cpp b/src/zenhttp/httpserver.cpp index 085275195..c4e67d4ed 100644 --- a/src/zenhttp/httpserver.cpp +++ b/src/zenhttp/httpserver.cpp @@ -1345,7 +1345,7 @@ TEST_CASE("http.common") "{a}", [&](auto& Req) { HandledA = true; - Captures = {std::string(Req.GetCapture(1))}; + Captures = {std::string(Req.GetCapture(0))}; }, HttpVerb::kGet); diff --git a/src/zenserver/main.cpp b/src/zenserver/main.cpp index da256d06d..78bce7d06 100644 --- a/src/zenserver/main.cpp +++ b/src/zenserver/main.cpp @@ -54,8 +54,6 @@ SignalCallbackHandler(int SigNum) namespace zen { -using namespace std::literals; - ////////////////////////////////////////////////////////////////////////// #if ZEN_PLATFORM_WINDOWS @@ -89,6 +87,13 @@ AppMain(int argc, char* argv[]) { using namespace std::literals; + signal(SIGINT, utils::SignalCallbackHandler); + signal(SIGTERM, utils::SignalCallbackHandler); + +#if ZEN_PLATFORM_LINUX + IgnoreChildSignals(); +#endif + try { typename Main::Config ServerOptions; @@ -227,26 +232,49 @@ main(int argc, char* argv[]) #endif // ZEN_PLATFORM_WINDOWS using namespace zen; + using namespace std::literals; + + auto _ = zen::MakeGuard([] { + // Allow some time for worker threads to unravel, in an effort + // to prevent shutdown races in TLS object destruction + WaitForThreads(1000); + }); + + enum + { + kHub, + kStore, + kTest + } ServerMode = kStore; if (argc >= 2) { - if (argv[1] == "test"sv) + if (argv[1] == "hub"sv) { + ServerMode = kHub; + } + else if (argv[1] == "store"sv) + { + ServerMode = kStore; + } + else if (argv[1] == "test"sv) + { + ServerMode = kTest; + } + } + + switch (ServerMode) + { + case kTest: #if ZEN_WITH_TESTS return test_main(argc, argv); #else fprintf(stderr, "test option not available in release mode!\n"); exit(5); #endif - } + break; + default: + case kStore: + return AppMain<ZenStorageServerMain>(argc, argv); } - - signal(SIGINT, utils::SignalCallbackHandler); - signal(SIGTERM, utils::SignalCallbackHandler); - -#if ZEN_PLATFORM_LINUX - IgnoreChildSignals(); -#endif - - return AppMain<ZenStorageServerMain>(argc, argv); } diff --git a/src/zenserver/storage/zenstorageserver.cpp b/src/zenserver/storage/zenstorageserver.cpp index 559695a94..b2cae6482 100644 --- a/src/zenserver/storage/zenstorageserver.cpp +++ b/src/zenserver/storage/zenstorageserver.cpp @@ -17,6 +17,7 @@ #include <zencore/sentryintegration.h> #include <zencore/session.h> #include <zencore/string.h> +#include <zencore/system.h> #include <zencore/thread.h> #include <zencore/timer.h> #include <zencore/trace.h> @@ -676,8 +677,8 @@ ZenStorageServer::Run() " \\/ \\/ \\/ \\/ \\/ \n"); ExtendableStringBuilder<256> BuildOptions; - GetBuildOptions(BuildOptions); - ZEN_INFO("Build options: {}", BuildOptions); + GetBuildOptions(BuildOptions, '\n'); + ZEN_INFO("Build options ({}/{}):\n{}", GetOperatingSystemName(), GetCpuName(), BuildOptions); } ZEN_INFO(ZEN_APP_NAME " now running (pid: {})", GetCurrentProcessId()); @@ -897,6 +898,16 @@ ZenStorageServerMain::ZenStorageServerMain(ZenStorageServerConfig& ServerOptions { } +ZenStorageServerMain::~ZenStorageServerMain() +{ +} + +void +ZenStorageServerMain::InitializeLogging() +{ + InitializeServerLogging(m_ServerOptions, /* WithCacheService */ true); +} + void ZenStorageServerMain::DoRun(ZenServerState::ZenServerEntry* Entry) { diff --git a/src/zenserver/storage/zenstorageserver.h b/src/zenserver/storage/zenstorageserver.h index f79c55bc8..5ccb587d6 100644 --- a/src/zenserver/storage/zenstorageserver.h +++ b/src/zenserver/storage/zenstorageserver.h @@ -103,7 +103,10 @@ class ZenStorageServerMain : public ZenServerMain { public: ZenStorageServerMain(ZenStorageServerConfig& ServerOptions); + ~ZenStorageServerMain(); + virtual void DoRun(ZenServerState::ZenServerEntry* Entry) override; + virtual void InitializeLogging() override; ZenStorageServerMain(const ZenStorageServerMain&) = delete; ZenStorageServerMain& operator=(const ZenStorageServerMain&) = delete; diff --git a/src/zenserver/zenserver.cpp b/src/zenserver/zenserver.cpp index 95ea114bb..c5c36a4a8 100644 --- a/src/zenserver/zenserver.cpp +++ b/src/zenserver/zenserver.cpp @@ -151,6 +151,8 @@ ZenServerBase::Initialize(const ZenServerConfig& ServerOptions, ZenServerState:: EnqueueStatsReportingTimer(); } + LogSettingsSummary(ServerOptions); + return EffectiveBasePort; } @@ -163,24 +165,24 @@ ZenServerBase::Finalize() } void -ZenServerBase::GetBuildOptions(StringBuilderBase& OutOptions) +ZenServerBase::GetBuildOptions(StringBuilderBase& OutOptions, char Separator) const { ZEN_MEMSCOPE(GetZenserverTag()); OutOptions << "ZEN_ADDRESS_SANITIZER=" << (ZEN_ADDRESS_SANITIZER ? "1" : "0"); - OutOptions << ","; + OutOptions << Separator; OutOptions << "ZEN_USE_SENTRY=" << (ZEN_USE_SENTRY ? "1" : "0"); - OutOptions << ","; + OutOptions << Separator; OutOptions << "ZEN_WITH_TESTS=" << (ZEN_WITH_TESTS ? "1" : "0"); - OutOptions << ","; + OutOptions << Separator; OutOptions << "ZEN_USE_MIMALLOC=" << (ZEN_USE_MIMALLOC ? "1" : "0"); - OutOptions << ","; + OutOptions << Separator; OutOptions << "ZEN_USE_RPMALLOC=" << (ZEN_USE_RPMALLOC ? "1" : "0"); - OutOptions << ","; + OutOptions << Separator; OutOptions << "ZEN_WITH_HTTPSYS=" << (ZEN_WITH_HTTPSYS ? "1" : "0"); - OutOptions << ","; + OutOptions << Separator; OutOptions << "ZEN_WITH_MEMTRACK=" << (ZEN_WITH_MEMTRACK ? "1" : "0"); - OutOptions << ","; + OutOptions << Separator; OutOptions << "ZEN_WITH_TRACE=" << (ZEN_WITH_TRACE ? "1" : "0"); } @@ -374,6 +376,57 @@ ZenServerBase::HandleStatusRequest(HttpServerRequest& Request) Request.WriteResponse(HttpResponseCode::OK, Cbo.Save()); } +void +ZenServerBase::LogSettingsSummary(const ZenServerConfig& ServerConfig) +{ + // clang-format off + std::list<std::pair<std::string_view, std::string>> Settings = { + {"DataDir"sv, ServerConfig.DataDir.string()}, + {"AbsLogFile"sv, ServerConfig.AbsLogFile.string()}, + {"SystemRootDir"sv, ServerConfig.SystemRootDir.string()}, + {"ContentDir"sv, ServerConfig.ContentDir.string()}, + {"BasePort"sv, fmt::to_string(ServerConfig.BasePort)}, + {"IsDebug"sv, fmt::to_string(ServerConfig.IsDebug)}, + {"IsCleanStart"sv, fmt::to_string(ServerConfig.IsCleanStart)}, + {"IsPowerCycle"sv, fmt::to_string(ServerConfig.IsPowerCycle)}, + {"IsTest"sv, fmt::to_string(ServerConfig.IsTest)}, + {"Detach"sv, fmt::to_string(ServerConfig.Detach)}, + {"NoConsoleOutput"sv, fmt::to_string(ServerConfig.NoConsoleOutput)}, + {"QuietConsole"sv, fmt::to_string(ServerConfig.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.LogId}, + {"Sentry DSN"sv, ServerConfig.SentryConfig.Dsn.empty() ? "not set" : ServerConfig.SentryConfig.Dsn}, + {"Sentry Environment"sv, ServerConfig.SentryConfig.Environment}, + {"Statsd Enabled"sv, fmt::to_string(ServerConfig.StatsConfig.Enabled)}, + }; + // clang-format on + + if (ServerConfig.StatsConfig.Enabled) + { + Settings.emplace_back("Statsd Host", ServerConfig.StatsConfig.StatsdHost); + Settings.emplace_back("Statsd Port", fmt::to_string(ServerConfig.StatsConfig.StatsdPort)); + } + + size_t MaxWidth = 0; + for (const auto& Setting : Settings) + { + MaxWidth = std::max(MaxWidth, Setting.first.size()); + } + + ZEN_INFO("Server settings summary:"); + + for (const auto& Setting : Settings) + { + if (!Setting.second.empty()) + { + ZEN_INFO(" {:<{}} : {}", Setting.first, MaxWidth, Setting.second); + } + } +} + ////////////////////////////////////////////////////////////////////////// ZenServerMain::ZenServerMain(ZenServerConfig& ServerOptions) : m_ServerOptions(ServerOptions) @@ -384,6 +437,12 @@ ZenServerMain::~ZenServerMain() { } +void +ZenServerMain::InitializeLogging() +{ + InitializeServerLogging(m_ServerOptions, /* WithCacheService */ false); +} + int ZenServerMain::Run() { @@ -511,7 +570,7 @@ ZenServerMain::Run() } } - InitializeServerLogging(m_ServerOptions, /* WithCacheService */ true); + InitializeLogging(); ZEN_INFO("Command line: {}", m_ServerOptions.CommandLine); diff --git a/src/zenserver/zenserver.h b/src/zenserver/zenserver.h index 4de865a5f..ab7122fcc 100644 --- a/src/zenserver/zenserver.h +++ b/src/zenserver/zenserver.h @@ -10,6 +10,7 @@ #include <memory> #include <string_view> +#include "config/config.h" ZEN_THIRD_PARTY_INCLUDES_START #include <asio.hpp> @@ -45,7 +46,8 @@ public: protected: int Initialize(const ZenServerConfig& ServerOptions, ZenServerState::ZenServerEntry* ServerEntry); void Finalize(); - void GetBuildOptions(StringBuilderBase& OutOptions); + void GetBuildOptions(StringBuilderBase& OutOptions, char Separator = ',') const; + void LogSettingsSummary(const ZenServerConfig& ServerConfig); protected: NamedMutex m_ServerMutex; @@ -122,6 +124,7 @@ protected: ZenServerConfig& m_ServerOptions; LockFile m_LockFile; + virtual void InitializeLogging(); virtual void DoRun(ZenServerState::ZenServerEntry* Entry) = 0; void NotifyReady(); |