diff --git a/src/common/Banner.cpp b/src/common/Banner.cpp index 6e6db0fcc..9f7eb8c0f 100644 --- a/src/common/Banner.cpp +++ b/src/common/Banner.cpp @@ -6,9 +6,9 @@ #include "GitRevision.h" #include "StringFormat.h" -void Acore::Banner::Show(char const* applicationName, void(*log)(char const* text), void(*logExtraInfo)()) +void Acore::Banner::Show(std::string_view applicationName, void(*log)(std::string_view text), void(*logExtraInfo)()) { - log(Acore::StringFormat("%s (%s)", GitRevision::GetFullVersion(), applicationName).c_str()); + log(Acore::StringFormatFmt("{} ({})", GitRevision::GetFullVersion(), applicationName)); log(" to stop.\n"); log(" █████╗ ███████╗███████╗██████╗ ██████╗ ████████╗██╗ ██╗"); log(" ██╔══██╗╚══███╔╝██╔════╝██╔══██╗██╔═══██╗╚══██╔══╝██║ ██║"); diff --git a/src/common/Banner.h b/src/common/Banner.h index b8d99836a..2a4ba19fe 100644 --- a/src/common/Banner.h +++ b/src/common/Banner.h @@ -6,13 +6,11 @@ #define AZEROTHCORE_BANNER_H #include "Define.h" +#include -namespace Acore +namespace Acore::Banner { - namespace Banner - { - void Show(char const* applicationName, void(*log)(char const* text), void(*logExtraInfo)()); - } + AC_COMMON_API void Show(std::string_view applicationName, void(*log)(std::string_view text), void(*logExtraInfo)()); } #endif // AZEROTHCORE_BANNER_H diff --git a/src/common/Logging/Log.cpp b/src/common/Logging/Log.cpp index bc317a134..665851e34 100644 --- a/src/common/Logging/Log.cpp +++ b/src/common/Logging/Log.cpp @@ -222,6 +222,11 @@ void Log::outMessage(std::string const& filter, LogLevel level, std::string&& me write(std::make_unique(level, filter, std::move(message))); } +void Log::_outMessageFmt(std::string const& filter, LogLevel level, std::string&& message) +{ + write(std::make_unique(level, filter, std::move(message))); +} + void Log::outCommand(std::string&& message, std::string&& param1) { write(std::make_unique(LOG_LEVEL_INFO, "commands.gm", std::move(message), std::move(param1))); diff --git a/src/common/Logging/Log.h b/src/common/Logging/Log.h index 0d6914a6a..037b11720 100644 --- a/src/common/Logging/Log.h +++ b/src/common/Logging/Log.h @@ -9,7 +9,6 @@ #include "Define.h" #include "LogCommon.h" #include "StringFormat.h" - #include #include #include @@ -55,6 +54,12 @@ public: outMessage(filter, level, Acore::StringFormat(std::forward(fmt), std::forward(args)...)); } + template + inline void outMessageFmt(std::string const& filter, LogLevel const level, std::string_view fmt, Args&&... args) + { + _outMessageFmt(filter, level, fmt::format(fmt, std::forward(args)...)); + } + template void outCommand(uint32 account, Format&& fmt, Args&&... args) { @@ -177,6 +182,7 @@ private: void ReadLoggersFromConfig(); void RegisterAppender(uint8 index, AppenderCreatorFn appenderCreateFn); void outMessage(std::string const& filter, LogLevel level, std::string&& message); + void _outMessageFmt(std::string const& filter, LogLevel level, std::string&& message); void outCommand(std::string&& message, std::string&& param1); std::unordered_map appenderFactory; @@ -265,4 +271,49 @@ void check_args(std::string const&, ...); #define LOG_GM(accountId__, ...) \ sLog->outCommand(accountId__, __VA_ARGS__) +// New format logging +#define FMT_LOG_EXCEPTION_FREE(filterType__, level__, ...) \ + { \ + try \ + { \ + sLog->outMessageFmt(filterType__, level__, fmt::format(__VA_ARGS__)); \ + } \ + catch (const std::exception& e) \ + { \ + sLog->outMessageFmt("server", LogLevel::LOG_LEVEL_ERROR, "Wrong format occurred ({}) at '{}:{}'", \ + e.what(), __FILE__, __LINE__); \ + } \ + } + +#define FMT_LOG_MESSAGE_BODY(filterType__, level__, ...) \ + do \ + { \ + if (sLog->ShouldLog(filterType__, level__)) \ + FMT_LOG_EXCEPTION_FREE(filterType__, level__, __VA_ARGS__); \ + } while (0) + +// Fatal - 1 +#define FMT_LOG_FATAL(filterType__, ...) \ + FMT_LOG_MESSAGE_BODY(filterType__, LogLevel::LOG_LEVEL_FATAL, __VA_ARGS__) + +// Error - 2 +#define FMT_LOG_ERROR(filterType__, ...) \ + FMT_LOG_MESSAGE_BODY(filterType__, LogLevel::LOG_LEVEL_ERROR, __VA_ARGS__) + +// Warning - 3 +#define FMT_LOG_WARN(filterType__, ...) \ + FMT_LOG_MESSAGE_BODY(filterType__, LogLevel::LOG_LEVEL_WARN, __VA_ARGS__) + +// Info - 4 +#define FMT_LOG_INFO(filterType__, ...) \ + FMT_LOG_MESSAGE_BODY(filterType__, LogLevel::LOG_LEVEL_INFO, __VA_ARGS__) + +// Debug - 5 +#define FMT_LOG_DEBUG(filterType__, ...) \ + FMT_LOG_MESSAGE_BODY(filterType__, LogLevel::LOG_LEVEL_DEBUG, __VA_ARGS__) + +// Trace - 6 +#define FMT_LOG_TRACE(filterType__, ...) \ + FMT_LOG_MESSAGE_BODY(filterType__, LogLevel::LOG_LEVEL_TRACE, __VA_ARGS__) + #endif // _LOG_H__ diff --git a/src/common/Utilities/StringFormat.h b/src/common/Utilities/StringFormat.h index a5bf59f2a..b8176ed21 100644 --- a/src/common/Utilities/StringFormat.h +++ b/src/common/Utilities/StringFormat.h @@ -8,6 +8,7 @@ #ifndef _STRING_FORMAT_H_ #define _STRING_FORMAT_H_ +#include #include namespace Acore @@ -27,6 +28,20 @@ namespace Acore } } + // Default string format function. + template + inline std::string StringFormatFmt(std::string_view fmt, Args&&... args) + { + try + { + return fmt::format(fmt, std::forward(args)...); + } + catch (const fmt::format_error& formatError) + { + return fmt::format("An error occurred formatting string \"{}\": {}", fmt, formatError.what()); + } + } + /// Returns true if the given char pointer is null. inline bool IsFormatEmptyOrNull(char const* fmt) { @@ -34,7 +49,7 @@ namespace Acore } /// Returns true if the given std::string is empty. - inline bool IsFormatEmptyOrNull(std::string const& fmt) + inline bool IsFormatEmptyOrNull(std::string_view fmt) { return fmt.empty(); } diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp index a9505596d..f96e23b47 100644 --- a/src/server/authserver/Main.cpp +++ b/src/server/authserver/Main.cpp @@ -91,17 +91,16 @@ int main(int argc, char** argv) sLog->Initialize(); Acore::Banner::Show("authserver", - [](char const* text) + [](std::string_view text) { - LOG_INFO("server.authserver", "%s", text); + FMT_LOG_INFO("server.authserver", text); }, []() { - LOG_INFO("server.authserver", "> Using configuration file %s.", sConfigMgr->GetFilename().c_str()); - LOG_INFO("server.authserver", "> Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); - LOG_INFO("server.authserver", "> Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); - } - ); + FMT_LOG_INFO("server.authserver", "> Using configuration file {}", sConfigMgr->GetFilename()); + FMT_LOG_INFO("server.authserver", "> Using SSL version: {} (library: {})", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); + FMT_LOG_INFO("server.authserver", "> Using Boost version: {}.{}.{}", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); + }); // authserver PID file creation std::string pidFile = sConfigMgr->GetOption("PidFile", ""); diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index 3dde54ba4..3ffd40486 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -199,17 +199,16 @@ int main(int argc, char** argv) sLog->Initialize(); Acore::Banner::Show("worldserver-daemon", - [](char const* text) + [](std::string_view text) { - LOG_INFO("server.worldserver", "%s", text); + FMT_LOG_INFO("server.worldserver", text); }, []() { - LOG_INFO("server.worldserver", "> Using configuration file: %s", sConfigMgr->GetFilename().c_str()); - LOG_INFO("server.worldserver", "> Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); - LOG_INFO("server.worldserver", "> Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); - } - ); + FMT_LOG_INFO("server.worldserver", "> Using configuration file {}", sConfigMgr->GetFilename()); + FMT_LOG_INFO("server.worldserver", "> Using SSL version: {} (library: {})", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); + FMT_LOG_INFO("server.worldserver", "> Using Boost version: {}.{}.{}", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); + }); OpenSSLCrypto::threadsSetup();