diff --git a/cmake/modules/BaseConfig.cmake b/cmake/modules/BaseConfig.cmake index e772f78b3a1..14dc6e22153 100644 --- a/cmake/modules/BaseConfig.cmake +++ b/cmake/modules/BaseConfig.cmake @@ -87,6 +87,7 @@ endif() # cmake -DDEBUG_LOG=ON .. if(DEBUG_LOG) add_definitions(-DDEBUG_LOG=ON) + add_definitions(-DSPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_TRACE) log_option_enabled("DEBUG LOG") else() log_option_disabled("DEBUG LOG") diff --git a/config.lua.dist b/config.lua.dist index 07792a0289b..4d28a2033cd 100644 --- a/config.lua.dist +++ b/config.lua.dist @@ -9,7 +9,8 @@ coreDirectory = "data" -- Set log level -- It can be trace, debug, info, warning, error, critical, off (default: info). --- NOTE: Will only display logs with level higher or equal the one set. +-- NOTE: It will only be valid after the server starts up and only display logs with level higher or equal the one set. +-- NOTE: Debug and trace logs are only available if compiled in debug mode. logLevel = "info" --- Toggles the server's maintenance mode. @@ -52,7 +53,7 @@ cleanProtectionZones = false -- Connection Config -- NOTE: allowOldProtocol can allow login on 10x protocol. (11.00) -- NOTE: maxPlayers set to 0 means no limit --- NOTE: MaxPacketsPerSeconds if you change you will be subject to bugs by WPE, keep the default value of 25, +-- NOTE: MaxPacketsPerSeconds if you change you will be subject to bugs by WPE, keep the default value of 25, -- It's recommended to use a range like min 50 in this function, otherwise you will be disconnected after equipping two-handed distance weapons. ip = "127.0.0.1" allowOldProtocol = false diff --git a/src/account/account.cpp b/src/account/account.cpp index 8b67c09ebca..2cd411ef3e7 100644 --- a/src/account/account.cpp +++ b/src/account/account.cpp @@ -14,7 +14,6 @@ #include "utils/definitions.hpp" #include "security/argon.hpp" #include "utils/tools.hpp" -#include "lib/logging/log_with_spd_log.hpp" #include "enums/account_type.hpp" #include "enums/account_coins.hpp" diff --git a/src/account/account_repository_db.cpp b/src/account/account_repository_db.cpp index a6d169ef4af..10f3d6f3a41 100644 --- a/src/account/account_repository_db.cpp +++ b/src/account/account_repository_db.cpp @@ -10,7 +10,6 @@ #include "account/account_repository_db.hpp" #include "database/database.hpp" -#include "lib/logging/logger.hpp" #include "utils/definitions.hpp" #include "utils/tools.hpp" #include "enums/account_type.hpp" diff --git a/src/canary_server.cpp b/src/canary_server.cpp index 7606a026362..aaf1de80530 100644 --- a/src/canary_server.cpp +++ b/src/canary_server.cpp @@ -97,7 +97,6 @@ int CanaryServer::run() { #endif g_game().start(&serviceManager); - g_game().setGameState(GAME_STATE_NORMAL); if (g_configManager().getBoolean(TOGGLE_MAINTAIN_MODE)) { g_game().setGameState(GAME_STATE_CLOSED); g_logger().warn("Initialized in maintain mode!"); @@ -133,6 +132,7 @@ int CanaryServer::run() { } logger.info("{} {}", g_configManager().getString(SERVER_NAME), "server online!"); + g_logger().setLevel(g_configManager().getString(LOGLEVEL)); serviceManager.run(); @@ -203,7 +203,7 @@ void CanaryServer::logInfos() { logger.info("{} - Version {}", ProtocolStatus::SERVER_NAME, SERVER_RELEASE_VERSION); #endif - logger.debug("Compiled with {}, on {} {}, for platform {}\n", getCompiler(), __DATE__, __TIME__, getPlatform()); + logger.debug("Compiled with {}, on {} {}, for platform {}", getCompiler(), __DATE__, __TIME__, getPlatform()); #if defined(LUAJIT_VERSION) logger.debug("Linked with {} for Lua support", LUAJIT_VERSION); diff --git a/src/config/configmanager.cpp b/src/config/configmanager.cpp index 2cae928382f..aa028b52284 100644 --- a/src/config/configmanager.cpp +++ b/src/config/configmanager.cpp @@ -35,10 +35,6 @@ bool ConfigManager::load() { return false; } -#ifndef DEBUG_LOG - g_logger().setLevel(loadStringConfig(L, LOGLEVEL, "logLevel", "info")); -#endif - // Parse config // Info that must be loaded one time (unless we reset the modules involved) if (!loaded) { @@ -363,6 +359,7 @@ bool ConfigManager::load() { loadStringConfig(L, TIBIADROME_CONCOCTION_TICK_TYPE, "tibiadromeConcoctionTickType", "online"); loadStringConfig(L, URL, "url", ""); loadStringConfig(L, WORLD_TYPE, "worldType", "pvp"); + loadStringConfig(L, LOGLEVEL, "logLevel", "info"); loaded = true; lua_close(L); diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index 6cec2e21b16..59d1d6a718a 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -7484,7 +7484,9 @@ void Player::forgeTransferItemTier(ForgeAction_t actionType, uint16_t donorItemI sendForgeError(RETURNVALUE_CONTACTADMINISTRATOR); break; } - auto tierPriecs = itemClassification->tiers.at(donorItem->getTier()); + + const uint8_t toTier = convergence ? donorItem->getTier() : donorItem->getTier() - 1; + auto tierPriecs = itemClassification->tiers.at(toTier); cost = convergence ? tierPriecs.convergenceTransferPrice : tierPriecs.regularPrice; coresAmount = tierPriecs.corePrice; break; diff --git a/src/database/database.hpp b/src/database/database.hpp index 72918193975..4984873ed62 100644 --- a/src/database/database.hpp +++ b/src/database/database.hpp @@ -10,7 +10,6 @@ #pragma once #include "declarations.hpp" -#include "lib/logging/log_with_spd_log.hpp" #ifndef USE_PRECOMPILED_HEADERS #include diff --git a/src/game/scheduling/task.cpp b/src/game/scheduling/task.cpp index 0e1f6489516..8e1b984a905 100644 --- a/src/game/scheduling/task.cpp +++ b/src/game/scheduling/task.cpp @@ -9,7 +9,6 @@ #include "task.hpp" -#include "lib/logging/log_with_spd_log.hpp" #include "lib/metrics/metrics.hpp" std::atomic_uint_fast64_t Task::LAST_EVENT_ID = 0; diff --git a/src/kv/kv.hpp b/src/kv/kv.hpp index fa32461b24b..c00a0fd4204 100644 --- a/src/kv/kv.hpp +++ b/src/kv/kv.hpp @@ -20,7 +20,6 @@ #include #endif -#include "lib/logging/logger.hpp" #include "kv/value_wrapper.hpp" class KV : public std::enable_shared_from_this { diff --git a/src/kv/kv_sql.cpp b/src/kv/kv_sql.cpp index 0391425884c..18f3c7a3205 100644 --- a/src/kv/kv_sql.cpp +++ b/src/kv/kv_sql.cpp @@ -10,7 +10,6 @@ #include "kv/kv_sql.hpp" #include "database/database.hpp" -#include "lib/logging/logger.hpp" #include "kv/value_wrapper_proto.hpp" #include "utils/tools.hpp" diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 55709c59ac3..d24f72347fc 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -1,5 +1,6 @@ target_sources(${PROJECT_NAME}_lib PRIVATE di/soft_singleton.cpp + logging/logger.cpp logging/log_with_spd_log.cpp thread/thread_pool.cpp ) diff --git a/src/lib/di/soft_singleton.hpp b/src/lib/di/soft_singleton.hpp index 12d90aa3bea..b64df1c77b6 100644 --- a/src/lib/di/soft_singleton.hpp +++ b/src/lib/di/soft_singleton.hpp @@ -9,7 +9,6 @@ #pragma once #include -#include "lib/logging/log_with_spd_log.hpp" class SoftSingleton { public: diff --git a/src/lib/logging/log_with_spd_log.cpp b/src/lib/logging/log_with_spd_log.cpp index a1893e3d501..6e6f8a298ca 100644 --- a/src/lib/logging/log_with_spd_log.cpp +++ b/src/lib/logging/log_with_spd_log.cpp @@ -6,8 +6,8 @@ * Contributors: https://github.com/opentibiabr/canary/graphs/contributors * Website: https://docs.opentibiabr.com/ */ -#include +#include #include "lib/di/container.hpp" LogWithSpdLog::LogWithSpdLog() { @@ -23,17 +23,39 @@ Logger &LogWithSpdLog::getInstance() { return inject(); } -void LogWithSpdLog::setLevel(const std::string &name) { +void LogWithSpdLog::setLevel(const std::string &name) const { debug("Setting log level to: {}.", name); - auto level = spdlog::level::from_str(name); + const auto level = spdlog::level::from_str(name); spdlog::set_level(level); } std::string LogWithSpdLog::getLevel() const { - auto level = spdlog::level::to_string_view(spdlog::get_level()); + const auto level = spdlog::level::to_string_view(spdlog::get_level()); return std::string { level.begin(), level.end() }; } -void LogWithSpdLog::log(const std::string &lvl, const fmt::basic_string_view msg) const { - spdlog::log(spdlog::level::from_str(lvl), msg); +void LogWithSpdLog::info(const std::string &msg) const { + SPDLOG_INFO(msg); +} + +void LogWithSpdLog::warn(const std::string &msg) const { + SPDLOG_WARN(msg); } + +void LogWithSpdLog::error(const std::string &msg) const { + SPDLOG_ERROR(msg); +} + +void LogWithSpdLog::critical(const std::string &msg) const { + SPDLOG_CRITICAL(msg); +} + +#if defined(DEBUG_LOG) +void LogWithSpdLog::debug(const std::string &msg) const { + SPDLOG_DEBUG(msg); +} + +void LogWithSpdLog::trace(const std::string &msg) const { + SPDLOG_TRACE(msg); +} +#endif diff --git a/src/lib/logging/log_with_spd_log.hpp b/src/lib/logging/log_with_spd_log.hpp index 983ee716c0d..84dc09a1ea3 100644 --- a/src/lib/logging/log_with_spd_log.hpp +++ b/src/lib/logging/log_with_spd_log.hpp @@ -17,10 +17,37 @@ class LogWithSpdLog final : public Logger { static Logger &getInstance(); - void setLevel(const std::string &name) override; + void setLevel(const std::string &name) const override; std::string getLevel() const override; - void log(const std::string &lvl, fmt::basic_string_view msg) const override; + void info(const std::string &msg) const override; + void warn(const std::string &msg) const override; + void error(const std::string &msg) const override; + void critical(const std::string &msg) const override; + +#if defined(DEBUG_LOG) + void debug(const std::string &msg) const override; + void trace(const std::string &msg) const override; + + template + void debug(const fmt::format_string &fmt, Args &&... args) const { + debug(fmt::format(fmt, std::forward(args)...)); + } + + template + void trace(const fmt::format_string &fmt, Args &&... args) const { + trace(fmt::format(fmt, std::forward(args)...)); + } +#else + void debug(const std::string &) const override { } + void trace(const std::string &) const override { } + + template + void debug(const fmt::format_string &, Args &&...) const { } + + template + void trace(const fmt::format_string &, Args &&...) const { } +#endif }; constexpr auto g_logger = LogWithSpdLog::getInstance; diff --git a/src/lib/logging/logger.cpp b/src/lib/logging/logger.cpp new file mode 100644 index 00000000000..b9a3c889d18 --- /dev/null +++ b/src/lib/logging/logger.cpp @@ -0,0 +1,74 @@ +/** + * Canary - A free and open-source MMORPG server emulator + * Copyright (©) 2019-2024 OpenTibiaBR + * Repository: https://github.com/opentibiabr/canary + * License: https://github.com/opentibiabr/canary/blob/main/LICENSE + * Contributors: https://github.com/opentibiabr/canary/graphs/contributors + * Website: https://docs.opentibiabr.com/ + */ + +#include +#include +#include +#include "lib/di/container.hpp" + +void Logger::setLevel(const std::string &name) const { + debug("Setting log level to: {}.", name); + const auto level = spdlog::level::from_str(name); + spdlog::set_level(level); +} + +std::string Logger::getLevel() const { + const auto level = spdlog::level::to_string_view(spdlog::get_level()); + return std::string { level.begin(), level.end() }; +} + +void Logger::logProfile(const std::string &name, double duration_ms) const { + std::string mutable_name = name; + + std::ranges::replace(mutable_name, ':', '_'); + std::ranges::replace(mutable_name, '\\', '_'); + std::ranges::replace(mutable_name, '/', '_'); + + std::string filename = "log/profile_log-" + mutable_name + ".txt"; + + const auto it = profile_loggers_.find(filename); + if (it == profile_loggers_.end()) { + try { + auto file_sink = std::make_shared(filename, true); + const auto profile_logger = std::make_shared(mutable_name, file_sink); + profile_loggers_[filename] = profile_logger; + profile_logger->info("Function {} executed in {} ms", name, duration_ms); + } catch (const spdlog::spdlog_ex &ex) { + error("Profile log initialization failed: {}", ex.what()); + } + } else { + it->second->info("Function {} executed in {} ms", mutable_name, duration_ms); + } +} + +void Logger::info(const std::string &msg) const { + SPDLOG_INFO(msg); +} + +void Logger::warn(const std::string &msg) const { + SPDLOG_WARN(msg); +} + +void Logger::error(const std::string &msg) const { + SPDLOG_ERROR(msg); +} + +void Logger::critical(const std::string &msg) const { + SPDLOG_CRITICAL(msg); +} + +#if defined(DEBUG_LOG) +void Logger::debug(const std::string &msg) const { + SPDLOG_DEBUG(msg); +} + +void Logger::trace(const std::string &msg) const { + SPDLOG_TRACE(msg); +} +#endif diff --git a/src/lib/logging/logger.hpp b/src/lib/logging/logger.hpp index bc6c455fbde..05c4ba751e5 100644 --- a/src/lib/logging/logger.hpp +++ b/src/lib/logging/logger.hpp @@ -8,34 +8,11 @@ */ #pragma once -#ifndef USE_PRECOMPILED_HEADERS - #include -#endif +#include "utils/transparent_string_hash.hpp" -#define LOG_LEVEL_TRACE \ - std::string { \ - "trace" \ - } -#define LOG_LEVEL_DEBUG \ - std::string { \ - "debug" \ - } -#define LOG_LEVEL_INFO \ - std::string { \ - "info" \ - } -#define LOG_LEVEL_WARNING \ - std::string { \ - "warning" \ - } -#define LOG_LEVEL_ERROR \ - std::string { \ - "error" \ - } -#define LOG_LEVEL_CRITICAL \ - std::string { \ - "critical" \ - } +namespace spdlog { + class logger; +} class Logger { public: @@ -46,67 +23,121 @@ class Logger { Logger(const Logger &) = delete; virtual Logger &operator=(const Logger &) = delete; - virtual void setLevel(const std::string &name) = 0; - [[nodiscard]] virtual std::string getLevel() const = 0; - virtual void log(const std::string &lvl, fmt::basic_string_view msg) const = 0; + virtual void setLevel(const std::string &name) const = 0; + virtual std::string getLevel() const = 0; + + /** + * @brief Logs the execution time of a given operation to a profile log file. + * + * This function records the duration of a named operation in a log file specific + * to that operation. If the log file doesn't exist, it creates a new one. + * The log file name is derived from the provided operation name. + * + * @param name Name of the operation to profile. + * @param duration_ms Execution duration in milliseconds. + * + * Example usage: + * @code + * class ExampleClass { + * public: + * void run() { + * g_logger().profile("quickTask", [this]() { + * quickTask(); + * }); + * } + * + * private: + * void quickTask() { + * std::this_thread::sleep_for(std::chrono::milliseconds(100)); + * } + * }; + * @endcode + */ + void logProfile(const std::string &name, double duration_ms) const; + + virtual void info(const std::string &msg) const; + virtual void warn(const std::string &msg) const; + virtual void error(const std::string &msg) const; + virtual void critical(const std::string &msg) const; + + template + auto profile(const std::string &name, Func func) -> decltype(func()) { + const auto start = std::chrono::high_resolution_clock::now(); + auto result = func(); + const auto end = std::chrono::high_resolution_clock::now(); + + const std::chrono::duration duration = end - start; + logProfile(name, duration.count()); + info("Function {} executed in {} ms", name, duration.count()); + + return result; + } + +#if defined(DEBUG_LOG) + virtual void debug(const std::string &msg) const; template - void trace(const fmt::format_string &fmt, Args &&... args) { - trace(fmt::format(fmt, std::forward(args)...)); + void debug(const fmt::format_string &fmt, Args &&... args) const { + debug(fmt::format(fmt, std::forward(args)...)); } + virtual void trace(const std::string &msg) const; + template - void debug(const fmt::format_string &fmt, Args &&... args) { - debug(fmt::format(fmt, std::forward(args)...)); + void trace(const fmt::format_string &fmt, Args &&... args) const { + trace(fmt::format(fmt, std::forward(args)...)); } +#else + virtual void debug(const std::string &) const { } + + template + void debug(const fmt::format_string &, Args &&...) const { } + + virtual void trace(const std::string &) const { } template - void info(fmt::format_string fmt, Args &&... args) { + void trace(const fmt::format_string &, Args &&...) const { } +#endif + + template + void info(const fmt::format_string &fmt, Args &&... args) const { info(fmt::format(fmt, std::forward(args)...)); } template - void warn(const fmt::format_string &fmt, Args &&... args) { + void warn(const fmt::format_string &fmt, Args &&... args) const { warn(fmt::format(fmt, std::forward(args)...)); } template - void error(const fmt::format_string fmt, Args &&... args) { + void error(const fmt::format_string &fmt, Args &&... args) const { error(fmt::format(fmt, std::forward(args)...)); } template - void critical(const fmt::format_string fmt, Args &&... args) { + void critical(const fmt::format_string &fmt, Args &&... args) const { critical(fmt::format(fmt, std::forward(args)...)); } - template - void trace(const T &msg) { - log(LOG_LEVEL_TRACE, msg); - } +private: + mutable std::unordered_map< + std::string, + std::shared_ptr, + TransparentStringHasher, + std::equal_to<>> + profile_loggers_; - template - void debug(const T &msg) { - log(LOG_LEVEL_DEBUG, msg); - } + std::tm get_local_time() const { + const auto now = std::chrono::system_clock::now(); + std::time_t now_time = std::chrono::system_clock::to_time_t(now); + std::tm local_tm {}; - template - void info(const T &msg) { - log(LOG_LEVEL_INFO, msg); - } - - template - void warn(const T &msg) { - log(LOG_LEVEL_WARNING, msg); - } - - template - void error(const T &msg) { - log(LOG_LEVEL_ERROR, msg); - } +#if defined(_WIN32) || defined(_WIN64) + localtime_s(&local_tm, &now_time); +#else + localtime_r(&now_time, &local_tm); +#endif - template - void critical(const T &msg) { - log(LOG_LEVEL_CRITICAL, msg); + return local_tm; } }; diff --git a/src/lib/thread/thread_pool.hpp b/src/lib/thread/thread_pool.hpp index ea24d3486cb..be5aac0f701 100644 --- a/src/lib/thread/thread_pool.hpp +++ b/src/lib/thread/thread_pool.hpp @@ -8,7 +8,6 @@ */ #pragma once -#include "lib/logging/logger.hpp" #include "BS_thread_pool.hpp" class ThreadPool : public BS::thread_pool { diff --git a/src/lua/scripts/luascript.hpp b/src/lua/scripts/luascript.hpp index 06654c35a21..a376babedde 100644 --- a/src/lua/scripts/luascript.hpp +++ b/src/lua/scripts/luascript.hpp @@ -9,7 +9,6 @@ #pragma once -#include "lib/logging/log_with_spd_log.hpp" #include "lua/functions/lua_functions_loader.hpp" #include "lua/scripts/script_environment.hpp" diff --git a/src/main.cpp b/src/main.cpp index a2a77bd636c..8534bbb6911 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,26 +9,7 @@ #include "canary_server.hpp" #include "lib/di/container.hpp" -// Define um conceito para garantir que a função só aceite contêineres de números -template -concept NumberContainer = requires(T a) { - typename T::value_type; - requires std::integral || std::floating_point; -}; - -// Função que calcula a média de um contêiner de números -auto calculateAverage(const NumberContainer auto &container) { - // Utiliza ranges e std::views para processar o contêiner - return std::accumulate(container.begin(), container.end(), 0.0) / std::ranges::distance(container); -} int main() { - std::vector numbers = { 1, 2, 3, 4, 5 }; - - // Calcula a média usando a função com suporte a C++23 - double average = calculateAverage(numbers); - - std::cout << "Average: " << average << std::endl; - return inject().run(); } diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index e924b489c25..ae67bad447f 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -5595,14 +5595,23 @@ void ProtocolGame::parseForgeEnter(NetworkMessage &msg) { } // 0xBF -> 0 = fusion, 1 = transfer, 2 = dust to sliver, 3 = sliver to core, 4 = increase dust limit - auto actionType = static_cast(msg.getByte()); - bool convergence = msg.getByte(); - uint16_t firstItem = msg.get(); - uint8_t tier = msg.getByte(); - uint16_t secondItem = msg.get(); - bool usedCore = msg.getByte(); - bool reduceTierLoss = msg.getByte(); + const auto actionType = static_cast(msg.getByte()); + + bool convergence = false; + uint16_t firstItem = 0; + uint8_t tier = 0; + uint16_t secondItem = 0; + + if (actionType == ForgeAction_t::FUSION || actionType == ForgeAction_t::TRANSFER) { + convergence = msg.getByte(); + firstItem = msg.get(); + tier = msg.getByte(); + secondItem = msg.get(); + } + if (actionType == ForgeAction_t::FUSION) { + const bool usedCore = convergence ? false : msg.getByte(); + const bool reduceTierLoss = convergence ? false : msg.getByte(); g_game().playerForgeFuseItems(player->getID(), actionType, firstItem, tier, secondItem, usedCore, reduceTierLoss, convergence); } else if (actionType == ForgeAction_t::TRANSFER) { g_game().playerForgeTransferItemTier(player->getID(), actionType, firstItem, tier, secondItem, convergence); diff --git a/src/server/server.hpp b/src/server/server.hpp index 42134f765b0..dfb6aef5cf8 100644 --- a/src/server/server.hpp +++ b/src/server/server.hpp @@ -9,7 +9,6 @@ #pragma once -#include "lib/logging/logger.hpp" #include "lib/metrics/metrics.hpp" #include "server/network/connection/connection.hpp" #include "server/signals.hpp" diff --git a/src/utils/pugicast.cpp b/src/utils/pugicast.cpp index 2269e62b1fb..5791a8383a8 100644 --- a/src/utils/pugicast.cpp +++ b/src/utils/pugicast.cpp @@ -7,8 +7,6 @@ * Website: https://docs.opentibiabr.com/ */ -#include "lib/logging/log_with_spd_log.hpp" - namespace pugi { void logError(const std::string &str) { g_logger().error(str); diff --git a/src/utils/transparent_string_hash.hpp b/src/utils/transparent_string_hash.hpp new file mode 100644 index 00000000000..2092aa2cb98 --- /dev/null +++ b/src/utils/transparent_string_hash.hpp @@ -0,0 +1,24 @@ +/** + * Canary - A free and open-source MMORPG server emulator + * Copyright (©) 2019-2024 OpenTibiaBR + * Repository: https://github.com/opentibiabr/canary + * License: https://github.com/opentibiabr/canary/blob/main/LICENSE + * Contributors: https://github.com/opentibiabr/canary/graphs/contributors + * Website: https://docs.opentibiabr.com/ + */ + +#pragma once + +class TransparentStringHasher { +public: + using is_transparent = void; + size_t operator()(const std::string &key) const noexcept { + return std::hash {}(key); + } + size_t operator()(std::string_view key) const noexcept { + return std::hash {}(key); + } + size_t operator()(const char* key) const noexcept { + return std::hash {}(key); + } +}; diff --git a/tests/fixture/lib/logging/in_memory_logger.hpp b/tests/fixture/lib/logging/in_memory_logger.hpp index 76f0e7307d6..b45af91715e 100644 --- a/tests/fixture/lib/logging/in_memory_logger.hpp +++ b/tests/fixture/lib/logging/in_memory_logger.hpp @@ -51,7 +51,7 @@ class InMemoryLogger : public Logger { return false; } - void setLevel(const std::string &name) override { + void setLevel(const std::string &name) const override { // For the stub, setting a level might not have any behavior. // But you can implement level filtering if you like. } @@ -61,10 +61,34 @@ class InMemoryLogger : public Logger { return "DEBUG"; } - virtual void log(const std::string &lvl, const fmt::basic_string_view msg) const override { - logs.push_back({ lvl, { msg.data(), msg.size() } }); + virtual void info(const std::string &msg) const override { + logs.push_back({ "info", msg }); } + virtual void warn(const std::string &msg) const override { + logs.push_back({ "warning", msg }); + } + + virtual void error(const std::string &msg) const override { + logs.push_back({ "error", msg }); + } + + virtual void critical(const std::string &msg) const override { + logs.push_back({ "critical", msg }); + } + +#if defined(DEBUG_LOG) + virtual void debug(const std::string &msg) const override { + logs.push_back({ "debug", msg }); + } + + virtual void trace(const std::string &msg) const override { + logs.push_back({ "trace", msg }); + } +#else + virtual void debug(const std::string &) const override { } + virtual void trace(const std::string &) const override { } +#endif // Helper methods for testing size_t logCount() const { return logs.size(); diff --git a/vcproj/canary.vcxproj b/vcproj/canary.vcxproj index 135389e491d..7cbdd118ccc 100644 --- a/vcproj/canary.vcxproj +++ b/vcproj/canary.vcxproj @@ -316,6 +316,7 @@ +