diff options
Diffstat (limited to 'src/zencore/logging')
| -rw-r--r-- | src/zencore/logging/ansicolorsink.cpp | 68 | ||||
| -rw-r--r-- | src/zencore/logging/logger.cpp | 54 | ||||
| -rw-r--r-- | src/zencore/logging/registry.cpp | 4 |
3 files changed, 59 insertions, 67 deletions
diff --git a/src/zencore/logging/ansicolorsink.cpp b/src/zencore/logging/ansicolorsink.cpp index 03aae068a..fb127bede 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 @@ -197,7 +205,7 @@ IsColorTerminal() // Windows console supports ANSI color by default in modern versions return true; #else - // Unknown terminal — be conservative + // Unknown terminal - be conservative return false; #endif } diff --git a/src/zencore/logging/logger.cpp b/src/zencore/logging/logger.cpp index dd1675bb1..ff1db3edc 100644 --- a/src/zencore/logging/logger.cpp +++ b/src/zencore/logging/logger.cpp @@ -4,27 +4,20 @@ #include <zencore/thread.h> #include <string> -#include <vector> namespace zen::logging { struct Logger::Impl { - std::string m_Name; - std::vector<SinkPtr> m_Sinks; - ErrorHandler* m_ErrorHandler = nullptr; + std::string m_Name; + SinkPtr m_Sink; + ErrorHandler* m_ErrorHandler = nullptr; }; Logger::Logger(std::string_view InName, SinkPtr InSink) : m_Impl(std::make_unique<Impl>()) { m_Impl->m_Name = InName; - m_Impl->m_Sinks.push_back(std::move(InSink)); -} - -Logger::Logger(std::string_view InName, std::span<const SinkPtr> InSinks) : m_Impl(std::make_unique<Impl>()) -{ - m_Impl->m_Name = InName; - m_Impl->m_Sinks.assign(InSinks.begin(), InSinks.end()); + m_Impl->m_Sink = std::move(InSink); } Logger::~Logger() = default; @@ -49,20 +42,17 @@ Logger::Log(const LogPoint& Point, fmt::format_args Args) void Logger::SinkIt(const LogMessage& Msg) { - for (auto& CurrentSink : m_Impl->m_Sinks) + if (m_Impl->m_Sink && m_Impl->m_Sink->ShouldLog(Msg.GetLevel())) { - if (CurrentSink->ShouldLog(Msg.GetLevel())) + try { - try - { - CurrentSink->Log(Msg); - } - catch (const std::exception& Ex) + m_Impl->m_Sink->Log(Msg); + } + catch (const std::exception& Ex) + { + if (m_Impl->m_ErrorHandler) { - if (m_Impl->m_ErrorHandler) - { - m_Impl->m_ErrorHandler->HandleError(Ex.what()); - } + m_Impl->m_ErrorHandler->HandleError(Ex.what()); } } } @@ -80,11 +70,11 @@ Logger::FlushIfNeeded(LogLevel InLevel) void Logger::Flush() { - for (auto& CurrentSink : m_Impl->m_Sinks) + if (m_Impl->m_Sink) { try { - CurrentSink->Flush(); + m_Impl->m_Sink->Flush(); } catch (const std::exception& Ex) { @@ -97,15 +87,9 @@ Logger::Flush() } void -Logger::SetSinks(std::vector<SinkPtr> InSinks) -{ - m_Impl->m_Sinks = std::move(InSinks); -} - -void -Logger::AddSink(SinkPtr InSink) +Logger::SetSink(SinkPtr InSink) { - m_Impl->m_Sinks.push_back(std::move(InSink)); + m_Impl->m_Sink = std::move(InSink); } void @@ -117,9 +101,9 @@ Logger::SetErrorHandler(ErrorHandler* Handler) void Logger::SetFormatter(std::unique_ptr<Formatter> InFormatter) { - for (auto& CurrentSink : m_Impl->m_Sinks) + if (m_Impl->m_Sink) { - CurrentSink->SetFormatter(InFormatter->Clone()); + m_Impl->m_Sink->SetFormatter(std::move(InFormatter)); } } @@ -132,7 +116,7 @@ Logger::Name() const Ref<Logger> Logger::Clone(std::string_view NewName) const { - Ref<Logger> Cloned(new Logger(NewName, m_Impl->m_Sinks)); + Ref<Logger> Cloned(new Logger(NewName, m_Impl->m_Sink)); Cloned->SetLevel(m_Level.load(std::memory_order_relaxed)); Cloned->SetFlushLevel(m_FlushLevel.load(std::memory_order_relaxed)); Cloned->SetErrorHandler(m_Impl->m_ErrorHandler); diff --git a/src/zencore/logging/registry.cpp b/src/zencore/logging/registry.cpp index 383a5d8ba..0f552aced 100644 --- a/src/zencore/logging/registry.cpp +++ b/src/zencore/logging/registry.cpp @@ -137,7 +137,7 @@ struct Registry::Impl { if (Pattern.find_first_of("*?") == std::string::npos) { - // Exact match — fast path via map lookup. + // Exact match - fast path via map lookup. auto It = m_Loggers.find(Pattern); if (It != m_Loggers.end()) { @@ -146,7 +146,7 @@ struct Registry::Impl } else { - // Wildcard pattern — iterate all loggers. + // Wildcard pattern - iterate all loggers. for (auto& [Name, CurLogger] : m_Loggers) { if (MatchLoggerPattern(Pattern, Name)) |