aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/logging
diff options
context:
space:
mode:
Diffstat (limited to 'src/zencore/logging')
-rw-r--r--src/zencore/logging/ansicolorsink.cpp68
-rw-r--r--src/zencore/logging/logger.cpp54
-rw-r--r--src/zencore/logging/registry.cpp4
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))