aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2026-04-13 12:09:05 +0200
committerGitHub Enterprise <[email protected]>2026-04-13 12:09:05 +0200
commite0879bed083eab09cfa28043a3b210714d0884b9 (patch)
tree00d5dddc9a046bd0112e1fddcfce430ced14a355 /src
parentupdate minio (#947) (diff)
downloadzen-e0879bed083eab09cfa28043a3b210714d0884b9.tar.xz
zen-e0879bed083eab09cfa28043a3b210714d0884b9.zip
Logging and diagnostics improvements (#941)
Core logging and system diagnostics improvements, extracted from the compute branch. ### Logging - **Elapsed timestamps**: Console log now shows elapsed time since launch `[HH:MM:SS.mmm]` instead of full date/time; file logging is unchanged - **Short level names**: 3-letter short level names (`trc`/`dbg`/`inf`/`wrn`/`err`/`crt`) used by both console and file formatters via `ShortToStringView()` - **Consistent field order**: Standardized to `[timestamp] [level] [logger]` across both console and file formatters - **Slim LogMessage/LogPoint**: Remove redundant fields from `LogMessage` (derive level/source from `LogPoint`), flatten `LogPoint` to inline filename/line fields, shrink `LogLevel` to `int8_t` with `static_assert(sizeof(LogPoint) <= 32)` - **Remove default member initializers** and static default `LogPoint` from `LogMessage` — all fields initialized by constructor - **LoggerRef string constructor**: Convenience constructor accepting a string directly - **Fix SendMessage macro collision**: Replace `thread.h` include in `logmsg.h` with a forward declaration of `GetCurrentThreadId()` to avoid pulling in `windows.h` transitively ### System Diagnostics - **Cache static system metrics**: Add `RefreshDynamicSystemMetrics()` that only queries values that change at runtime (available memory, uptime, swap). `SystemMetricsTracker` snapshots full `GetSystemMetrics()` once at construction and reuses cached topology/total memory on each `Query()`, avoiding repeated `GetLogicalProcessorInformationEx` traversal on Windows, `/proc/cpuinfo` parsing on Linux, and `sysctl` topology calls on macOS
Diffstat (limited to 'src')
-rw-r--r--src/zencompute/include/zencompute/orchestratorservice.h7
-rw-r--r--src/zencore/include/zencore/logbase.h13
-rw-r--r--src/zencore/include/zencore/logging.h60
-rw-r--r--src/zencore/include/zencore/logging/helpers.h2
-rw-r--r--src/zencore/include/zencore/logging/logmsg.h49
-rw-r--r--src/zencore/include/zencore/system.h5
-rw-r--r--src/zencore/logging.cpp29
-rw-r--r--src/zencore/logging/ansicolorsink.cpp66
-rw-r--r--src/zencore/system.cpp97
-rw-r--r--src/zenremotestore/include/zenremotestore/operationlogoutput.h14
-rw-r--r--src/zenserver/diag/logging.cpp2
-rw-r--r--src/zenutil/logging/fullformatter.cpp30
-rw-r--r--src/zenutil/logging/logging.cpp4
-rw-r--r--src/zenutil/splitconsole/logstreamlistener.cpp2
14 files changed, 269 insertions, 111 deletions
diff --git a/src/zencompute/include/zencompute/orchestratorservice.h b/src/zencompute/include/zencompute/orchestratorservice.h
index 071e902b3..549ff8e3c 100644
--- a/src/zencompute/include/zencompute/orchestratorservice.h
+++ b/src/zencompute/include/zencompute/orchestratorservice.h
@@ -7,6 +7,8 @@
#if ZEN_WITH_COMPUTE_SERVICES
# include <zencore/compactbinary.h>
+# include <zencore/compactbinarybuilder.h>
+# include <zencore/logbase.h>
# include <zencore/thread.h>
# include <zencore/timer.h>
# include <zencore/uid.h>
@@ -164,7 +166,10 @@ private:
void RecordClientEvent(ClientEvent::Type Type, std::string_view ClientId, std::string_view Hostname);
- bool m_EnableWorkerWebSocket = false;
+ LoggerRef Log() { return m_Log; }
+
+ LoggerRef m_Log{"compute.orchestrator"};
+ bool m_EnableWorkerWebSocket = false;
std::thread m_ProbeThread;
std::atomic<bool> m_ProbeThreadEnabled{true};
diff --git a/src/zencore/include/zencore/logbase.h b/src/zencore/include/zencore/logbase.h
index ad2ab218d..65f8a9dbe 100644
--- a/src/zencore/include/zencore/logbase.h
+++ b/src/zencore/include/zencore/logbase.h
@@ -8,7 +8,7 @@
#include <string_view>
namespace zen::logging {
-enum LogLevel : int
+enum LogLevel : int8_t
{
Trace,
Debug,
@@ -22,6 +22,7 @@ enum LogLevel : int
LogLevel ParseLogLevelString(std::string_view String);
std::string_view ToStringView(LogLevel Level);
+std::string_view ShortToStringView(LogLevel Level);
void SetLogLevel(LogLevel NewLogLevel);
LogLevel GetLogLevel();
@@ -49,11 +50,16 @@ struct SourceLocation
*/
struct LogPoint
{
- SourceLocation Location;
+ const char* Filename;
+ int Line;
LogLevel Level;
std::string_view FormatString;
+
+ [[nodiscard]] SourceLocation Location() const { return SourceLocation{Filename, Line}; }
};
+static_assert(sizeof(LogPoint) <= 32);
+
class Logger;
/** This is the base class for all loggers
@@ -91,6 +97,7 @@ struct LoggerRef
{
LoggerRef() = default;
explicit LoggerRef(logging::Logger& InLogger);
+ explicit LoggerRef(std::string_view LogCategory);
// This exists so that logging macros can pass LoggerRef or LogCategory
// to ZEN_LOG without needing to know which one it is
@@ -104,6 +111,8 @@ struct LoggerRef
bool ShouldLog(logging::LogLevel Level) const { return m_Logger->ShouldLog(Level); }
void SetLogLevel(logging::LogLevel NewLogLevel) { m_Logger->SetLevel(NewLogLevel); }
logging::LogLevel GetLogLevel() { return m_Logger->GetLevel(); }
+ std::string_view GetLogLevelString() { return logging::ToStringView(GetLogLevel()); }
+ std::string_view GetShortLogLevelString() { return logging::ShortToStringView(GetLogLevel()); }
void Flush();
diff --git a/src/zencore/include/zencore/logging.h b/src/zencore/include/zencore/logging.h
index 1608ad523..8c236d09b 100644
--- a/src/zencore/include/zencore/logging.h
+++ b/src/zencore/include/zencore/logging.h
@@ -131,31 +131,31 @@ using zen::Log;
}
#endif
-#define ZEN_LOG_WITH_LOCATION(InLogger, InLevel, fmtstr, ...) \
- do \
- { \
- using namespace std::literals; \
- static constinit ZEN_LOG_SECTION(".zlog$l") \
- zen::logging::LogPoint LogPoint{zen::logging::SourceLocation{__FILE__, __LINE__}, InLevel, std::string_view(fmtstr)}; \
- zen::LoggerRef Logger = InLogger; \
- ZEN_CHECK_FORMAT_STRING(fmtstr##sv, ##__VA_ARGS__); \
- if (Logger.ShouldLog(InLevel)) \
- { \
- zen::logging::EmitLogMessage(Logger, LogPoint, zen::logging::LogCaptureArguments(__VA_ARGS__)); \
- } \
+#define ZEN_LOG_WITH_LOCATION(InLogger, InLevel, fmtstr, ...) \
+ do \
+ { \
+ using namespace std::literals; \
+ static constinit ZEN_LOG_SECTION(".zlog$l") \
+ zen::logging::LogPoint LogPoint{__FILE__, __LINE__, InLevel, std::string_view(fmtstr)}; \
+ zen::LoggerRef Logger = InLogger; \
+ ZEN_CHECK_FORMAT_STRING(fmtstr##sv, ##__VA_ARGS__); \
+ if (Logger.ShouldLog(InLevel)) \
+ { \
+ zen::logging::EmitLogMessage(Logger, LogPoint, zen::logging::LogCaptureArguments(__VA_ARGS__)); \
+ } \
} while (false);
-#define ZEN_LOG(InLogger, InLevel, fmtstr, ...) \
- do \
- { \
- using namespace std::literals; \
- static constinit ZEN_LOG_SECTION(".zlog$l") zen::logging::LogPoint LogPoint{{}, InLevel, std::string_view(fmtstr)}; \
- zen::LoggerRef Logger = InLogger; \
- ZEN_CHECK_FORMAT_STRING(fmtstr##sv, ##__VA_ARGS__); \
- if (Logger.ShouldLog(InLevel)) \
- { \
- zen::logging::EmitLogMessage(Logger, LogPoint, zen::logging::LogCaptureArguments(__VA_ARGS__)); \
- } \
+#define ZEN_LOG(InLogger, InLevel, fmtstr, ...) \
+ do \
+ { \
+ using namespace std::literals; \
+ static constinit ZEN_LOG_SECTION(".zlog$l") zen::logging::LogPoint LogPoint{0, 0, InLevel, std::string_view(fmtstr)}; \
+ zen::LoggerRef Logger = InLogger; \
+ ZEN_CHECK_FORMAT_STRING(fmtstr##sv, ##__VA_ARGS__); \
+ if (Logger.ShouldLog(InLevel)) \
+ { \
+ zen::logging::EmitLogMessage(Logger, LogPoint, zen::logging::LogCaptureArguments(__VA_ARGS__)); \
+ } \
} while (false);
#define ZEN_DEFINE_LOG_CATEGORY_STATIC(Category, Name) \
@@ -175,13 +175,13 @@ using zen::Log;
#define ZEN_ERROR(fmtstr, ...) ZEN_LOG_WITH_LOCATION(Log(), zen::logging::Err, fmtstr, ##__VA_ARGS__)
#define ZEN_CRITICAL(fmtstr, ...) ZEN_LOG_WITH_LOCATION(Log(), zen::logging::Critical, fmtstr, ##__VA_ARGS__)
-#define ZEN_CONSOLE_LOG(InLevel, fmtstr, ...) \
- do \
- { \
- using namespace std::literals; \
- static constinit ZEN_LOG_SECTION(".zlog$l") zen::logging::LogPoint LogPoint{{}, InLevel, std::string_view(fmtstr)}; \
- ZEN_CHECK_FORMAT_STRING(fmtstr##sv, ##__VA_ARGS__); \
- zen::logging::EmitConsoleLogMessage(LogPoint, zen::logging::LogCaptureArguments(__VA_ARGS__)); \
+#define ZEN_CONSOLE_LOG(InLevel, fmtstr, ...) \
+ do \
+ { \
+ using namespace std::literals; \
+ static constinit ZEN_LOG_SECTION(".zlog$l") zen::logging::LogPoint LogPoint{0, 0, InLevel, std::string_view(fmtstr)}; \
+ ZEN_CHECK_FORMAT_STRING(fmtstr##sv, ##__VA_ARGS__); \
+ zen::logging::EmitConsoleLogMessage(LogPoint, zen::logging::LogCaptureArguments(__VA_ARGS__)); \
} while (false)
#define ZEN_CONSOLE(fmtstr, ...) ZEN_CONSOLE_LOG(zen::logging::Info, fmtstr, ##__VA_ARGS__)
diff --git a/src/zencore/include/zencore/logging/helpers.h b/src/zencore/include/zencore/logging/helpers.h
index 765aa59e3..1092e7095 100644
--- a/src/zencore/include/zencore/logging/helpers.h
+++ b/src/zencore/include/zencore/logging/helpers.h
@@ -116,7 +116,7 @@ ShortFilename(const char* Path)
inline std::string_view
LevelToShortString(LogLevel Level)
{
- return ToStringView(Level);
+ return ShortToStringView(Level);
}
inline std::string_view
diff --git a/src/zencore/include/zencore/logging/logmsg.h b/src/zencore/include/zencore/logging/logmsg.h
index 4a777c71e..644af2730 100644
--- a/src/zencore/include/zencore/logging/logmsg.h
+++ b/src/zencore/include/zencore/logging/logmsg.h
@@ -7,49 +7,50 @@
#include <chrono>
#include <string_view>
+namespace zen {
+int GetCurrentThreadId();
+}
+
namespace zen::logging {
using LogClock = std::chrono::system_clock;
+/**
+ * This represents a single log event, with all the data needed to format and
+ * emit the final log message.
+ *
+ * LogMessage is what gets passed to Sinks, and it's what contains all the
+ * contextual information about the log event.
+ */
+
struct LogMessage
{
- LogMessage() = default;
-
LogMessage(const LogPoint& InPoint, std::string_view InLoggerName, std::string_view InPayload)
: m_LoggerName(InLoggerName)
- , m_Level(InPoint.Level)
, m_Time(LogClock::now())
- , m_Source(InPoint.Location)
+ , m_ThreadId(zen::GetCurrentThreadId())
, m_Payload(InPayload)
, m_Point(&InPoint)
{
}
- std::string_view GetPayload() const { return m_Payload; }
- int GetThreadId() const { return m_ThreadId; }
- LogClock::time_point GetTime() const { return m_Time; }
- LogLevel GetLevel() const { return m_Level; }
- std::string_view GetLoggerName() const { return m_LoggerName; }
- const SourceLocation& GetSource() const { return m_Source; }
- const LogPoint& GetLogPoint() const { return *m_Point; }
+ [[nodiscard]] std::string_view GetPayload() const { return m_Payload; }
+ [[nodiscard]] int GetThreadId() const { return m_ThreadId; }
+ [[nodiscard]] LogClock::time_point GetTime() const { return m_Time; }
+ [[nodiscard]] LogLevel GetLevel() const { return m_Point->Level; }
+ [[nodiscard]] std::string_view GetLoggerName() const { return m_LoggerName; }
+ [[nodiscard]] SourceLocation GetSource() const { return m_Point->Location(); }
+ [[nodiscard]] const LogPoint& GetLogPoint() const { return *m_Point; }
void SetThreadId(int InThreadId) { m_ThreadId = InThreadId; }
- void SetPayload(std::string_view InPayload) { m_Payload = InPayload; }
- void SetLoggerName(std::string_view InName) { m_LoggerName = InName; }
- void SetLevel(LogLevel InLevel) { m_Level = InLevel; }
void SetTime(LogClock::time_point InTime) { m_Time = InTime; }
- void SetSource(const SourceLocation& InSource) { m_Source = InSource; }
private:
- static constexpr LogPoint s_DefaultPoint{{}, Off, {}};
-
- std::string_view m_LoggerName;
- LogLevel m_Level = Off;
- std::chrono::system_clock::time_point m_Time;
- SourceLocation m_Source;
- std::string_view m_Payload;
- const LogPoint* m_Point = &s_DefaultPoint;
- int m_ThreadId = 0;
+ std::string_view m_LoggerName;
+ LogClock::time_point m_Time;
+ int m_ThreadId;
+ std::string_view m_Payload;
+ const LogPoint* m_Point;
};
} // namespace zen::logging
diff --git a/src/zencore/include/zencore/system.h b/src/zencore/include/zencore/system.h
index 52dafc18b..efc9bb6d2 100644
--- a/src/zencore/include/zencore/system.h
+++ b/src/zencore/include/zencore/system.h
@@ -46,6 +46,11 @@ struct ExtendedSystemMetrics : SystemMetrics
SystemMetrics GetSystemMetrics();
+/// Lightweight query that only refreshes fields that change at runtime
+/// (available memory, uptime). Topology fields (CPU/core counts, total memory)
+/// are left at their default values and must be filled from a cached snapshot.
+void RefreshDynamicSystemMetrics(SystemMetrics& InOutMetrics);
+
void SetCpuCountForReporting(int FakeCpuCount);
SystemMetrics GetSystemMetricsForReporting();
diff --git a/src/zencore/logging.cpp b/src/zencore/logging.cpp
index 5ada0cac7..ca34b7d0e 100644
--- a/src/zencore/logging.cpp
+++ b/src/zencore/logging.cpp
@@ -112,6 +112,14 @@ constinit std::string_view LevelNames[] = {std::string_view("trace", 5),
std::string_view("critical", 8),
std::string_view("off", 3)};
+constinit std::string_view ShortNames[] = {std::string_view("trc", 3),
+ std::string_view("dbg", 3),
+ std::string_view("inf", 3),
+ std::string_view("wrn", 3),
+ std::string_view("err", 3),
+ std::string_view("crt", 3),
+ std::string_view("off", 3)};
+
LogLevel
ParseLogLevelString(std::string_view Name)
{
@@ -139,12 +147,27 @@ ParseLogLevelString(std::string_view Name)
std::string_view
ToStringView(LogLevel Level)
{
+ using namespace std::literals;
+
if (int(Level) < LogLevelCount)
{
return LevelNames[int(Level)];
}
- return "None";
+ return "None"sv;
+}
+
+std::string_view
+ShortToStringView(LogLevel Level)
+{
+ using namespace std::literals;
+
+ if (int(Level) < LogLevelCount)
+ {
+ return ShortNames[int(Level)];
+ }
+
+ return "None"sv;
}
} // namespace zen::logging
@@ -476,6 +499,10 @@ LoggerRef::LoggerRef(logging::Logger& InLogger) : m_Logger(static_cast<logging::
{
}
+LoggerRef::LoggerRef(std::string_view LogCategory) : m_Logger(zen::logging::Get(LogCategory).m_Logger)
+{
+}
+
void
LoggerRef::Flush()
{
diff --git a/src/zencore/logging/ansicolorsink.cpp b/src/zencore/logging/ansicolorsink.cpp
index 03aae068a..1a8201876 100644
--- a/src/zencore/logging/ansicolorsink.cpp
+++ b/src/zencore/logging/ansicolorsink.cpp
@@ -5,6 +5,7 @@
#include <zencore/logging/messageonlyformatter.h>
#include <zencore/thread.h>
+#include <zencore/timer.h>
#include <cstdio>
#include <cstdlib>
@@ -22,48 +23,37 @@
namespace zen::logging {
-// Default formatter replicating spdlog's %+ pattern:
-// [YYYY-MM-DD HH:MM:SS.mmm] [logger_name] [level] message\n
+// Default formatter for console output:
+// [HH:MM:SS.mmm] [logger_name] [level] message\n
+// Timestamps show elapsed time since process launch.
class DefaultConsoleFormatter : public Formatter
{
public:
+ DefaultConsoleFormatter() : m_Epoch(std::chrono::system_clock::now() - std::chrono::milliseconds(GetTimeSinceProcessStart())) {}
+
void Format(const LogMessage& Msg, MemoryBuffer& Dest) override
{
- // timestamp
- auto Secs = std::chrono::duration_cast<std::chrono::seconds>(Msg.GetTime().time_since_epoch());
- if (Secs != m_LastLogSecs)
- {
- m_LastLogSecs = Secs;
- m_CachedLocalTm = helpers::SafeLocaltime(LogClock::to_time_t(Msg.GetTime()));
- }
+ // Elapsed time since process launch
+ auto Elapsed = Msg.GetTime() - m_Epoch;
+ auto TotalSecs = std::chrono::duration_cast<std::chrono::seconds>(Elapsed);
+ int Count = static_cast<int>(TotalSecs.count());
+ int LogSecs = Count % 60;
+ Count /= 60;
+ int LogMins = Count % 60;
+ int LogHours = Count / 60;
Dest.push_back('[');
- helpers::AppendInt(m_CachedLocalTm.tm_year + 1900, Dest);
- Dest.push_back('-');
- helpers::Pad2(m_CachedLocalTm.tm_mon + 1, Dest);
- Dest.push_back('-');
- helpers::Pad2(m_CachedLocalTm.tm_mday, Dest);
- Dest.push_back(' ');
- helpers::Pad2(m_CachedLocalTm.tm_hour, Dest);
+ helpers::Pad2(LogHours, Dest);
Dest.push_back(':');
- helpers::Pad2(m_CachedLocalTm.tm_min, Dest);
+ helpers::Pad2(LogMins, Dest);
Dest.push_back(':');
- helpers::Pad2(m_CachedLocalTm.tm_sec, Dest);
+ helpers::Pad2(LogSecs, Dest);
Dest.push_back('.');
auto Millis = helpers::TimeFraction<std::chrono::milliseconds>(Msg.GetTime());
helpers::Pad3(static_cast<uint32_t>(Millis.count()), Dest);
Dest.push_back(']');
Dest.push_back(' ');
- // logger name
- if (Msg.GetLoggerName().size() > 0)
- {
- Dest.push_back('[');
- helpers::AppendStringView(Msg.GetLoggerName(), Dest);
- Dest.push_back(']');
- Dest.push_back(' ');
- }
-
// level
Dest.push_back('[');
if (IsColorEnabled())
@@ -78,6 +68,25 @@ public:
Dest.push_back(']');
Dest.push_back(' ');
+ using namespace std::literals;
+
+ // logger name
+ if (Msg.GetLoggerName().size() > 0)
+ {
+ if (IsColorEnabled())
+ {
+ Dest.append("\033[97m"sv);
+ }
+ Dest.push_back('[');
+ helpers::AppendStringView(Msg.GetLoggerName(), Dest);
+ Dest.push_back(']');
+ if (IsColorEnabled())
+ {
+ Dest.append("\033[0m"sv);
+ }
+ Dest.push_back(' ');
+ }
+
// message (align continuation lines with the first line)
size_t AnsiBytes = IsColorEnabled() ? (helpers::AnsiColorForLevel(Msg.GetLevel()).size() + helpers::kAnsiReset.size()) : 0;
size_t LinePrefixCount = Dest.size() - AnsiBytes;
@@ -128,8 +137,7 @@ public:
}
private:
- std::chrono::seconds m_LastLogSecs{0};
- std::tm m_CachedLocalTm{};
+ LogClock::time_point m_Epoch;
};
bool
diff --git a/src/zencore/system.cpp b/src/zencore/system.cpp
index 6909e1a9b..486050d83 100644
--- a/src/zencore/system.cpp
+++ b/src/zencore/system.cpp
@@ -148,6 +148,18 @@ GetSystemMetrics()
return Metrics;
}
+void
+RefreshDynamicSystemMetrics(SystemMetrics& Metrics)
+{
+ MEMORYSTATUSEX MemStatus{.dwLength = sizeof(MEMORYSTATUSEX)};
+ GlobalMemoryStatusEx(&MemStatus);
+
+ Metrics.AvailSystemMemoryMiB = MemStatus.ullAvailPhys / 1024 / 1024;
+ Metrics.AvailVirtualMemoryMiB = MemStatus.ullAvailVirtual / 1024 / 1024;
+ Metrics.AvailPageFileMiB = MemStatus.ullAvailPageFile / 1024 / 1024;
+ Metrics.UptimeSeconds = GetTickCount64() / 1000;
+}
+
std::vector<std::string>
GetLocalIpAddresses()
{
@@ -324,6 +336,51 @@ GetSystemMetrics()
return Metrics;
}
+
+void
+RefreshDynamicSystemMetrics(SystemMetrics& Metrics)
+{
+ long PageSize = sysconf(_SC_PAGE_SIZE);
+ long AvailPages = sysconf(_SC_AVPHYS_PAGES);
+
+ if (AvailPages > 0 && PageSize > 0)
+ {
+ Metrics.AvailSystemMemoryMiB = (AvailPages * PageSize) / 1024 / 1024;
+ Metrics.AvailVirtualMemoryMiB = Metrics.AvailSystemMemoryMiB;
+ }
+
+ if (FILE* UptimeFile = fopen("/proc/uptime", "r"))
+ {
+ double UptimeSec = 0;
+ if (fscanf(UptimeFile, "%lf", &UptimeSec) == 1)
+ {
+ Metrics.UptimeSeconds = static_cast<uint64_t>(UptimeSec);
+ }
+ fclose(UptimeFile);
+ }
+
+ if (FILE* MemInfo = fopen("/proc/meminfo", "r"))
+ {
+ char Line[256];
+ long SwapFree = 0;
+
+ while (fgets(Line, sizeof(Line), MemInfo))
+ {
+ if (strncmp(Line, "SwapFree:", 9) == 0)
+ {
+ sscanf(Line, "SwapFree: %ld kB", &SwapFree);
+ break;
+ }
+ }
+ fclose(MemInfo);
+
+ if (SwapFree > 0)
+ {
+ Metrics.AvailPageFileMiB = SwapFree / 1024;
+ }
+ }
+}
+
#elif ZEN_PLATFORM_MAC
std::string
GetMachineName()
@@ -398,6 +455,36 @@ GetSystemMetrics()
return Metrics;
}
+
+void
+RefreshDynamicSystemMetrics(SystemMetrics& Metrics)
+{
+ vm_size_t PageSize = 0;
+ host_page_size(mach_host_self(), &PageSize);
+
+ vm_statistics64_data_t VmStats;
+ mach_msg_type_number_t InfoCount = sizeof(VmStats) / sizeof(natural_t);
+ host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t)&VmStats, &InfoCount);
+
+ uint64_t FreeMemory = (uint64_t)(VmStats.free_count + VmStats.inactive_count) * PageSize;
+ Metrics.AvailSystemMemoryMiB = FreeMemory / 1024 / 1024;
+ Metrics.AvailVirtualMemoryMiB = Metrics.VirtualMemoryMiB;
+
+ xsw_usage SwapUsage;
+ size_t Size = sizeof(SwapUsage);
+ sysctlbyname("vm.swapusage", &SwapUsage, &Size, nullptr, 0);
+ Metrics.AvailPageFileMiB = (SwapUsage.xsu_total - SwapUsage.xsu_used) / 1024 / 1024;
+
+ struct timeval BootTime
+ {
+ };
+ Size = sizeof(BootTime);
+ if (sysctlbyname("kern.boottime", &BootTime, &Size, nullptr, 0) == 0)
+ {
+ Metrics.UptimeSeconds = static_cast<uint64_t>(time(nullptr) - BootTime.tv_sec);
+ }
+}
+
#else
# error "Unknown platform"
#endif
@@ -655,11 +742,16 @@ struct SystemMetricsTracker::Impl
std::mutex Mutex;
CpuSampler Sampler;
+ SystemMetrics CachedMetrics;
float CachedCpuPercent = 0.0f;
Clock::time_point NextSampleTime = Clock::now();
std::chrono::milliseconds MinInterval;
- explicit Impl(std::chrono::milliseconds InMinInterval) : MinInterval(InMinInterval) {}
+ explicit Impl(std::chrono::milliseconds InMinInterval) : MinInterval(InMinInterval)
+ {
+ // Capture topology and total memory once; these don't change at runtime
+ CachedMetrics = GetSystemMetrics();
+ }
float SampleCpu()
{
@@ -683,7 +775,8 @@ ExtendedSystemMetrics
SystemMetricsTracker::Query()
{
ExtendedSystemMetrics Metrics;
- static_cast<SystemMetrics&>(Metrics) = GetSystemMetrics();
+ static_cast<SystemMetrics&>(Metrics) = m_Impl->CachedMetrics;
+ RefreshDynamicSystemMetrics(Metrics);
std::lock_guard Lock(m_Impl->Mutex);
Metrics.CpuUsagePercent = m_Impl->SampleCpu();
diff --git a/src/zenremotestore/include/zenremotestore/operationlogoutput.h b/src/zenremotestore/include/zenremotestore/operationlogoutput.h
index 32b95f50f..904dc166b 100644
--- a/src/zenremotestore/include/zenremotestore/operationlogoutput.h
+++ b/src/zenremotestore/include/zenremotestore/operationlogoutput.h
@@ -60,13 +60,13 @@ public:
OperationLogOutput* CreateStandardLogOutput(LoggerRef Log);
-#define ZEN_OPERATION_LOG(OutputTarget, InLevel, fmtstr, ...) \
- do \
- { \
- using namespace std::literals; \
- static constinit zen::logging::LogPoint LogPoint{{}, InLevel, std::string_view(fmtstr)}; \
- ZEN_CHECK_FORMAT_STRING(fmtstr##sv, ##__VA_ARGS__); \
- (OutputTarget).EmitLogMessage(LogPoint, zen::logging::LogCaptureArguments(__VA_ARGS__)); \
+#define ZEN_OPERATION_LOG(OutputTarget, InLevel, fmtstr, ...) \
+ do \
+ { \
+ using namespace std::literals; \
+ static constinit zen::logging::LogPoint LogPoint{0, 0, InLevel, std::string_view(fmtstr)}; \
+ ZEN_CHECK_FORMAT_STRING(fmtstr##sv, ##__VA_ARGS__); \
+ (OutputTarget).EmitLogMessage(LogPoint, zen::logging::LogCaptureArguments(__VA_ARGS__)); \
} while (false)
#define ZEN_OPERATION_LOG_INFO(OutputTarget, fmtstr, ...) ZEN_OPERATION_LOG(OutputTarget, zen::logging::Info, fmtstr, ##__VA_ARGS__)
diff --git a/src/zenserver/diag/logging.cpp b/src/zenserver/diag/logging.cpp
index f3d8dbfe3..e1a8fed7d 100644
--- a/src/zenserver/diag/logging.cpp
+++ b/src/zenserver/diag/logging.cpp
@@ -112,7 +112,7 @@ InitializeServerLogging(const ZenServerConfig& InOptions, bool WithCacheService)
const zen::Oid ServerSessionId = zen::GetSessionId();
logging::Registry::Instance().ApplyAll([&](auto Logger) {
- static constinit logging::LogPoint SessionIdPoint{{}, logging::Info, "server session id: {}"};
+ static constinit logging::LogPoint SessionIdPoint{0, 0, logging::Info, "server session id: {}"};
ZEN_MEMSCOPE(ELLMTag::Logging);
Logger->Log(SessionIdPoint, fmt::make_format_args(ServerSessionId));
});
diff --git a/src/zenutil/logging/fullformatter.cpp b/src/zenutil/logging/fullformatter.cpp
index 2a4840241..283a8bc37 100644
--- a/src/zenutil/logging/fullformatter.cpp
+++ b/src/zenutil/logging/fullformatter.cpp
@@ -12,6 +12,7 @@
#include <atomic>
#include <chrono>
#include <string>
+#include "zencore/logging.h"
namespace zen::logging {
@@ -25,7 +26,7 @@ struct FullFormatter::Impl
{
}
- explicit Impl(std::string_view LogId) : m_LogId(LogId), m_LinePrefix(128, ' '), m_UseFullDate(true) {}
+ explicit Impl(std::string_view LogId) : m_LogId(LogId), m_LinePrefix(128, ' ') {}
std::chrono::time_point<std::chrono::system_clock> m_Epoch;
std::tm m_CachedLocalTm{};
@@ -155,15 +156,7 @@ FullFormatter::Format(const LogMessage& Msg, MemoryBuffer& OutBuffer)
OutBuffer.push_back(' ');
}
- // append logger name if exists
- if (Msg.GetLoggerName().size() > 0)
- {
- OutBuffer.push_back('[');
- helpers::AppendStringView(Msg.GetLoggerName(), OutBuffer);
- OutBuffer.push_back(']');
- OutBuffer.push_back(' ');
- }
-
+ // level
OutBuffer.push_back('[');
if (IsColorEnabled())
{
@@ -177,6 +170,23 @@ FullFormatter::Format(const LogMessage& Msg, MemoryBuffer& OutBuffer)
OutBuffer.push_back(']');
OutBuffer.push_back(' ');
+ // logger name
+ if (Msg.GetLoggerName().size() > 0)
+ {
+ if (IsColorEnabled())
+ {
+ OutBuffer.append("\033[1m"sv);
+ }
+ OutBuffer.push_back('[');
+ helpers::AppendStringView(Msg.GetLoggerName(), OutBuffer);
+ OutBuffer.push_back(']');
+ if (IsColorEnabled())
+ {
+ OutBuffer.append("\033[0m"sv);
+ }
+ OutBuffer.push_back(' ');
+ }
+
// add source location if present
if (Msg.GetSource())
{
diff --git a/src/zenutil/logging/logging.cpp b/src/zenutil/logging/logging.cpp
index aa34fc50c..df0d6b9d2 100644
--- a/src/zenutil/logging/logging.cpp
+++ b/src/zenutil/logging/logging.cpp
@@ -179,7 +179,7 @@ BeginInitializeLogging(const LoggingOptions& LogOptions)
{
return;
}
- static constinit logging::LogPoint ErrorPoint{{}, logging::Err, "{}"};
+ static constinit logging::LogPoint ErrorPoint{0, 0, logging::Err, "{}"};
if (auto ErrLogger = zen::logging::ErrorLog())
{
try
@@ -249,7 +249,7 @@ FinishInitializeLogging(const LoggingOptions& LogOptions)
const std::string StartLogTime = zen::DateTime::Now().ToIso8601();
logging::Registry::Instance().ApplyAll([&](auto Logger) {
- static constinit logging::LogPoint LogStartPoint{{}, logging::Info, "log starting at {}"};
+ static constinit logging::LogPoint LogStartPoint{0, 0, logging::Info, "log starting at {}"};
Logger->Log(LogStartPoint, fmt::make_format_args(StartLogTime));
});
}
diff --git a/src/zenutil/splitconsole/logstreamlistener.cpp b/src/zenutil/splitconsole/logstreamlistener.cpp
index 04718b543..289bc73a2 100644
--- a/src/zenutil/splitconsole/logstreamlistener.cpp
+++ b/src/zenutil/splitconsole/logstreamlistener.cpp
@@ -312,7 +312,7 @@ namespace {
logging::LogMessage MakeLogMessage(std::string_view Text, logging::LogLevel Level = logging::Info)
{
- static logging::LogPoint Point{{}, Level, {}};
+ static logging::LogPoint Point{0, 0, Level, {}};
Point.Level = Level;
return logging::LogMessage(Point, "test", Text);
}