diff --git a/include/logit_cpp/logit/LogMacros.hpp b/include/logit_cpp/logit/LogMacros.hpp index 19c4539..66233fb 100644 --- a/include/logit_cpp/logit/LogMacros.hpp +++ b/include/logit_cpp/logit/LogMacros.hpp @@ -1608,6 +1608,33 @@ static_assert(LOGIT_LEVEL_FATAL == static_cast(logit::LogLevel::LOG_LVL_FAT std::make_unique(LOGIT_UNIQUE_FILE_LOGGER_PATTERN), \ true) +/// \brief Macro for adding a crash logger with custom configuration. +/// \param path Path where the crash log should be written. +/// \param buffer_size Size of the in-memory buffer preserving recent messages. +/// This version uses `std::make_unique`, available in C++17 and later. +#define LOGIT_ADD_CRASH_LOGGER(path, buffer_size) \ + logit::Logger::get_instance().add_logger( \ + std::make_unique( \ + logit::CrashLogger::Config{path, buffer_size}), \ + std::make_unique(LOGIT_FILE_LOGGER_PATTERN)) + +/// \brief Macro for adding a crash logger with custom configuration in single_mode. +/// In single_mode, the crash logger can only be invoked using macros like `LOGIT_TRACE_TO`. +/// This version uses `std::make_unique`, available in C++17 and later. +#define LOGIT_ADD_CRASH_LOGGER_SINGLE_MODE(path, buffer_size) \ + logit::Logger::get_instance().add_logger( \ + std::make_unique( \ + logit::CrashLogger::Config{path, buffer_size}), \ + std::make_unique(LOGIT_FILE_LOGGER_PATTERN), \ + true) + +/// \brief Macro for adding a crash logger with default configuration. +/// This version uses `std::make_unique`, available in C++17 and later. +#define LOGIT_ADD_CRASH_LOGGER_DEFAULT() \ + logit::Logger::get_instance().add_logger( \ + std::make_unique(), \ + std::make_unique(LOGIT_FILE_LOGGER_PATTERN)) + #define LOGIT_ADD_SYSLOG(ident, facility, async) \ logit::Logger::get_instance().add_logger( \ std::make_unique(ident, facility, async), \ @@ -1823,6 +1850,35 @@ static_assert(LOGIT_LEVEL_FATAL == static_cast(logit::LogLevel::LOG_LVL_FAT std::unique_ptr(new logit::SimpleLogFormatter(LOGIT_UNIQUE_FILE_LOGGER_PATTERN)), \ true) +/// \brief Macro for adding a crash logger with custom configuration. +/// \param path Path where the crash log should be written. +/// \param buffer_size Size of the in-memory buffer preserving recent messages. +/// This version uses `new` and `std::unique_ptr` for C++11 compatibility. +#define LOGIT_ADD_CRASH_LOGGER(path, buffer_size) \ + logit::Logger::get_instance().add_logger( \ + std::unique_ptr( \ + new logit::CrashLogger( \ + logit::CrashLogger::Config{path, buffer_size})), \ + std::unique_ptr(new logit::SimpleLogFormatter(LOGIT_FILE_LOGGER_PATTERN))) + +/// \brief Macro for adding a crash logger with custom configuration in single_mode. +/// In single_mode, the crash logger can only be invoked using macros like `LOGIT_TRACE_TO`. +/// This version uses `new` and `std::unique_ptr` for C++11 compatibility. +#define LOGIT_ADD_CRASH_LOGGER_SINGLE_MODE(path, buffer_size) \ + logit::Logger::get_instance().add_logger( \ + std::unique_ptr( \ + new logit::CrashLogger( \ + logit::CrashLogger::Config{path, buffer_size})), \ + std::unique_ptr(new logit::SimpleLogFormatter(LOGIT_FILE_LOGGER_PATTERN)), \ + true) + +/// \brief Macro for adding a crash logger with default configuration. +/// This version uses `new` and `std::unique_ptr` for C++11 compatibility. +#define LOGIT_ADD_CRASH_LOGGER_DEFAULT() \ + logit::Logger::get_instance().add_logger( \ + std::unique_ptr(new logit::CrashLogger()), \ + std::unique_ptr(new logit::SimpleLogFormatter(LOGIT_FILE_LOGGER_PATTERN))) + #define LOGIT_ADD_SYSLOG(ident, facility, async) \ logit::Logger::get_instance().add_logger( \ std::unique_ptr(new logit::SyslogLogger(ident, facility, async)), \ diff --git a/include/logit_cpp/logit/loggers/CrashWindowsLogger.hpp b/include/logit_cpp/logit/loggers/CrashWindowsLogger.hpp index 8e5e586..5fbc8ca 100644 --- a/include/logit_cpp/logit/loggers/CrashWindowsLogger.hpp +++ b/include/logit_cpp/logit/loggers/CrashWindowsLogger.hpp @@ -67,7 +67,7 @@ namespace logit { OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); - s_active_logger.store(this, std::memory_order_release); + active_logger().store(this, std::memory_order_release); } CrashWindowsLogger(const CrashWindowsLogger&) = delete; @@ -76,7 +76,7 @@ namespace logit { /// \\brief Close the crash log handle on destruction. ~CrashWindowsLogger() override { CrashWindowsLogger* expected = this; - s_active_logger.compare_exchange_strong( + active_logger().compare_exchange_strong( expected, nullptr, std::memory_order_release, std::memory_order_relaxed); if (m_file != INVALID_HANDLE_VALUE) { ::CloseHandle(m_file); @@ -180,7 +180,7 @@ namespace logit { private: static LONG WINAPI exception_filter(EXCEPTION_POINTERS* exception_info) { - CrashWindowsLogger* logger = s_active_logger.load(std::memory_order_acquire); + CrashWindowsLogger* logger = active_logger().load(std::memory_order_acquire); if (logger != nullptr) { DWORD code = 0; if (exception_info != nullptr && exception_info->ExceptionRecord != nullptr) { @@ -279,7 +279,10 @@ namespace logit { std::atomic m_log_level{static_cast(LogLevel::LOG_LVL_TRACE)}; std::array m_buffer{}; - inline static std::atomic s_active_logger{nullptr}; + static std::atomic& active_logger() noexcept { + static std::atomic instance(nullptr); + return instance; + } }; #else // Stub for non-Windows systems