From 425f2aa013a9051a15b58a722668358a2dae5c70 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 20 Oct 2020 15:37:02 -0400 Subject: [PATCH] Common/Log: Add basic fmt-capable functions to the interface. Provides a basic extension to the interface to begin migration off of the printf-based logging system. Everything will go through macros with the same style naming as the old logging system, except the macros will have the _FMT suffix, while the migration is in process. This allows for peacemeal migration over time instead of pulling everything out and replacing it all in a single pull request, which makes for much easier reviewing. --- Source/Core/AudioCommon/CubebUtils.cpp | 14 +++---- Source/Core/Common/Logging/Log.h | 51 ++++++++++++++++++++++- Source/Core/Common/Logging/LogManager.cpp | 48 +++++++++++++++------ Source/Core/Common/Logging/LogManager.h | 8 ++-- 4 files changed, 95 insertions(+), 26 deletions(-) diff --git a/Source/Core/AudioCommon/CubebUtils.cpp b/Source/Core/AudioCommon/CubebUtils.cpp index b4af87115b..2088956e4b 100644 --- a/Source/Core/AudioCommon/CubebUtils.cpp +++ b/Source/Core/AudioCommon/CubebUtils.cpp @@ -18,19 +18,19 @@ static ptrdiff_t s_path_cutoff_point = 0; static void LogCallback(const char* format, ...) { - if (!Common::Log::LogManager::GetInstance()) + auto* instance = Common::Log::LogManager::GetInstance(); + if (instance == nullptr) return; va_list args; va_start(args, format); - const char* filename = va_arg(args, const char*) + s_path_cutoff_point; - int lineno = va_arg(args, int); - std::string adapted_format(StripSpaces(format + strlen("%s:%d:"))); - - Common::Log::LogManager::GetInstance()->LogWithFullPath( - Common::Log::LNOTICE, Common::Log::AUDIO, filename, lineno, adapted_format.c_str(), args); + const int lineno = va_arg(args, int); + const std::string adapted_format(StripSpaces(format + strlen("%s:%d:"))); + const std::string message = StringFromFormatV(adapted_format.c_str(), args); va_end(args); + + instance->Log(Common::Log::LNOTICE, Common::Log::AUDIO, filename, lineno, message.c_str()); } static void DestroyContext(cubeb* ctx) diff --git a/Source/Core/Common/Logging/Log.h b/Source/Core/Common/Logging/Log.h index a0d9e631b0..95f76b138a 100644 --- a/Source/Core/Common/Logging/Log.h +++ b/Source/Core/Common/Logging/Log.h @@ -4,6 +4,9 @@ #pragma once +#include +#include + namespace Common::Log { enum LOG_TYPE @@ -72,8 +75,17 @@ enum LOG_LEVELS static const char LOG_LEVEL_TO_CHAR[7] = "-NEWID"; -void GenericLog(Common::Log::LOG_LEVELS level, Common::Log::LOG_TYPE type, const char* file, - int line, const char* fmt, ...) +void GenericLogFmtImpl(LOG_LEVELS level, LOG_TYPE type, const char* file, int line, + std::string_view format, const fmt::format_args& args); + +template +void GenericLogFmt(LOG_LEVELS level, LOG_TYPE type, const char* file, int line, + std::string_view format, const Args&... args) +{ + GenericLogFmtImpl(level, type, file, line, format, fmt::make_format_args(args...)); +} + +void GenericLog(LOG_LEVELS level, LOG_TYPE type, const char* file, int line, const char* fmt, ...) #ifdef __GNUC__ __attribute__((format(printf, 5, 6))) #endif @@ -121,3 +133,38 @@ void GenericLog(Common::Log::LOG_LEVELS level, Common::Log::LOG_TYPE type, const { \ GENERIC_LOG(Common::Log::t, Common::Log::LDEBUG, __VA_ARGS__); \ } while (0) + +// fmtlib capable API + +#define GENERIC_LOG_FMT(t, v, ...) \ + do \ + { \ + if (v <= MAX_LOGLEVEL) \ + Common::Log::GenericLogFmt(v, t, __FILE__, __LINE__, __VA_ARGS__); \ + } while (0) + +#define ERROR_LOG_FMT(t, ...) \ + do \ + { \ + GENERIC_LOG_FMT(Common::Log::t, Common::Log::LERROR, __VA_ARGS__); \ + } while (0) +#define WARN_LOG_FMT(t, ...) \ + do \ + { \ + GENERIC_LOG_FMT(Common::Log::t, Common::Log::LWARNING, __VA_ARGS__); \ + } while (0) +#define NOTICE_LOG_FMT(t, ...) \ + do \ + { \ + GENERIC_LOG_FMT(Common::Log::t, Common::Log::LNOTICE, __VA_ARGS__); \ + } while (0) +#define INFO_LOG_FMT(t, ...) \ + do \ + { \ + GENERIC_LOG_FMT(Common::Log::t, Common::Log::LINFO, __VA_ARGS__); \ + } while (0) +#define DEBUG_LOG_FMT(t, ...) \ + do \ + { \ + GENERIC_LOG_FMT(Common::Log::t, Common::Log::LDEBUG, __VA_ARGS__); \ + } while (0) diff --git a/Source/Core/Common/Logging/LogManager.cpp b/Source/Core/Common/Logging/LogManager.cpp index 99ddf83d67..2255fc6f8e 100644 --- a/Source/Core/Common/Logging/LogManager.cpp +++ b/Source/Core/Common/Logging/LogManager.cpp @@ -64,11 +64,34 @@ private: void GenericLog(LOG_LEVELS level, LOG_TYPE type, const char* file, int line, const char* fmt, ...) { + auto* instance = LogManager::GetInstance(); + if (instance == nullptr) + return; + + if (!instance->IsEnabled(type, level)) + return; + va_list args; va_start(args, fmt); - if (LogManager::GetInstance()) - LogManager::GetInstance()->Log(level, type, file, line, fmt, args); + char message[MAX_MSGLEN]; + CharArrayFromFormatV(message, MAX_MSGLEN, fmt, args); va_end(args); + + instance->Log(level, type, file, line, message); +} + +void GenericLogFmtImpl(LOG_LEVELS level, LOG_TYPE type, const char* file, int line, + std::string_view format, const fmt::format_args& args) +{ + auto* instance = LogManager::GetInstance(); + if (instance == nullptr) + return; + + if (!instance->IsEnabled(type, level)) + return; + + const auto message = fmt::vformat(format, args); + instance->Log(level, type, file, line, message.c_str()); } static size_t DeterminePathCutOffPoint() @@ -196,27 +219,26 @@ void LogManager::SaveSettings() } void LogManager::Log(LOG_LEVELS level, LOG_TYPE type, const char* file, int line, - const char* format, va_list args) -{ - return LogWithFullPath(level, type, file + m_path_cutoff_point, line, format, args); -} - -void LogManager::LogWithFullPath(LOG_LEVELS level, LOG_TYPE type, const char* file, int line, - const char* format, va_list args) + const char* message) { if (!IsEnabled(type, level) || !static_cast(m_listener_ids)) return; - char temp[MAX_MSGLEN]; - CharArrayFromFormatV(temp, MAX_MSGLEN, format, args); + LogWithFullPath(level, type, file + m_path_cutoff_point, line, message); +} +void LogManager::LogWithFullPath(LOG_LEVELS level, LOG_TYPE type, const char* file, int line, + const char* message) +{ const std::string msg = fmt::format("{} {}:{} {}[{}]: {}\n", Common::Timer::GetTimeFormatted(), file, line, - LOG_LEVEL_TO_CHAR[static_cast(level)], GetShortName(type), temp); + LOG_LEVEL_TO_CHAR[static_cast(level)], GetShortName(type), message); - for (auto listener_id : m_listener_ids) + for (const auto listener_id : m_listener_ids) + { if (m_listeners[listener_id]) m_listeners[listener_id]->Log(level, msg.c_str()); + } } LOG_LEVELS LogManager::GetLogLevel() const diff --git a/Source/Core/Common/Logging/LogManager.h b/Source/Core/Common/Logging/LogManager.h index eeff12d2f3..9332bfc074 100644 --- a/Source/Core/Common/Logging/LogManager.h +++ b/Source/Core/Common/Logging/LogManager.h @@ -38,10 +38,7 @@ public: static void Init(); static void Shutdown(); - void Log(LOG_LEVELS level, LOG_TYPE type, const char* file, int line, const char* fmt, - va_list args); - void LogWithFullPath(LOG_LEVELS level, LOG_TYPE type, const char* file, int line, const char* fmt, - va_list args); + void Log(LOG_LEVELS level, LOG_TYPE type, const char* file, int line, const char* message); LOG_LEVELS GetLogLevel() const; void SetLogLevel(LOG_LEVELS level); @@ -76,6 +73,9 @@ private: LogManager(LogManager&&) = delete; LogManager& operator=(LogManager&&) = delete; + void LogWithFullPath(LOG_LEVELS level, LOG_TYPE type, const char* file, int line, + const char* message); + LOG_LEVELS m_level; std::array m_log{}; std::array m_listeners{};