diff --git a/Bigfoot/Sources/Utils/Include/Utils/Log/Log.fbs b/Bigfoot/Sources/Utils/Include/Utils/Log/Log.fbs index 727798b..be9ae90 100644 --- a/Bigfoot/Sources/Utils/Include/Utils/Log/Log.fbs +++ b/Bigfoot/Sources/Utils/Include/Utils/Log/Log.fbs @@ -2,7 +2,8 @@ namespace Bigfoot.Flat; enum LogSinkType: byte { - Console + Console, + File } enum LogLevel: byte diff --git a/Bigfoot/Sources/Utils/Include/Utils/Log/Log.hpp b/Bigfoot/Sources/Utils/Include/Utils/Log/Log.hpp index 79be60a..c7180aa 100644 --- a/Bigfoot/Sources/Utils/Include/Utils/Log/Log.hpp +++ b/Bigfoot/Sources/Utils/Include/Utils/Log/Log.hpp @@ -12,6 +12,7 @@ #include #include +#include #ifdef BIGFOOT_WINDOWS #pragma warning(disable: 4702) @@ -21,6 +22,7 @@ #include #include #include +#include #if defined BIGFOOT_WINDOWS #pragma warning(default: 4702) #endif @@ -36,6 +38,11 @@ class Log Flat::LogLevel m_level; }; + /** + * The path of the file the File sink writes to + */ + static constexpr eastl::string_view FILE_SINK_PATH = "Bigfoot.log"; + Log(); Log(const Log& p_logger) = delete; @@ -95,7 +102,7 @@ class Log /* * The sinks */ - eastl::array, 1> m_sinks; + eastl::array, 2> m_sinks; }; } // namespace Bigfoot #endif diff --git a/Bigfoot/Sources/Utils/Include/Utils/Log/LogMacros.hpp b/Bigfoot/Sources/Utils/Include/Utils/Log/LogMacros.hpp index 61e3cd7..b26df0d 100644 --- a/Bigfoot/Sources/Utils/Include/Utils/Log/LogMacros.hpp +++ b/Bigfoot/Sources/Utils/Include/Utils/Log/LogMacros.hpp @@ -101,4 +101,58 @@ #define BIGFOOT_LOG_ERROR(loggerName, fmt, ...) #define BIGFOOT_LOG_FATAL(loggerName, fmt, ...) #endif + +#define BIGFOOT_LOG_DEBUG_IF(condition, loggerName, fmt, ...) \ + do \ + { \ + if (condition) \ + { \ + BIGFOOT_LOG_DEBUG(loggerName, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) + +#define BIGFOOT_LOG_TRACE_IF(condition, loggerName, fmt, ...) \ + do \ + { \ + if (condition) \ + { \ + BIGFOOT_LOG_TRACE(loggerName, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) + +#define BIGFOOT_LOG_INFO_IF(condition, loggerName, fmt, ...) \ + do \ + { \ + if (condition) \ + { \ + BIGFOOT_LOG_INFO(loggerName, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) + +#define BIGFOOT_LOG_WARN_IF(condition, loggerName, fmt, ...) \ + do \ + { \ + if (condition) \ + { \ + BIGFOOT_LOG_WARN(loggerName, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) + +#define BIGFOOT_LOG_ERROR_IF(condition, loggerName, fmt, ...) \ + do \ + { \ + if (condition) \ + { \ + BIGFOOT_LOG_ERROR(loggerName, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) + +#define BIGFOOT_LOG_FATAL_IF(condition, loggerName, fmt, ...) \ + do \ + { \ + if (condition) \ + { \ + BIGFOOT_LOG_FATAL(loggerName, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) #endif diff --git a/Bigfoot/Sources/Utils/Include/Utils/Log/Log_generated.hpp b/Bigfoot/Sources/Utils/Include/Utils/Log/Log_generated.hpp index 887afbe..5cdcc17 100644 --- a/Bigfoot/Sources/Utils/Include/Utils/Log/Log_generated.hpp +++ b/Bigfoot/Sources/Utils/Include/Utils/Log/Log_generated.hpp @@ -29,27 +29,30 @@ namespace Flat { enum class LogSinkType : int8_t { Console = 0, + File = 1, MIN = Console, - MAX = Console + MAX = File }; -inline const LogSinkType (&EnumValuesLogSinkType())[1] { +inline const LogSinkType (&EnumValuesLogSinkType())[2] { static const LogSinkType values[] = { - LogSinkType::Console + LogSinkType::Console, + LogSinkType::File }; return values; } inline const char * const *EnumNamesLogSinkType() { - static const char * const names[2] = { + static const char * const names[3] = { "Console", + "File", nullptr }; return names; } inline const char *EnumNameLogSinkType(LogSinkType e) { - if (::flatbuffers::IsOutRange(e, LogSinkType::Console, LogSinkType::Console)) return ""; + if (::flatbuffers::IsOutRange(e, LogSinkType::Console, LogSinkType::File)) return ""; const size_t index = static_cast(e); return EnumNamesLogSinkType()[index]; } @@ -98,13 +101,14 @@ inline const char *EnumNameLogLevel(LogLevel e) { inline const ::flatbuffers::TypeTable *LogSinkTypeTypeTable() { static const ::flatbuffers::TypeCode type_codes[] = { + { ::flatbuffers::ET_CHAR, 0, 0 }, { ::flatbuffers::ET_CHAR, 0, 0 } }; static const ::flatbuffers::TypeFunction type_refs[] = { Bigfoot::Flat::LogSinkTypeTypeTable }; static const ::flatbuffers::TypeTable tt = { - ::flatbuffers::ST_ENUM, 1, type_codes, type_refs, nullptr, nullptr, nullptr + ::flatbuffers::ST_ENUM, 2, type_codes, type_refs, nullptr, nullptr, nullptr }; return &tt; } diff --git a/Bigfoot/Sources/Utils/Log/Log.cpp b/Bigfoot/Sources/Utils/Log/Log.cpp index 033594b..8398a86 100644 --- a/Bigfoot/Sources/Utils/Log/Log.cpp +++ b/Bigfoot/Sources/Utils/Log/Log.cpp @@ -17,6 +17,12 @@ Log::Log() m_sinks[static_cast(Flat::LogSinkType::Console)] = quill::Frontend::create_or_get_sink( std::string {Flat::EnumNameLogSinkType(Flat::LogSinkType::Console)}); + + quill::FileSinkConfig fileSinkConfig; + fileSinkConfig.set_open_mode('w'); + m_sinks[static_cast(Flat::LogSinkType::File)] = quill::Frontend::create_or_get_sink( + std::string {FILE_SINK_PATH.data()}, + fileSinkConfig); } /****************************************************************************************/ @@ -25,7 +31,8 @@ quill::Logger* Log::RegisterLogger(const LoggerInfo& p_loggerInfo) { quill::Logger* logger = quill::Frontend::create_or_get_logger( p_loggerInfo.m_name, - m_sinks[static_cast(Flat::LogSinkType::Console)]); + {m_sinks[static_cast(Flat::LogSinkType::Console)], + m_sinks[static_cast(Flat::LogSinkType::File)]}); SetLoggerLevel(p_loggerInfo); return logger; diff --git a/Bigfoot/Tests/Utils/Log/LogMacros.cpp b/Bigfoot/Tests/Utils/Log/LogMacros.cpp index aa6e328..3f4ac93 100644 --- a/Bigfoot/Tests/Utils/Log/LogMacros.cpp +++ b/Bigfoot/Tests/Utils/Log/LogMacros.cpp @@ -6,59 +6,80 @@ *********************************************************************/ #include +#include + #include #if defined BIGFOOT_NOT_OPTIMIZED +#include #include +#include +#include + namespace Bigfoot { class LogMacrosFixture: public ::testing::Test { protected: + eastl::string ReadFileSinkContent() + { + Singleton::GetInstance().Flush(); + + std::ifstream file {std::string {Log::FILE_SINK_PATH.data()}}; + std::stringstream buffer; + buffer << file.rdbuf(); + return eastl::string {buffer.str().c_str()}; + } }; /****************************************************************************************/ TEST_F(LogMacrosFixture, LogDebug) { - BIGFOOT_LOG_DEBUG(UTILSTESTS_LOGGER, "Hello"); + BIGFOOT_LOG_DEBUG(UTILSTESTS_LOGGER, "Hello Debug"); + EXPECT_NE(ReadFileSinkContent().find("Hello Debug"), eastl::string::npos); } /****************************************************************************************/ TEST_F(LogMacrosFixture, LogTrace) { - BIGFOOT_LOG_TRACE(UTILSTESTS_LOGGER, "Hello"); + BIGFOOT_LOG_TRACE(UTILSTESTS_LOGGER, "Hello Trace"); + EXPECT_NE(ReadFileSinkContent().find("Hello Trace"), eastl::string::npos); } /****************************************************************************************/ TEST_F(LogMacrosFixture, LogInfo) { - BIGFOOT_LOG_INFO(UTILSTESTS_LOGGER, "Hello"); + BIGFOOT_LOG_INFO(UTILSTESTS_LOGGER, "Hello Info"); + EXPECT_NE(ReadFileSinkContent().find("Hello Info"), eastl::string::npos); } /****************************************************************************************/ TEST_F(LogMacrosFixture, LogWarn) { - BIGFOOT_LOG_WARN(UTILSTESTS_LOGGER, "Hello"); + BIGFOOT_LOG_WARN(UTILSTESTS_LOGGER, "Hello Warn"); + EXPECT_NE(ReadFileSinkContent().find("Hello Warn"), eastl::string::npos); } /****************************************************************************************/ TEST_F(LogMacrosFixture, LogError) { - BIGFOOT_LOG_ERROR(UTILSTESTS_LOGGER, "Hello"); + BIGFOOT_LOG_ERROR(UTILSTESTS_LOGGER, "Hello Error"); + EXPECT_NE(ReadFileSinkContent().find("Hello Error"), eastl::string::npos); } /****************************************************************************************/ TEST_F(LogMacrosFixture, LogFatal) { - BIGFOOT_LOG_FATAL(UTILSTESTS_LOGGER, "Hello"); + BIGFOOT_LOG_FATAL(UTILSTESTS_LOGGER, "Hello Fatal"); + EXPECT_NE(ReadFileSinkContent().find("Hello Fatal"), eastl::string::npos); } } // namespace Bigfoot #endif