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 | |
| 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')
| -rw-r--r-- | src/zencompute/include/zencompute/orchestratorservice.h | 7 | ||||
| -rw-r--r-- | src/zencore/include/zencore/logbase.h | 13 | ||||
| -rw-r--r-- | src/zencore/include/zencore/logging.h | 60 | ||||
| -rw-r--r-- | src/zencore/include/zencore/logging/helpers.h | 2 | ||||
| -rw-r--r-- | src/zencore/include/zencore/logging/logmsg.h | 49 | ||||
| -rw-r--r-- | src/zencore/include/zencore/system.h | 5 | ||||
| -rw-r--r-- | src/zencore/logging.cpp | 29 | ||||
| -rw-r--r-- | src/zencore/logging/ansicolorsink.cpp | 66 | ||||
| -rw-r--r-- | src/zencore/system.cpp | 97 | ||||
| -rw-r--r-- | src/zenremotestore/include/zenremotestore/operationlogoutput.h | 14 | ||||
| -rw-r--r-- | src/zenserver/diag/logging.cpp | 2 | ||||
| -rw-r--r-- | src/zenutil/logging/fullformatter.cpp | 30 | ||||
| -rw-r--r-- | src/zenutil/logging/logging.cpp | 4 | ||||
| -rw-r--r-- | src/zenutil/splitconsole/logstreamlistener.cpp | 2 |
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); } |