diff options
| author | Stefan Boberg <[email protected]> | 2026-04-13 12:09:05 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2026-04-13 12:09:05 +0200 |
| commit | e0879bed083eab09cfa28043a3b210714d0884b9 (patch) | |
| tree | 00d5dddc9a046bd0112e1fddcfce430ced14a355 /src/zencore/system.cpp | |
| parent | update minio (#947) (diff) | |
| download | zen-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/zencore/system.cpp')
| -rw-r--r-- | src/zencore/system.cpp | 97 |
1 files changed, 95 insertions, 2 deletions
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(); |