diff options
Diffstat (limited to 'external/include/easylogging++.h')
-rw-r--r-- | external/include/easylogging++.h | 4594 |
1 files changed, 0 insertions, 4594 deletions
diff --git a/external/include/easylogging++.h b/external/include/easylogging++.h deleted file mode 100644 index f8741ce..0000000 --- a/external/include/easylogging++.h +++ /dev/null @@ -1,4594 +0,0 @@ -// -// Bismillah ar-Rahmaan ar-Raheem -// -// Easylogging++ v9.94.2 -// Single-header only, cross-platform logging library for C++ applications -// -// Copyright (c) 2017 muflihun.com -// -// This library is released under the MIT Licence. -// http://labs.muflihun.com/easyloggingpp/licence.php -// -// https://github.com/muflihun/easyloggingpp -// https://muflihun.github.io/easyloggingpp -// http://muflihun.com -// -#ifndef EASYLOGGINGPP_H -#define EASYLOGGINGPP_H -// Compilers and C++0x/C++11 Evaluation -#if __cplusplus >= 201103L -# define ELPP_CXX11 1 -#endif // __cplusplus >= 201103L -#if (defined(__GNUC__)) -# define ELPP_COMPILER_GCC 1 -#else -# define ELPP_COMPILER_GCC 0 -#endif -#if ELPP_COMPILER_GCC -# define ELPP_GCC_VERSION (__GNUC__ * 10000 \ -+ __GNUC_MINOR__ * 100 \ -+ __GNUC_PATCHLEVEL__) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define ELPP_CXX0X 1 -# endif -#endif -// Visual C++ -#if defined(_MSC_VER) -# define ELPP_COMPILER_MSVC 1 -#else -# define ELPP_COMPILER_MSVC 0 -#endif -#define ELPP_CRT_DBG_WARNINGS ELPP_COMPILER_MSVC -#if ELPP_COMPILER_MSVC -# if (_MSC_VER == 1600) -# define ELPP_CXX0X 1 -# elif(_MSC_VER >= 1700) -# define ELPP_CXX11 1 -# endif -#endif -// Clang++ -#if (defined(__clang__) && (__clang__ == 1)) -# define ELPP_COMPILER_CLANG 1 -#else -# define ELPP_COMPILER_CLANG 0 -#endif -#if ELPP_COMPILER_CLANG -# if __has_include(<thread>) -# include <cstddef> // Make __GLIBCXX__ defined when using libstdc++ -# if !defined(__GLIBCXX__) || __GLIBCXX__ >= 20150426 -# define ELPP_CLANG_SUPPORTS_THREAD -# endif // !defined(__GLIBCXX__) || __GLIBCXX__ >= 20150426 -# endif // __has_include(<thread>) -#endif -#if (defined(__MINGW32__) || defined(__MINGW64__)) -# define ELPP_MINGW 1 -#else -# define ELPP_MINGW 0 -#endif -#if (defined(__CYGWIN__) && (__CYGWIN__ == 1)) -# define ELPP_CYGWIN 1 -#else -# define ELPP_CYGWIN 0 -#endif -#if (defined(__INTEL_COMPILER)) -# define ELPP_COMPILER_INTEL 1 -#else -# define ELPP_COMPILER_INTEL 0 -#endif -// Operating System Evaluation -// Windows -#if (defined(_WIN32) || defined(_WIN64)) -# define ELPP_OS_WINDOWS 1 -#else -# define ELPP_OS_WINDOWS 0 -#endif -// Linux -#if (defined(__linux) || defined(__linux__)) -# define ELPP_OS_LINUX 1 -#else -# define ELPP_OS_LINUX 0 -#endif -#if (defined(__APPLE__)) -# define ELPP_OS_MAC 1 -#else -# define ELPP_OS_MAC 0 -#endif -#if (defined(__FreeBSD__)) -# define ELPP_OS_FREEBSD 1 -#else -# define ELPP_OS_FREEBSD 0 -#endif -#if (defined(__sun)) -# define ELPP_OS_SOLARIS 1 -#else -# define ELPP_OS_SOLARIS 0 -#endif -// Unix -#if ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_SOLARIS) && (!ELPP_OS_WINDOWS)) -# define ELPP_OS_UNIX 1 -#else -# define ELPP_OS_UNIX 0 -#endif -#if (defined(__ANDROID__)) -# define ELPP_OS_ANDROID 1 -#else -# define ELPP_OS_ANDROID 0 -#endif -// Evaluating Cygwin as *nix OS -#if !ELPP_OS_UNIX && !ELPP_OS_WINDOWS && ELPP_CYGWIN -# undef ELPP_OS_UNIX -# undef ELPP_OS_LINUX -# define ELPP_OS_UNIX 1 -# define ELPP_OS_LINUX 1 -#endif // !ELPP_OS_UNIX && !ELPP_OS_WINDOWS && ELPP_CYGWIN -#if !defined(ELPP_INTERNAL_DEBUGGING_OUT_INFO) -# define ELPP_INTERNAL_DEBUGGING_OUT_INFO std::cout -#endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT) -#if !defined(ELPP_INTERNAL_DEBUGGING_OUT_ERROR) -# define ELPP_INTERNAL_DEBUGGING_OUT_ERROR std::cerr -#endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT) -#if !defined(ELPP_INTERNAL_DEBUGGING_ENDL) -# define ELPP_INTERNAL_DEBUGGING_ENDL std::endl -#endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT) -#if !defined(ELPP_INTERNAL_DEBUGGING_MSG) -# define ELPP_INTERNAL_DEBUGGING_MSG(msg) msg -#endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT) -// Internal Assertions and errors -#if !defined(ELPP_DISABLE_ASSERT) -# if (defined(ELPP_DEBUG_ASSERT_FAILURE)) -# define ELPP_ASSERT(expr, msg) if (!(expr)) { \ -std::stringstream internalInfoStream; internalInfoStream << msg; \ -ELPP_INTERNAL_DEBUGGING_OUT_ERROR \ -<< "EASYLOGGING++ ASSERTION FAILED (LINE: " << __LINE__ << ") [" #expr << "] WITH MESSAGE \"" \ -<< ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << "\"" << ELPP_INTERNAL_DEBUGGING_ENDL; base::utils::abort(1, \ -"ELPP Assertion failure, please define ELPP_DEBUG_ASSERT_FAILURE"); } -# else -# define ELPP_ASSERT(expr, msg) if (!(expr)) { \ -std::stringstream internalInfoStream; internalInfoStream << msg; \ -ELPP_INTERNAL_DEBUGGING_OUT_ERROR\ -<< "ASSERTION FAILURE FROM EASYLOGGING++ (LINE: " \ -<< __LINE__ << ") [" #expr << "] WITH MESSAGE \"" << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << "\"" \ -<< ELPP_INTERNAL_DEBUGGING_ENDL; } -# endif // (defined(ELPP_DEBUG_ASSERT_FAILURE)) -#else -# define ELPP_ASSERT(x, y) -#endif //(!defined(ELPP_DISABLE_ASSERT) -#if ELPP_COMPILER_MSVC -# define ELPP_INTERNAL_DEBUGGING_WRITE_PERROR \ -{ char buff[256]; strerror_s(buff, 256, errno); \ -ELPP_INTERNAL_DEBUGGING_OUT_ERROR << ": " << buff << " [" << errno << "]";} (void)0 -#else -# define ELPP_INTERNAL_DEBUGGING_WRITE_PERROR \ -ELPP_INTERNAL_DEBUGGING_OUT_ERROR << ": " << strerror(errno) << " [" << errno << "]"; (void)0 -#endif // ELPP_COMPILER_MSVC -#if defined(ELPP_DEBUG_ERRORS) -# if !defined(ELPP_INTERNAL_ERROR) -# define ELPP_INTERNAL_ERROR(msg, pe) { \ -std::stringstream internalInfoStream; internalInfoStream << "<ERROR> " << msg; \ -ELPP_INTERNAL_DEBUGGING_OUT_ERROR \ -<< "ERROR FROM EASYLOGGING++ (LINE: " << __LINE__ << ") " \ -<< ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << ELPP_INTERNAL_DEBUGGING_ENDL; \ -if (pe) { ELPP_INTERNAL_DEBUGGING_OUT_ERROR << " "; ELPP_INTERNAL_DEBUGGING_WRITE_PERROR; }} (void)0 -# endif -#else -# undef ELPP_INTERNAL_INFO -# define ELPP_INTERNAL_ERROR(msg, pe) -#endif // defined(ELPP_DEBUG_ERRORS) -#if (defined(ELPP_DEBUG_INFO)) -# if !(defined(ELPP_INTERNAL_INFO_LEVEL)) -# define ELPP_INTERNAL_INFO_LEVEL 9 -# endif // !(defined(ELPP_INTERNAL_INFO_LEVEL)) -# if !defined(ELPP_INTERNAL_INFO) -# define ELPP_INTERNAL_INFO(lvl, msg) { if (lvl <= ELPP_INTERNAL_INFO_LEVEL) { \ -std::stringstream internalInfoStream; internalInfoStream << "<INFO> " << msg; \ -ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) \ -<< ELPP_INTERNAL_DEBUGGING_ENDL; }} -# endif -#else -# undef ELPP_INTERNAL_INFO -# define ELPP_INTERNAL_INFO(lvl, msg) -#endif // (defined(ELPP_DEBUG_INFO)) -#if (defined(ELPP_FEATURE_ALL)) || (defined(ELPP_FEATURE_CRASH_LOG)) -# if (ELPP_COMPILER_GCC && !ELPP_MINGW && !ELPP_OS_ANDROID) -# define ELPP_STACKTRACE 1 -# else -# if ELPP_COMPILER_MSVC -# pragma message("Stack trace not available for this compiler") -# else -# warning "Stack trace not available for this compiler"; -# endif // ELPP_COMPILER_MSVC -# define ELPP_STACKTRACE 0 -# endif // ELPP_COMPILER_GCC -#else -# define ELPP_STACKTRACE 0 -#endif // (defined(ELPP_FEATURE_ALL)) || (defined(ELPP_FEATURE_CRASH_LOG)) -// Miscellaneous macros -#define ELPP_UNUSED(x) (void)x -#if ELPP_OS_UNIX -// Log file permissions for unix-based systems -# define ELPP_LOG_PERMS S_IRUSR | S_IWUSR | S_IXUSR | S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IXOTH -#endif // ELPP_OS_UNIX -#if defined(ELPP_AS_DLL) && ELPP_COMPILER_MSVC -# if defined(ELPP_EXPORT_SYMBOLS) -# define ELPP_EXPORT __declspec(dllexport) -# else -# define ELPP_EXPORT __declspec(dllimport) -# endif // defined(ELPP_EXPORT_SYMBOLS) -#else -# define ELPP_EXPORT -#endif // defined(ELPP_AS_DLL) && ELPP_COMPILER_MSVC -// Some special functions that are VC++ specific -#undef STRTOK -#undef STRERROR -#undef STRCAT -#undef STRCPY -#if ELPP_CRT_DBG_WARNINGS -# define STRTOK(a, b, c) strtok_s(a, b, c) -# define STRERROR(a, b, c) strerror_s(a, b, c) -# define STRCAT(a, b, len) strcat_s(a, len, b) -# define STRCPY(a, b, len) strcpy_s(a, len, b) -#else -# define STRTOK(a, b, c) strtok(a, b) -# define STRERROR(a, b, c) strerror(c) -# define STRCAT(a, b, len) strcat(a, b) -# define STRCPY(a, b, len) strcpy(a, b) -#endif -// Compiler specific support evaluations -#if (ELPP_MINGW && !defined(ELPP_FORCE_USE_STD_THREAD)) -# define ELPP_USE_STD_THREADING 0 -#else -# if ((ELPP_COMPILER_CLANG && defined(ELPP_CLANG_SUPPORTS_THREAD)) || \ - (!ELPP_COMPILER_CLANG && defined(ELPP_CXX11)) || \ - defined(ELPP_FORCE_USE_STD_THREAD)) -# define ELPP_USE_STD_THREADING 1 -# else -# define ELPP_USE_STD_THREADING 0 -# endif -#endif -#undef ELPP_FINAL -#if ELPP_COMPILER_INTEL || (ELPP_GCC_VERSION < 40702) -# define ELPP_FINAL -#else -# define ELPP_FINAL final -#endif // ELPP_COMPILER_INTEL || (ELPP_GCC_VERSION < 40702) -#if defined(ELPP_EXPERIMENTAL_ASYNC) -# define ELPP_ASYNC_LOGGING 1 -#else -# define ELPP_ASYNC_LOGGING 0 -#endif // defined(ELPP_EXPERIMENTAL_ASYNC) -#if defined(ELPP_THREAD_SAFE) || ELPP_ASYNC_LOGGING -# define ELPP_THREADING_ENABLED 1 -#else -# define ELPP_THREADING_ENABLED 0 -#endif // defined(ELPP_THREAD_SAFE) || ELPP_ASYNC_LOGGING -// Function macro ELPP_FUNC -#undef ELPP_FUNC -#if ELPP_COMPILER_MSVC // Visual C++ -# define ELPP_FUNC __FUNCSIG__ -#elif ELPP_COMPILER_GCC // GCC -# define ELPP_FUNC __PRETTY_FUNCTION__ -#elif ELPP_COMPILER_INTEL // Intel C++ -# define ELPP_FUNC __PRETTY_FUNCTION__ -#elif ELPP_COMPILER_CLANG // Clang++ -# define ELPP_FUNC __PRETTY_FUNCTION__ -#else -# if defined(__func__) -# define ELPP_FUNC __func__ -# else -# define ELPP_FUNC "" -# endif // defined(__func__) -#endif // defined(_MSC_VER) -#undef ELPP_VARIADIC_TEMPLATES_SUPPORTED -// Keep following line commented until features are fixed -#define ELPP_VARIADIC_TEMPLATES_SUPPORTED \ -(ELPP_COMPILER_GCC || ELPP_COMPILER_CLANG || ELPP_COMPILER_INTEL || (ELPP_COMPILER_MSVC && _MSC_VER >= 1800)) -// Logging Enable/Disable macros -#if defined(ELPP_DISABLE_LOGS) -#define ELPP_LOGGING_ENABLED 0 -#else -#define ELPP_LOGGING_ENABLED 1 -#endif -#if (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED) && ((defined(_DEBUG)) || (!defined(NDEBUG)))) -# define ELPP_DEBUG_LOG 1 -#else -# define ELPP_DEBUG_LOG 0 -#endif // (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED) && ((defined(_DEBUG)) || (!defined(NDEBUG)))) -#if (!defined(ELPP_DISABLE_INFO_LOGS) && (ELPP_LOGGING_ENABLED)) -# define ELPP_INFO_LOG 1 -#else -# define ELPP_INFO_LOG 0 -#endif // (!defined(ELPP_DISABLE_INFO_LOGS) && (ELPP_LOGGING_ENABLED)) -#if (!defined(ELPP_DISABLE_WARNING_LOGS) && (ELPP_LOGGING_ENABLED)) -# define ELPP_WARNING_LOG 1 -#else -# define ELPP_WARNING_LOG 0 -#endif // (!defined(ELPP_DISABLE_WARNING_LOGS) && (ELPP_LOGGING_ENABLED)) -#if (!defined(ELPP_DISABLE_ERROR_LOGS) && (ELPP_LOGGING_ENABLED)) -# define ELPP_ERROR_LOG 1 -#else -# define ELPP_ERROR_LOG 0 -#endif // (!defined(ELPP_DISABLE_ERROR_LOGS) && (ELPP_LOGGING_ENABLED)) -#if (!defined(ELPP_DISABLE_FATAL_LOGS) && (ELPP_LOGGING_ENABLED)) -# define ELPP_FATAL_LOG 1 -#else -# define ELPP_FATAL_LOG 0 -#endif // (!defined(ELPP_DISABLE_FATAL_LOGS) && (ELPP_LOGGING_ENABLED)) -#if (!defined(ELPP_DISABLE_TRACE_LOGS) && (ELPP_LOGGING_ENABLED)) -# define ELPP_TRACE_LOG 1 -#else -# define ELPP_TRACE_LOG 0 -#endif // (!defined(ELPP_DISABLE_TRACE_LOGS) && (ELPP_LOGGING_ENABLED)) -#if (!defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED)) -# define ELPP_VERBOSE_LOG 1 -#else -# define ELPP_VERBOSE_LOG 0 -#endif // (!defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED)) -#if (!(ELPP_CXX0X || ELPP_CXX11)) -# error "C++0x (or higher) support not detected! (Is `-std=c++11' missing?)" -#endif // (!(ELPP_CXX0X || ELPP_CXX11)) -// Headers -#if defined(ELPP_SYSLOG) -# include <syslog.h> -#endif // defined(ELPP_SYSLOG) -#include <ctime> -#include <cstring> -#include <cstdlib> -#include <cctype> -#include <cwchar> -#include <csignal> -#include <cerrno> -#include <cstdarg> -#if defined(ELPP_UNICODE) -# include <locale> -# if ELPP_OS_WINDOWS -# include <codecvt> -# endif // ELPP_OS_WINDOWS -#endif // defined(ELPP_UNICODE) -#if ELPP_STACKTRACE -# include <cxxabi.h> -# include <execinfo.h> -#endif // ELPP_STACKTRACE -#if ELPP_OS_ANDROID -# include <sys/system_properties.h> -#endif // ELPP_OS_ANDROID -#if ELPP_OS_UNIX -# include <sys/stat.h> -# include <sys/time.h> -#elif ELPP_OS_WINDOWS -# include <direct.h> -# include <windows.h> -# if defined(WIN32_LEAN_AND_MEAN) -# if defined(ELPP_WINSOCK2) -# include <winsock2.h> -# else -# include <winsock.h> -# endif // defined(ELPP_WINSOCK2) -# endif // defined(WIN32_LEAN_AND_MEAN) -#endif // ELPP_OS_UNIX -#include <string> -#include <vector> -#include <map> -#include <utility> -#include <functional> -#include <algorithm> -#include <fstream> -#include <iostream> -#include <sstream> -#include <memory> -#include <type_traits> -#if ELPP_THREADING_ENABLED -# if ELPP_USE_STD_THREADING -# include <mutex> -# include <thread> -# else -# if ELPP_OS_UNIX -# include <pthread.h> -# endif // ELPP_OS_UNIX -# endif // ELPP_USE_STD_THREADING -#endif // ELPP_THREADING_ENABLED -#if ELPP_ASYNC_LOGGING -# if defined(ELPP_NO_SLEEP_FOR) -# include <unistd.h> -# endif // defined(ELPP_NO_SLEEP_FOR) -# include <thread> -# include <queue> -# include <condition_variable> -#endif // ELPP_ASYNC_LOGGING -#if defined(ELPP_STL_LOGGING) -// For logging STL based templates -# include <list> -# include <queue> -# include <deque> -# include <set> -# include <bitset> -# include <stack> -# if defined(ELPP_LOG_STD_ARRAY) -# include <array> -# endif // defined(ELPP_LOG_STD_ARRAY) -# if defined(ELPP_LOG_UNORDERED_MAP) -# include <unordered_map> -# endif // defined(ELPP_LOG_UNORDERED_MAP) -# if defined(ELPP_LOG_UNORDERED_SET) -# include <unordered_set> -# endif // defined(ELPP_UNORDERED_SET) -#endif // defined(ELPP_STL_LOGGING) -#if defined(ELPP_QT_LOGGING) -// For logging Qt based classes & templates -# include <QString> -# include <QByteArray> -# include <QVector> -# include <QList> -# include <QPair> -# include <QMap> -# include <QQueue> -# include <QSet> -# include <QLinkedList> -# include <QHash> -# include <QMultiHash> -# include <QStack> -#endif // defined(ELPP_QT_LOGGING) -#if defined(ELPP_BOOST_LOGGING) -// For logging boost based classes & templates -# include <boost/container/vector.hpp> -# include <boost/container/stable_vector.hpp> -# include <boost/container/list.hpp> -# include <boost/container/deque.hpp> -# include <boost/container/map.hpp> -# include <boost/container/flat_map.hpp> -# include <boost/container/set.hpp> -# include <boost/container/flat_set.hpp> -#endif // defined(ELPP_BOOST_LOGGING) -#if defined(ELPP_WXWIDGETS_LOGGING) -// For logging wxWidgets based classes & templates -# include <wx/vector.h> -#endif // defined(ELPP_WXWIDGETS_LOGGING) -#if defined(ELPP_UTC_DATETIME) -# define elpptime_r gmtime_r -# define elpptime_s gmtime_s -# define elpptime gmtime -#else -# define elpptime_r localtime_r -# define elpptime_s localtime_s -# define elpptime localtime -#endif // defined(ELPP_UTC_DATETIME) -// Forward declarations -namespace el { -class Logger; -class LogMessage; -class PerformanceTrackingData; -class Loggers; -class Helpers; -template <typename T> class Callback; -class LogDispatchCallback; -class PerformanceTrackingCallback; -class LoggerRegistrationCallback; -class LogDispatchData; -namespace base { -class Storage; -class RegisteredLoggers; -class PerformanceTracker; -class MessageBuilder; -class Writer; -class PErrorWriter; -class LogDispatcher; -class DefaultLogBuilder; -class DefaultLogDispatchCallback; -#if ELPP_ASYNC_LOGGING -class AsyncLogDispatchCallback; -class AsyncDispatchWorker; -#endif // ELPP_ASYNC_LOGGING -class DefaultPerformanceTrackingCallback; -} // namespace base -} // namespace el -/// @brief Easylogging++ entry namespace -namespace el { -/// @brief Namespace containing base/internal functionality used by Easylogging++ -namespace base { -/// @brief Data types used by Easylogging++ -namespace type { -#undef ELPP_LITERAL -#undef ELPP_STRLEN -#undef ELPP_COUT -#if defined(ELPP_UNICODE) -# define ELPP_LITERAL(txt) L##txt -# define ELPP_STRLEN wcslen -# if defined ELPP_CUSTOM_COUT -# define ELPP_COUT ELPP_CUSTOM_COUT -# else -# define ELPP_COUT std::wcout -# endif // defined ELPP_CUSTOM_COUT -typedef wchar_t char_t; -typedef std::wstring string_t; -typedef std::wstringstream stringstream_t; -typedef std::wfstream fstream_t; -typedef std::wostream ostream_t; -#else -# define ELPP_LITERAL(txt) txt -# define ELPP_STRLEN strlen -# if defined ELPP_CUSTOM_COUT -# define ELPP_COUT ELPP_CUSTOM_COUT -# else -# define ELPP_COUT std::cout -# endif // defined ELPP_CUSTOM_COUT -typedef char char_t; -typedef std::string string_t; -typedef std::stringstream stringstream_t; -typedef std::fstream fstream_t; -typedef std::ostream ostream_t; -#endif // defined(ELPP_UNICODE) -#if defined(ELPP_CUSTOM_COUT_LINE) -# define ELPP_COUT_LINE(logLine) ELPP_CUSTOM_COUT_LINE(logLine) -#else -# define ELPP_COUT_LINE(logLine) logLine << std::flush -#endif // defined(ELPP_CUSTOM_COUT_LINE) -typedef unsigned int EnumType; -typedef unsigned short VerboseLevel; -typedef unsigned long int LineNumber; -typedef std::shared_ptr<base::Storage> StoragePointer; -typedef std::shared_ptr<LogDispatchCallback> LogDispatchCallbackPtr; -typedef std::shared_ptr<PerformanceTrackingCallback> PerformanceTrackingCallbackPtr; -typedef std::shared_ptr<LoggerRegistrationCallback> LoggerRegistrationCallbackPtr; -typedef std::unique_ptr<el::base::PerformanceTracker> PerformanceTrackerPtr; -} // namespace type -/// @brief Internal helper class that prevent copy constructor for class -/// -/// @detail When using this class simply inherit it privately -class NoCopy { - protected: - NoCopy(void) {} - private: - NoCopy(const NoCopy&); - NoCopy& operator=(const NoCopy&); -}; -/// @brief Internal helper class that makes all default constructors private. -/// -/// @detail This prevents initializing class making it static unless an explicit constructor is declared. -/// When using this class simply inherit it privately -class StaticClass { - private: - StaticClass(void); - StaticClass(const StaticClass&); - StaticClass& operator=(const StaticClass&); -}; -} // namespace base -/// @brief Represents enumeration for severity level used to determine level of logging -/// -/// @detail With Easylogging++, developers may disable or enable any level regardless of -/// what the severity is. Or they can choose to log using hierarchical logging flag -enum class Level : base::type::EnumType { - /// @brief Generic level that represents all the levels. Useful when setting global configuration for all levels - Global = 1, - /// @brief Information that can be useful to back-trace certain events - mostly useful than debug logs. - Trace = 2, - /// @brief Informational events most useful for developers to debug application - Debug = 4, - /// @brief Severe error information that will presumably abort application - Fatal = 8, - /// @brief Information representing errors in application but application will keep running - Error = 16, - /// @brief Useful when application has potentially harmful situtaions - Warning = 32, - /// @brief Information that can be highly useful and vary with verbose logging level. - Verbose = 64, - /// @brief Mainly useful to represent current progress of application - Info = 128, - /// @brief Represents unknown level - Unknown = 1010 -}; -/// @brief Static class that contains helper functions for el::Level -class LevelHelper : base::StaticClass { - public: - /// @brief Represents minimum valid level. Useful when iterating through enum. - static const base::type::EnumType kMinValid = static_cast<base::type::EnumType>(Level::Trace); - /// @brief Represents maximum valid level. This is used internally and you should not need it. - static const base::type::EnumType kMaxValid = static_cast<base::type::EnumType>(Level::Info); - /// @brief Casts level to int, useful for iterating through enum. - static base::type::EnumType castToInt(Level level) { - return static_cast<base::type::EnumType>(level); - } - /// @brief Casts int(ushort) to level, useful for iterating through enum. - static Level castFromInt(base::type::EnumType l) { - return static_cast<Level>(l); - } - /// @brief Converts level to associated const char* - /// @return Upper case string based level. - static const char* convertToString(Level level); - /// @brief Converts from levelStr to Level - /// @param levelStr Upper case string based level. - /// Lower case is also valid but providing upper case is recommended. - static Level convertFromString(const char* levelStr); - /// @brief Applies specified function to each level starting from startIndex - /// @param startIndex initial value to start the iteration from. This is passed as pointer and - /// is left-shifted so this can be used inside function (fn) to represent current level. - /// @param fn function to apply with each level. This bool represent whether or not to stop iterating through levels. - static void forEachLevel(base::type::EnumType* startIndex, const std::function<bool(void)>& fn); -}; -/// @brief Represents enumeration of ConfigurationType used to configure or access certain aspect -/// of logging -enum class ConfigurationType : base::type::EnumType { - /// @brief Determines whether or not corresponding level and logger of logging is enabled - /// You may disable all logs by using el::Level::Global - Enabled = 1, - /// @brief Whether or not to write corresponding log to log file - ToFile = 2, - /// @brief Whether or not to write corresponding level and logger log to standard output. - /// By standard output meaning termnal, command prompt etc - ToStandardOutput = 4, - /// @brief Determines format of logging corresponding level and logger. - Format = 8, - /// @brief Determines log file (full path) to write logs to for correponding level and logger - Filename = 16, - /// @brief Specifies precision of the subsecond part. It should be within range (1-6). - SubsecondPrecision = 32, - /// @brief Alias of SubsecondPrecision (for backward compatibility) - MillisecondsWidth = SubsecondPrecision, - /// @brief Determines whether or not performance tracking is enabled. - /// - /// @detail This does not depend on logger or level. Performance tracking always uses 'performance' logger - PerformanceTracking = 64, - /// @brief Specifies log file max size. - /// - /// @detail If file size of corresponding log file (for corresponding level) is >= specified size, log file will - /// be truncated and re-initiated. - MaxLogFileSize = 128, - /// @brief Specifies number of log entries to hold until we flush pending log data - LogFlushThreshold = 256, - /// @brief Represents unknown configuration - Unknown = 1010 -}; -/// @brief Static class that contains helper functions for el::ConfigurationType -class ConfigurationTypeHelper : base::StaticClass { - public: - /// @brief Represents minimum valid configuration type. Useful when iterating through enum. - static const base::type::EnumType kMinValid = static_cast<base::type::EnumType>(ConfigurationType::Enabled); - /// @brief Represents maximum valid configuration type. This is used internally and you should not need it. - static const base::type::EnumType kMaxValid = static_cast<base::type::EnumType>(ConfigurationType::MaxLogFileSize); - /// @brief Casts configuration type to int, useful for iterating through enum. - static base::type::EnumType castToInt(ConfigurationType configurationType) { - return static_cast<base::type::EnumType>(configurationType); - } - /// @brief Casts int(ushort) to configurationt type, useful for iterating through enum. - static ConfigurationType castFromInt(base::type::EnumType c) { - return static_cast<ConfigurationType>(c); - } - /// @brief Converts configuration type to associated const char* - /// @returns Upper case string based configuration type. - static const char* convertToString(ConfigurationType configurationType); - /// @brief Converts from configStr to ConfigurationType - /// @param configStr Upper case string based configuration type. - /// Lower case is also valid but providing upper case is recommended. - static ConfigurationType convertFromString(const char* configStr); - /// @brief Applies specified function to each configuration type starting from startIndex - /// @param startIndex initial value to start the iteration from. This is passed by pointer and is left-shifted - /// so this can be used inside function (fn) to represent current configuration type. - /// @param fn function to apply with each configuration type. - /// This bool represent whether or not to stop iterating through configurations. - static inline void forEachConfigType(base::type::EnumType* startIndex, const std::function<bool(void)>& fn); -}; -/// @brief Flags used while writing logs. This flags are set by user -enum class LoggingFlag : base::type::EnumType { - /// @brief Makes sure we have new line for each container log entry - NewLineForContainer = 1, - /// @brief Makes sure if -vmodule is used and does not specifies a module, then verbose - /// logging is allowed via that module. - AllowVerboseIfModuleNotSpecified = 2, - /// @brief When handling crashes by default, detailed crash reason will be logged as well - LogDetailedCrashReason = 4, - /// @brief Allows to disable application abortion when logged using FATAL level - DisableApplicationAbortOnFatalLog = 8, - /// @brief Flushes log with every log-entry (performance sensative) - Disabled by default - ImmediateFlush = 16, - /// @brief Enables strict file rolling - StrictLogFileSizeCheck = 32, - /// @brief Make terminal output colorful for supported terminals - ColoredTerminalOutput = 64, - /// @brief Supports use of multiple logging in same macro, e.g, CLOG(INFO, "default", "network") - MultiLoggerSupport = 128, - /// @brief Disables comparing performance tracker's checkpoints - DisablePerformanceTrackingCheckpointComparison = 256, - /// @brief Disable VModules - DisableVModules = 512, - /// @brief Disable VModules extensions - DisableVModulesExtensions = 1024, - /// @brief Enables hierarchical logging - HierarchicalLogging = 2048, - /// @brief Creates logger automatically when not available - CreateLoggerAutomatically = 4096, - /// @brief Adds spaces b/w logs that separated by left-shift operator - AutoSpacing = 8192, - /// @brief Preserves time format and does not convert it to sec, hour etc (performance tracking only) - FixedTimeFormat = 16384 -}; -namespace base { -/// @brief Namespace containing constants used internally. -namespace consts { -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-variable" -#endif -// Level log values - These are values that are replaced in place of %level format specifier -// Extra spaces after format specifiers are only for readability purposes in log files -static const base::type::char_t* kInfoLevelLogValue = ELPP_LITERAL("INFO"); -static const base::type::char_t* kDebugLevelLogValue = ELPP_LITERAL("DEBUG"); -static const base::type::char_t* kWarningLevelLogValue = ELPP_LITERAL("WARNING"); -static const base::type::char_t* kErrorLevelLogValue = ELPP_LITERAL("ERROR"); -static const base::type::char_t* kFatalLevelLogValue = ELPP_LITERAL("FATAL"); -static const base::type::char_t* kVerboseLevelLogValue = - ELPP_LITERAL("VERBOSE"); // will become VERBOSE-x where x = verbose level -static const base::type::char_t* kTraceLevelLogValue = ELPP_LITERAL("TRACE"); -static const base::type::char_t* kInfoLevelShortLogValue = ELPP_LITERAL("I"); -static const base::type::char_t* kDebugLevelShortLogValue = ELPP_LITERAL("D"); -static const base::type::char_t* kWarningLevelShortLogValue = ELPP_LITERAL("W"); -static const base::type::char_t* kErrorLevelShortLogValue = ELPP_LITERAL("E"); -static const base::type::char_t* kFatalLevelShortLogValue = ELPP_LITERAL("F"); -static const base::type::char_t* kVerboseLevelShortLogValue = ELPP_LITERAL("V"); -static const base::type::char_t* kTraceLevelShortLogValue = ELPP_LITERAL("T"); -// Format specifiers - These are used to define log format -static const base::type::char_t* kAppNameFormatSpecifier = ELPP_LITERAL("%app"); -static const base::type::char_t* kLoggerIdFormatSpecifier = ELPP_LITERAL("%logger"); -static const base::type::char_t* kThreadIdFormatSpecifier = ELPP_LITERAL("%thread"); -static const base::type::char_t* kSeverityLevelFormatSpecifier = ELPP_LITERAL("%level"); -static const base::type::char_t* kSeverityLevelShortFormatSpecifier = ELPP_LITERAL("%levshort"); -static const base::type::char_t* kDateTimeFormatSpecifier = ELPP_LITERAL("%datetime"); -static const base::type::char_t* kLogFileFormatSpecifier = ELPP_LITERAL("%file"); -static const base::type::char_t* kLogFileBaseFormatSpecifier = ELPP_LITERAL("%fbase"); -static const base::type::char_t* kLogLineFormatSpecifier = ELPP_LITERAL("%line"); -static const base::type::char_t* kLogLocationFormatSpecifier = ELPP_LITERAL("%loc"); -static const base::type::char_t* kLogFunctionFormatSpecifier = ELPP_LITERAL("%func"); -static const base::type::char_t* kCurrentUserFormatSpecifier = ELPP_LITERAL("%user"); -static const base::type::char_t* kCurrentHostFormatSpecifier = ELPP_LITERAL("%host"); -static const base::type::char_t* kMessageFormatSpecifier = ELPP_LITERAL("%msg"); -static const base::type::char_t* kVerboseLevelFormatSpecifier = ELPP_LITERAL("%vlevel"); -static const char* kDateTimeFormatSpecifierForFilename = "%datetime"; -// Date/time -static const char* kDays[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; -static const char* kDaysAbbrev[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; -static const char* kMonths[12] = { "January", "February", "March", "Apri", "May", "June", "July", "August", - "September", "October", "November", "December" - }; -static const char* kMonthsAbbrev[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; -static const char* kDefaultDateTimeFormat = "%Y-%M-%d %H:%m:%s,%g"; -static const char* kDefaultDateTimeFormatInFilename = "%Y-%M-%d_%H-%m"; -static const int kYearBase = 1900; -static const char* kAm = "AM"; -static const char* kPm = "PM"; -// Miscellaneous constants -#ifdef ELPP_DEFAULT_LOGGER -static const char* kDefaultLoggerId = ELPP_DEFAULT_LOGGER; -#else -static const char* kDefaultLoggerId = "default"; -#endif -#ifdef ELPP_DEFAULT_PERFORMANCE_LOGGER -static const char* kPerformanceLoggerId = ELPP_DEFAULT_PERFORMANCE_LOGGER; -#else -static const char* kPerformanceLoggerId = "performance"; -#endif -#if defined(ELPP_SYSLOG) -static const char* kSysLogLoggerId = "syslog"; -#endif // defined(ELPP_SYSLOG) -static const char* kNullPointer = "nullptr"; -static const char kFormatSpecifierChar = '%'; -#if ELPP_VARIADIC_TEMPLATES_SUPPORTED -static const char kFormatSpecifierCharValue = 'v'; -#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED -static const unsigned int kMaxLogPerContainer = 100; -static const unsigned int kMaxLogPerCounter = 100000; -static const unsigned int kDefaultSubsecondPrecision = 3; -static const base::type::VerboseLevel kMaxVerboseLevel = 9; -static const char* kUnknownUser = "user"; -static const char* kUnknownHost = "unknown-host"; -#if defined(ELPP_DEFAULT_LOG_FILE) -static const char* kDefaultLogFile = ELPP_DEFAULT_LOG_FILE; -#else -# if ELPP_OS_UNIX -# if ELPP_OS_ANDROID -static const char* kDefaultLogFile = "logs/myeasylog.log"; -# else -static const char* kDefaultLogFile = "logs/myeasylog.log"; -# endif // ELPP_OS_ANDROID -# elif ELPP_OS_WINDOWS -static const char* kDefaultLogFile = "logs\\myeasylog.log"; -# endif // ELPP_OS_UNIX -#endif // defined(ELPP_DEFAULT_LOG_FILE) -#if !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG) -static const char* kDefaultLogFileParam = "--default-log-file"; -#endif // !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG) -#if defined(ELPP_LOGGING_FLAGS_FROM_ARG) -static const char* kLoggingFlagsParam = "--logging-flags"; -#endif // defined(ELPP_LOGGING_FLAGS_FROM_ARG) -#if ELPP_OS_WINDOWS -static const char* kFilePathSeperator = "\\"; -#else -static const char* kFilePathSeperator = "/"; -#endif // ELPP_OS_WINDOWS -static const char* kValidLoggerIdSymbols = - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._"; -static const char* kConfigurationComment = "##"; -static const char* kConfigurationLevel = "*"; -static const char* kConfigurationLoggerId = "--"; -static const std::size_t kSourceFilenameMaxLength = 100; -static const std::size_t kSourceLineMaxLength = 10; -static const Level kPerformanceTrackerDefaultLevel = Level::Info; -const struct { - double value; - const base::type::char_t* unit; -} kTimeFormats[] = { - { 1000.0f, ELPP_LITERAL("us") }, - { 1000.0f, ELPP_LITERAL("ms") }, - { 60.0f, ELPP_LITERAL("seconds") }, - { 60.0f, ELPP_LITERAL("minutes") }, - { 24.0f, ELPP_LITERAL("hours") }, - { 7.0f, ELPP_LITERAL("days") } -}; -static const int kTimeFormatsCount = sizeof(kTimeFormats) / sizeof(kTimeFormats[0]); -const struct { - int numb; - const char* name; - const char* brief; - const char* detail; -} kCrashSignals[] = { - // NOTE: Do not re-order, if you do please check CrashHandler(bool) constructor and CrashHandler::setHandler(..) - { - SIGABRT, "SIGABRT", "Abnormal termination", - "Program was abnormally terminated." - }, - { - SIGFPE, "SIGFPE", "Erroneous arithmetic operation", - "Arithemetic operation issue such as division by zero or operation resulting in overflow." - }, - { - SIGILL, "SIGILL", "Illegal instruction", - "Generally due to a corruption in the code or to an attempt to execute data." - }, - { - SIGSEGV, "SIGSEGV", "Invalid access to memory", - "Program is trying to read an invalid (unallocated, deleted or corrupted) or inaccessible memory." - }, - { - SIGINT, "SIGINT", "Interactive attention signal", - "Interruption generated (generally) by user or operating system." - }, -}; -static const int kCrashSignalsCount = sizeof(kCrashSignals) / sizeof(kCrashSignals[0]); -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif -} // namespace consts -} // namespace base -typedef std::function<void(const char*, std::size_t)> PreRollOutCallback; -namespace base { -static inline void defaultPreRollOutCallback(const char*, std::size_t) {} -/// @brief Enum to represent timestamp unit -enum class TimestampUnit : base::type::EnumType { - Microsecond = 0, Millisecond = 1, Second = 2, Minute = 3, Hour = 4, Day = 5 -}; -/// @brief Format flags used to determine specifiers that are active for performance improvements. -enum class FormatFlags : base::type::EnumType { - DateTime = 1 << 1, - LoggerId = 1 << 2, - File = 1 << 3, - Line = 1 << 4, - Location = 1 << 5, - Function = 1 << 6, - User = 1 << 7, - Host = 1 << 8, - LogMessage = 1 << 9, - VerboseLevel = 1 << 10, - AppName = 1 << 11, - ThreadId = 1 << 12, - Level = 1 << 13, - FileBase = 1 << 14, - LevelShort = 1 << 15 -}; -/// @brief A subsecond precision class containing actual width and offset of the subsecond part -class SubsecondPrecision { - public: - SubsecondPrecision(void) { - init(base::consts::kDefaultSubsecondPrecision); - } - explicit SubsecondPrecision(int width) { - init(width); - } - bool operator==(const SubsecondPrecision& ssPrec) { - return m_width == ssPrec.m_width && m_offset == ssPrec.m_offset; - } - int m_width; - unsigned int m_offset; - private: - void init(int width); -}; -/// @brief Type alias of SubsecondPrecision -typedef SubsecondPrecision MillisecondsWidth; -/// @brief Namespace containing utility functions/static classes used internally -namespace utils { -/// @brief Deletes memory safely and points to null -template <typename T> -static -typename std::enable_if<std::is_pointer<T*>::value, void>::type -safeDelete(T*& pointer) { - if (pointer == nullptr) - return; - delete pointer; - pointer = nullptr; -} -/// @brief Bitwise operations for C++11 strong enum class. This casts e into Flag_T and returns value after bitwise operation -/// Use these function as <pre>flag = bitwise::Or<MyEnum>(MyEnum::val1, flag);</pre> -namespace bitwise { -template <typename Enum> -static inline base::type::EnumType And(Enum e, base::type::EnumType flag) { - return static_cast<base::type::EnumType>(flag) & static_cast<base::type::EnumType>(e); -} -template <typename Enum> -static inline base::type::EnumType Not(Enum e, base::type::EnumType flag) { - return static_cast<base::type::EnumType>(flag) & ~(static_cast<base::type::EnumType>(e)); -} -template <typename Enum> -static inline base::type::EnumType Or(Enum e, base::type::EnumType flag) { - return static_cast<base::type::EnumType>(flag) | static_cast<base::type::EnumType>(e); -} -} // namespace bitwise -template <typename Enum> -static inline void addFlag(Enum e, base::type::EnumType* flag) { - *flag = base::utils::bitwise::Or<Enum>(e, *flag); -} -template <typename Enum> -static inline void removeFlag(Enum e, base::type::EnumType* flag) { - *flag = base::utils::bitwise::Not<Enum>(e, *flag); -} -template <typename Enum> -static inline bool hasFlag(Enum e, base::type::EnumType flag) { - return base::utils::bitwise::And<Enum>(e, flag) > 0x0; -} -} // namespace utils -namespace threading { -#if ELPP_THREADING_ENABLED -# if !ELPP_USE_STD_THREADING -namespace internal { -/// @brief A mutex wrapper for compiler that dont yet support std::recursive_mutex -class Mutex : base::NoCopy { - public: - Mutex(void) { -# if ELPP_OS_UNIX - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&m_underlyingMutex, &attr); - pthread_mutexattr_destroy(&attr); -# elif ELPP_OS_WINDOWS - InitializeCriticalSection(&m_underlyingMutex); -# endif // ELPP_OS_UNIX - } - - virtual ~Mutex(void) { -# if ELPP_OS_UNIX - pthread_mutex_destroy(&m_underlyingMutex); -# elif ELPP_OS_WINDOWS - DeleteCriticalSection(&m_underlyingMutex); -# endif // ELPP_OS_UNIX - } - - inline void lock(void) { -# if ELPP_OS_UNIX - pthread_mutex_lock(&m_underlyingMutex); -# elif ELPP_OS_WINDOWS - EnterCriticalSection(&m_underlyingMutex); -# endif // ELPP_OS_UNIX - } - - inline bool try_lock(void) { -# if ELPP_OS_UNIX - return (pthread_mutex_trylock(&m_underlyingMutex) == 0); -# elif ELPP_OS_WINDOWS - return TryEnterCriticalSection(&m_underlyingMutex); -# endif // ELPP_OS_UNIX - } - - inline void unlock(void) { -# if ELPP_OS_UNIX - pthread_mutex_unlock(&m_underlyingMutex); -# elif ELPP_OS_WINDOWS - LeaveCriticalSection(&m_underlyingMutex); -# endif // ELPP_OS_UNIX - } - - private: -# if ELPP_OS_UNIX - pthread_mutex_t m_underlyingMutex; -# elif ELPP_OS_WINDOWS - CRITICAL_SECTION m_underlyingMutex; -# endif // ELPP_OS_UNIX -}; -/// @brief Scoped lock for compiler that dont yet support std::lock_guard -template <typename M> -class ScopedLock : base::NoCopy { - public: - explicit ScopedLock(M& mutex) { - m_mutex = &mutex; - m_mutex->lock(); - } - - virtual ~ScopedLock(void) { - m_mutex->unlock(); - } - private: - M* m_mutex; - ScopedLock(void); -}; -} // namespace internal -typedef base::threading::internal::Mutex Mutex; -typedef base::threading::internal::ScopedLock<base::threading::Mutex> ScopedLock; -# else -typedef std::recursive_mutex Mutex; -typedef std::lock_guard<base::threading::Mutex> ScopedLock; -# endif // !ELPP_USE_STD_THREADING -#else -namespace internal { -/// @brief Mutex wrapper used when multi-threading is disabled. -class NoMutex : base::NoCopy { - public: - NoMutex(void) {} - inline void lock(void) {} - inline bool try_lock(void) { - return true; - } - inline void unlock(void) {} -}; -/// @brief Lock guard wrapper used when multi-threading is disabled. -template <typename Mutex> -class NoScopedLock : base::NoCopy { - public: - explicit NoScopedLock(Mutex&) { - } - virtual ~NoScopedLock(void) { - } - private: - NoScopedLock(void); -}; -} // namespace internal -typedef base::threading::internal::NoMutex Mutex; -typedef base::threading::internal::NoScopedLock<base::threading::Mutex> ScopedLock; -#endif // ELPP_THREADING_ENABLED -/// @brief Base of thread safe class, this class is inheritable-only -class ThreadSafe { - public: - virtual inline void acquireLock(void) ELPP_FINAL { m_mutex.lock(); } - virtual inline void releaseLock(void) ELPP_FINAL { m_mutex.unlock(); } - virtual inline base::threading::Mutex& lock(void) ELPP_FINAL { return m_mutex; } - protected: - ThreadSafe(void) {} - virtual ~ThreadSafe(void) {} - private: - base::threading::Mutex m_mutex; -}; - -#if ELPP_THREADING_ENABLED -# if !ELPP_USE_STD_THREADING -/// @brief Gets ID of currently running threading in windows systems. On unix, nothing is returned. -static std::string getCurrentThreadId(void) { - std::stringstream ss; -# if (ELPP_OS_WINDOWS) - ss << GetCurrentThreadId(); -# endif // (ELPP_OS_WINDOWS) - return ss.str(); -} -# else -/// @brief Gets ID of currently running threading using std::this_thread::get_id() -static std::string getCurrentThreadId(void) { - std::stringstream ss; - ss << std::this_thread::get_id(); - return ss.str(); -} -# endif // !ELPP_USE_STD_THREADING -#else -static inline std::string getCurrentThreadId(void) { - return std::string(); -} -#endif // ELPP_THREADING_ENABLED -} // namespace threading -namespace utils { -class File : base::StaticClass { - public: - /// @brief Creates new out file stream for specified filename. - /// @return Pointer to newly created fstream or nullptr - static base::type::fstream_t* newFileStream(const std::string& filename); - - /// @brief Gets size of file provided in stream - static std::size_t getSizeOfFile(base::type::fstream_t* fs); - - /// @brief Determines whether or not provided path exist in current file system - static bool pathExists(const char* path, bool considerFile = false); - - /// @brief Creates specified path on file system - /// @param path Path to create. - static bool createPath(const std::string& path); - /// @brief Extracts path of filename with leading slash - static std::string extractPathFromFilename(const std::string& fullPath, - const char* seperator = base::consts::kFilePathSeperator); - /// @brief builds stripped filename and puts it in buff - static void buildStrippedFilename(const char* filename, char buff[], - std::size_t limit = base::consts::kSourceFilenameMaxLength); - /// @brief builds base filename and puts it in buff - static void buildBaseFilename(const std::string& fullPath, char buff[], - std::size_t limit = base::consts::kSourceFilenameMaxLength, - const char* seperator = base::consts::kFilePathSeperator); -}; -/// @brief String utilities helper class used internally. You should not use it. -class Str : base::StaticClass { - public: - /// @brief Checks if character is digit. Dont use libc implementation of it to prevent locale issues. - static inline bool isDigit(char c) { - return c >= '0' && c <= '9'; - } - - /// @brief Matches wildcards, '*' and '?' only supported. - static bool wildCardMatch(const char* str, const char* pattern); - - static std::string& ltrim(std::string& str); - static std::string& rtrim(std::string& str); - static std::string& trim(std::string& str); - - /// @brief Determines whether or not str starts with specified string - /// @param str String to check - /// @param start String to check against - /// @return Returns true if starts with specified string, false otherwise - static bool startsWith(const std::string& str, const std::string& start); - - /// @brief Determines whether or not str ends with specified string - /// @param str String to check - /// @param end String to check against - /// @return Returns true if ends with specified string, false otherwise - static bool endsWith(const std::string& str, const std::string& end); - - /// @brief Replaces all instances of replaceWhat with 'replaceWith'. Original variable is changed for performance. - /// @param [in,out] str String to replace from - /// @param replaceWhat Character to replace - /// @param replaceWith Character to replace with - /// @return Modified version of str - static std::string& replaceAll(std::string& str, char replaceWhat, char replaceWith); - - /// @brief Replaces all instances of 'replaceWhat' with 'replaceWith'. (String version) Replaces in place - /// @param str String to replace from - /// @param replaceWhat Character to replace - /// @param replaceWith Character to replace with - /// @return Modified (original) str - static std::string& replaceAll(std::string& str, const std::string& replaceWhat, - const std::string& replaceWith); - - static void replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat, - const base::type::string_t& replaceWith); -#if defined(ELPP_UNICODE) - static void replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat, - const std::string& replaceWith); -#endif // defined(ELPP_UNICODE) - /// @brief Converts string to uppercase - /// @param str String to convert - /// @return Uppercase string - static std::string& toUpper(std::string& str); - - /// @brief Compares cstring equality - uses strcmp - static bool cStringEq(const char* s1, const char* s2); - - /// @brief Compares cstring equality (case-insensitive) - uses toupper(char) - /// Dont use strcasecmp because of CRT (VC++) - static bool cStringCaseEq(const char* s1, const char* s2); - - /// @brief Returns true if c exist in str - static bool contains(const char* str, char c); - - static char* convertAndAddToBuff(std::size_t n, int len, char* buf, const char* bufLim, bool zeroPadded = true); - static char* addToBuff(const char* str, char* buf, const char* bufLim); - static char* clearBuff(char buff[], std::size_t lim); - - /// @brief Converst wchar* to char* - /// NOTE: Need to free return value after use! - static char* wcharPtrToCharPtr(const wchar_t* line); -}; -/// @brief Operating System helper static class used internally. You should not use it. -class OS : base::StaticClass { - public: -#if ELPP_OS_WINDOWS - /// @brief Gets environment variables for Windows based OS. - /// We are not using <code>getenv(const char*)</code> because of CRT deprecation - /// @param varname Variable name to get environment variable value for - /// @return If variable exist the value of it otherwise nullptr - static const char* getWindowsEnvironmentVariable(const char* varname); -#endif // ELPP_OS_WINDOWS -#if ELPP_OS_ANDROID - /// @brief Reads android property value - static std::string getProperty(const char* prop); - - /// @brief Reads android device name - static std::string getDeviceName(void); -#endif // ELPP_OS_ANDROID - - /// @brief Runs command on terminal and returns the output. - /// - /// @detail This is applicable only on unix based systems, for all other OS, an empty string is returned. - /// @param command Bash command - /// @return Result of bash output or empty string if no result found. - static const std::string getBashOutput(const char* command); - - /// @brief Gets environment variable. This is cross-platform and CRT safe (for VC++) - /// @param variableName Environment variable name - /// @param defaultVal If no environment variable or value found the value to return by default - /// @param alternativeBashCommand If environment variable not found what would be alternative bash command - /// in order to look for value user is looking for. E.g, for 'user' alternative command will 'whoami' - static std::string getEnvironmentVariable(const char* variableName, const char* defaultVal, - const char* alternativeBashCommand = nullptr); - /// @brief Gets current username. - static std::string currentUser(void); - - /// @brief Gets current host name or computer name. - /// - /// @detail For android systems this is device name with its manufacturer and model seperated by hyphen - static std::string currentHost(void); - /// @brief Whether or not terminal supports colors - static bool termSupportsColor(void); -}; -/// @brief Contains utilities for cross-platform date/time. This class make use of el::base::utils::Str -class DateTime : base::StaticClass { - public: - /// @brief Cross platform gettimeofday for Windows and unix platform. This can be used to determine current microsecond. - /// - /// @detail For unix system it uses gettimeofday(timeval*, timezone*) and for Windows, a seperate implementation is provided - /// @param [in,out] tv Pointer that gets updated - static void gettimeofday(struct timeval* tv); - - /// @brief Gets current date and time with a subsecond part. - /// @param format User provided date/time format - /// @param ssPrec A pointer to base::SubsecondPrecision from configuration (non-null) - /// @returns string based date time in specified format. - static std::string getDateTime(const char* format, const base::SubsecondPrecision* ssPrec); - - /// @brief Converts timeval (struct from ctime) to string using specified format and subsecond precision - static std::string timevalToString(struct timeval tval, const char* format, - const el::base::SubsecondPrecision* ssPrec); - - /// @brief Formats time to get unit accordingly, units like second if > 1000 or minutes if > 60000 etc - static base::type::string_t formatTime(unsigned long long time, base::TimestampUnit timestampUnit); - - /// @brief Gets time difference in milli/micro second depending on timestampUnit - static unsigned long long getTimeDifference(const struct timeval& endTime, const struct timeval& startTime, - base::TimestampUnit timestampUnit); - - - private: - static struct ::tm* buildTimeInfo(struct timeval* currTime, struct ::tm* timeInfo); - static char* parseFormat(char* buf, std::size_t bufSz, const char* format, const struct tm* tInfo, - std::size_t msec, const base::SubsecondPrecision* ssPrec); -}; -/// @brief Command line arguments for application if specified using el::Helpers::setArgs(..) or START_EASYLOGGINGPP(..) -class CommandLineArgs { - public: - CommandLineArgs(void) { - setArgs(0, static_cast<char**>(nullptr)); - } - CommandLineArgs(int argc, const char** argv) { - setArgs(argc, argv); - } - CommandLineArgs(int argc, char** argv) { - setArgs(argc, argv); - } - virtual ~CommandLineArgs(void) {} - /// @brief Sets arguments and parses them - inline void setArgs(int argc, const char** argv) { - setArgs(argc, const_cast<char**>(argv)); - } - /// @brief Sets arguments and parses them - void setArgs(int argc, char** argv); - /// @brief Returns true if arguments contain paramKey with a value (seperated by '=') - bool hasParamWithValue(const char* paramKey) const; - /// @brief Returns value of arguments - /// @see hasParamWithValue(const char*) - const char* getParamValue(const char* paramKey) const; - /// @brief Return true if arguments has a param (not having a value) i,e without '=' - bool hasParam(const char* paramKey) const; - /// @brief Returns true if no params available. This exclude argv[0] - bool empty(void) const; - /// @brief Returns total number of arguments. This exclude argv[0] - std::size_t size(void) const; - friend base::type::ostream_t& operator<<(base::type::ostream_t& os, const CommandLineArgs& c); - - private: - int m_argc; - char** m_argv; - std::map<std::string, std::string> m_paramsWithValue; - std::vector<std::string> m_params; -}; -/// @brief Abstract registry (aka repository) that provides basic interface for pointer repository specified by T_Ptr type. -/// -/// @detail Most of the functions are virtual final methods but anything implementing this abstract class should implement -/// unregisterAll() and deepCopy(const AbstractRegistry<T_Ptr, Container>&) and write registerNew() method according to container -/// and few more methods; get() to find element, unregister() to unregister single entry. -/// Please note that this is thread-unsafe and should also implement thread-safety mechanisms in implementation. -template <typename T_Ptr, typename Container> -class AbstractRegistry : public base::threading::ThreadSafe { - public: - typedef typename Container::iterator iterator; - typedef typename Container::const_iterator const_iterator; - - /// @brief Default constructor - AbstractRegistry(void) {} - - /// @brief Move constructor that is useful for base classes - AbstractRegistry(AbstractRegistry&& sr) { - if (this == &sr) { - return; - } - unregisterAll(); - m_list = std::move(sr.m_list); - } - - bool operator==(const AbstractRegistry<T_Ptr, Container>& other) { - if (size() != other.size()) { - return false; - } - for (std::size_t i = 0; i < m_list.size(); ++i) { - if (m_list.at(i) != other.m_list.at(i)) { - return false; - } - } - return true; - } - - bool operator!=(const AbstractRegistry<T_Ptr, Container>& other) { - if (size() != other.size()) { - return true; - } - for (std::size_t i = 0; i < m_list.size(); ++i) { - if (m_list.at(i) != other.m_list.at(i)) { - return true; - } - } - return false; - } - - /// @brief Assignment move operator - AbstractRegistry& operator=(AbstractRegistry&& sr) { - if (this == &sr) { - return *this; - } - unregisterAll(); - m_list = std::move(sr.m_list); - return *this; - } - - virtual ~AbstractRegistry(void) { - } - - /// @return Iterator pointer from start of repository - virtual inline iterator begin(void) ELPP_FINAL { - return m_list.begin(); - } - - /// @return Iterator pointer from end of repository - virtual inline iterator end(void) ELPP_FINAL { - return m_list.end(); - } - - - /// @return Constant iterator pointer from start of repository - virtual inline const_iterator cbegin(void) const ELPP_FINAL { - return m_list.cbegin(); - } - - /// @return End of repository - virtual inline const_iterator cend(void) const ELPP_FINAL { - return m_list.cend(); - } - - /// @return Whether or not repository is empty - virtual inline bool empty(void) const ELPP_FINAL { - return m_list.empty(); - } - - /// @return Size of repository - virtual inline std::size_t size(void) const ELPP_FINAL { - return m_list.size(); - } - - /// @brief Returns underlying container by reference - virtual inline Container& list(void) ELPP_FINAL { - return m_list; - } - - /// @brief Returns underlying container by constant reference. - virtual inline const Container& list(void) const ELPP_FINAL { - return m_list; - } - - /// @brief Unregisters all the pointers from current repository. - virtual void unregisterAll(void) = 0; - - protected: - virtual void deepCopy(const AbstractRegistry<T_Ptr, Container>&) = 0; - void reinitDeepCopy(const AbstractRegistry<T_Ptr, Container>& sr) { - unregisterAll(); - deepCopy(sr); - } - - private: - Container m_list; -}; - -/// @brief A pointer registry mechanism to manage memory and provide search functionalities. (non-predicate version) -/// -/// @detail NOTE: This is thread-unsafe implementation (although it contains lock function, it does not use these functions) -/// of AbstractRegistry<T_Ptr, Container>. Any implementation of this class should be -/// explicitly (by using lock functions) -template <typename T_Ptr, typename T_Key = const char*> -class Registry : public AbstractRegistry<T_Ptr, std::map<T_Key, T_Ptr*>> { - public: - typedef typename Registry<T_Ptr, T_Key>::iterator iterator; - typedef typename Registry<T_Ptr, T_Key>::const_iterator const_iterator; - - Registry(void) {} - - /// @brief Copy constructor that is useful for base classes. Try to avoid this constructor, use move constructor. - Registry(const Registry& sr) : AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>() { - if (this == &sr) { - return; - } - this->reinitDeepCopy(sr); - } - - /// @brief Assignment operator that unregisters all the existing registeries and deeply copies each of repo element - /// @see unregisterAll() - /// @see deepCopy(const AbstractRegistry&) - Registry& operator=(const Registry& sr) { - if (this == &sr) { - return *this; - } - this->reinitDeepCopy(sr); - return *this; - } - - virtual ~Registry(void) { - unregisterAll(); - } - - protected: - virtual void unregisterAll(void) ELPP_FINAL { - if (!this->empty()) { - for (auto&& curr : this->list()) { - base::utils::safeDelete(curr.second); - } - this->list().clear(); - } - } - -/// @brief Registers new registry to repository. - virtual void registerNew(const T_Key& uniqKey, T_Ptr* ptr) ELPP_FINAL { - unregister(uniqKey); - this->list().insert(std::make_pair(uniqKey, ptr)); - } - -/// @brief Unregisters single entry mapped to specified unique key - void unregister(const T_Key& uniqKey) { - T_Ptr* existing = get(uniqKey); - if (existing != nullptr) { - base::utils::safeDelete(existing); - this->list().erase(uniqKey); - } - } - -/// @brief Gets pointer from repository. If none found, nullptr is returned. - T_Ptr* get(const T_Key& uniqKey) { - iterator it = this->list().find(uniqKey); - return it == this->list().end() - ? nullptr - : it->second; - } - - private: - virtual void deepCopy(const AbstractRegistry<T_Ptr, std::map<T_Key, T_Ptr*>>& sr) ELPP_FINAL { - for (const_iterator it = sr.cbegin(); it != sr.cend(); ++it) { - registerNew(it->first, new T_Ptr(*it->second)); - } - } -}; - -/// @brief A pointer registry mechanism to manage memory and provide search functionalities. (predicate version) -/// -/// @detail NOTE: This is thread-unsafe implementation of AbstractRegistry<T_Ptr, Container>. Any implementation of this class -/// should be made thread-safe explicitly -template <typename T_Ptr, typename Pred> -class RegistryWithPred : public AbstractRegistry<T_Ptr, std::vector<T_Ptr*>> { - public: - typedef typename RegistryWithPred<T_Ptr, Pred>::iterator iterator; - typedef typename RegistryWithPred<T_Ptr, Pred>::const_iterator const_iterator; - - RegistryWithPred(void) { - } - - virtual ~RegistryWithPred(void) { - unregisterAll(); - } - - /// @brief Copy constructor that is useful for base classes. Try to avoid this constructor, use move constructor. - RegistryWithPred(const RegistryWithPred& sr) : AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>() { - if (this == &sr) { - return; - } - this->reinitDeepCopy(sr); - } - - /// @brief Assignment operator that unregisters all the existing registeries and deeply copies each of repo element - /// @see unregisterAll() - /// @see deepCopy(const AbstractRegistry&) - RegistryWithPred& operator=(const RegistryWithPred& sr) { - if (this == &sr) { - return *this; - } - this->reinitDeepCopy(sr); - return *this; - } - - friend base::type::ostream_t& operator<<(base::type::ostream_t& os, const RegistryWithPred& sr) { - for (const_iterator it = sr.list().begin(); it != sr.list().end(); ++it) { - os << ELPP_LITERAL(" ") << **it << ELPP_LITERAL("\n"); - } - return os; - } - - protected: - virtual void unregisterAll(void) ELPP_FINAL { - if (!this->empty()) { - for (auto&& curr : this->list()) { - base::utils::safeDelete(curr); - } - this->list().clear(); - } - } - - virtual void unregister(T_Ptr*& ptr) ELPP_FINAL { - if (ptr) { - iterator iter = this->begin(); - for (; iter != this->end(); ++iter) { - if (ptr == *iter) { - break; - } - } - if (iter != this->end() && *iter != nullptr) { - this->list().erase(iter); - base::utils::safeDelete(*iter); - } - } - } - - virtual inline void registerNew(T_Ptr* ptr) ELPP_FINAL { - this->list().push_back(ptr); - } - -/// @brief Gets pointer from repository with speicifed arguments. Arguments are passed to predicate -/// in order to validate pointer. - template <typename T, typename T2> - T_Ptr* get(const T& arg1, const T2 arg2) { - iterator iter = std::find_if(this->list().begin(), this->list().end(), Pred(arg1, arg2)); - if (iter != this->list().end() && *iter != nullptr) { - return *iter; - } - return nullptr; - } - - private: - virtual void deepCopy(const AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>& sr) { - for (const_iterator it = sr.list().begin(); it != sr.list().end(); ++it) { - registerNew(new T_Ptr(**it)); - } - } -}; -class Utils { - public: - template <typename T, typename TPtr> - static bool installCallback(const std::string& id, std::map<std::string, TPtr>* mapT) { - if (mapT->find(id) == mapT->end()) { - mapT->insert(std::make_pair(id, TPtr(new T()))); - return true; - } - return false; - } - - template <typename T, typename TPtr> - static void uninstallCallback(const std::string& id, std::map<std::string, TPtr>* mapT) { - if (mapT->find(id) != mapT->end()) { - mapT->erase(id); - } - } - - template <typename T, typename TPtr> - static T* callback(const std::string& id, std::map<std::string, TPtr>* mapT) { - typename std::map<std::string, TPtr>::iterator iter = mapT->find(id); - if (iter != mapT->end()) { - return static_cast<T*>(iter->second.get()); - } - return nullptr; - } -}; -} // namespace utils -} // namespace base -/// @brief Base of Easylogging++ friendly class -/// -/// @detail After inheriting this class publicly, implement pure-virtual function `void log(std::ostream&) const` -class Loggable { - public: - virtual ~Loggable(void) {} - virtual void log(el::base::type::ostream_t&) const = 0; - private: - friend inline el::base::type::ostream_t& operator<<(el::base::type::ostream_t& os, const Loggable& loggable) { - loggable.log(os); - return os; - } -}; -namespace base { -/// @brief Represents log format containing flags and date format. This is used internally to start initial log -class LogFormat : public Loggable { - public: - LogFormat(void); - LogFormat(Level level, const base::type::string_t& format); - LogFormat(const LogFormat& logFormat); - LogFormat(LogFormat&& logFormat); - LogFormat& operator=(const LogFormat& logFormat); - virtual ~LogFormat(void) {} - bool operator==(const LogFormat& other); - - /// @brief Updates format to be used while logging. - /// @param userFormat User provided format - void parseFromFormat(const base::type::string_t& userFormat); - - inline Level level(void) const { - return m_level; - } - - inline const base::type::string_t& userFormat(void) const { - return m_userFormat; - } - - inline const base::type::string_t& format(void) const { - return m_format; - } - - inline const std::string& dateTimeFormat(void) const { - return m_dateTimeFormat; - } - - inline base::type::EnumType flags(void) const { - return m_flags; - } - - inline bool hasFlag(base::FormatFlags flag) const { - return base::utils::hasFlag(flag, m_flags); - } - - virtual void log(el::base::type::ostream_t& os) const { - os << m_format; - } - - protected: - /// @brief Updates date time format if available in currFormat. - /// @param index Index where %datetime, %date or %time was found - /// @param [in,out] currFormat current format that is being used to format - virtual void updateDateFormat(std::size_t index, base::type::string_t& currFormat) ELPP_FINAL; - - /// @brief Updates %level from format. This is so that we dont have to do it at log-writing-time. It uses m_format and m_level - virtual void updateFormatSpec(void) ELPP_FINAL; - - inline void addFlag(base::FormatFlags flag) { - base::utils::addFlag(flag, &m_flags); - } - - private: - Level m_level; - base::type::string_t m_userFormat; - base::type::string_t m_format; - std::string m_dateTimeFormat; - base::type::EnumType m_flags; - std::string m_currentUser; - std::string m_currentHost; - friend class el::Logger; // To resolve loggerId format specifier easily -}; -} // namespace base -/// @brief Resolving function for format specifier -typedef std::function<std::string(const LogMessage*)> FormatSpecifierValueResolver; -/// @brief User-provided custom format specifier -/// @see el::Helpers::installCustomFormatSpecifier -/// @see FormatSpecifierValueResolver -class CustomFormatSpecifier { - public: - CustomFormatSpecifier(const char* formatSpecifier, const FormatSpecifierValueResolver& resolver) : - m_formatSpecifier(formatSpecifier), m_resolver(resolver) {} - inline const char* formatSpecifier(void) const { - return m_formatSpecifier; - } - inline const FormatSpecifierValueResolver& resolver(void) const { - return m_resolver; - } - inline bool operator==(const char* formatSpecifier) { - return strcmp(m_formatSpecifier, formatSpecifier) == 0; - } - - private: - const char* m_formatSpecifier; - FormatSpecifierValueResolver m_resolver; -}; -/// @brief Represents single configuration that has representing level, configuration type and a string based value. -/// -/// @detail String based value means any value either its boolean, integer or string itself, it will be embedded inside quotes -/// and will be parsed later. -/// -/// Consider some examples below: -/// * el::Configuration confEnabledInfo(el::Level::Info, el::ConfigurationType::Enabled, "true"); -/// * el::Configuration confMaxLogFileSizeInfo(el::Level::Info, el::ConfigurationType::MaxLogFileSize, "2048"); -/// * el::Configuration confFilenameInfo(el::Level::Info, el::ConfigurationType::Filename, "/var/log/my.log"); -class Configuration : public Loggable { - public: - Configuration(const Configuration& c); - Configuration& operator=(const Configuration& c); - - virtual ~Configuration(void) { - } - - /// @brief Full constructor used to sets value of configuration - Configuration(Level level, ConfigurationType configurationType, const std::string& value); - - /// @brief Gets level of current configuration - inline Level level(void) const { - return m_level; - } - - /// @brief Gets configuration type of current configuration - inline ConfigurationType configurationType(void) const { - return m_configurationType; - } - - /// @brief Gets string based configuration value - inline const std::string& value(void) const { - return m_value; - } - - /// @brief Set string based configuration value - /// @param value Value to set. Values have to be std::string; For boolean values use "true", "false", for any integral values - /// use them in quotes. They will be parsed when configuring - inline void setValue(const std::string& value) { - m_value = value; - } - - virtual void log(el::base::type::ostream_t& os) const; - - /// @brief Used to find configuration from configuration (pointers) repository. Avoid using it. - class Predicate { - public: - Predicate(Level level, ConfigurationType configurationType); - - bool operator()(const Configuration* conf) const; - - private: - Level m_level; - ConfigurationType m_configurationType; - }; - - private: - Level m_level; - ConfigurationType m_configurationType; - std::string m_value; -}; - -/// @brief Thread-safe Configuration repository -/// -/// @detail This repository represents configurations for all the levels and configuration type mapped to a value. -class Configurations : public base::utils::RegistryWithPred<Configuration, Configuration::Predicate> { - public: - /// @brief Default constructor with empty repository - Configurations(void); - - /// @brief Constructor used to set configurations using configuration file. - /// @param configurationFile Full path to configuration file - /// @param useDefaultsForRemaining Lets you set the remaining configurations to default. - /// @param base If provided, this configuration will be based off existing repository that this argument is pointing to. - /// @see parseFromFile(const std::string&, Configurations* base) - /// @see setRemainingToDefault() - Configurations(const std::string& configurationFile, bool useDefaultsForRemaining = true, - Configurations* base = nullptr); - - virtual ~Configurations(void) { - } - - /// @brief Parses configuration from file. - /// @param configurationFile Full path to configuration file - /// @param base Configurations to base new configuration repository off. This value is used when you want to use - /// existing Configurations to base all the values and then set rest of configuration via configuration file. - /// @return True if successfully parsed, false otherwise. You may define 'ELPP_DEBUG_ASSERT_FAILURE' to make sure you - /// do not proceed without successful parse. - bool parseFromFile(const std::string& configurationFile, Configurations* base = nullptr); - - /// @brief Parse configurations from configuration string. - /// - /// @detail This configuration string has same syntax as configuration file contents. Make sure all the necessary - /// new line characters are provided. - /// @param base Configurations to base new configuration repository off. This value is used when you want to use - /// existing Configurations to base all the values and then set rest of configuration via configuration text. - /// @return True if successfully parsed, false otherwise. You may define 'ELPP_DEBUG_ASSERT_FAILURE' to make sure you - /// do not proceed without successful parse. - bool parseFromText(const std::string& configurationsString, Configurations* base = nullptr); - - /// @brief Sets configuration based-off an existing configurations. - /// @param base Pointer to existing configurations. - void setFromBase(Configurations* base); - - /// @brief Determines whether or not specified configuration type exists in the repository. - /// - /// @detail Returns as soon as first level is found. - /// @param configurationType Type of configuration to check existence for. - bool hasConfiguration(ConfigurationType configurationType); - - /// @brief Determines whether or not specified configuration type exists for specified level - /// @param level Level to check - /// @param configurationType Type of configuration to check existence for. - bool hasConfiguration(Level level, ConfigurationType configurationType); - - /// @brief Sets value of configuration for specified level. - /// - /// @detail Any existing configuration for specified level will be replaced. Also note that configuration types - /// ConfigurationType::SubsecondPrecision and ConfigurationType::PerformanceTracking will be ignored if not set for - /// Level::Global because these configurations are not dependant on level. - /// @param level Level to set configuration for (el::Level). - /// @param configurationType Type of configuration (el::ConfigurationType) - /// @param value A string based value. Regardless of what the data type of configuration is, it will always be string - /// from users' point of view. This is then parsed later to be used internally. - /// @see Configuration::setValue(const std::string& value) - /// @see el::Level - /// @see el::ConfigurationType - void set(Level level, ConfigurationType configurationType, const std::string& value); - - /// @brief Sets single configuration based on other single configuration. - /// @see set(Level level, ConfigurationType configurationType, const std::string& value) - void set(Configuration* conf); - - inline Configuration* get(Level level, ConfigurationType configurationType) { - base::threading::ScopedLock scopedLock(lock()); - return RegistryWithPred<Configuration, Configuration::Predicate>::get(level, configurationType); - } - - /// @brief Sets configuration for all levels. - /// @param configurationType Type of configuration - /// @param value String based value - /// @see Configurations::set(Level level, ConfigurationType configurationType, const std::string& value) - inline void setGlobally(ConfigurationType configurationType, const std::string& value) { - setGlobally(configurationType, value, false); - } - - /// @brief Clears repository so that all the configurations are unset - inline void clear(void) { - base::threading::ScopedLock scopedLock(lock()); - unregisterAll(); - } - - /// @brief Gets configuration file used in parsing this configurations. - /// - /// @detail If this repository was set manually or by text this returns empty string. - inline const std::string& configurationFile(void) const { - return m_configurationFile; - } - - /// @brief Sets configurations to "factory based" configurations. - void setToDefault(void); - - /// @brief Lets you set the remaining configurations to default. - /// - /// @detail By remaining, it means that the level/type a configuration does not exist for. - /// This function is useful when you want to minimize chances of failures, e.g, if you have a configuration file that sets - /// configuration for all the configurations except for Enabled or not, we use this so that ENABLED is set to default i.e, - /// true. If you dont do this explicitly (either by calling this function or by using second param in Constructor - /// and try to access a value, an error is thrown - void setRemainingToDefault(void); - - /// @brief Parser used internally to parse configurations from file or text. - /// - /// @detail This class makes use of base::utils::Str. - /// You should not need this unless you are working on some tool for Easylogging++ - class Parser : base::StaticClass { - public: - /// @brief Parses configuration from file. - /// @param configurationFile Full path to configuration file - /// @param sender Sender configurations pointer. Usually 'this' is used from calling class - /// @param base Configurations to base new configuration repository off. This value is used when you want to use - /// existing Configurations to base all the values and then set rest of configuration via configuration file. - /// @return True if successfully parsed, false otherwise. You may define '_STOP_ON_FIRSTELPP_ASSERTION' to make sure you - /// do not proceed without successful parse. - static bool parseFromFile(const std::string& configurationFile, Configurations* sender, - Configurations* base = nullptr); - - /// @brief Parse configurations from configuration string. - /// - /// @detail This configuration string has same syntax as configuration file contents. Make sure all the necessary - /// new line characters are provided. You may define '_STOP_ON_FIRSTELPP_ASSERTION' to make sure you - /// do not proceed without successful parse (This is recommended) - /// @param configurationsString the configuration in plain text format - /// @param sender Sender configurations pointer. Usually 'this' is used from calling class - /// @param base Configurations to base new configuration repository off. This value is used when you want to use - /// existing Configurations to base all the values and then set rest of configuration via configuration text. - /// @return True if successfully parsed, false otherwise. - static bool parseFromText(const std::string& configurationsString, Configurations* sender, - Configurations* base = nullptr); - - private: - friend class el::Loggers; - static void ignoreComments(std::string* line); - static bool isLevel(const std::string& line); - static bool isComment(const std::string& line); - static inline bool isConfig(const std::string& line); - static bool parseLine(std::string* line, std::string* currConfigStr, std::string* currLevelStr, Level* currLevel, - Configurations* conf); - }; - - private: - std::string m_configurationFile; - bool m_isFromFile; - friend class el::Loggers; - - /// @brief Unsafely sets configuration if does not already exist - void unsafeSetIfNotExist(Level level, ConfigurationType configurationType, const std::string& value); - - /// @brief Thread unsafe set - void unsafeSet(Level level, ConfigurationType configurationType, const std::string& value); - - /// @brief Sets configurations for all levels including Level::Global if includeGlobalLevel is true - /// @see Configurations::setGlobally(ConfigurationType configurationType, const std::string& value) - void setGlobally(ConfigurationType configurationType, const std::string& value, bool includeGlobalLevel); - - /// @brief Sets configurations (Unsafely) for all levels including Level::Global if includeGlobalLevel is true - /// @see Configurations::setGlobally(ConfigurationType configurationType, const std::string& value) - void unsafeSetGlobally(ConfigurationType configurationType, const std::string& value, bool includeGlobalLevel); -}; - -namespace base { -typedef std::shared_ptr<base::type::fstream_t> FileStreamPtr; -typedef std::map<std::string, FileStreamPtr> LogStreamsReferenceMap; -/// @brief Configurations with data types. -/// -/// @detail el::Configurations have string based values. This is whats used internally in order to read correct configurations. -/// This is to perform faster while writing logs using correct configurations. -/// -/// This is thread safe and final class containing non-virtual destructor (means nothing should inherit this class) -class TypedConfigurations : public base::threading::ThreadSafe { - public: - /// @brief Constructor to initialize (construct) the object off el::Configurations - /// @param configurations Configurations pointer/reference to base this typed configurations off. - /// @param logStreamsReference Use ELPP->registeredLoggers()->logStreamsReference() - TypedConfigurations(Configurations* configurations, base::LogStreamsReferenceMap* logStreamsReference); - - TypedConfigurations(const TypedConfigurations& other); - - virtual ~TypedConfigurations(void) { - } - - const Configurations* configurations(void) const { - return m_configurations; - } - - bool enabled(Level level); - bool toFile(Level level); - const std::string& filename(Level level); - bool toStandardOutput(Level level); - const base::LogFormat& logFormat(Level level); - const base::SubsecondPrecision& subsecondPrecision(Level level = Level::Global); - const base::MillisecondsWidth& millisecondsWidth(Level level = Level::Global); - bool performanceTracking(Level level = Level::Global); - base::type::fstream_t* fileStream(Level level); - std::size_t maxLogFileSize(Level level); - std::size_t logFlushThreshold(Level level); - - private: - Configurations* m_configurations; - std::map<Level, bool> m_enabledMap; - std::map<Level, bool> m_toFileMap; - std::map<Level, std::string> m_filenameMap; - std::map<Level, bool> m_toStandardOutputMap; - std::map<Level, base::LogFormat> m_logFormatMap; - std::map<Level, base::SubsecondPrecision> m_subsecondPrecisionMap; - std::map<Level, bool> m_performanceTrackingMap; - std::map<Level, base::FileStreamPtr> m_fileStreamMap; - std::map<Level, std::size_t> m_maxLogFileSizeMap; - std::map<Level, std::size_t> m_logFlushThresholdMap; - base::LogStreamsReferenceMap* m_logStreamsReference; - - friend class el::Helpers; - friend class el::base::MessageBuilder; - friend class el::base::Writer; - friend class el::base::DefaultLogDispatchCallback; - friend class el::base::LogDispatcher; - - template <typename Conf_T> - inline Conf_T getConfigByVal(Level level, const std::map<Level, Conf_T>* confMap, const char* confName) { - base::threading::ScopedLock scopedLock(lock()); - return unsafeGetConfigByVal(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope - } - - template <typename Conf_T> - inline Conf_T& getConfigByRef(Level level, std::map<Level, Conf_T>* confMap, const char* confName) { - base::threading::ScopedLock scopedLock(lock()); - return unsafeGetConfigByRef(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope - } - - template <typename Conf_T> - Conf_T unsafeGetConfigByVal(Level level, const std::map<Level, Conf_T>* confMap, const char* confName) { - ELPP_UNUSED(confName); - typename std::map<Level, Conf_T>::const_iterator it = confMap->find(level); - if (it == confMap->end()) { - try { - return confMap->at(Level::Global); - } catch (...) { - ELPP_INTERNAL_ERROR("Unable to get configuration [" << confName << "] for level [" - << LevelHelper::convertToString(level) << "]" - << std::endl << "Please ensure you have properly configured logger.", false); - return Conf_T(); - } - } - return it->second; - } - - template <typename Conf_T> - Conf_T& unsafeGetConfigByRef(Level level, std::map<Level, Conf_T>* confMap, const char* confName) { - ELPP_UNUSED(confName); - typename std::map<Level, Conf_T>::iterator it = confMap->find(level); - if (it == confMap->end()) { - try { - return confMap->at(Level::Global); - } catch (...) { - ELPP_INTERNAL_ERROR("Unable to get configuration [" << confName << "] for level [" - << LevelHelper::convertToString(level) << "]" - << std::endl << "Please ensure you have properly configured logger.", false); - } - } - return it->second; - } - - template <typename Conf_T> - void setValue(Level level, const Conf_T& value, std::map<Level, Conf_T>* confMap, bool includeGlobalLevel = true) { - // If map is empty and we are allowed to add into generic level (Level::Global), do it! - if (confMap->empty() && includeGlobalLevel) { - confMap->insert(std::make_pair(Level::Global, value)); - return; - } - // If same value exist in generic level already, dont add it to explicit level - typename std::map<Level, Conf_T>::iterator it = confMap->find(Level::Global); - if (it != confMap->end() && it->second == value) { - return; - } - // Now make sure we dont double up values if we really need to add it to explicit level - it = confMap->find(level); - if (it == confMap->end()) { - // Value not found for level, add new - confMap->insert(std::make_pair(level, value)); - } else { - // Value found, just update value - confMap->at(level) = value; - } - } - - void build(Configurations* configurations); - unsigned long getULong(std::string confVal); - std::string resolveFilename(const std::string& filename); - void insertFile(Level level, const std::string& fullFilename); - bool unsafeValidateFileRolling(Level level, const PreRollOutCallback& preRollOutCallback); - - inline bool validateFileRolling(Level level, const PreRollOutCallback& preRollOutCallback) { - base::threading::ScopedLock scopedLock(lock()); - return unsafeValidateFileRolling(level, preRollOutCallback); - } -}; -/// @brief Class that keeps record of current line hit for occasional logging -class HitCounter { - public: - HitCounter(void) : - m_filename(""), - m_lineNumber(0), - m_hitCounts(0) { - } - - HitCounter(const char* filename, base::type::LineNumber lineNumber) : - m_filename(filename), - m_lineNumber(lineNumber), - m_hitCounts(0) { - } - - HitCounter(const HitCounter& hitCounter) : - m_filename(hitCounter.m_filename), - m_lineNumber(hitCounter.m_lineNumber), - m_hitCounts(hitCounter.m_hitCounts) { - } - - HitCounter& operator=(const HitCounter& hitCounter) { - if (&hitCounter != this) { - m_filename = hitCounter.m_filename; - m_lineNumber = hitCounter.m_lineNumber; - m_hitCounts = hitCounter.m_hitCounts; - } - return *this; - } - - virtual ~HitCounter(void) { - } - - /// @brief Resets location of current hit counter - inline void resetLocation(const char* filename, base::type::LineNumber lineNumber) { - m_filename = filename; - m_lineNumber = lineNumber; - } - - /// @brief Validates hit counts and resets it if necessary - inline void validateHitCounts(std::size_t n) { - if (m_hitCounts >= base::consts::kMaxLogPerCounter) { - m_hitCounts = (n >= 1 ? base::consts::kMaxLogPerCounter % n : 0); - } - ++m_hitCounts; - } - - inline const char* filename(void) const { - return m_filename; - } - - inline base::type::LineNumber lineNumber(void) const { - return m_lineNumber; - } - - inline std::size_t hitCounts(void) const { - return m_hitCounts; - } - - inline void increment(void) { - ++m_hitCounts; - } - - class Predicate { - public: - Predicate(const char* filename, base::type::LineNumber lineNumber) - : m_filename(filename), - m_lineNumber(lineNumber) { - } - inline bool operator()(const HitCounter* counter) { - return ((counter != nullptr) && - (strcmp(counter->m_filename, m_filename) == 0) && - (counter->m_lineNumber == m_lineNumber)); - } - - private: - const char* m_filename; - base::type::LineNumber m_lineNumber; - }; - - private: - const char* m_filename; - base::type::LineNumber m_lineNumber; - std::size_t m_hitCounts; -}; -/// @brief Repository for hit counters used across the application -class RegisteredHitCounters : public base::utils::RegistryWithPred<base::HitCounter, base::HitCounter::Predicate> { - public: - /// @brief Validates counter for every N, i.e, registers new if does not exist otherwise updates original one - /// @return True if validation resulted in triggering hit. Meaning logs should be written everytime true is returned - bool validateEveryN(const char* filename, base::type::LineNumber lineNumber, std::size_t n); - - /// @brief Validates counter for hits >= N, i.e, registers new if does not exist otherwise updates original one - /// @return True if validation resulted in triggering hit. Meaning logs should be written everytime true is returned - bool validateAfterN(const char* filename, base::type::LineNumber lineNumber, std::size_t n); - - /// @brief Validates counter for hits are <= n, i.e, registers new if does not exist otherwise updates original one - /// @return True if validation resulted in triggering hit. Meaning logs should be written everytime true is returned - bool validateNTimes(const char* filename, base::type::LineNumber lineNumber, std::size_t n); - - /// @brief Gets hit counter registered at specified position - inline const base::HitCounter* getCounter(const char* filename, base::type::LineNumber lineNumber) { - base::threading::ScopedLock scopedLock(lock()); - return get(filename, lineNumber); - } -}; -/// @brief Action to be taken for dispatching -enum class DispatchAction : base::type::EnumType { - None = 1, NormalLog = 2, SysLog = 4 -}; -} // namespace base -template <typename T> -class Callback : protected base::threading::ThreadSafe { - public: - Callback(void) : m_enabled(true) {} - inline bool enabled(void) const { - return m_enabled; - } - inline void setEnabled(bool enabled) { - base::threading::ScopedLock scopedLock(lock()); - m_enabled = enabled; - } - protected: - virtual void handle(const T* handlePtr) = 0; - private: - bool m_enabled; -}; -class LogDispatchData { - public: - LogDispatchData() : m_logMessage(nullptr), m_dispatchAction(base::DispatchAction::None) {} - inline const LogMessage* logMessage(void) const { - return m_logMessage; - } - inline base::DispatchAction dispatchAction(void) const { - return m_dispatchAction; - } - private: - LogMessage* m_logMessage; - base::DispatchAction m_dispatchAction; - friend class base::LogDispatcher; - - inline void setLogMessage(LogMessage* logMessage) { - m_logMessage = logMessage; - } - inline void setDispatchAction(base::DispatchAction dispatchAction) { - m_dispatchAction = dispatchAction; - } -}; -class LogDispatchCallback : public Callback<LogDispatchData> { - private: - friend class base::LogDispatcher; -}; -class PerformanceTrackingCallback : public Callback<PerformanceTrackingData> { - private: - friend class base::PerformanceTracker; -}; -class LoggerRegistrationCallback : public Callback<Logger> { - private: - friend class base::RegisteredLoggers; -}; -class LogBuilder : base::NoCopy { - public: - LogBuilder() : m_termSupportsColor(base::utils::OS::termSupportsColor()) {} - virtual ~LogBuilder(void) { - ELPP_INTERNAL_INFO(3, "Destroying log builder...") - } - virtual base::type::string_t build(const LogMessage* logMessage, bool appendNewLine) const = 0; - void convertToColoredOutput(base::type::string_t* logLine, Level level); - private: - bool m_termSupportsColor; - friend class el::base::DefaultLogDispatchCallback; -}; -typedef std::shared_ptr<LogBuilder> LogBuilderPtr; -/// @brief Represents a logger holding ID and configurations we need to write logs -/// -/// @detail This class does not write logs itself instead its used by writer to read configuations from. -class Logger : public base::threading::ThreadSafe, public Loggable { - public: - Logger(const std::string& id, base::LogStreamsReferenceMap* logStreamsReference); - Logger(const std::string& id, const Configurations& configurations, base::LogStreamsReferenceMap* logStreamsReference); - Logger(const Logger& logger); - Logger& operator=(const Logger& logger); - - virtual ~Logger(void) { - base::utils::safeDelete(m_typedConfigurations); - } - - virtual inline void log(el::base::type::ostream_t& os) const { - os << m_id.c_str(); - } - - /// @brief Configures the logger using specified configurations. - void configure(const Configurations& configurations); - - /// @brief Reconfigures logger using existing configurations - void reconfigure(void); - - inline const std::string& id(void) const { - return m_id; - } - - inline const std::string& parentApplicationName(void) const { - return m_parentApplicationName; - } - - inline void setParentApplicationName(const std::string& parentApplicationName) { - m_parentApplicationName = parentApplicationName; - } - - inline Configurations* configurations(void) { - return &m_configurations; - } - - inline base::TypedConfigurations* typedConfigurations(void) { - return m_typedConfigurations; - } - - static bool isValidId(const std::string& id); - - /// @brief Flushes logger to sync all log files for all levels - void flush(void); - - void flush(Level level, base::type::fstream_t* fs); - - inline bool isFlushNeeded(Level level) { - return ++m_unflushedCount.find(level)->second >= m_typedConfigurations->logFlushThreshold(level); - } - - inline LogBuilder* logBuilder(void) const { - return m_logBuilder.get(); - } - - inline void setLogBuilder(const LogBuilderPtr& logBuilder) { - m_logBuilder = logBuilder; - } - - inline bool enabled(Level level) const { - return m_typedConfigurations->enabled(level); - } - -#if ELPP_VARIADIC_TEMPLATES_SUPPORTED -# define LOGGER_LEVEL_WRITERS_SIGNATURES(FUNCTION_NAME)\ -template <typename T, typename... Args>\ -inline void FUNCTION_NAME(const char*, const T&, const Args&...);\ -template <typename T>\ -inline void FUNCTION_NAME(const T&); - - template <typename T, typename... Args> - inline void verbose(int, const char*, const T&, const Args&...); - - template <typename T> - inline void verbose(int, const T&); - - LOGGER_LEVEL_WRITERS_SIGNATURES(info) - LOGGER_LEVEL_WRITERS_SIGNATURES(debug) - LOGGER_LEVEL_WRITERS_SIGNATURES(warn) - LOGGER_LEVEL_WRITERS_SIGNATURES(error) - LOGGER_LEVEL_WRITERS_SIGNATURES(fatal) - LOGGER_LEVEL_WRITERS_SIGNATURES(trace) -# undef LOGGER_LEVEL_WRITERS_SIGNATURES -#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED - private: - std::string m_id; - base::TypedConfigurations* m_typedConfigurations; - base::type::stringstream_t m_stream; - std::string m_parentApplicationName; - bool m_isConfigured; - Configurations m_configurations; - std::map<Level, unsigned int> m_unflushedCount; - base::LogStreamsReferenceMap* m_logStreamsReference; - LogBuilderPtr m_logBuilder; - - friend class el::LogMessage; - friend class el::Loggers; - friend class el::Helpers; - friend class el::base::RegisteredLoggers; - friend class el::base::DefaultLogDispatchCallback; - friend class el::base::MessageBuilder; - friend class el::base::Writer; - friend class el::base::PErrorWriter; - friend class el::base::Storage; - friend class el::base::PerformanceTracker; - friend class el::base::LogDispatcher; - - Logger(void); - -#if ELPP_VARIADIC_TEMPLATES_SUPPORTED - template <typename T, typename... Args> - void log_(Level, int, const char*, const T&, const Args&...); - - template <typename T> - inline void log_(Level, int, const T&); - - template <typename T, typename... Args> - void log(Level, const char*, const T&, const Args&...); - - template <typename T> - inline void log(Level, const T&); -#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED - - void initUnflushedCount(void); - - inline base::type::stringstream_t& stream(void) { - return m_stream; - } - - void resolveLoggerFormatSpec(void) const; -}; -namespace base { -/// @brief Loggers repository -class RegisteredLoggers : public base::utils::Registry<Logger, std::string> { - public: - explicit RegisteredLoggers(const LogBuilderPtr& defaultLogBuilder); - - virtual ~RegisteredLoggers(void) { - unsafeFlushAll(); - } - - inline void setDefaultConfigurations(const Configurations& configurations) { - base::threading::ScopedLock scopedLock(lock()); - m_defaultConfigurations.setFromBase(const_cast<Configurations*>(&configurations)); - } - - inline Configurations* defaultConfigurations(void) { - return &m_defaultConfigurations; - } - - Logger* get(const std::string& id, bool forceCreation = true); - - template <typename T> - inline bool installLoggerRegistrationCallback(const std::string& id) { - return base::utils::Utils::installCallback<T, base::type::LoggerRegistrationCallbackPtr>(id, - &m_loggerRegistrationCallbacks); - } - - template <typename T> - inline void uninstallLoggerRegistrationCallback(const std::string& id) { - base::utils::Utils::uninstallCallback<T, base::type::LoggerRegistrationCallbackPtr>(id, &m_loggerRegistrationCallbacks); - } - - template <typename T> - inline T* loggerRegistrationCallback(const std::string& id) { - return base::utils::Utils::callback<T, base::type::LoggerRegistrationCallbackPtr>(id, &m_loggerRegistrationCallbacks); - } - - bool remove(const std::string& id); - - inline bool has(const std::string& id) { - return get(id, false) != nullptr; - } - - inline void unregister(Logger*& logger) { - base::threading::ScopedLock scopedLock(lock()); - base::utils::Registry<Logger, std::string>::unregister(logger->id()); - } - - inline base::LogStreamsReferenceMap* logStreamsReference(void) { - return &m_logStreamsReference; - } - - inline void flushAll(void) { - base::threading::ScopedLock scopedLock(lock()); - unsafeFlushAll(); - } - - inline void setDefaultLogBuilder(LogBuilderPtr& logBuilderPtr) { - base::threading::ScopedLock scopedLock(lock()); - m_defaultLogBuilder = logBuilderPtr; - } - - private: - LogBuilderPtr m_defaultLogBuilder; - Configurations m_defaultConfigurations; - base::LogStreamsReferenceMap m_logStreamsReference; - std::map<std::string, base::type::LoggerRegistrationCallbackPtr> m_loggerRegistrationCallbacks; - friend class el::base::Storage; - - void unsafeFlushAll(void); -}; -/// @brief Represents registries for verbose logging -class VRegistry : base::NoCopy, public base::threading::ThreadSafe { - public: - explicit VRegistry(base::type::VerboseLevel level, base::type::EnumType* pFlags); - - /// @brief Sets verbose level. Accepted range is 0-9 - void setLevel(base::type::VerboseLevel level); - - inline base::type::VerboseLevel level(void) const { - return m_level; - } - - inline void clearModules(void) { - base::threading::ScopedLock scopedLock(lock()); - m_modules.clear(); - } - - void setModules(const char* modules); - - bool allowed(base::type::VerboseLevel vlevel, const char* file); - - inline const std::map<std::string, base::type::VerboseLevel>& modules(void) const { - return m_modules; - } - - void setFromArgs(const base::utils::CommandLineArgs* commandLineArgs); - - /// @brief Whether or not vModules enabled - inline bool vModulesEnabled(void) { - return !base::utils::hasFlag(LoggingFlag::DisableVModules, *m_pFlags); - } - - private: - base::type::VerboseLevel m_level; - base::type::EnumType* m_pFlags; - std::map<std::string, base::type::VerboseLevel> m_modules; -}; -} // namespace base -class LogMessage { - public: - LogMessage(Level level, const std::string& file, base::type::LineNumber line, const std::string& func, - base::type::VerboseLevel verboseLevel, Logger* logger) : - m_level(level), m_file(file), m_line(line), m_func(func), - m_verboseLevel(verboseLevel), m_logger(logger), m_message(logger->stream().str()) { - } - inline Level level(void) const { - return m_level; - } - inline const std::string& file(void) const { - return m_file; - } - inline base::type::LineNumber line(void) const { - return m_line; - } - inline const std::string& func(void) const { - return m_func; - } - inline base::type::VerboseLevel verboseLevel(void) const { - return m_verboseLevel; - } - inline Logger* logger(void) const { - return m_logger; - } - inline const base::type::string_t& message(void) const { - return m_message; - } - private: - Level m_level; - std::string m_file; - base::type::LineNumber m_line; - std::string m_func; - base::type::VerboseLevel m_verboseLevel; - Logger* m_logger; - base::type::string_t m_message; -}; -namespace base { -#if ELPP_ASYNC_LOGGING -class AsyncLogItem { - public: - explicit AsyncLogItem(const LogMessage& logMessage, const LogDispatchData& data, const base::type::string_t& logLine) - : m_logMessage(logMessage), m_dispatchData(data), m_logLine(logLine) {} - virtual ~AsyncLogItem() {} - inline LogMessage* logMessage(void) { - return &m_logMessage; - } - inline LogDispatchData* data(void) { - return &m_dispatchData; - } - inline base::type::string_t logLine(void) { - return m_logLine; - } - private: - LogMessage m_logMessage; - LogDispatchData m_dispatchData; - base::type::string_t m_logLine; -}; -class AsyncLogQueue : public base::threading::ThreadSafe { - public: - virtual ~AsyncLogQueue() { - ELPP_INTERNAL_INFO(6, "~AsyncLogQueue"); - } - - inline AsyncLogItem next(void) { - base::threading::ScopedLock scopedLock(lock()); - AsyncLogItem result = m_queue.front(); - m_queue.pop(); - return result; - } - - inline void push(const AsyncLogItem& item) { - base::threading::ScopedLock scopedLock(lock()); - m_queue.push(item); - } - inline void pop(void) { - base::threading::ScopedLock scopedLock(lock()); - m_queue.pop(); - } - inline AsyncLogItem front(void) { - base::threading::ScopedLock scopedLock(lock()); - return m_queue.front(); - } - inline bool empty(void) { - base::threading::ScopedLock scopedLock(lock()); - return m_queue.empty(); - } - private: - std::queue<AsyncLogItem> m_queue; -}; -class IWorker { - public: - virtual ~IWorker() {} - virtual void start() = 0; -}; -#endif // ELPP_ASYNC_LOGGING -/// @brief Easylogging++ management storage -class Storage : base::NoCopy, public base::threading::ThreadSafe { - public: -#if ELPP_ASYNC_LOGGING - Storage(const LogBuilderPtr& defaultLogBuilder, base::IWorker* asyncDispatchWorker); -#else - explicit Storage(const LogBuilderPtr& defaultLogBuilder); -#endif // ELPP_ASYNC_LOGGING - - virtual ~Storage(void); - - inline bool validateEveryNCounter(const char* filename, base::type::LineNumber lineNumber, std::size_t occasion) { - return hitCounters()->validateEveryN(filename, lineNumber, occasion); - } - - inline bool validateAfterNCounter(const char* filename, base::type::LineNumber lineNumber, std::size_t n) { - return hitCounters()->validateAfterN(filename, lineNumber, n); - } - - inline bool validateNTimesCounter(const char* filename, base::type::LineNumber lineNumber, std::size_t n) { - return hitCounters()->validateNTimes(filename, lineNumber, n); - } - - inline base::RegisteredHitCounters* hitCounters(void) const { - return m_registeredHitCounters; - } - - inline base::RegisteredLoggers* registeredLoggers(void) const { - return m_registeredLoggers; - } - - inline base::VRegistry* vRegistry(void) const { - return m_vRegistry; - } - -#if ELPP_ASYNC_LOGGING - inline base::AsyncLogQueue* asyncLogQueue(void) const { - return m_asyncLogQueue; - } -#endif // ELPP_ASYNC_LOGGING - - inline const base::utils::CommandLineArgs* commandLineArgs(void) const { - return &m_commandLineArgs; - } - - inline void addFlag(LoggingFlag flag) { - base::utils::addFlag(flag, &m_flags); - } - - inline void removeFlag(LoggingFlag flag) { - base::utils::removeFlag(flag, &m_flags); - } - - inline bool hasFlag(LoggingFlag flag) const { - return base::utils::hasFlag(flag, m_flags); - } - - inline base::type::EnumType flags(void) const { - return m_flags; - } - - inline void setFlags(base::type::EnumType flags) { - m_flags = flags; - } - - inline void setPreRollOutCallback(const PreRollOutCallback& callback) { - m_preRollOutCallback = callback; - } - - inline void unsetPreRollOutCallback(void) { - m_preRollOutCallback = base::defaultPreRollOutCallback; - } - - inline PreRollOutCallback& preRollOutCallback(void) { - return m_preRollOutCallback; - } - - bool hasCustomFormatSpecifier(const char* formatSpecifier); - void installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier); - bool uninstallCustomFormatSpecifier(const char* formatSpecifier); - - const std::vector<CustomFormatSpecifier>* customFormatSpecifiers(void) const { - return &m_customFormatSpecifiers; - } - - inline void setLoggingLevel(Level level) { - m_loggingLevel = level; - } - - template <typename T> - inline bool installLogDispatchCallback(const std::string& id) { - return base::utils::Utils::installCallback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks); - } - - template <typename T> - inline void uninstallLogDispatchCallback(const std::string& id) { - base::utils::Utils::uninstallCallback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks); - } - template <typename T> - inline T* logDispatchCallback(const std::string& id) { - return base::utils::Utils::callback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks); - } - -#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) - template <typename T> - inline bool installPerformanceTrackingCallback(const std::string& id) { - return base::utils::Utils::installCallback<T, base::type::PerformanceTrackingCallbackPtr>(id, - &m_performanceTrackingCallbacks); - } - - template <typename T> - inline void uninstallPerformanceTrackingCallback(const std::string& id) { - base::utils::Utils::uninstallCallback<T, base::type::PerformanceTrackingCallbackPtr>(id, - &m_performanceTrackingCallbacks); - } - - template <typename T> - inline T* performanceTrackingCallback(const std::string& id) { - return base::utils::Utils::callback<T, base::type::PerformanceTrackingCallbackPtr>(id, &m_performanceTrackingCallbacks); - } -#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) - - /// @brief Sets thread name for current thread. Requires std::thread - inline void setThreadName(const std::string& name) { - if (name.empty()) return; - base::threading::ScopedLock scopedLock(lock()); - m_threadNames[base::threading::getCurrentThreadId()] = name; - } - - inline std::string getThreadName(const std::string& threadId) { - std::map<std::string, std::string>::const_iterator it = m_threadNames.find(threadId); - if (it == m_threadNames.end()) { - return threadId; - } - return it->second; - } - private: - base::RegisteredHitCounters* m_registeredHitCounters; - base::RegisteredLoggers* m_registeredLoggers; - base::type::EnumType m_flags; - base::VRegistry* m_vRegistry; -#if ELPP_ASYNC_LOGGING - base::AsyncLogQueue* m_asyncLogQueue; - base::IWorker* m_asyncDispatchWorker; -#endif // ELPP_ASYNC_LOGGING - base::utils::CommandLineArgs m_commandLineArgs; - PreRollOutCallback m_preRollOutCallback; - std::map<std::string, base::type::LogDispatchCallbackPtr> m_logDispatchCallbacks; - std::map<std::string, base::type::PerformanceTrackingCallbackPtr> m_performanceTrackingCallbacks; - std::map<std::string, std::string> m_threadNames; - std::vector<CustomFormatSpecifier> m_customFormatSpecifiers; - Level m_loggingLevel; - - friend class el::Helpers; - friend class el::base::DefaultLogDispatchCallback; - friend class el::LogBuilder; - friend class el::base::MessageBuilder; - friend class el::base::Writer; - friend class el::base::PerformanceTracker; - friend class el::base::LogDispatcher; - - void setApplicationArguments(int argc, char** argv); - - inline void setApplicationArguments(int argc, const char** argv) { - setApplicationArguments(argc, const_cast<char**>(argv)); - } -}; -extern ELPP_EXPORT base::type::StoragePointer elStorage; -#define ELPP el::base::elStorage -class DefaultLogDispatchCallback : public LogDispatchCallback { - protected: - void handle(const LogDispatchData* data); - private: - const LogDispatchData* m_data; - void dispatch(base::type::string_t&& logLine); -}; -#if ELPP_ASYNC_LOGGING -class AsyncLogDispatchCallback : public LogDispatchCallback { - protected: - void handle(const LogDispatchData* data); -}; -class AsyncDispatchWorker : public base::IWorker, public base::threading::ThreadSafe { - public: - AsyncDispatchWorker(); - virtual ~AsyncDispatchWorker(); - - bool clean(void); - void emptyQueue(void); - virtual void start(void); - void handle(AsyncLogItem* logItem); - void run(void); - - void setContinueRunning(bool value) { - base::threading::ScopedLock scopedLock(m_continueRunningMutex); - m_continueRunning = value; - } - - bool continueRunning(void) const { - return m_continueRunning; - } - private: - std::condition_variable cv; - bool m_continueRunning; - base::threading::Mutex m_continueRunningMutex; -}; -#endif // ELPP_ASYNC_LOGGING -} // namespace base -namespace base { -class DefaultLogBuilder : public LogBuilder { - public: - base::type::string_t build(const LogMessage* logMessage, bool appendNewLine) const; -}; -/// @brief Dispatches log messages -class LogDispatcher : base::NoCopy { - public: - LogDispatcher(bool proceed, LogMessage&& logMessage, base::DispatchAction dispatchAction) : - m_proceed(proceed), - m_logMessage(std::move(logMessage)), - m_dispatchAction(std::move(dispatchAction)) { - } - - void dispatch(void); - - private: - bool m_proceed; - LogMessage m_logMessage; - base::DispatchAction m_dispatchAction; -}; -#if defined(ELPP_STL_LOGGING) -/// @brief Workarounds to write some STL logs -/// -/// @detail There is workaround needed to loop through some stl containers. In order to do that, we need iterable containers -/// of same type and provide iterator interface and pass it on to writeIterator(). -/// Remember, this is passed by value in constructor so that we dont change original containers. -/// This operation is as expensive as Big-O(std::min(class_.size(), base::consts::kMaxLogPerContainer)) -namespace workarounds { -/// @brief Abstract IterableContainer template that provides interface for iterable classes of type T -template <typename T, typename Container> -class IterableContainer { - public: - typedef typename Container::iterator iterator; - typedef typename Container::const_iterator const_iterator; - IterableContainer(void) {} - virtual ~IterableContainer(void) {} - iterator begin(void) { - return getContainer().begin(); - } - iterator end(void) { - return getContainer().end(); - } - private: - virtual Container& getContainer(void) = 0; -}; -/// @brief Implements IterableContainer and provides iterable std::priority_queue class -template<typename T, typename Container = std::vector<T>, typename Comparator = std::less<typename Container::value_type>> -class IterablePriorityQueue : public IterableContainer<T, Container>, - public std::priority_queue<T, Container, Comparator> { - public: - IterablePriorityQueue(std::priority_queue<T, Container, Comparator> queue_) { - std::size_t count_ = 0; - while (++count_ < base::consts::kMaxLogPerContainer && !queue_.empty()) { - this->push(queue_.top()); - queue_.pop(); - } - } - private: - inline Container& getContainer(void) { - return this->c; - } -}; -/// @brief Implements IterableContainer and provides iterable std::queue class -template<typename T, typename Container = std::deque<T>> -class IterableQueue : public IterableContainer<T, Container>, public std::queue<T, Container> { - public: - IterableQueue(std::queue<T, Container> queue_) { - std::size_t count_ = 0; - while (++count_ < base::consts::kMaxLogPerContainer && !queue_.empty()) { - this->push(queue_.front()); - queue_.pop(); - } - } - private: - inline Container& getContainer(void) { - return this->c; - } -}; -/// @brief Implements IterableContainer and provides iterable std::stack class -template<typename T, typename Container = std::deque<T>> -class IterableStack : public IterableContainer<T, Container>, public std::stack<T, Container> { - public: - IterableStack(std::stack<T, Container> stack_) { - std::size_t count_ = 0; - while (++count_ < base::consts::kMaxLogPerContainer && !stack_.empty()) { - this->push(stack_.top()); - stack_.pop(); - } - } - private: - inline Container& getContainer(void) { - return this->c; - } -}; -} // namespace workarounds -#endif // defined(ELPP_STL_LOGGING) -// Log message builder -class MessageBuilder { - public: - MessageBuilder(void) : m_logger(nullptr), m_containerLogSeperator(ELPP_LITERAL("")) {} - void initialize(Logger* logger); - -# define ELPP_SIMPLE_LOG(LOG_TYPE)\ -MessageBuilder& operator<<(LOG_TYPE msg) {\ -m_logger->stream() << msg;\ -if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) {\ -m_logger->stream() << " ";\ -}\ -return *this;\ -} - - inline MessageBuilder& operator<<(const std::string& msg) { - return operator<<(msg.c_str()); - } - ELPP_SIMPLE_LOG(char) - ELPP_SIMPLE_LOG(bool) - ELPP_SIMPLE_LOG(signed short) - ELPP_SIMPLE_LOG(unsigned short) - ELPP_SIMPLE_LOG(signed int) - ELPP_SIMPLE_LOG(unsigned int) - ELPP_SIMPLE_LOG(signed long) - ELPP_SIMPLE_LOG(unsigned long) - ELPP_SIMPLE_LOG(float) - ELPP_SIMPLE_LOG(double) - ELPP_SIMPLE_LOG(char*) - ELPP_SIMPLE_LOG(const char*) - ELPP_SIMPLE_LOG(const void*) - ELPP_SIMPLE_LOG(long double) - inline MessageBuilder& operator<<(const std::wstring& msg) { - return operator<<(msg.c_str()); - } - MessageBuilder& operator<<(const wchar_t* msg); - // ostream manipulators - inline MessageBuilder& operator<<(std::ostream& (*OStreamMani)(std::ostream&)) { - m_logger->stream() << OStreamMani; - return *this; - } -#define ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(temp) \ -template <typename T> \ -inline MessageBuilder& operator<<(const temp<T>& template_inst) { \ -return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ -} -#define ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(temp) \ -template <typename T1, typename T2> \ -inline MessageBuilder& operator<<(const temp<T1, T2>& template_inst) { \ -return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ -} -#define ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(temp) \ -template <typename T1, typename T2, typename T3> \ -inline MessageBuilder& operator<<(const temp<T1, T2, T3>& template_inst) { \ -return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ -} -#define ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(temp) \ -template <typename T1, typename T2, typename T3, typename T4> \ -inline MessageBuilder& operator<<(const temp<T1, T2, T3, T4>& template_inst) { \ -return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ -} -#define ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(temp) \ -template <typename T1, typename T2, typename T3, typename T4, typename T5> \ -inline MessageBuilder& operator<<(const temp<T1, T2, T3, T4, T5>& template_inst) { \ -return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ -} - -#if defined(ELPP_STL_LOGGING) - ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::vector) - ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::list) - ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::deque) - ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(std::set) - ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(std::multiset) - ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::map) - ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::multimap) - template <class T, class Container> - inline MessageBuilder& operator<<(const std::queue<T, Container>& queue_) { - base::workarounds::IterableQueue<T, Container> iterableQueue_ = - static_cast<base::workarounds::IterableQueue<T, Container> >(queue_); - return writeIterator(iterableQueue_.begin(), iterableQueue_.end(), iterableQueue_.size()); - } - template <class T, class Container> - inline MessageBuilder& operator<<(const std::stack<T, Container>& stack_) { - base::workarounds::IterableStack<T, Container> iterableStack_ = - static_cast<base::workarounds::IterableStack<T, Container> >(stack_); - return writeIterator(iterableStack_.begin(), iterableStack_.end(), iterableStack_.size()); - } - template <class T, class Container, class Comparator> - inline MessageBuilder& operator<<(const std::priority_queue<T, Container, Comparator>& priorityQueue_) { - base::workarounds::IterablePriorityQueue<T, Container, Comparator> iterablePriorityQueue_ = - static_cast<base::workarounds::IterablePriorityQueue<T, Container, Comparator> >(priorityQueue_); - return writeIterator(iterablePriorityQueue_.begin(), iterablePriorityQueue_.end(), iterablePriorityQueue_.size()); - } - template <class First, class Second> - MessageBuilder& operator<<(const std::pair<First, Second>& pair_) { - m_logger->stream() << ELPP_LITERAL("("); - operator << (static_cast<First>(pair_.first)); - m_logger->stream() << ELPP_LITERAL(", "); - operator << (static_cast<Second>(pair_.second)); - m_logger->stream() << ELPP_LITERAL(")"); - return *this; - } - template <std::size_t Size> - MessageBuilder& operator<<(const std::bitset<Size>& bitset_) { - m_logger->stream() << ELPP_LITERAL("["); - operator << (bitset_.to_string()); - m_logger->stream() << ELPP_LITERAL("]"); - return *this; - } -# if defined(ELPP_LOG_STD_ARRAY) - template <class T, std::size_t Size> - inline MessageBuilder& operator<<(const std::array<T, Size>& array) { - return writeIterator(array.begin(), array.end(), array.size()); - } -# endif // defined(ELPP_LOG_STD_ARRAY) -# if defined(ELPP_LOG_UNORDERED_MAP) - ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(std::unordered_map) - ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(std::unordered_multimap) -# endif // defined(ELPP_LOG_UNORDERED_MAP) -# if defined(ELPP_LOG_UNORDERED_SET) - ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::unordered_set) - ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::unordered_multiset) -# endif // defined(ELPP_LOG_UNORDERED_SET) -#endif // defined(ELPP_STL_LOGGING) -#if defined(ELPP_QT_LOGGING) - inline MessageBuilder& operator<<(const QString& msg) { -# if defined(ELPP_UNICODE) - m_logger->stream() << msg.toStdWString(); -# else - m_logger->stream() << msg.toStdString(); -# endif // defined(ELPP_UNICODE) - return *this; - } - inline MessageBuilder& operator<<(const QByteArray& msg) { - return operator << (QString(msg)); - } - inline MessageBuilder& operator<<(const QStringRef& msg) { - return operator<<(msg.toString()); - } - inline MessageBuilder& operator<<(qint64 msg) { -# if defined(ELPP_UNICODE) - m_logger->stream() << QString::number(msg).toStdWString(); -# else - m_logger->stream() << QString::number(msg).toStdString(); -# endif // defined(ELPP_UNICODE) - return *this; - } - inline MessageBuilder& operator<<(quint64 msg) { -# if defined(ELPP_UNICODE) - m_logger->stream() << QString::number(msg).toStdWString(); -# else - m_logger->stream() << QString::number(msg).toStdString(); -# endif // defined(ELPP_UNICODE) - return *this; - } - inline MessageBuilder& operator<<(QChar msg) { - m_logger->stream() << msg.toLatin1(); - return *this; - } - inline MessageBuilder& operator<<(const QLatin1String& msg) { - m_logger->stream() << msg.latin1(); - return *this; - } - ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QList) - ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QVector) - ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QQueue) - ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QSet) - ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QLinkedList) - ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QStack) - template <typename First, typename Second> - MessageBuilder& operator<<(const QPair<First, Second>& pair_) { - m_logger->stream() << ELPP_LITERAL("("); - operator << (static_cast<First>(pair_.first)); - m_logger->stream() << ELPP_LITERAL(", "); - operator << (static_cast<Second>(pair_.second)); - m_logger->stream() << ELPP_LITERAL(")"); - return *this; - } - template <typename K, typename V> - MessageBuilder& operator<<(const QMap<K, V>& map_) { - m_logger->stream() << ELPP_LITERAL("["); - QList<K> keys = map_.keys(); - typename QList<K>::const_iterator begin = keys.begin(); - typename QList<K>::const_iterator end = keys.end(); - int max_ = static_cast<int>(base::consts::kMaxLogPerContainer); // to prevent warning - for (int index_ = 0; begin != end && index_ < max_; ++index_, ++begin) { - m_logger->stream() << ELPP_LITERAL("("); - operator << (static_cast<K>(*begin)); - m_logger->stream() << ELPP_LITERAL(", "); - operator << (static_cast<V>(map_.value(*begin))); - m_logger->stream() << ELPP_LITERAL(")"); - m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL("")); - } - if (begin != end) { - m_logger->stream() << ELPP_LITERAL("..."); - } - m_logger->stream() << ELPP_LITERAL("]"); - return *this; - } - template <typename K, typename V> - inline MessageBuilder& operator<<(const QMultiMap<K, V>& map_) { - operator << (static_cast<QMap<K, V>>(map_)); - return *this; - } - template <typename K, typename V> - MessageBuilder& operator<<(const QHash<K, V>& hash_) { - m_logger->stream() << ELPP_LITERAL("["); - QList<K> keys = hash_.keys(); - typename QList<K>::const_iterator begin = keys.begin(); - typename QList<K>::const_iterator end = keys.end(); - int max_ = static_cast<int>(base::consts::kMaxLogPerContainer); // prevent type warning - for (int index_ = 0; begin != end && index_ < max_; ++index_, ++begin) { - m_logger->stream() << ELPP_LITERAL("("); - operator << (static_cast<K>(*begin)); - m_logger->stream() << ELPP_LITERAL(", "); - operator << (static_cast<V>(hash_.value(*begin))); - m_logger->stream() << ELPP_LITERAL(")"); - m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL("")); - } - if (begin != end) { - m_logger->stream() << ELPP_LITERAL("..."); - } - m_logger->stream() << ELPP_LITERAL("]"); - return *this; - } - template <typename K, typename V> - inline MessageBuilder& operator<<(const QMultiHash<K, V>& multiHash_) { - operator << (static_cast<QHash<K, V>>(multiHash_)); - return *this; - } -#endif // defined(ELPP_QT_LOGGING) -#if defined(ELPP_BOOST_LOGGING) - ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::vector) - ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::stable_vector) - ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::list) - ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::deque) - ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(boost::container::map) - ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(boost::container::flat_map) - ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(boost::container::set) - ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(boost::container::flat_set) -#endif // defined(ELPP_BOOST_LOGGING) - - /// @brief Macro used internally that can be used externally to make containers easylogging++ friendly - /// - /// @detail This macro expands to write an ostream& operator<< for container. This container is expected to - /// have begin() and end() methods that return respective iterators - /// @param ContainerType Type of container e.g, MyList from WX_DECLARE_LIST(int, MyList); in wxwidgets - /// @param SizeMethod Method used to get size of container. - /// @param ElementInstance Instance of element to be fed out. Insance name is "elem". See WXELPP_ENABLED macro - /// for an example usage -#define MAKE_CONTAINERELPP_FRIENDLY(ContainerType, SizeMethod, ElementInstance) \ -el::base::type::ostream_t& operator<<(el::base::type::ostream_t& ss, const ContainerType& container) {\ -const el::base::type::char_t* sep = ELPP->hasFlag(el::LoggingFlag::NewLineForContainer) ? \ -ELPP_LITERAL("\n ") : ELPP_LITERAL(", ");\ -ContainerType::const_iterator elem = container.begin();\ -ContainerType::const_iterator endElem = container.end();\ -std::size_t size_ = container.SizeMethod; \ -ss << ELPP_LITERAL("[");\ -for (std::size_t i = 0; elem != endElem && i < el::base::consts::kMaxLogPerContainer; ++i, ++elem) { \ -ss << ElementInstance;\ -ss << ((i < size_ - 1) ? sep : ELPP_LITERAL(""));\ -}\ -if (elem != endElem) {\ -ss << ELPP_LITERAL("...");\ -}\ -ss << ELPP_LITERAL("]");\ -return ss;\ -} -#if defined(ELPP_WXWIDGETS_LOGGING) - ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(wxVector) -# define ELPP_WX_PTR_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), *(*elem)) -# define ELPP_WX_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), (*elem)) -# define ELPP_WX_HASH_MAP_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), \ -ELPP_LITERAL("(") << elem->first << ELPP_LITERAL(", ") << elem->second << ELPP_LITERAL(")") -#else -# define ELPP_WX_PTR_ENABLED(ContainerType) -# define ELPP_WX_ENABLED(ContainerType) -# define ELPP_WX_HASH_MAP_ENABLED(ContainerType) -#endif // defined(ELPP_WXWIDGETS_LOGGING) - // Other classes - template <class Class> - ELPP_SIMPLE_LOG(const Class&) -#undef ELPP_SIMPLE_LOG -#undef ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG -#undef ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG -#undef ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG -#undef ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG -#undef ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG - private: - Logger* m_logger; - const base::type::char_t* m_containerLogSeperator; - - template<class Iterator> - MessageBuilder& writeIterator(Iterator begin_, Iterator end_, std::size_t size_) { - m_logger->stream() << ELPP_LITERAL("["); - for (std::size_t i = 0; begin_ != end_ && i < base::consts::kMaxLogPerContainer; ++i, ++begin_) { - operator << (*begin_); - m_logger->stream() << ((i < size_ - 1) ? m_containerLogSeperator : ELPP_LITERAL("")); - } - if (begin_ != end_) { - m_logger->stream() << ELPP_LITERAL("..."); - } - m_logger->stream() << ELPP_LITERAL("]"); - if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) { - m_logger->stream() << " "; - } - return *this; - } -}; -/// @brief Writes nothing - Used when certain log is disabled -class NullWriter : base::NoCopy { - public: - NullWriter(void) {} - - // Null manipulator - inline NullWriter& operator<<(std::ostream& (*)(std::ostream&)) { - return *this; - } - - template <typename T> - inline NullWriter& operator<<(const T&) { - return *this; - } - - inline operator bool() { - return true; - } -}; -/// @brief Main entry point of each logging -class Writer : base::NoCopy { - public: - Writer(Level level, const char* file, base::type::LineNumber line, - const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog, - base::type::VerboseLevel verboseLevel = 0) : - m_level(level), m_file(file), m_line(line), m_func(func), m_verboseLevel(verboseLevel), - m_logger(nullptr), m_proceed(false), m_dispatchAction(dispatchAction) { - } - - virtual ~Writer(void) { - processDispatch(); - } - - template <typename T> - inline Writer& operator<<(const T& log) { -#if ELPP_LOGGING_ENABLED - if (m_proceed) { - m_messageBuilder << log; - } -#endif // ELPP_LOGGING_ENABLED - return *this; - } - - inline Writer& operator<<(std::ostream& (*log)(std::ostream&)) { -#if ELPP_LOGGING_ENABLED - if (m_proceed) { - m_messageBuilder << log; - } -#endif // ELPP_LOGGING_ENABLED - return *this; - } - - inline operator bool() { - return true; - } - - Writer& construct(Logger* logger, bool needLock = true); - Writer& construct(int count, const char* loggerIds, ...); - protected: - Level m_level; - const char* m_file; - const base::type::LineNumber m_line; - const char* m_func; - base::type::VerboseLevel m_verboseLevel; - Logger* m_logger; - bool m_proceed; - base::MessageBuilder m_messageBuilder; - base::DispatchAction m_dispatchAction; - std::vector<std::string> m_loggerIds; - friend class el::Helpers; - - void initializeLogger(const std::string& loggerId, bool lookup = true, bool needLock = true); - void processDispatch(); - void triggerDispatch(void); -}; -class PErrorWriter : public base::Writer { - public: - PErrorWriter(Level level, const char* file, base::type::LineNumber line, - const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog, - base::type::VerboseLevel verboseLevel = 0) : - base::Writer(level, file, line, func, dispatchAction, verboseLevel) { - } - - virtual ~PErrorWriter(void); -}; -} // namespace base -// Logging from Logger class. Why this is here? Because we have Storage and Writer class available -#if ELPP_VARIADIC_TEMPLATES_SUPPORTED -template <typename T, typename... Args> -void Logger::log_(Level level, int vlevel, const char* s, const T& value, const Args&... args) { - base::MessageBuilder b; - b.initialize(this); - while (*s) { - if (*s == base::consts::kFormatSpecifierChar) { - if (*(s + 1) == base::consts::kFormatSpecifierChar) { - ++s; - } else { - if (*(s + 1) == base::consts::kFormatSpecifierCharValue) { - ++s; - b << value; - log_(level, vlevel, ++s, args...); - return; - } - } - } - b << *s++; - } - ELPP_INTERNAL_ERROR("Too many arguments provided. Unable to handle. Please provide more format specifiers", false); -} -template <typename T> -void Logger::log_(Level level, int vlevel, const T& log) { - if (level == Level::Verbose) { - if (ELPP->vRegistry()->allowed(vlevel, __FILE__)) { - base::Writer(Level::Verbose, "FILE", 0, "FUNCTION", - base::DispatchAction::NormalLog, vlevel).construct(this, false) << log; - } else { - stream().str(ELPP_LITERAL("")); - } - } else { - base::Writer(level, "FILE", 0, "FUNCTION").construct(this, false) << log; - } -} -template <typename T, typename... Args> -inline void Logger::log(Level level, const char* s, const T& value, const Args&... args) { - base::threading::ScopedLock scopedLock(lock()); - log_(level, 0, s, value, args...); -} -template <typename T> -inline void Logger::log(Level level, const T& log) { - base::threading::ScopedLock scopedLock(lock()); - log_(level, 0, log); -} -# if ELPP_VERBOSE_LOG -template <typename T, typename... Args> -inline void Logger::verbose(int vlevel, const char* s, const T& value, const Args&... args) { - base::threading::ScopedLock scopedLock(lock()); - log_(el::Level::Verbose, vlevel, s, value, args...); -} -template <typename T> -inline void Logger::verbose(int vlevel, const T& log) { - base::threading::ScopedLock scopedLock(lock()); - log_(el::Level::Verbose, vlevel, log); -} -# else -template <typename T, typename... Args> -inline void Logger::verbose(int, const char*, const T&, const Args&...) { - return; -} -template <typename T> -inline void Logger::verbose(int, const T&) { - return; -} -# endif // ELPP_VERBOSE_LOG -# define LOGGER_LEVEL_WRITERS(FUNCTION_NAME, LOG_LEVEL)\ -template <typename T, typename... Args>\ -inline void Logger::FUNCTION_NAME(const char* s, const T& value, const Args&... args) {\ -log(LOG_LEVEL, s, value, args...);\ -}\ -template <typename T>\ -inline void Logger::FUNCTION_NAME(const T& value) {\ -log(LOG_LEVEL, value);\ -} -# define LOGGER_LEVEL_WRITERS_DISABLED(FUNCTION_NAME, LOG_LEVEL)\ -template <typename T, typename... Args>\ -inline void Logger::FUNCTION_NAME(const char*, const T&, const Args&...) {\ -return;\ -}\ -template <typename T>\ -inline void Logger::FUNCTION_NAME(const T&) {\ -return;\ -} - -# if ELPP_INFO_LOG -LOGGER_LEVEL_WRITERS(info, Level::Info) -# else -LOGGER_LEVEL_WRITERS_DISABLED(info, Level::Info) -# endif // ELPP_INFO_LOG -# if ELPP_DEBUG_LOG -LOGGER_LEVEL_WRITERS(debug, Level::Debug) -# else -LOGGER_LEVEL_WRITERS_DISABLED(debug, Level::Debug) -# endif // ELPP_DEBUG_LOG -# if ELPP_WARNING_LOG -LOGGER_LEVEL_WRITERS(warn, Level::Warning) -# else -LOGGER_LEVEL_WRITERS_DISABLED(warn, Level::Warning) -# endif // ELPP_WARNING_LOG -# if ELPP_ERROR_LOG -LOGGER_LEVEL_WRITERS(error, Level::Error) -# else -LOGGER_LEVEL_WRITERS_DISABLED(error, Level::Error) -# endif // ELPP_ERROR_LOG -# if ELPP_FATAL_LOG -LOGGER_LEVEL_WRITERS(fatal, Level::Fatal) -# else -LOGGER_LEVEL_WRITERS_DISABLED(fatal, Level::Fatal) -# endif // ELPP_FATAL_LOG -# if ELPP_TRACE_LOG -LOGGER_LEVEL_WRITERS(trace, Level::Trace) -# else -LOGGER_LEVEL_WRITERS_DISABLED(trace, Level::Trace) -# endif // ELPP_TRACE_LOG -# undef LOGGER_LEVEL_WRITERS -# undef LOGGER_LEVEL_WRITERS_DISABLED -#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED -#if ELPP_COMPILER_MSVC -# define ELPP_VARIADIC_FUNC_MSVC(variadicFunction, variadicArgs) variadicFunction variadicArgs -# define ELPP_VARIADIC_FUNC_MSVC_RUN(variadicFunction, ...) ELPP_VARIADIC_FUNC_MSVC(variadicFunction, (__VA_ARGS__)) -# define el_getVALength(...) ELPP_VARIADIC_FUNC_MSVC_RUN(el_resolveVALength, 0, ## __VA_ARGS__,\ -10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) -#else -# if ELPP_COMPILER_CLANG -# define el_getVALength(...) el_resolveVALength(0, __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) -# else -# define el_getVALength(...) el_resolveVALength(0, ## __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) -# endif // ELPP_COMPILER_CLANG -#endif // ELPP_COMPILER_MSVC -#define el_resolveVALength(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N -#define ELPP_WRITE_LOG(writer, level, dispatchAction, ...) \ -writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) -#define ELPP_WRITE_LOG_IF(writer, condition, level, dispatchAction, ...) if (condition) \ -writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) -#define ELPP_WRITE_LOG_EVERY_N(writer, occasion, level, dispatchAction, ...) \ -ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion) && \ -writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) -#define ELPP_WRITE_LOG_AFTER_N(writer, n, level, dispatchAction, ...) \ -ELPP->validateAfterNCounter(__FILE__, __LINE__, n) && \ -writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) -#define ELPP_WRITE_LOG_N_TIMES(writer, n, level, dispatchAction, ...) \ -ELPP->validateNTimesCounter(__FILE__, __LINE__, n) && \ -writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) -#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) -class PerformanceTrackingData { - public: - enum class DataType : base::type::EnumType { - Checkpoint = 1, Complete = 2 - }; - // Do not use constructor, will run into multiple definition error, use init(PerformanceTracker*) - explicit PerformanceTrackingData(DataType dataType) : m_performanceTracker(nullptr), - m_dataType(dataType), m_firstCheckpoint(false), m_file(""), m_line(0), m_func("") {} - inline const std::string* blockName(void) const; - inline const struct timeval* startTime(void) const; - inline const struct timeval* endTime(void) const; - inline const struct timeval* lastCheckpointTime(void) const; - inline const base::PerformanceTracker* performanceTracker(void) const { - return m_performanceTracker; - } - inline PerformanceTrackingData::DataType dataType(void) const { - return m_dataType; - } - inline bool firstCheckpoint(void) const { - return m_firstCheckpoint; - } - inline std::string checkpointId(void) const { - return m_checkpointId; - } - inline const char* file(void) const { - return m_file; - } - inline base::type::LineNumber line(void) const { - return m_line; - } - inline const char* func(void) const { - return m_func; - } - inline const base::type::string_t* formattedTimeTaken() const { - return &m_formattedTimeTaken; - } - inline const std::string& loggerId(void) const; - private: - base::PerformanceTracker* m_performanceTracker; - base::type::string_t m_formattedTimeTaken; - PerformanceTrackingData::DataType m_dataType; - bool m_firstCheckpoint; - std::string m_checkpointId; - const char* m_file; - base::type::LineNumber m_line; - const char* m_func; - inline void init(base::PerformanceTracker* performanceTracker, bool firstCheckpoint = false) { - m_performanceTracker = performanceTracker; - m_firstCheckpoint = firstCheckpoint; - } - - friend class el::base::PerformanceTracker; -}; -namespace base { -/// @brief Represents performanceTracker block of code that conditionally adds performance status to log -/// either when goes outside the scope of when checkpoint() is called -class PerformanceTracker : public base::threading::ThreadSafe, public Loggable { - public: - PerformanceTracker(const std::string& blockName, - base::TimestampUnit timestampUnit = base::TimestampUnit::Millisecond, - const std::string& loggerId = std::string(el::base::consts::kPerformanceLoggerId), - bool scopedLog = true, Level level = base::consts::kPerformanceTrackerDefaultLevel); - /// @brief Copy constructor - PerformanceTracker(const PerformanceTracker& t) : - m_blockName(t.m_blockName), m_timestampUnit(t.m_timestampUnit), m_loggerId(t.m_loggerId), m_scopedLog(t.m_scopedLog), - m_level(t.m_level), m_hasChecked(t.m_hasChecked), m_lastCheckpointId(t.m_lastCheckpointId), m_enabled(t.m_enabled), - m_startTime(t.m_startTime), m_endTime(t.m_endTime), m_lastCheckpointTime(t.m_lastCheckpointTime) { - } - virtual ~PerformanceTracker(void); - /// @brief A checkpoint for current performanceTracker block. - void checkpoint(const std::string& id = std::string(), const char* file = __FILE__, - base::type::LineNumber line = __LINE__, - const char* func = ""); - inline Level level(void) const { - return m_level; - } - private: - std::string m_blockName; - base::TimestampUnit m_timestampUnit; - std::string m_loggerId; - bool m_scopedLog; - Level m_level; - bool m_hasChecked; - std::string m_lastCheckpointId; - bool m_enabled; - struct timeval m_startTime, m_endTime, m_lastCheckpointTime; - - PerformanceTracker(void); - - friend class el::PerformanceTrackingData; - friend class base::DefaultPerformanceTrackingCallback; - - const inline base::type::string_t getFormattedTimeTaken() const { - return getFormattedTimeTaken(m_startTime); - } - - const base::type::string_t getFormattedTimeTaken(struct timeval startTime) const; - - virtual inline void log(el::base::type::ostream_t& os) const { - os << getFormattedTimeTaken(); - } -}; -class DefaultPerformanceTrackingCallback : public PerformanceTrackingCallback { - protected: - void handle(const PerformanceTrackingData* data) { - m_data = data; - base::type::stringstream_t ss; - if (m_data->dataType() == PerformanceTrackingData::DataType::Complete) { - ss << ELPP_LITERAL("Executed [") << m_data->blockName()->c_str() << ELPP_LITERAL("] in [") << - *m_data->formattedTimeTaken() << ELPP_LITERAL("]"); - } else { - ss << ELPP_LITERAL("Performance checkpoint"); - if (!m_data->checkpointId().empty()) { - ss << ELPP_LITERAL(" [") << m_data->checkpointId().c_str() << ELPP_LITERAL("]"); - } - ss << ELPP_LITERAL(" for block [") << m_data->blockName()->c_str() << ELPP_LITERAL("] : [") << - *m_data->performanceTracker(); - if (!ELPP->hasFlag(LoggingFlag::DisablePerformanceTrackingCheckpointComparison) - && m_data->performanceTracker()->m_hasChecked) { - ss << ELPP_LITERAL(" ([") << *m_data->formattedTimeTaken() << ELPP_LITERAL("] from "); - if (m_data->performanceTracker()->m_lastCheckpointId.empty()) { - ss << ELPP_LITERAL("last checkpoint"); - } else { - ss << ELPP_LITERAL("checkpoint '") << m_data->performanceTracker()->m_lastCheckpointId.c_str() << ELPP_LITERAL("'"); - } - ss << ELPP_LITERAL(")]"); - } else { - ss << ELPP_LITERAL("]"); - } - } - el::base::Writer(m_data->performanceTracker()->level(), m_data->file(), m_data->line(), m_data->func()).construct(1, - m_data->loggerId().c_str()) << ss.str(); - } - private: - const PerformanceTrackingData* m_data; -}; -} // namespace base -inline const std::string* PerformanceTrackingData::blockName() const { - return const_cast<const std::string*>(&m_performanceTracker->m_blockName); -} -inline const struct timeval* PerformanceTrackingData::startTime() const { - return const_cast<const struct timeval*>(&m_performanceTracker->m_startTime); -} -inline const struct timeval* PerformanceTrackingData::endTime() const { - return const_cast<const struct timeval*>(&m_performanceTracker->m_endTime); -} -inline const struct timeval* PerformanceTrackingData::lastCheckpointTime() const { - return const_cast<const struct timeval*>(&m_performanceTracker->m_lastCheckpointTime); -} -inline const std::string& PerformanceTrackingData::loggerId(void) const { - return m_performanceTracker->m_loggerId; -} -#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) -namespace base { -/// @brief Contains some internal debugging tools like crash handler and stack tracer -namespace debug { -#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) -class StackTrace : base::NoCopy { - public: - static const unsigned int kMaxStack = 64; - static const unsigned int kStackStart = 2; // We want to skip c'tor and StackTrace::generateNew() - class StackTraceEntry { - public: - StackTraceEntry(std::size_t index, const char* loc, const char* demang, const char* hex, const char* addr); - StackTraceEntry(std::size_t index, char* loc) : - m_index(index), - m_location(loc) { - } - std::size_t m_index; - std::string m_location; - std::string m_demangled; - std::string m_hex; - std::string m_addr; - friend std::ostream& operator<<(std::ostream& ss, const StackTraceEntry& si); - - private: - StackTraceEntry(void); - }; - - StackTrace(void) { - generateNew(); - } - - virtual ~StackTrace(void) { - } - - inline std::vector<StackTraceEntry>& getLatestStack(void) { - return m_stack; - } - - friend std::ostream& operator<<(std::ostream& os, const StackTrace& st); - - private: - std::vector<StackTraceEntry> m_stack; - - void generateNew(void); -}; -/// @brief Handles unexpected crashes -class CrashHandler : base::NoCopy { - public: - typedef void (*Handler)(int); - - explicit CrashHandler(bool useDefault); - explicit CrashHandler(const Handler& cHandler) { - setHandler(cHandler); - } - void setHandler(const Handler& cHandler); - - private: - Handler m_handler; -}; -#else -class CrashHandler { - public: - explicit CrashHandler(bool) {} -}; -#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) -} // namespace debug -} // namespace base -extern base::debug::CrashHandler elCrashHandler; -#define MAKE_LOGGABLE(ClassType, ClassInstance, OutputStreamInstance) \ -el::base::type::ostream_t& operator<<(el::base::type::ostream_t& OutputStreamInstance, const ClassType& ClassInstance) -/// @brief Initializes syslog with process ID, options and facility. calls closelog() on d'tor -class SysLogInitializer { - public: - SysLogInitializer(const char* processIdent, int options = 0, int facility = 0) { -#if defined(ELPP_SYSLOG) - openlog(processIdent, options, facility); -#else - ELPP_UNUSED(processIdent); - ELPP_UNUSED(options); - ELPP_UNUSED(facility); -#endif // defined(ELPP_SYSLOG) - } - virtual ~SysLogInitializer(void) { -#if defined(ELPP_SYSLOG) - closelog(); -#endif // defined(ELPP_SYSLOG) - } -}; -#define ELPP_INITIALIZE_SYSLOG(id, opt, fac) el::SysLogInitializer elSyslogInit(id, opt, fac) -/// @brief Static helpers for developers -class Helpers : base::StaticClass { - public: - /// @brief Shares logging repository (base::Storage) - static inline void setStorage(base::type::StoragePointer storage) { - ELPP = storage; - } - /// @return Main storage repository - static inline base::type::StoragePointer storage() { - return ELPP; - } - /// @brief Sets application arguments and figures out whats active for logging and whats not. - static inline void setArgs(int argc, char** argv) { - ELPP->setApplicationArguments(argc, argv); - } - /// @copydoc setArgs(int argc, char** argv) - static inline void setArgs(int argc, const char** argv) { - ELPP->setApplicationArguments(argc, const_cast<char**>(argv)); - } - /// @brief Sets thread name for current thread. Requires std::thread - static inline void setThreadName(const std::string& name) { - ELPP->setThreadName(name); - } - static inline std::string getThreadName() { - return ELPP->getThreadName(base::threading::getCurrentThreadId()); - } -#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) - /// @brief Overrides default crash handler and installs custom handler. - /// @param crashHandler A functor with no return type that takes single int argument. - /// Handler is a typedef with specification: void (*Handler)(int) - static inline void setCrashHandler(const el::base::debug::CrashHandler::Handler& crashHandler) { - el::elCrashHandler.setHandler(crashHandler); - } - /// @brief Abort due to crash with signal in parameter - /// @param sig Crash signal - static void crashAbort(int sig, const char* sourceFile = "", unsigned int long line = 0); - /// @brief Logs reason of crash as per sig - /// @param sig Crash signal - /// @param stackTraceIfAvailable Includes stack trace if available - /// @param level Logging level - /// @param logger Logger to use for logging - static void logCrashReason(int sig, bool stackTraceIfAvailable = false, - Level level = Level::Fatal, const char* logger = base::consts::kDefaultLoggerId); -#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) - /// @brief Installs pre rollout callback, this callback is triggered when log file is about to be rolled out - /// (can be useful for backing up) - static inline void installPreRollOutCallback(const PreRollOutCallback& callback) { - ELPP->setPreRollOutCallback(callback); - } - /// @brief Uninstalls pre rollout callback - static inline void uninstallPreRollOutCallback(void) { - ELPP->unsetPreRollOutCallback(); - } - /// @brief Installs post log dispatch callback, this callback is triggered when log is dispatched - template <typename T> - static inline bool installLogDispatchCallback(const std::string& id) { - return ELPP->installLogDispatchCallback<T>(id); - } - /// @brief Uninstalls log dispatch callback - template <typename T> - static inline void uninstallLogDispatchCallback(const std::string& id) { - ELPP->uninstallLogDispatchCallback<T>(id); - } - template <typename T> - static inline T* logDispatchCallback(const std::string& id) { - return ELPP->logDispatchCallback<T>(id); - } -#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) - /// @brief Installs post performance tracking callback, this callback is triggered when performance tracking is finished - template <typename T> - static inline bool installPerformanceTrackingCallback(const std::string& id) { - return ELPP->installPerformanceTrackingCallback<T>(id); - } - /// @brief Uninstalls post performance tracking handler - template <typename T> - static inline void uninstallPerformanceTrackingCallback(const std::string& id) { - ELPP->uninstallPerformanceTrackingCallback<T>(id); - } - template <typename T> - static inline T* performanceTrackingCallback(const std::string& id) { - return ELPP->performanceTrackingCallback<T>(id); - } -#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) - /// @brief Converts template to std::string - useful for loggable classes to log containers within log(std::ostream&) const - template <typename T> - static std::string convertTemplateToStdString(const T& templ) { - el::Logger* logger = - ELPP->registeredLoggers()->get(el::base::consts::kDefaultLoggerId); - if (logger == nullptr) { - return std::string(); - } - base::MessageBuilder b; - b.initialize(logger); - logger->acquireLock(); - b << templ; -#if defined(ELPP_UNICODE) - std::string s = std::string(logger->stream().str().begin(), logger->stream().str().end()); -#else - std::string s = logger->stream().str(); -#endif // defined(ELPP_UNICODE) - logger->stream().str(ELPP_LITERAL("")); - logger->releaseLock(); - return s; - } - /// @brief Returns command line arguments (pointer) provided to easylogging++ - static inline const el::base::utils::CommandLineArgs* commandLineArgs(void) { - return ELPP->commandLineArgs(); - } - /// @brief Installs user defined format specifier and handler - static inline void installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier) { - ELPP->installCustomFormatSpecifier(customFormatSpecifier); - } - /// @brief Uninstalls user defined format specifier and handler - static inline bool uninstallCustomFormatSpecifier(const char* formatSpecifier) { - return ELPP->uninstallCustomFormatSpecifier(formatSpecifier); - } - /// @brief Returns true if custom format specifier is installed - static inline bool hasCustomFormatSpecifier(const char* formatSpecifier) { - return ELPP->hasCustomFormatSpecifier(formatSpecifier); - } - static inline void validateFileRolling(Logger* logger, Level level) { - if (logger == nullptr) return; - logger->m_typedConfigurations->validateFileRolling(level, ELPP->preRollOutCallback()); - } -}; -/// @brief Static helpers to deal with loggers and their configurations -class Loggers : base::StaticClass { - public: - /// @brief Gets existing or registers new logger - static Logger* getLogger(const std::string& identity, bool registerIfNotAvailable = true); - /// @brief Changes default log builder for future loggers - static void setDefaultLogBuilder(el::LogBuilderPtr& logBuilderPtr); - /// @brief Installs logger registration callback, this callback is triggered when new logger is registered - template <typename T> - static inline bool installLoggerRegistrationCallback(const std::string& id) { - return ELPP->registeredLoggers()->installLoggerRegistrationCallback<T>(id); - } - /// @brief Uninstalls log dispatch callback - template <typename T> - static inline void uninstallLoggerRegistrationCallback(const std::string& id) { - ELPP->registeredLoggers()->uninstallLoggerRegistrationCallback<T>(id); - } - template <typename T> - static inline T* loggerRegistrationCallback(const std::string& id) { - return ELPP->registeredLoggers()->loggerRegistrationCallback<T>(id); - } - /// @brief Unregisters logger - use it only when you know what you are doing, you may unregister - /// loggers initialized / used by third-party libs. - static bool unregisterLogger(const std::string& identity); - /// @brief Whether or not logger with id is registered - static bool hasLogger(const std::string& identity); - /// @brief Reconfigures specified logger with new configurations - static Logger* reconfigureLogger(Logger* logger, const Configurations& configurations); - /// @brief Reconfigures logger with new configurations after looking it up using identity - static Logger* reconfigureLogger(const std::string& identity, const Configurations& configurations); - /// @brief Reconfigures logger's single configuration - static Logger* reconfigureLogger(const std::string& identity, ConfigurationType configurationType, - const std::string& value); - /// @brief Reconfigures all the existing loggers with new configurations - static void reconfigureAllLoggers(const Configurations& configurations); - /// @brief Reconfigures single configuration for all the loggers - static inline void reconfigureAllLoggers(ConfigurationType configurationType, const std::string& value) { - reconfigureAllLoggers(Level::Global, configurationType, value); - } - /// @brief Reconfigures single configuration for all the loggers for specified level - static void reconfigureAllLoggers(Level level, ConfigurationType configurationType, - const std::string& value); - /// @brief Sets default configurations. This configuration is used for future (and conditionally for existing) loggers - static void setDefaultConfigurations(const Configurations& configurations, - bool reconfigureExistingLoggers = false); - /// @brief Returns current default - static const Configurations* defaultConfigurations(void); - /// @brief Returns log stream reference pointer if needed by user - static const base::LogStreamsReferenceMap* logStreamsReference(void); - /// @brief Default typed configuration based on existing defaultConf - static base::TypedConfigurations defaultTypedConfigurations(void); - /// @brief Populates all logger IDs in current repository. - /// @param [out] targetList List of fill up. - static std::vector<std::string>* populateAllLoggerIds(std::vector<std::string>* targetList); - /// @brief Sets configurations from global configuration file. - static void configureFromGlobal(const char* globalConfigurationFilePath); - /// @brief Configures loggers using command line arg. Ensure you have already set command line args, - /// @return False if invalid argument or argument with no value provided, true if attempted to configure logger. - /// If true is returned that does not mean it has been configured successfully, it only means that it - /// has attempeted to configure logger using configuration file provided in argument - static bool configureFromArg(const char* argKey); - /// @brief Flushes all loggers for all levels - Be careful if you dont know how many loggers are registered - static void flushAll(void); - /// @brief Adds logging flag used internally. - static inline void addFlag(LoggingFlag flag) { - ELPP->addFlag(flag); - } - /// @brief Removes logging flag used internally. - static inline void removeFlag(LoggingFlag flag) { - ELPP->removeFlag(flag); - } - /// @brief Determines whether or not certain flag is active - static inline bool hasFlag(LoggingFlag flag) { - return ELPP->hasFlag(flag); - } - /// @brief Adds flag and removes it when scope goes out - class ScopedAddFlag { - public: - ScopedAddFlag(LoggingFlag flag) : m_flag(flag) { - Loggers::addFlag(m_flag); - } - ~ScopedAddFlag(void) { - Loggers::removeFlag(m_flag); - } - private: - LoggingFlag m_flag; - }; - /// @brief Removes flag and add it when scope goes out - class ScopedRemoveFlag { - public: - ScopedRemoveFlag(LoggingFlag flag) : m_flag(flag) { - Loggers::removeFlag(m_flag); - } - ~ScopedRemoveFlag(void) { - Loggers::addFlag(m_flag); - } - private: - LoggingFlag m_flag; - }; - /// @brief Sets hierarchy for logging. Needs to enable logging flag (HierarchicalLogging) - static void setLoggingLevel(Level level) { - ELPP->setLoggingLevel(level); - } - /// @brief Sets verbose level on the fly - static void setVerboseLevel(base::type::VerboseLevel level); - /// @brief Gets current verbose level - static base::type::VerboseLevel verboseLevel(void); - /// @brief Sets vmodules as specified (on the fly) - static void setVModules(const char* modules); - /// @brief Clears vmodules - static void clearVModules(void); -}; -class VersionInfo : base::StaticClass { - public: - /// @brief Current version number - static const std::string version(void); - - /// @brief Release date of current version - static const std::string releaseDate(void); -}; -} // namespace el -#undef VLOG_IS_ON -/// @brief Determines whether verbose logging is on for specified level current file. -#define VLOG_IS_ON(verboseLevel) (ELPP->vRegistry()->allowed(verboseLevel, __FILE__)) -#undef TIMED_BLOCK -#undef TIMED_SCOPE -#undef TIMED_SCOPE_IF -#undef TIMED_FUNC -#undef TIMED_FUNC_IF -#undef ELPP_MIN_UNIT -#if defined(ELPP_PERFORMANCE_MICROSECONDS) -# define ELPP_MIN_UNIT el::base::TimestampUnit::Microsecond -#else -# define ELPP_MIN_UNIT el::base::TimestampUnit::Millisecond -#endif // (defined(ELPP_PERFORMANCE_MICROSECONDS)) -/// @brief Performance tracked scope. Performance gets written when goes out of scope using -/// 'performance' logger. -/// -/// @detail Please note in order to check the performance at a certain time you can use obj->checkpoint(); -/// @see el::base::PerformanceTracker -/// @see el::base::PerformanceTracker::checkpoint -// Note: Do not surround this definition with null macro because of obj instance -#define TIMED_SCOPE_IF(obj, blockname, condition) el::base::type::PerformanceTrackerPtr obj( condition ? \ - new el::base::PerformanceTracker(blockname, ELPP_MIN_UNIT) : nullptr ) -#define TIMED_SCOPE(obj, blockname) TIMED_SCOPE_IF(obj, blockname, true) -#define TIMED_BLOCK(obj, blockName) for (struct { int i; el::base::type::PerformanceTrackerPtr timer; } obj = { 0, \ - el::base::type::PerformanceTrackerPtr(new el::base::PerformanceTracker(blockName, ELPP_MIN_UNIT)) }; obj.i < 1; ++obj.i) -/// @brief Performance tracked function. Performance gets written when goes out of scope using -/// 'performance' logger. -/// -/// @detail Please note in order to check the performance at a certain time you can use obj->checkpoint(); -/// @see el::base::PerformanceTracker -/// @see el::base::PerformanceTracker::checkpoint -#define TIMED_FUNC_IF(obj,condition) TIMED_SCOPE_IF(obj, ELPP_FUNC, condition) -#define TIMED_FUNC(obj) TIMED_SCOPE(obj, ELPP_FUNC) -#undef PERFORMANCE_CHECKPOINT -#undef PERFORMANCE_CHECKPOINT_WITH_ID -#define PERFORMANCE_CHECKPOINT(obj) obj->checkpoint(std::string(), __FILE__, __LINE__, ELPP_FUNC) -#define PERFORMANCE_CHECKPOINT_WITH_ID(obj, id) obj->checkpoint(id, __FILE__, __LINE__, ELPP_FUNC) -#undef ELPP_COUNTER -#undef ELPP_COUNTER_POS -/// @brief Gets hit counter for file/line -#define ELPP_COUNTER (ELPP->hitCounters()->getCounter(__FILE__, __LINE__)) -/// @brief Gets hit counter position for file/line, -1 if not registered yet -#define ELPP_COUNTER_POS (ELPP_COUNTER == nullptr ? -1 : ELPP_COUNTER->hitCounts()) -// Undef levels to support LOG(LEVEL) -#undef INFO -#undef WARNING -#undef DEBUG -#undef ERROR -#undef FATAL -#undef TRACE -#undef VERBOSE -// Undef existing -#undef CINFO -#undef CWARNING -#undef CDEBUG -#undef CFATAL -#undef CERROR -#undef CTRACE -#undef CVERBOSE -#undef CINFO_IF -#undef CWARNING_IF -#undef CDEBUG_IF -#undef CERROR_IF -#undef CFATAL_IF -#undef CTRACE_IF -#undef CVERBOSE_IF -#undef CINFO_EVERY_N -#undef CWARNING_EVERY_N -#undef CDEBUG_EVERY_N -#undef CERROR_EVERY_N -#undef CFATAL_EVERY_N -#undef CTRACE_EVERY_N -#undef CVERBOSE_EVERY_N -#undef CINFO_AFTER_N -#undef CWARNING_AFTER_N -#undef CDEBUG_AFTER_N -#undef CERROR_AFTER_N -#undef CFATAL_AFTER_N -#undef CTRACE_AFTER_N -#undef CVERBOSE_AFTER_N -#undef CINFO_N_TIMES -#undef CWARNING_N_TIMES -#undef CDEBUG_N_TIMES -#undef CERROR_N_TIMES -#undef CFATAL_N_TIMES -#undef CTRACE_N_TIMES -#undef CVERBOSE_N_TIMES -// Normal logs -#if ELPP_INFO_LOG -# define CINFO(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Info, dispatchAction, __VA_ARGS__) -#else -# define CINFO(writer, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_INFO_LOG -#if ELPP_WARNING_LOG -# define CWARNING(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Warning, dispatchAction, __VA_ARGS__) -#else -# define CWARNING(writer, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_WARNING_LOG -#if ELPP_DEBUG_LOG -# define CDEBUG(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Debug, dispatchAction, __VA_ARGS__) -#else -# define CDEBUG(writer, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_DEBUG_LOG -#if ELPP_ERROR_LOG -# define CERROR(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Error, dispatchAction, __VA_ARGS__) -#else -# define CERROR(writer, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_ERROR_LOG -#if ELPP_FATAL_LOG -# define CFATAL(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Fatal, dispatchAction, __VA_ARGS__) -#else -# define CFATAL(writer, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_FATAL_LOG -#if ELPP_TRACE_LOG -# define CTRACE(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Trace, dispatchAction, __VA_ARGS__) -#else -# define CTRACE(writer, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_TRACE_LOG -#if ELPP_VERBOSE_LOG -# define CVERBOSE(writer, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel)) writer(\ -el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) -#else -# define CVERBOSE(writer, vlevel, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_VERBOSE_LOG -// Conditional logs -#if ELPP_INFO_LOG -# define CINFO_IF(writer, condition_, dispatchAction, ...) \ -ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Info, dispatchAction, __VA_ARGS__) -#else -# define CINFO_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_INFO_LOG -#if ELPP_WARNING_LOG -# define CWARNING_IF(writer, condition_, dispatchAction, ...)\ -ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Warning, dispatchAction, __VA_ARGS__) -#else -# define CWARNING_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_WARNING_LOG -#if ELPP_DEBUG_LOG -# define CDEBUG_IF(writer, condition_, dispatchAction, ...)\ -ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Debug, dispatchAction, __VA_ARGS__) -#else -# define CDEBUG_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_DEBUG_LOG -#if ELPP_ERROR_LOG -# define CERROR_IF(writer, condition_, dispatchAction, ...)\ -ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Error, dispatchAction, __VA_ARGS__) -#else -# define CERROR_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_ERROR_LOG -#if ELPP_FATAL_LOG -# define CFATAL_IF(writer, condition_, dispatchAction, ...)\ -ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Fatal, dispatchAction, __VA_ARGS__) -#else -# define CFATAL_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_FATAL_LOG -#if ELPP_TRACE_LOG -# define CTRACE_IF(writer, condition_, dispatchAction, ...)\ -ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Trace, dispatchAction, __VA_ARGS__) -#else -# define CTRACE_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_TRACE_LOG -#if ELPP_VERBOSE_LOG -# define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel) && (condition_)) writer( \ -el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) -#else -# define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_VERBOSE_LOG -// Occasional logs -#if ELPP_INFO_LOG -# define CINFO_EVERY_N(writer, occasion, dispatchAction, ...)\ -ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Info, dispatchAction, __VA_ARGS__) -#else -# define CINFO_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_INFO_LOG -#if ELPP_WARNING_LOG -# define CWARNING_EVERY_N(writer, occasion, dispatchAction, ...)\ -ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Warning, dispatchAction, __VA_ARGS__) -#else -# define CWARNING_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_WARNING_LOG -#if ELPP_DEBUG_LOG -# define CDEBUG_EVERY_N(writer, occasion, dispatchAction, ...)\ -ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Debug, dispatchAction, __VA_ARGS__) -#else -# define CDEBUG_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_DEBUG_LOG -#if ELPP_ERROR_LOG -# define CERROR_EVERY_N(writer, occasion, dispatchAction, ...)\ -ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Error, dispatchAction, __VA_ARGS__) -#else -# define CERROR_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_ERROR_LOG -#if ELPP_FATAL_LOG -# define CFATAL_EVERY_N(writer, occasion, dispatchAction, ...)\ -ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Fatal, dispatchAction, __VA_ARGS__) -#else -# define CFATAL_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_FATAL_LOG -#if ELPP_TRACE_LOG -# define CTRACE_EVERY_N(writer, occasion, dispatchAction, ...)\ -ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Trace, dispatchAction, __VA_ARGS__) -#else -# define CTRACE_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_TRACE_LOG -#if ELPP_VERBOSE_LOG -# define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...)\ -CVERBOSE_IF(writer, ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion), vlevel, dispatchAction, __VA_ARGS__) -#else -# define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_VERBOSE_LOG -// After N logs -#if ELPP_INFO_LOG -# define CINFO_AFTER_N(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Info, dispatchAction, __VA_ARGS__) -#else -# define CINFO_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_INFO_LOG -#if ELPP_WARNING_LOG -# define CWARNING_AFTER_N(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Warning, dispatchAction, __VA_ARGS__) -#else -# define CWARNING_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_WARNING_LOG -#if ELPP_DEBUG_LOG -# define CDEBUG_AFTER_N(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Debug, dispatchAction, __VA_ARGS__) -#else -# define CDEBUG_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_DEBUG_LOG -#if ELPP_ERROR_LOG -# define CERROR_AFTER_N(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Error, dispatchAction, __VA_ARGS__) -#else -# define CERROR_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_ERROR_LOG -#if ELPP_FATAL_LOG -# define CFATAL_AFTER_N(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Fatal, dispatchAction, __VA_ARGS__) -#else -# define CFATAL_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_FATAL_LOG -#if ELPP_TRACE_LOG -# define CTRACE_AFTER_N(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Trace, dispatchAction, __VA_ARGS__) -#else -# define CTRACE_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_TRACE_LOG -#if ELPP_VERBOSE_LOG -# define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...)\ -CVERBOSE_IF(writer, ELPP->validateAfterNCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__) -#else -# define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_VERBOSE_LOG -// N Times logs -#if ELPP_INFO_LOG -# define CINFO_N_TIMES(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Info, dispatchAction, __VA_ARGS__) -#else -# define CINFO_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_INFO_LOG -#if ELPP_WARNING_LOG -# define CWARNING_N_TIMES(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Warning, dispatchAction, __VA_ARGS__) -#else -# define CWARNING_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_WARNING_LOG -#if ELPP_DEBUG_LOG -# define CDEBUG_N_TIMES(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Debug, dispatchAction, __VA_ARGS__) -#else -# define CDEBUG_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_DEBUG_LOG -#if ELPP_ERROR_LOG -# define CERROR_N_TIMES(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Error, dispatchAction, __VA_ARGS__) -#else -# define CERROR_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_ERROR_LOG -#if ELPP_FATAL_LOG -# define CFATAL_N_TIMES(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Fatal, dispatchAction, __VA_ARGS__) -#else -# define CFATAL_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_FATAL_LOG -#if ELPP_TRACE_LOG -# define CTRACE_N_TIMES(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Trace, dispatchAction, __VA_ARGS__) -#else -# define CTRACE_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_TRACE_LOG -#if ELPP_VERBOSE_LOG -# define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...)\ -CVERBOSE_IF(writer, ELPP->validateNTimesCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__) -#else -# define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_VERBOSE_LOG -// -// Custom Loggers - Requires (level, dispatchAction, loggerId/s) -// -// undef existing -#undef CLOG -#undef CLOG_VERBOSE -#undef CVLOG -#undef CLOG_IF -#undef CLOG_VERBOSE_IF -#undef CVLOG_IF -#undef CLOG_EVERY_N -#undef CVLOG_EVERY_N -#undef CLOG_AFTER_N -#undef CVLOG_AFTER_N -#undef CLOG_N_TIMES -#undef CVLOG_N_TIMES -// Normal logs -#define CLOG(LEVEL, ...)\ -C##LEVEL(el::base::Writer, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define CVLOG(vlevel, ...) CVERBOSE(el::base::Writer, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) -// Conditional logs -#define CLOG_IF(condition, LEVEL, ...)\ -C##LEVEL##_IF(el::base::Writer, condition, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define CVLOG_IF(condition, vlevel, ...)\ -CVERBOSE_IF(el::base::Writer, condition, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) -// Hit counts based logs -#define CLOG_EVERY_N(n, LEVEL, ...)\ -C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define CVLOG_EVERY_N(n, vlevel, ...)\ -CVERBOSE_EVERY_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define CLOG_AFTER_N(n, LEVEL, ...)\ -C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define CVLOG_AFTER_N(n, vlevel, ...)\ -CVERBOSE_AFTER_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define CLOG_N_TIMES(n, LEVEL, ...)\ -C##LEVEL##_N_TIMES(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define CVLOG_N_TIMES(n, vlevel, ...)\ -CVERBOSE_N_TIMES(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) -// -// Default Loggers macro using CLOG(), CLOG_VERBOSE() and CVLOG() macros -// -// undef existing -#undef LOG -#undef VLOG -#undef LOG_IF -#undef VLOG_IF -#undef LOG_EVERY_N -#undef VLOG_EVERY_N -#undef LOG_AFTER_N -#undef VLOG_AFTER_N -#undef LOG_N_TIMES -#undef VLOG_N_TIMES -#undef ELPP_CURR_FILE_LOGGER_ID -#if defined(ELPP_DEFAULT_LOGGER) -# define ELPP_CURR_FILE_LOGGER_ID ELPP_DEFAULT_LOGGER -#else -# define ELPP_CURR_FILE_LOGGER_ID el::base::consts::kDefaultLoggerId -#endif -#undef ELPP_TRACE -#define ELPP_TRACE CLOG(TRACE, ELPP_CURR_FILE_LOGGER_ID) -// Normal logs -#define LOG(LEVEL) CLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define VLOG(vlevel) CVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID) -// Conditional logs -#define LOG_IF(condition, LEVEL) CLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define VLOG_IF(condition, vlevel) CVLOG_IF(condition, vlevel, ELPP_CURR_FILE_LOGGER_ID) -// Hit counts based logs -#define LOG_EVERY_N(n, LEVEL) CLOG_EVERY_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define VLOG_EVERY_N(n, vlevel) CVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) -#define LOG_AFTER_N(n, LEVEL) CLOG_AFTER_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define VLOG_AFTER_N(n, vlevel) CVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) -#define LOG_N_TIMES(n, LEVEL) CLOG_N_TIMES(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define VLOG_N_TIMES(n, vlevel) CVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) -// Generic PLOG() -#undef CPLOG -#undef CPLOG_IF -#undef PLOG -#undef PLOG_IF -#undef DCPLOG -#undef DCPLOG_IF -#undef DPLOG -#undef DPLOG_IF -#define CPLOG(LEVEL, ...)\ -C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define CPLOG_IF(condition, LEVEL, ...)\ -C##LEVEL##_IF(el::base::PErrorWriter, condition, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define DCPLOG(LEVEL, ...)\ -if (ELPP_DEBUG_LOG) C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define DCPLOG_IF(condition, LEVEL, ...)\ -C##LEVEL##_IF(el::base::PErrorWriter, (ELPP_DEBUG_LOG) && (condition), el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define PLOG(LEVEL) CPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define PLOG_IF(condition, LEVEL) CPLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define DPLOG(LEVEL) DCPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define DPLOG_IF(condition, LEVEL) DCPLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -// Generic SYSLOG() -#undef CSYSLOG -#undef CSYSLOG_IF -#undef CSYSLOG_EVERY_N -#undef CSYSLOG_AFTER_N -#undef CSYSLOG_N_TIMES -#undef SYSLOG -#undef SYSLOG_IF -#undef SYSLOG_EVERY_N -#undef SYSLOG_AFTER_N -#undef SYSLOG_N_TIMES -#undef DCSYSLOG -#undef DCSYSLOG_IF -#undef DCSYSLOG_EVERY_N -#undef DCSYSLOG_AFTER_N -#undef DCSYSLOG_N_TIMES -#undef DSYSLOG -#undef DSYSLOG_IF -#undef DSYSLOG_EVERY_N -#undef DSYSLOG_AFTER_N -#undef DSYSLOG_N_TIMES -#if defined(ELPP_SYSLOG) -# define CSYSLOG(LEVEL, ...)\ -C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__) -# define CSYSLOG_IF(condition, LEVEL, ...)\ -C##LEVEL##_IF(el::base::Writer, condition, el::base::DispatchAction::SysLog, __VA_ARGS__) -# define CSYSLOG_EVERY_N(n, LEVEL, ...) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) -# define CSYSLOG_AFTER_N(n, LEVEL, ...) C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) -# define CSYSLOG_N_TIMES(n, LEVEL, ...) C##LEVEL##_N_TIMES(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) -# define SYSLOG(LEVEL) CSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId) -# define SYSLOG_IF(condition, LEVEL) CSYSLOG_IF(condition, LEVEL, el::base::consts::kSysLogLoggerId) -# define SYSLOG_EVERY_N(n, LEVEL) CSYSLOG_EVERY_N(n, LEVEL, el::base::consts::kSysLogLoggerId) -# define SYSLOG_AFTER_N(n, LEVEL) CSYSLOG_AFTER_N(n, LEVEL, el::base::consts::kSysLogLoggerId) -# define SYSLOG_N_TIMES(n, LEVEL) CSYSLOG_N_TIMES(n, LEVEL, el::base::consts::kSysLogLoggerId) -# define DCSYSLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__) -# define DCSYSLOG_IF(condition, LEVEL, ...)\ -C##LEVEL##_IF(el::base::Writer, (ELPP_DEBUG_LOG) && (condition), el::base::DispatchAction::SysLog, __VA_ARGS__) -# define DCSYSLOG_EVERY_N(n, LEVEL, ...)\ -if (ELPP_DEBUG_LOG) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) -# define DCSYSLOG_AFTER_N(n, LEVEL, ...)\ -if (ELPP_DEBUG_LOG) C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) -# define DCSYSLOG_N_TIMES(n, LEVEL, ...)\ -if (ELPP_DEBUG_LOG) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) -# define DSYSLOG(LEVEL) DCSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId) -# define DSYSLOG_IF(condition, LEVEL) DCSYSLOG_IF(condition, LEVEL, el::base::consts::kSysLogLoggerId) -# define DSYSLOG_EVERY_N(n, LEVEL) DCSYSLOG_EVERY_N(n, LEVEL, el::base::consts::kSysLogLoggerId) -# define DSYSLOG_AFTER_N(n, LEVEL) DCSYSLOG_AFTER_N(n, LEVEL, el::base::consts::kSysLogLoggerId) -# define DSYSLOG_N_TIMES(n, LEVEL) DCSYSLOG_N_TIMES(n, LEVEL, el::base::consts::kSysLogLoggerId) -#else -# define CSYSLOG(LEVEL, ...) el::base::NullWriter() -# define CSYSLOG_IF(condition, LEVEL, ...) el::base::NullWriter() -# define CSYSLOG_EVERY_N(n, LEVEL, ...) el::base::NullWriter() -# define CSYSLOG_AFTER_N(n, LEVEL, ...) el::base::NullWriter() -# define CSYSLOG_N_TIMES(n, LEVEL, ...) el::base::NullWriter() -# define SYSLOG(LEVEL) el::base::NullWriter() -# define SYSLOG_IF(condition, LEVEL) el::base::NullWriter() -# define SYSLOG_EVERY_N(n, LEVEL) el::base::NullWriter() -# define SYSLOG_AFTER_N(n, LEVEL) el::base::NullWriter() -# define SYSLOG_N_TIMES(n, LEVEL) el::base::NullWriter() -# define DCSYSLOG(LEVEL, ...) el::base::NullWriter() -# define DCSYSLOG_IF(condition, LEVEL, ...) el::base::NullWriter() -# define DCSYSLOG_EVERY_N(n, LEVEL, ...) el::base::NullWriter() -# define DCSYSLOG_AFTER_N(n, LEVEL, ...) el::base::NullWriter() -# define DCSYSLOG_N_TIMES(n, LEVEL, ...) el::base::NullWriter() -# define DSYSLOG(LEVEL) el::base::NullWriter() -# define DSYSLOG_IF(condition, LEVEL) el::base::NullWriter() -# define DSYSLOG_EVERY_N(n, LEVEL) el::base::NullWriter() -# define DSYSLOG_AFTER_N(n, LEVEL) el::base::NullWriter() -# define DSYSLOG_N_TIMES(n, LEVEL) el::base::NullWriter() -#endif // defined(ELPP_SYSLOG) -// -// Custom Debug Only Loggers - Requires (level, loggerId/s) -// -// undef existing -#undef DCLOG -#undef DCVLOG -#undef DCLOG_IF -#undef DCVLOG_IF -#undef DCLOG_EVERY_N -#undef DCVLOG_EVERY_N -#undef DCLOG_AFTER_N -#undef DCVLOG_AFTER_N -#undef DCLOG_N_TIMES -#undef DCVLOG_N_TIMES -// Normal logs -#define DCLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG(LEVEL, __VA_ARGS__) -#define DCLOG_VERBOSE(vlevel, ...) if (ELPP_DEBUG_LOG) CLOG_VERBOSE(vlevel, __VA_ARGS__) -#define DCVLOG(vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG(vlevel, __VA_ARGS__) -// Conditional logs -#define DCLOG_IF(condition, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_IF(condition, LEVEL, __VA_ARGS__) -#define DCVLOG_IF(condition, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_IF(condition, vlevel, __VA_ARGS__) -// Hit counts based logs -#define DCLOG_EVERY_N(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_EVERY_N(n, LEVEL, __VA_ARGS__) -#define DCVLOG_EVERY_N(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_EVERY_N(n, vlevel, __VA_ARGS__) -#define DCLOG_AFTER_N(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_AFTER_N(n, LEVEL, __VA_ARGS__) -#define DCVLOG_AFTER_N(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_AFTER_N(n, vlevel, __VA_ARGS__) -#define DCLOG_N_TIMES(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_N_TIMES(n, LEVEL, __VA_ARGS__) -#define DCVLOG_N_TIMES(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_N_TIMES(n, vlevel, __VA_ARGS__) -// -// Default Debug Only Loggers macro using CLOG(), CLOG_VERBOSE() and CVLOG() macros -// -#if !defined(ELPP_NO_DEBUG_MACROS) -// undef existing -#undef DLOG -#undef DVLOG -#undef DLOG_IF -#undef DVLOG_IF -#undef DLOG_EVERY_N -#undef DVLOG_EVERY_N -#undef DLOG_AFTER_N -#undef DVLOG_AFTER_N -#undef DLOG_N_TIMES -#undef DVLOG_N_TIMES -// Normal logs -#define DLOG(LEVEL) DCLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define DVLOG(vlevel) DCVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID) -// Conditional logs -#define DLOG_IF(condition, LEVEL) DCLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define DVLOG_IF(condition, vlevel) DCVLOG_IF(condition, vlevel, ELPP_CURR_FILE_LOGGER_ID) -// Hit counts based logs -#define DLOG_EVERY_N(n, LEVEL) DCLOG_EVERY_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define DVLOG_EVERY_N(n, vlevel) DCVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) -#define DLOG_AFTER_N(n, LEVEL) DCLOG_AFTER_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define DVLOG_AFTER_N(n, vlevel) DCVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) -#define DLOG_N_TIMES(n, LEVEL) DCLOG_N_TIMES(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define DVLOG_N_TIMES(n, vlevel) DCVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) -#endif // defined(ELPP_NO_DEBUG_MACROS) -#if !defined(ELPP_NO_CHECK_MACROS) -// Check macros -#undef CCHECK -#undef CPCHECK -#undef CCHECK_EQ -#undef CCHECK_NE -#undef CCHECK_LT -#undef CCHECK_GT -#undef CCHECK_LE -#undef CCHECK_GE -#undef CCHECK_BOUNDS -#undef CCHECK_NOTNULL -#undef CCHECK_STRCASEEQ -#undef CCHECK_STRCASENE -#undef CHECK -#undef PCHECK -#undef CHECK_EQ -#undef CHECK_NE -#undef CHECK_LT -#undef CHECK_GT -#undef CHECK_LE -#undef CHECK_GE -#undef CHECK_BOUNDS -#undef CHECK_NOTNULL -#undef CHECK_STRCASEEQ -#undef CHECK_STRCASENE -#define CCHECK(condition, ...) CLOG_IF(!(condition), FATAL, __VA_ARGS__) << "Check failed: [" << #condition << "] " -#define CPCHECK(condition, ...) CPLOG_IF(!(condition), FATAL, __VA_ARGS__) << "Check failed: [" << #condition << "] " -#define CHECK(condition) CCHECK(condition, ELPP_CURR_FILE_LOGGER_ID) -#define PCHECK(condition) CPCHECK(condition, ELPP_CURR_FILE_LOGGER_ID) -#define CCHECK_EQ(a, b, ...) CCHECK(a == b, __VA_ARGS__) -#define CCHECK_NE(a, b, ...) CCHECK(a != b, __VA_ARGS__) -#define CCHECK_LT(a, b, ...) CCHECK(a < b, __VA_ARGS__) -#define CCHECK_GT(a, b, ...) CCHECK(a > b, __VA_ARGS__) -#define CCHECK_LE(a, b, ...) CCHECK(a <= b, __VA_ARGS__) -#define CCHECK_GE(a, b, ...) CCHECK(a >= b, __VA_ARGS__) -#define CCHECK_BOUNDS(val, min, max, ...) CCHECK(val >= min && val <= max, __VA_ARGS__) -#define CHECK_EQ(a, b) CCHECK_EQ(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_NE(a, b) CCHECK_NE(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_LT(a, b) CCHECK_LT(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_GT(a, b) CCHECK_GT(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_LE(a, b) CCHECK_LE(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_GE(a, b) CCHECK_GE(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_BOUNDS(val, min, max) CCHECK_BOUNDS(val, min, max, ELPP_CURR_FILE_LOGGER_ID) -#define CCHECK_NOTNULL(ptr, ...) CCHECK((ptr) != nullptr, __VA_ARGS__) -#define CCHECK_STREQ(str1, str2, ...) CLOG_IF(!el::base::utils::Str::cStringEq(str1, str2), FATAL, __VA_ARGS__) \ -<< "Check failed: [" << #str1 << " == " << #str2 << "] " -#define CCHECK_STRNE(str1, str2, ...) CLOG_IF(el::base::utils::Str::cStringEq(str1, str2), FATAL, __VA_ARGS__) \ -<< "Check failed: [" << #str1 << " != " << #str2 << "] " -#define CCHECK_STRCASEEQ(str1, str2, ...) CLOG_IF(!el::base::utils::Str::cStringCaseEq(str1, str2), FATAL, __VA_ARGS__) \ -<< "Check failed: [" << #str1 << " == " << #str2 << "] " -#define CCHECK_STRCASENE(str1, str2, ...) CLOG_IF(el::base::utils::Str::cStringCaseEq(str1, str2), FATAL, __VA_ARGS__) \ -<< "Check failed: [" << #str1 << " != " << #str2 << "] " -#define CHECK_NOTNULL(ptr) CCHECK_NOTNULL((ptr), ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_STREQ(str1, str2) CCHECK_STREQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_STRNE(str1, str2) CCHECK_STRNE(str1, str2, ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_STRCASEEQ(str1, str2) CCHECK_STRCASEEQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_STRCASENE(str1, str2) CCHECK_STRCASENE(str1, str2, ELPP_CURR_FILE_LOGGER_ID) -#undef DCCHECK -#undef DCCHECK_EQ -#undef DCCHECK_NE -#undef DCCHECK_LT -#undef DCCHECK_GT -#undef DCCHECK_LE -#undef DCCHECK_GE -#undef DCCHECK_BOUNDS -#undef DCCHECK_NOTNULL -#undef DCCHECK_STRCASEEQ -#undef DCCHECK_STRCASENE -#undef DCPCHECK -#undef DCHECK -#undef DCHECK_EQ -#undef DCHECK_NE -#undef DCHECK_LT -#undef DCHECK_GT -#undef DCHECK_LE -#undef DCHECK_GE -#undef DCHECK_BOUNDS_ -#undef DCHECK_NOTNULL -#undef DCHECK_STRCASEEQ -#undef DCHECK_STRCASENE -#undef DPCHECK -#define DCCHECK(condition, ...) if (ELPP_DEBUG_LOG) CCHECK(condition, __VA_ARGS__) -#define DCCHECK_EQ(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_EQ(a, b, __VA_ARGS__) -#define DCCHECK_NE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_NE(a, b, __VA_ARGS__) -#define DCCHECK_LT(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_LT(a, b, __VA_ARGS__) -#define DCCHECK_GT(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_GT(a, b, __VA_ARGS__) -#define DCCHECK_LE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_LE(a, b, __VA_ARGS__) -#define DCCHECK_GE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_GE(a, b, __VA_ARGS__) -#define DCCHECK_BOUNDS(val, min, max, ...) if (ELPP_DEBUG_LOG) CCHECK_BOUNDS(val, min, max, __VA_ARGS__) -#define DCCHECK_NOTNULL(ptr, ...) if (ELPP_DEBUG_LOG) CCHECK_NOTNULL((ptr), __VA_ARGS__) -#define DCCHECK_STREQ(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STREQ(str1, str2, __VA_ARGS__) -#define DCCHECK_STRNE(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRNE(str1, str2, __VA_ARGS__) -#define DCCHECK_STRCASEEQ(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRCASEEQ(str1, str2, __VA_ARGS__) -#define DCCHECK_STRCASENE(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRCASENE(str1, str2, __VA_ARGS__) -#define DCPCHECK(condition, ...) if (ELPP_DEBUG_LOG) CPCHECK(condition, __VA_ARGS__) -#define DCHECK(condition) DCCHECK(condition, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_EQ(a, b) DCCHECK_EQ(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_NE(a, b) DCCHECK_NE(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_LT(a, b) DCCHECK_LT(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_GT(a, b) DCCHECK_GT(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_LE(a, b) DCCHECK_LE(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_GE(a, b) DCCHECK_GE(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_BOUNDS(val, min, max) DCCHECK_BOUNDS(val, min, max, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_NOTNULL(ptr) DCCHECK_NOTNULL((ptr), ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_STREQ(str1, str2) DCCHECK_STREQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_STRNE(str1, str2) DCCHECK_STRNE(str1, str2, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_STRCASEEQ(str1, str2) DCCHECK_STRCASEEQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_STRCASENE(str1, str2) DCCHECK_STRCASENE(str1, str2, ELPP_CURR_FILE_LOGGER_ID) -#define DPCHECK(condition) DCPCHECK(condition, ELPP_CURR_FILE_LOGGER_ID) -#endif // defined(ELPP_NO_CHECK_MACROS) -#if defined(ELPP_DISABLE_DEFAULT_CRASH_HANDLING) -# define ELPP_USE_DEF_CRASH_HANDLER false -#else -# define ELPP_USE_DEF_CRASH_HANDLER true -#endif // defined(ELPP_DISABLE_DEFAULT_CRASH_HANDLING) -#define ELPP_CRASH_HANDLER_INIT -#define ELPP_INIT_EASYLOGGINGPP(val) \ -namespace el { \ -namespace base { \ -el::base::type::StoragePointer elStorage(val); \ -} \ -el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER); \ -} - -#if ELPP_ASYNC_LOGGING -# define INITIALIZE_EASYLOGGINGPP ELPP_INIT_EASYLOGGINGPP(new el::base::Storage(el::LogBuilderPtr(new el::base::DefaultLogBuilder()),\ -new el::base::AsyncDispatchWorker())) -#else -# define INITIALIZE_EASYLOGGINGPP ELPP_INIT_EASYLOGGINGPP(new el::base::Storage(el::LogBuilderPtr(new el::base::DefaultLogBuilder()))) -#endif // ELPP_ASYNC_LOGGING -#define INITIALIZE_NULL_EASYLOGGINGPP \ -namespace el {\ -namespace base {\ -el::base::type::StoragePointer elStorage;\ -}\ -el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\ -} -#define SHARE_EASYLOGGINGPP(initializedStorage)\ -namespace el {\ -namespace base {\ -el::base::type::StoragePointer elStorage(initializedStorage);\ -}\ -el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\ -} - -#if defined(ELPP_UNICODE) -# define START_EASYLOGGINGPP(argc, argv) el::Helpers::setArgs(argc, argv); std::locale::global(std::locale("")) -#else -# define START_EASYLOGGINGPP(argc, argv) el::Helpers::setArgs(argc, argv) -#endif // defined(ELPP_UNICODE) -#endif // EASYLOGGINGPP_H |