aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/logging.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/zencore/logging.cpp')
-rw-r--r--src/zencore/logging.cpp241
1 files changed, 216 insertions, 25 deletions
diff --git a/src/zencore/logging.cpp b/src/zencore/logging.cpp
index c366df812..0d34372a9 100644
--- a/src/zencore/logging.cpp
+++ b/src/zencore/logging.cpp
@@ -7,39 +7,239 @@
#include <spdlog/sinks/null_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
+#include <spdlog/spdlog.h>
+
+#if ZEN_PLATFORM_WINDOWS
+# pragma section(".zlog$a", read)
+# pragma section(".zlog$f", read)
+# pragma section(".zlog$m", read)
+# pragma section(".zlog$s", read)
+# pragma section(".zlog$z", read)
+#endif
namespace zen {
// We shadow the underlying spdlog default logger, in order to avoid a bunch of overhead
-spdlog::logger* TheDefaultLogger;
+LoggerRef TheDefaultLogger;
} // namespace zen
namespace zen::logging {
-spdlog::logger&
+using MemoryBuffer_t = fmt::basic_memory_buffer<char, 250>;
+
+struct LoggingContext
+{
+ inline LoggingContext();
+ inline ~LoggingContext();
+
+ zen::logging::MemoryBuffer_t MessageBuffer;
+
+ inline std::string_view Message() const { return std::string_view(MessageBuffer.data(), MessageBuffer.size()); }
+};
+
+LoggingContext::LoggingContext()
+{
+}
+
+LoggingContext::~LoggingContext()
+{
+}
+
+static inline bool
+IsErrorLevel(int LogLevel)
+{
+ return (LogLevel == zen::logging::level::Err || LogLevel == zen::logging::level::Critical);
+};
+
+static_assert(sizeof(spdlog::source_loc) == sizeof(SourceLocation));
+static_assert(offsetof(spdlog::source_loc, filename) == offsetof(SourceLocation, filename));
+static_assert(offsetof(spdlog::source_loc, line) == offsetof(SourceLocation, line));
+static_assert(offsetof(spdlog::source_loc, funcname) == offsetof(SourceLocation, funcname));
+
+void
+EmitLogMessage(LoggerRef& Logger, int LogLevel, const std::string_view Message)
+{
+ const spdlog::level::level_enum InLevel = (spdlog::level::level_enum)LogLevel;
+ Logger.SpdLogger->log(InLevel, Message);
+ if (IsErrorLevel(LogLevel))
+ {
+ if (LoggerRef ErrLogger = zen::logging::ErrorLog())
+ {
+ ErrLogger.SpdLogger->log(InLevel, Message);
+ }
+ }
+}
+
+void
+EmitLogMessage(LoggerRef& Logger, int LogLevel, std::string_view Format, fmt::format_args Args)
+{
+ zen::logging::LoggingContext LogCtx;
+ fmt::vformat_to(fmt::appender(LogCtx.MessageBuffer), Format, Args);
+ zen::logging::EmitLogMessage(Logger, LogLevel, LogCtx.Message());
+}
+
+void
+EmitLogMessage(LoggerRef& Logger, const SourceLocation& InLocation, int LogLevel, const std::string_view Message)
+{
+ const spdlog::source_loc& Location = *reinterpret_cast<const spdlog::source_loc*>(&InLocation);
+ const spdlog::level::level_enum InLevel = (spdlog::level::level_enum)LogLevel;
+ Logger.SpdLogger->log(Location, InLevel, Message);
+ if (IsErrorLevel(LogLevel))
+ {
+ if (LoggerRef ErrLogger = zen::logging::ErrorLog())
+ {
+ ErrLogger.SpdLogger->log(Location, InLevel, Message);
+ }
+ }
+}
+
+void
+EmitLogMessage(LoggerRef& Logger, const SourceLocation& InLocation, int LogLevel, std::string_view Format, fmt::format_args Args)
+{
+ zen::logging::LoggingContext LogCtx;
+ fmt::vformat_to(fmt::appender(LogCtx.MessageBuffer), Format, Args);
+ zen::logging::EmitLogMessage(Logger, InLocation, LogLevel, LogCtx.Message());
+}
+
+void
+EmitConsoleLogMessage(int LogLevel, const std::string_view Message)
+{
+ const spdlog::level::level_enum InLevel = (spdlog::level::level_enum)LogLevel;
+ ConsoleLog().SpdLogger->log(InLevel, Message);
+}
+
+void
+EmitConsoleLogMessage(int LogLevel, std::string_view Format, fmt::format_args Args)
+{
+ zen::logging::LoggingContext LogCtx;
+ fmt::vformat_to(fmt::appender(LogCtx.MessageBuffer), Format, Args);
+ zen::logging::EmitConsoleLogMessage(LogLevel, LogCtx.Message());
+}
+
+} // namespace zen::logging
+
+namespace zen::logging::level {
+
+spdlog::level::level_enum
+to_spdlog_level(LogLevel NewLogLevel)
+{
+ return static_cast<spdlog::level::level_enum>((int)NewLogLevel);
+}
+
+LogLevel
+to_logging_level(spdlog::level::level_enum NewLogLevel)
+{
+ return static_cast<LogLevel>((int)NewLogLevel);
+}
+
+constinit std::string_view LevelNames[] = {ZEN_LEVEL_NAME_TRACE,
+ ZEN_LEVEL_NAME_DEBUG,
+ ZEN_LEVEL_NAME_INFO,
+ ZEN_LEVEL_NAME_WARNING,
+ ZEN_LEVEL_NAME_ERROR,
+ ZEN_LEVEL_NAME_CRITICAL,
+ ZEN_LEVEL_NAME_OFF};
+
+level::LogLevel
+ParseLogLevelString(std::string_view Name)
+{
+ for (int Level = 0; Level < level::LogLevelCount; ++Level)
+ {
+ if (LevelNames[Level] == Name)
+ return static_cast<level::LogLevel>(Level);
+ }
+
+ if (Name == "warn")
+ {
+ return level::Warn;
+ }
+
+ if (Name == "err")
+ {
+ return level::Err;
+ }
+
+ return level::Off;
+}
+
+std::string_view
+ToStringView(level::LogLevel Level)
+{
+ if (int(Level) < level::LogLevelCount)
+ {
+ return LevelNames[int(Level)];
+ }
+
+ return "None";
+}
+
+} // namespace zen::logging::level
+
+namespace zen::logging {
+
+void
+SetLogLevel(level::LogLevel NewLogLevel)
+{
+ spdlog::set_level(to_spdlog_level(NewLogLevel));
+}
+
+level::LogLevel
+GetLogLevel()
+{
+ return level::to_logging_level(spdlog::get_level());
+}
+
+LoggerRef
Default()
{
ZEN_ASSERT(TheDefaultLogger);
- return *TheDefaultLogger;
+ return TheDefaultLogger;
}
void
-SetDefault(std::shared_ptr<spdlog::logger> NewDefaultLogger)
+SetDefault(std::string_view NewDefaultLoggerId)
{
+ auto NewDefaultLogger = spdlog::get(std::string(NewDefaultLoggerId));
ZEN_ASSERT(NewDefaultLogger);
+
spdlog::set_default_logger(NewDefaultLogger);
- TheDefaultLogger = spdlog::default_logger_raw();
+ TheDefaultLogger = LoggerRef(*NewDefaultLogger);
+}
+
+LoggerRef TheErrorLogger;
+
+LoggerRef
+ErrorLog()
+{
+ return TheErrorLogger;
}
-spdlog::logger&
+void
+SetErrorLog(std::string_view NewErrorLoggerId)
+{
+ if (NewErrorLoggerId.empty())
+ {
+ TheErrorLogger = {};
+ }
+ else
+ {
+ auto NewErrorLogger = spdlog::get(std::string(NewErrorLoggerId));
+
+ ZEN_ASSERT(NewErrorLogger);
+
+ TheErrorLogger = LoggerRef(*NewErrorLogger.get());
+ }
+}
+
+LoggerRef
Get(std::string_view Name)
{
std::shared_ptr<spdlog::logger> Logger = spdlog::get(std::string(Name));
if (!Logger)
{
- Logger = Default().clone(std::string(Name));
+ Logger = Default().SpdLogger->clone(std::string(Name));
spdlog::register_logger(Logger);
}
@@ -55,7 +255,7 @@ SuppressConsoleLog()
ConLogger = spdlog::null_logger_mt("console");
}
-spdlog::logger&
+LoggerRef
ConsoleLog()
{
std::call_once(ConsoleInitFlag, [&] {
@@ -70,25 +270,10 @@ ConsoleLog()
return *ConLogger;
}
-std::shared_ptr<spdlog::logger> TheErrorLogger;
-
-spdlog::logger*
-ErrorLog()
-{
- // This may return nullptr
- return TheErrorLogger.get();
-}
-
-void
-SetErrorLog(std::shared_ptr<spdlog::logger>&& NewErrorLogger)
-{
- TheErrorLogger = std::move(NewErrorLogger);
-}
-
void
InitializeLogging()
{
- TheDefaultLogger = spdlog::default_logger_raw();
+ TheDefaultLogger = *spdlog::default_logger_raw();
}
void
@@ -96,7 +281,7 @@ ShutdownLogging()
{
spdlog::drop_all();
spdlog::shutdown();
- TheDefaultLogger = nullptr;
+ TheDefaultLogger = {};
}
bool
@@ -130,6 +315,12 @@ EnableVTMode()
namespace zen {
+bool
+LoggerRef::ShouldLog(int Level) const
+{
+ return SpdLogger->should_log(static_cast<spdlog::level::level_enum>(Level));
+}
+
thread_local ScopedActivityBase* t_ScopeStack = nullptr;
ScopedActivityBase*