16 #ifndef EASYLOGGINGPP_H
17 #define EASYLOGGINGPP_H
20 # define ELPP_COMPILER_GCC 1
21 # define ELPP_GCC_VERSION (__GNUC__ * 10000 \
22 + __GNUC_MINOR__ * 100 \
23 + __GNUC_PATCHLEVEL__)
24 # if defined(__GXX_EXPERIMENTAL_CXX0X__)
26 # elif(ELPP_GCC_VERSION >= 40801)
28 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
29 #endif // defined(__GNUC__)
32 # define ELPP_COMPILER_MSVC 1
33 # define ELPP_CRT_DBG_WARNINGS 1
34 # if (_MSC_VER == 1600)
36 # elif(_MSC_VER >= 1700)
38 # endif // (_MSC_VER == 1600)
39 #endif // defined(_MSC_VER)
41 #if defined(__clang__) && (__clang__ == 1)
42 # define ELPP_COMPILER_CLANG 1
43 # define ELPP_CLANG_VERSION (__clang_major__ * 10000 \
44 + __clang_minor__ * 100 \
45 + __clang_patchlevel__)
46 # if (ELPP_CLANG_VERSION >= 30300)
48 # endif // (ELPP_CLANG_VERSION >= 30300)
49 #endif // defined(__clang__) && (__clang__ == 1)
51 #if defined(__MINGW32__) || defined(__MINGW64__)
53 #endif // defined(__MINGW32__) || defined(__MINGW64__)
55 #if defined(__CYGWIN__) && (__CYGWIN__ == 1)
56 # define ELPP_CYGWIN 1
57 #endif // defined(__CYGWIN__) && (__CYGWIN__ == 1)
59 #if defined(__INTEL_COMPILER)
60 # define ELPP_COMPILER_INTEL 1
64 #if defined(_WIN32) || defined(_WIN64)
65 # define ELPP_OS_WINDOWS 1
66 #endif // defined(_WIN32) || defined(_WIN64)
68 #if (defined(__linux) || defined(__linux__))
69 # define ELPP_OS_LINUX 1
70 #endif // (defined(__linux) || defined(__linux__))
72 #if defined(__APPLE__)
73 # define ELPP_OS_MAC 1
74 #endif // defined(__APPLE__)
76 #if defined(__FreeBSD__)
77 # define ELPP_OS_FREEBSD 1
81 # define ELPP_OS_SOLARIS 1
84 #if ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_SOLARIS) && (!ELPP_OS_WINDOWS))
85 # define ELPP_OS_UNIX 1
86 #endif // ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_SOLARIS) && (!ELPP_OS_WINDOWS))
88 #if defined(__ANDROID__)
89 # define ELPP_OS_ANDROID 1
90 #endif // defined(__ANDROID__)
92 #if !ELPP_OS_UNIX && !ELPP_OS_WINDOWS && ELPP_CYGWIN
95 # define ELPP_OS_UNIX 1
96 # define ELPP_OS_LINUX 1
97 #endif // !ELPP_OS_UNIX && !ELPP_OS_WINDOWS && ELPP_CYGWIN
98 #if !defined(ELPP_INTERNAL_DEBUGGING_OUT_INFO)
99 # define ELPP_INTERNAL_DEBUGGING_OUT_INFO std::cout
100 #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
101 #if !defined(ELPP_INTERNAL_DEBUGGING_OUT_ERROR)
102 # define ELPP_INTERNAL_DEBUGGING_OUT_ERROR std::cerr
103 #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
104 #if !defined(ELPP_INTERNAL_DEBUGGING_ENDL)
105 # define ELPP_INTERNAL_DEBUGGING_ENDL std::endl
106 #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
107 #if !defined(ELPP_INTERNAL_DEBUGGING_MSG)
108 # define ELPP_INTERNAL_DEBUGGING_MSG(msg) msg
109 #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
111 #if !defined(ELPP_DISABLE_ASSERT)
112 # if (defined(ELPP_DEBUG_ASSERT_FAILURE))
113 # define ELPP_ASSERT(expr, msg) if (!(expr)) { \
114 std::stringstream internalInfoStream; internalInfoStream << msg; \
115 ELPP_INTERNAL_DEBUGGING_OUT_ERROR \
116 << "EASYLOGGING++ ASSERTION FAILED (LINE: " << __LINE__ << ") [" #expr << "] WITH MESSAGE \"" \
117 << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << "\"" << ELPP_INTERNAL_DEBUGGING_ENDL; base::utils::abort(1, \
118 "ELPP Assertion failure, please define ELPP_DEBUG_ASSERT_FAILURE"); }
120 # define ELPP_ASSERT(expr, msg) if (!(expr)) { \
121 std::stringstream internalInfoStream; internalInfoStream << msg; \
122 ELPP_INTERNAL_DEBUGGING_OUT_ERROR\
123 << "ASSERTION FAILURE FROM EASYLOGGING++ (LINE: " \
124 << __LINE__ << ") [" #expr << "] WITH MESSAGE \"" << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << "\"" \
125 << ELPP_INTERNAL_DEBUGGING_ENDL; }
126 # endif // (defined(ELPP_DEBUG_ASSERT_FAILURE))
128 # define ELPP_ASSERT(x, y)
129 #endif //(!defined(ELPP_DISABLE_ASSERT)
130 #if ELPP_COMPILER_MSVC
131 # define ELPP_INTERNAL_DEBUGGING_WRITE_PERROR \
132 { char buff[256]; strerror_s(buff, 256, errno); \
133 ELPP_INTERNAL_DEBUGGING_OUT_ERROR << ": " << buff << " [" << errno << "]";} (void)0
135 # define ELPP_INTERNAL_DEBUGGING_WRITE_PERROR \
136 ELPP_INTERNAL_DEBUGGING_OUT_ERROR << ": " << strerror(errno) << " [" << errno << "]"; (void)0
137 #endif // ELPP_COMPILER_MSVC
138 #if defined(ELPP_DEBUG_ERRORS)
139 # if !defined(ELPP_INTERNAL_ERROR)
140 # define ELPP_INTERNAL_ERROR(msg, pe) { \
141 std::stringstream internalInfoStream; internalInfoStream << "<ERROR> " << msg; \
142 ELPP_INTERNAL_DEBUGGING_OUT_ERROR \
143 << "ERROR FROM EASYLOGGING++ (LINE: " << __LINE__ << ") " \
144 << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << ELPP_INTERNAL_DEBUGGING_ENDL; \
145 if (pe) { ELPP_INTERNAL_DEBUGGING_OUT_ERROR << " "; ELPP_INTERNAL_DEBUGGING_WRITE_PERROR; }} (void)0
148 # undef ELPP_INTERNAL_INFO
149 # define ELPP_INTERNAL_ERROR(msg, pe)
150 #endif // defined(ELPP_DEBUG_ERRORS)
151 #if (defined(ELPP_DEBUG_INFO))
152 # if !(defined(ELPP_INTERNAL_INFO_LEVEL))
153 # define ELPP_INTERNAL_INFO_LEVEL 9
154 # endif // !(defined(ELPP_INTERNAL_INFO_LEVEL))
155 # if !defined(ELPP_INTERNAL_INFO)
156 # define ELPP_INTERNAL_INFO(lvl, msg) { if (lvl <= ELPP_INTERNAL_INFO_LEVEL) { \
157 std::stringstream internalInfoStream; internalInfoStream << "<INFO> " << msg; \
158 ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) \
159 << ELPP_INTERNAL_DEBUGGING_ENDL; }}
162 # undef ELPP_INTERNAL_INFO
163 # define ELPP_INTERNAL_INFO(lvl, msg)
164 #endif // (defined(ELPP_DEBUG_INFO))
165 #if defined(ELPP_STACKTRACE_ON_CRASH)
166 # if (ELPP_COMPILER_GCC && !ELPP_MINGW)
167 # define ELPP_STACKTRACE 1
169 # if ELPP_COMPILER_MSVC
170 # pragma message("Stack trace not available for this compiler")
172 # warning "Stack trace not available for this compiler";
173 # endif // ELPP_COMPILER_MSVC
174 # endif // ELPP_COMPILER_GCC
175 #endif // (defined(ELPP_STACKTRACE_ON_CRASH))
177 #define ELPP_UNUSED(x) (void)x
180 # define ELPP_LOG_PERMS S_IRUSR | S_IWUSR | S_IXUSR | S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IXOTH
181 #endif // ELPP_OS_UNIX
182 #if defined(ELPP_AS_DLL) && ELPP_COMPILER_MSVC
183 # if defined(ELPP_EXPORT_SYMBOLS)
184 # define ELPP_EXPORT __declspec(dllexport)
186 # define ELPP_EXPORT __declspec(dllimport)
187 # endif // defined(ELPP_EXPORT_SYMBOLS)
190 #endif // defined(ELPP_AS_DLL) && ELPP_COMPILER_MSVC
196 #if ELPP_CRT_DBG_WARNINGS
197 # define STRTOK(a, b, c) strtok_s(a, b, c)
198 # define STRERROR(a, b, c) strerror_s(a, b, c)
199 # define STRCAT(a, b, len) strcat_s(a, len, b)
200 # define STRCPY(a, b, len) strcpy_s(a, len, b)
202 # define STRTOK(a, b, c) strtok(a, b)
203 # define STRERROR(a, b, c) strerror(c)
204 # define STRCAT(a, b, len) strcat(a, b)
205 # define STRCPY(a, b, len) strcpy(a, b)
208 #if (!ELPP_MINGW && !ELPP_COMPILER_CLANG) || defined(ELPP_FORCE_USE_STD_THREAD)
209 # define ELPP_USE_STD_THREADING 1
210 #endif // (!ELPP_MINGW && !ELPP_COMPILER_CLANG) || defined(ELPP_FORCE_USE_STD_THREAD)
212 #if ELPP_COMPILER_INTEL || (ELPP_GCC_VERSION < 40702)
215 # define ELPP_FINAL final
216 #endif // ELPP_COMPILER_INTEL || (ELPP_GCC_VERSION < 40702)
217 #if defined(ELPP_EXPERIMENTAL_ASYNC)
218 # define ELPP_ASYNC_LOGGING 1
220 # define ELPP_ASYNC_LOGGING 0
221 #endif // defined(ELPP_EXPERIMENTAL_ASYNC)
222 #if defined(ELPP_THREAD_SAFE) || ELPP_ASYNC_LOGGING
223 # define ELPP_THREADING_ENABLED 1
224 #endif // defined(ELPP_THREAD_SAFE) || ELPP_ASYNC_LOGGING
227 #if ELPP_COMPILER_MSVC // Visual C++
228 # define ELPP_FUNC __FUNCSIG__
229 #elif ELPP_COMPILER_GCC // GCC
230 # define ELPP_FUNC __PRETTY_FUNCTION__
231 #elif ELPP_COMPILER_INTEL // Intel C++
232 # define ELPP_FUNC __PRETTY_FUNCTION__
233 #elif ELPP_COMPILER_CLANG // Clang++
234 # define ELPP_FUNC __PRETTY_FUNCTION__
236 # if defined(__func__)
237 # define ELPP_FUNC __func__
239 # define ELPP_FUNC ""
240 # endif // defined(__func__)
241 #endif // defined(_MSC_VER)
242 #undef ELPP_VARIADIC_TEMPLATES_SUPPORTED
244 #if ELPP_COMPILER_GCC || ELPP_COMPILER_CLANG || ELPP_COMPILER_INTEL || (ELPP_COMPILER_MSVC && _MSC_VER >= 1800)
245 # define ELPP_VARIADIC_TEMPLATES_SUPPORTED 1
246 #endif // ELPP_COMPILER_GCC || ELPP_COMPILER_CLANG || ELPP_COMPILER_INTEL || (ELPP_COMPILER_MSVC && _MSC_VER >= 1800)
248 #if (!defined(ELPP_DISABLE_LOGS))
249 # define ELPP_LOGGING_ENABLED 1
250 #endif // (!defined(ELPP_DISABLE_LOGS))
251 #if (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED) && ((defined(_DEBUG)) || (!defined(NDEBUG))))
252 # define ELPP_DEBUG_LOG 1
254 # define ELPP_DEBUG_LOG 0
255 #endif // (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED) && ((defined(_DEBUG)) || (!defined(NDEBUG))))
256 #if (!defined(ELPP_DISABLE_INFO_LOGS) && (ELPP_LOGGING_ENABLED))
257 # define ELPP_INFO_LOG 1
259 # define ELPP_INFO_LOG 0
260 #endif // (!defined(ELPP_DISABLE_INFO_LOGS) && (ELPP_LOGGING_ENABLED))
261 #if (!defined(ELPP_DISABLE_WARNING_LOGS) && (ELPP_LOGGING_ENABLED))
262 # define ELPP_WARNING_LOG 1
264 # define ELPP_WARNING_LOG 0
265 #endif // (!defined(ELPP_DISABLE_WARNING_LOGS) && (ELPP_LOGGING_ENABLED))
266 #if (!defined(ELPP_DISABLE_ERROR_LOGS) && (ELPP_LOGGING_ENABLED))
267 # define ELPP_ERROR_LOG 1
269 # define ELPP_ERROR_LOG 0
270 #endif // (!defined(ELPP_DISABLE_ERROR_LOGS) && (ELPP_LOGGING_ENABLED))
271 #if (!defined(ELPP_DISABLE_FATAL_LOGS) && (ELPP_LOGGING_ENABLED))
272 # define ELPP_FATAL_LOG 1
274 # define ELPP_FATAL_LOG 0
275 #endif // (!defined(ELPP_DISABLE_FATAL_LOGS) && (ELPP_LOGGING_ENABLED))
276 #if (!defined(ELPP_DISABLE_TRACE_LOGS) && (ELPP_LOGGING_ENABLED))
277 # define ELPP_TRACE_LOG 1
279 # define ELPP_TRACE_LOG 0
280 #endif // (!defined(ELPP_DISABLE_TRACE_LOGS) && (ELPP_LOGGING_ENABLED))
281 #if (!defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED))
282 # define ELPP_VERBOSE_LOG 1
284 # define ELPP_VERBOSE_LOG 0
285 #endif // (!defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED))
286 #if (!(ELPP_CXX0X || ELPP_CXX11))
287 # error "Easylogging++ 9.0+ is only compatible with C++0x (or higher) compliant compiler"
288 #endif // (!(ELPP_CXX0X || ELPP_CXX11))
290 #if defined(ELPP_SYSLOG)
292 #endif // defined(ELPP_SYSLOG)
301 #if defined(ELPP_UNICODE)
305 # endif // ELPP_OS_WINDOWS
306 #endif // defined(ELPP_UNICODE)
309 # include <execinfo.h>
310 #endif // ELPP_STACKTRACE
312 # include <sys/system_properties.h>
313 #endif // ELPP_OS_ANDROID
315 # include <sys/stat.h>
316 # include <sys/time.h>
317 #elif ELPP_OS_WINDOWS
319 # include <windows.h>
320 # if defined(WIN32_LEAN_AND_MEAN)
321 # if defined(ELPP_WINSOCK2)
322 # include <winsock2.h>
324 # include <winsock.h>
325 # endif // defined(ELPP_WINSOCK2)
326 # endif // defined(WIN32_LEAN_AND_MEAN)
327 #endif // ELPP_OS_UNIX
332 #include <functional>
338 #include <type_traits>
339 #if ELPP_THREADING_ENABLED
340 # if ELPP_USE_STD_THREADING
345 # include <pthread.h>
346 # endif // ELPP_OS_UNIX
347 # endif // ELPP_USE_STD_THREADING
348 #endif // ELPP_THREADING_ENABLED
349 #if ELPP_ASYNC_LOGGING
352 # include <condition_variable>
353 #endif // ELPP_ASYNC_LOGGING
354 #if defined(ELPP_STL_LOGGING)
362 # if defined(ELPP_LOG_STD_ARRAY)
364 # endif // defined(ELPP_LOG_STD_ARRAY)
365 # if defined(ELPP_LOG_UNORDERED_MAP)
366 # include <unordered_map>
367 # endif // defined(ELPP_LOG_UNORDERED_MAP)
368 # if defined(ELPP_LOG_UNORDERED_SET)
369 # include <unordered_set>
370 # endif // defined(ELPP_UNORDERED_SET)
371 #endif // defined(ELPP_STL_LOGGING)
372 #if defined(ELPP_QT_LOGGING)
375 # include <QByteArray>
382 # include <QLinkedList>
384 # include <QMultiHash>
386 #endif // defined(ELPP_QT_LOGGING)
387 #if defined(ELPP_BOOST_LOGGING)
389 # include <boost/container/vector.hpp>
390 # include <boost/container/stable_vector.hpp>
391 # include <boost/container/list.hpp>
392 # include <boost/container/deque.hpp>
393 # include <boost/container/map.hpp>
394 # include <boost/container/flat_map.hpp>
395 # include <boost/container/set.hpp>
396 # include <boost/container/flat_set.hpp>
397 #endif // defined(ELPP_BOOST_LOGGING)
398 #if defined(ELPP_WXWIDGETS_LOGGING)
400 # include <wx/vector.h>
401 #endif // defined(ELPP_WXWIDGETS_LOGGING)
406 class PerformanceTrackingData;
409 template <
typename T>
class Callback;
410 class LogDispatchCallback;
411 class PerformanceTrackingCallback;
412 class LogDispatchData;
415 class RegisteredLoggers;
416 class PerformanceTracker;
417 class MessageBuilder;
421 class DefaultLogBuilder;
422 class DefaultLogDispatchCallback;
423 #if ELPP_ASYNC_LOGGING
424 class AsyncLogDispatchCallback;
425 class AsyncDispatchWorker;
426 #endif // ELPP_ASYNC_LOGGING
427 class DefaultPerformanceTrackingCallback;
439 #if defined(ELPP_UNICODE)
440 # define ELPP_LITERAL(txt) L##txt
441 # define ELPP_STRLEN wcslen
442 # if defined ELPP_CUSTOM_COUT
443 # define ELPP_COUT ELPP_CUSTOM_COUT
445 # define ELPP_COUT std::wcout
446 # endif // defined ELPP_CUSTOM_COUT
447 typedef wchar_t char_t;
448 typedef std::wstring string_t;
449 typedef std::wstringstream stringstream_t;
450 typedef std::wfstream fstream_t;
451 typedef std::wostream ostream_t;
453 # define ELPP_LITERAL(txt) txt
454 # define ELPP_STRLEN strlen
455 # if defined ELPP_CUSTOM_COUT
456 # define ELPP_COUT ELPP_CUSTOM_COUT
458 # define ELPP_COUT std::cout
459 # endif // defined ELPP_CUSTOM_COUT
461 typedef std::string string_t;
462 typedef std::stringstream stringstream_t;
463 typedef std::fstream fstream_t;
464 typedef std::ostream ostream_t;
465 #endif // defined(ELPP_UNICODE)
466 #if defined(ELPP_CUSTOM_COUT_LINE)
467 # define ELPP_COUT_LINE(logLine) ELPP_CUSTOM_COUT_LINE(logLine)
469 # define ELPP_COUT_LINE(logLine) logLine << std::flush
470 #endif // defined(ELPP_CUSTOM_COUT_LINE)
471 typedef unsigned short EnumType;
472 typedef std::shared_ptr<base::Storage> StoragePointer;
473 typedef int VerboseLevel;
474 typedef std::shared_ptr<LogDispatchCallback> LogDispatchCallbackPtr;
475 typedef std::shared_ptr<PerformanceTrackingCallback> PerformanceTrackingCallbackPtr;
485 NoCopy(
const NoCopy&);
486 NoCopy& operator=(
const NoCopy&);
496 StaticClass(
const StaticClass&);
497 StaticClass& operator=(
const StaticClass&);
504 enum class Level : base::type::EnumType {
525 class LevelHelper : base::StaticClass
529 static const base::type::EnumType kMinValid =
static_cast<base::type::EnumType
>(Level::Trace);
531 static const base::type::EnumType kMaxValid =
static_cast<base::type::EnumType
>(Level::Info);
533 static base::type::EnumType castToInt(Level level)
535 return static_cast<base::type::EnumType
>(level);
538 static Level castFromInt(base::type::EnumType l)
540 return static_cast<Level
>(l);
544 static const char* convertToString(Level level)
547 if (level == Level::Global)
return "GLOBAL";
548 if (level == Level::Debug)
return "DEBUG";
549 if (level == Level::Info)
return "INFO";
550 if (level == Level::Warning)
return "WARNING";
551 if (level == Level::Error)
return "ERROR";
552 if (level == Level::Fatal)
return "FATAL";
553 if (level == Level::Verbose)
return "VERBOSE";
554 if (level == Level::Trace)
return "TRACE";
560 static Level convertFromString(
const char* levelStr)
562 if ((strcmp(levelStr,
"GLOBAL") == 0) || (strcmp(levelStr,
"global") == 0))
563 return Level::Global;
564 if ((strcmp(levelStr,
"DEBUG") == 0) || (strcmp(levelStr,
"debug") == 0))
566 if ((strcmp(levelStr,
"INFO") == 0) || (strcmp(levelStr,
"info") == 0))
568 if ((strcmp(levelStr,
"WARNING") == 0) || (strcmp(levelStr,
"warning") == 0))
569 return Level::Warning;
570 if ((strcmp(levelStr,
"ERROR") == 0) || (strcmp(levelStr,
"error") == 0))
572 if ((strcmp(levelStr,
"FATAL") == 0) || (strcmp(levelStr,
"fatal") == 0))
574 if ((strcmp(levelStr,
"VERBOSE") == 0) || (strcmp(levelStr,
"verbose") == 0))
575 return Level::Verbose;
576 if ((strcmp(levelStr,
"TRACE") == 0) || (strcmp(levelStr,
"trace") == 0))
578 return Level::Unknown;
584 static inline void forEachLevel(base::type::EnumType* startIndex,
const std::function<
bool(
void)>& fn)
586 base::type::EnumType lIndexMax = LevelHelper::kMaxValid;
591 *startIndex =
static_cast<base::type::EnumType
>(*startIndex << 1);
592 }
while (*startIndex <= lIndexMax);
597 enum class ConfigurationType : base::type::EnumType {
605 ToStandardOutput = 4,
611 MillisecondsWidth = 32,
615 PerformanceTracking = 64,
620 MaxLogFileSize = 128,
622 LogFlushThreshold = 256,
627 class ConfigurationTypeHelper : base::StaticClass
631 static const base::type::EnumType kMinValid =
static_cast<base::type::EnumType
>(ConfigurationType::Enabled);
633 static const base::type::EnumType kMaxValid =
static_cast<base::type::EnumType
>(ConfigurationType::MaxLogFileSize);
635 static base::type::EnumType castToInt(ConfigurationType configurationType)
637 return static_cast<base::type::EnumType
>(configurationType);
640 static ConfigurationType castFromInt(base::type::EnumType c)
642 return static_cast<ConfigurationType
>(c);
646 static const char* convertToString(ConfigurationType configurationType)
649 if (configurationType == ConfigurationType::Enabled)
return "ENABLED";
650 if (configurationType == ConfigurationType::Filename)
return "FILENAME";
651 if (configurationType == ConfigurationType::Format)
return "FORMAT";
652 if (configurationType == ConfigurationType::ToFile)
return "TO_FILE";
653 if (configurationType == ConfigurationType::ToStandardOutput)
return "TO_STANDARD_OUTPUT";
654 if (configurationType == ConfigurationType::MillisecondsWidth)
return "MILLISECONDS_WIDTH";
655 if (configurationType == ConfigurationType::PerformanceTracking)
return "PERFORMANCE_TRACKING";
656 if (configurationType == ConfigurationType::MaxLogFileSize)
return "MAX_LOG_FILE_SIZE";
657 if (configurationType == ConfigurationType::LogFlushThreshold)
return "LOG_FLUSH_THRESHOLD";
663 static ConfigurationType convertFromString(
const char* configStr)
665 if ((strcmp(configStr,
"ENABLED") == 0) || (strcmp(configStr,
"enabled") == 0))
666 return ConfigurationType::Enabled;
667 if ((strcmp(configStr,
"TO_FILE") == 0) || (strcmp(configStr,
"to_file") == 0))
668 return ConfigurationType::ToFile;
669 if ((strcmp(configStr,
"TO_STANDARD_OUTPUT") == 0) || (strcmp(configStr,
"to_standard_output") == 0))
670 return ConfigurationType::ToStandardOutput;
671 if ((strcmp(configStr,
"FORMAT") == 0) || (strcmp(configStr,
"format") == 0))
672 return ConfigurationType::Format;
673 if ((strcmp(configStr,
"FILENAME") == 0) || (strcmp(configStr,
"filename") == 0))
674 return ConfigurationType::Filename;
675 if ((strcmp(configStr,
"MILLISECONDS_WIDTH") == 0) || (strcmp(configStr,
"milliseconds_width") == 0))
676 return ConfigurationType::MillisecondsWidth;
677 if ((strcmp(configStr,
"PERFORMANCE_TRACKING") == 0) || (strcmp(configStr,
"performance_tracking") == 0))
678 return ConfigurationType::PerformanceTracking;
679 if ((strcmp(configStr,
"MAX_LOG_FILE_SIZE") == 0) || (strcmp(configStr,
"max_log_file_size") == 0))
680 return ConfigurationType::MaxLogFileSize;
681 if ((strcmp(configStr,
"LOG_FLUSH_THRESHOLD") == 0) || (strcmp(configStr,
"log_flush_threshold") == 0))
682 return ConfigurationType::LogFlushThreshold;
683 return ConfigurationType::Unknown;
690 static inline void forEachConfigType(base::type::EnumType* startIndex,
const std::function<
bool(
void)>& fn)
692 base::type::EnumType cIndexMax = ConfigurationTypeHelper::kMaxValid;
697 *startIndex =
static_cast<base::type::EnumType
>(*startIndex << 1);
698 }
while (*startIndex <= cIndexMax);
702 enum class LoggingFlag : base::type::EnumType {
704 NewLineForContainer = 1,
707 AllowVerboseIfModuleNotSpecified = 2,
709 LogDetailedCrashReason = 4,
711 DisableApplicationAbortOnFatalLog = 8,
715 StrictLogFileSizeCheck = 32,
717 ColoredTerminalOutput = 64,
719 MultiLoggerSupport = 128,
721 DisablePerformanceTrackingCheckpointComparison = 256,
723 DisableVModules = 512,
725 DisableVModulesExtensions = 1024,
727 HierarchicalLogging = 2048,
729 CreateLoggerAutomatically = 4096,
733 FixedTimeFormat = 16384
739 static const base::type::char_t* kInfoLevelLogValue = ELPP_LITERAL(
"INFO ");
740 static const base::type::char_t* kDebugLevelLogValue = ELPP_LITERAL(
"DEBUG");
741 static const base::type::char_t* kWarningLevelLogValue = ELPP_LITERAL(
"WARN ");
742 static const base::type::char_t* kErrorLevelLogValue = ELPP_LITERAL(
"ERROR");
743 static const base::type::char_t* kFatalLevelLogValue = ELPP_LITERAL(
"FATAL");
744 static const base::type::char_t* kVerboseLevelLogValue = ELPP_LITERAL(
"VER");
745 static const base::type::char_t* kTraceLevelLogValue = ELPP_LITERAL(
"TRACE");
746 static const base::type::char_t* kInfoLevelShortLogValue = ELPP_LITERAL(
"I");
747 static const base::type::char_t* kDebugLevelShortLogValue = ELPP_LITERAL(
"D");
748 static const base::type::char_t* kWarningLevelShortLogValue = ELPP_LITERAL(
"W");
749 static const base::type::char_t* kErrorLevelShortLogValue = ELPP_LITERAL(
"E");
750 static const base::type::char_t* kFatalLevelShortLogValue = ELPP_LITERAL(
"F");
751 static const base::type::char_t* kVerboseLevelShortLogValue = ELPP_LITERAL(
"V");
752 static const base::type::char_t* kTraceLevelShortLogValue = ELPP_LITERAL(
"T");
754 static const base::type::char_t* kAppNameFormatSpecifier = ELPP_LITERAL(
"%app");
755 static const base::type::char_t* kLoggerIdFormatSpecifier = ELPP_LITERAL(
"%logger");
756 static const base::type::char_t* kThreadIdFormatSpecifier = ELPP_LITERAL(
"%thread");
757 static const base::type::char_t* kSeverityLevelFormatSpecifier = ELPP_LITERAL(
"%level");
758 static const base::type::char_t* kSeverityLevelShortFormatSpecifier = ELPP_LITERAL(
"%levshort");
759 static const base::type::char_t* kDateTimeFormatSpecifier = ELPP_LITERAL(
"%datetime");
760 static const base::type::char_t* kLogFileFormatSpecifier = ELPP_LITERAL(
"%file");
761 static const base::type::char_t* kLogFileBaseFormatSpecifier = ELPP_LITERAL(
"%fbase");
762 static const base::type::char_t* kLogLineFormatSpecifier = ELPP_LITERAL(
"%line");
763 static const base::type::char_t* kLogLocationFormatSpecifier = ELPP_LITERAL(
"%loc");
764 static const base::type::char_t* kLogFunctionFormatSpecifier = ELPP_LITERAL(
"%func");
765 static const base::type::char_t* kCurrentUserFormatSpecifier = ELPP_LITERAL(
"%user");
766 static const base::type::char_t* kCurrentHostFormatSpecifier = ELPP_LITERAL(
"%host");
767 static const base::type::char_t* kMessageFormatSpecifier = ELPP_LITERAL(
"%msg");
768 static const base::type::char_t* kVerboseLevelFormatSpecifier = ELPP_LITERAL(
"%vlevel");
769 static const char* kDateTimeFormatSpecifierForFilename =
"%datetime";
771 static const char* kDays[7] = {
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday" };
772 static const char* kDaysAbbrev[7] = {
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat" };
773 static const char* kMonths[12] = {
"January",
"February",
"March",
"Apri",
"May",
"June",
"July",
"August",
774 "September",
"October",
"November",
"December"
776 static const char* kMonthsAbbrev[12] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec" };
777 static const char* kDefaultDateTimeFormat =
"%Y-%M-%d %H:%m:%s,%g";
778 static const char* kDefaultDateTimeFormatInFilename =
"%Y-%M-%d_%H-%m";
779 static const int kYearBase = 1900;
780 static const char* kAm =
"AM";
781 static const char* kPm =
"PM";
783 static const char* kDefaultLoggerId =
"default";
784 static const char* kPerformanceLoggerId =
"performance";
785 static const char* kSysLogLoggerId =
"syslog";
786 static const char* kNullPointer =
"nullptr";
787 static const char kFormatSpecifierChar =
'%';
788 #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
789 static const char kFormatSpecifierCharValue =
'v';
790 #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
791 static const unsigned int kMaxLogPerContainer = 100;
792 static const unsigned int kMaxLogPerCounter = 100000;
793 static const unsigned int kDefaultMillisecondsWidth = 3;
794 static const base::type::VerboseLevel kMaxVerboseLevel = 9;
795 static const char* kUnknownUser =
"user";
796 static const char* kUnknownHost =
"unknown-host";
797 #if defined(ELPP_DEFAULT_LOG_FILE)
798 static const char* kDefaultLogFile = ELPP_DEFAULT_LOG_FILE;
802 static const char* kDefaultLogFile =
"logs/myeasylog.log";
804 static const char* kDefaultLogFile =
"logs/myeasylog.log";
805 # endif // ELPP_OS_ANDROID
806 # elif ELPP_OS_WINDOWS
807 static const char* kDefaultLogFile =
"logs\\myeasylog.log";
808 # endif // ELPP_OS_UNIX
809 #endif // defined(ELPP_DEFAULT_LOG_FILE)
810 #if !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG)
811 static const char* kDefaultLogFileParam =
"--default-log-file";
812 #endif // !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG)
813 #if defined(ELPP_LOGGING_FLAGS_FROM_ARG)
814 static const char* kLoggingFlagsParam =
"--logging-flags";
815 #endif // defined(ELPP_LOGGING_FLAGS_FROM_ARG)
817 static const char* kFilePathSeperator =
"\\";
819 static const char* kFilePathSeperator =
"/";
820 #endif // ELPP_OS_WINDOWS
821 static const char* kValidLoggerIdSymbols =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._";
822 static const char* kConfigurationComment =
"##";
823 static const char* kConfigurationLevel =
"*";
824 static const char* kConfigurationLoggerId =
"--";
825 static const std::size_t kSourceFilenameMaxLength = 100;
826 static const std::size_t kSourceLineMaxLength = 10;
827 static const Level kPerformanceTrackerDefaultLevel = Level::Info;
830 const base::type::char_t*
unit;
832 { 1000.0f, ELPP_LITERAL(
"mis") },
833 { 1000.0f, ELPP_LITERAL(
"ms") },
834 { 60.0f, ELPP_LITERAL(
"seconds") },
835 { 60.0f, ELPP_LITERAL(
"minutes") },
836 { 24.0f, ELPP_LITERAL(
"hours") },
837 { 7.0f, ELPP_LITERAL(
"days") }
839 static const int kTimeFormatsCount =
sizeof(kTimeFormats) /
sizeof(kTimeFormats[0]);
845 } kCrashSignals[] = {
848 SIGABRT,
"SIGABRT",
"Abnormal termination",
849 "Program was abnormally terminated."
852 SIGFPE,
"SIGFPE",
"Erroneous arithmetic operation",
853 "Arithemetic operation issue such as division by zero or operation resulting in overflow."
856 SIGILL,
"SIGILL",
"Illegal instruction",
857 "Generally due to a corruption in the code or to an attempt to execute data."
860 SIGSEGV,
"SIGSEGV",
"Invalid access to memory",
861 "Program is trying to read an invalid (unallocated, deleted or corrupted) or inaccessible memory."
864 SIGINT,
"SIGINT",
"Interactive attention signal",
865 "Interruption generated (generally) by user or operating system."
868 static const int kCrashSignalsCount =
sizeof(kCrashSignals) /
sizeof(kCrashSignals[0]);
871 typedef std::function<void(const char*, std::size_t)> PreRollOutCallback;
873 static inline void defaultPreRollOutCallback(
const char*, std::size_t) {}
875 enum class TimestampUnit : base::type::EnumType {
876 Microsecond = 0, Millisecond = 1, Second = 2, Minute = 3, Hour = 4, Day = 5
879 enum class FormatFlags : base::type::EnumType {
880 DateTime = 1 << 1, LoggerId = 1 << 2, File = 1 << 3, Line = 1 << 4, Location = 1 << 5, Function = 1 << 6,
881 User = 1 << 7, Host = 1 << 8, LogMessage = 1 << 9, VerboseLevel = 1 << 10, AppName = 1 << 11, ThreadId = 1 << 12,
882 Level = 1 << 13, FileBase = 1 << 14, LevelShort = 1 << 15
885 class MillisecondsWidth
888 MillisecondsWidth(
void) { init(base::consts::kDefaultMillisecondsWidth); }
889 explicit MillisecondsWidth(
int width) { init(width); }
890 bool operator==(
const MillisecondsWidth& msWidth) {
return m_width == msWidth.m_width && m_offset == msWidth.m_offset; }
892 unsigned int m_offset;
896 if (width < 1 || width > 6) {
897 width = base::consts::kDefaultMillisecondsWidth;
922 template <
typename T>
924 typename std::enable_if<std::is_pointer<T*>::value,
void>::type
925 safeDelete(T*& pointer)
927 if (pointer ==
nullptr)
933 static inline const char* charPtrVal(
const char* pointer)
935 return pointer ==
nullptr ? base::consts::kNullPointer : pointer;
938 static inline void abort(
int status,
const std::string& reason = std::string())
943 #if defined(ELPP_COMPILER_MSVC) && defined(_M_IX86) && defined(_DEBUG)
948 #endif // defined(ELPP_COMPILER_MSVC) && defined(_M_IX86) && defined(_DEBUG)
953 template <
typename Enum>
954 static inline base::type::EnumType And(Enum e, base::type::EnumType flag)
956 return static_cast<base::type::EnumType
>(flag) & static_cast<base::type::EnumType>(e);
958 template <
typename Enum>
959 static inline base::type::EnumType Not(Enum e, base::type::EnumType flag)
961 return static_cast<base::type::EnumType
>(flag) & ~(static_cast<base::type::EnumType>(e));
963 template <
typename Enum>
964 static inline base::type::EnumType Or(Enum e, base::type::EnumType flag)
966 return static_cast<base::type::EnumType
>(flag) | static_cast<base::type::EnumType>(e);
969 template <
typename Enum>
970 static inline void addFlag(Enum e, base::type::EnumType* flag)
972 *flag = base::utils::bitwise::Or<Enum>(e, *flag);
974 template <
typename Enum>
975 static inline void removeFlag(Enum e, base::type::EnumType* flag)
977 *flag = base::utils::bitwise::Not<Enum>(e, *flag);
979 template <
typename Enum>
980 static inline bool hasFlag(Enum e, base::type::EnumType flag)
982 return base::utils::bitwise::And<Enum>(e, flag) > 0x0;
985 namespace threading {
986 #if ELPP_THREADING_ENABLED
987 # if !ELPP_USE_STD_THREADING
990 class Mutex : base::NoCopy
996 pthread_mutex_init(&m_underlyingMutex,
nullptr);
997 # elif ELPP_OS_WINDOWS
998 InitializeCriticalSection(&m_underlyingMutex);
999 # endif // ELPP_OS_UNIX
1002 virtual ~Mutex(
void)
1005 pthread_mutex_destroy(&m_underlyingMutex);
1006 # elif ELPP_OS_WINDOWS
1007 DeleteCriticalSection(&m_underlyingMutex);
1008 # endif // ELPP_OS_UNIX
1011 inline void lock(
void)
1014 pthread_mutex_lock(&m_underlyingMutex);
1015 # elif ELPP_OS_WINDOWS
1016 EnterCriticalSection(&m_underlyingMutex);
1017 # endif // ELPP_OS_UNIX
1020 inline bool try_lock(
void)
1023 return (pthread_mutex_trylock(&m_underlyingMutex) == 0);
1024 # elif ELPP_OS_WINDOWS
1025 return TryEnterCriticalSection(&m_underlyingMutex);
1026 # endif // ELPP_OS_UNIX
1029 inline void unlock(
void)
1032 pthread_mutex_unlock(&m_underlyingMutex);
1033 # elif ELPP_OS_WINDOWS
1034 LeaveCriticalSection(&m_underlyingMutex);
1035 # endif // ELPP_OS_UNIX
1040 pthread_mutex_t m_underlyingMutex;
1041 # elif ELPP_OS_WINDOWS
1042 CRITICAL_SECTION m_underlyingMutex;
1043 # endif // ELPP_OS_UNIX
1046 template <
typename M>
1047 class ScopedLock : base::NoCopy
1050 explicit ScopedLock(M& mutex)
1056 virtual ~ScopedLock(
void)
1066 static inline std::string getCurrentThreadId(
void)
1068 std::stringstream ss;
1069 # if (ELPP_OS_WINDOWS)
1070 ss << GetCurrentThreadId();
1071 # endif // (ELPP_OS_WINDOWS)
1074 static inline void msleep(
int)
1078 typedef base::threading::internal::Mutex Mutex;
1079 typedef base::threading::internal::ScopedLock<base::threading::Mutex> ScopedLock;
1081 static inline std::string getCurrentThreadId(
void)
1084 std::stringstream ss;
1085 ss << std::this_thread::get_id();
1088 static inline void msleep(
int ms)
1091 #if ELPP_ASYNC_LOGGING
1092 std::this_thread::sleep_for(std::chrono::milliseconds(ms));
1093 #endif // ELPP_ASYNC_LOGGING
1095 typedef std::mutex Mutex;
1096 typedef std::lock_guard<std::mutex> ScopedLock;
1097 # endif // !ELPP_USE_STD_THREADING
1099 namespace internal {
1101 class NoMutex : base::NoCopy
1105 inline void lock(
void) {}
1106 inline bool try_lock(
void) {
return true; }
1107 inline void unlock(
void) {}
1110 template <
typename Mutex>
1111 class NoScopedLock : base::NoCopy
1114 explicit NoScopedLock(Mutex&)
1117 virtual ~NoScopedLock(
void)
1124 static inline std::string getCurrentThreadId(
void)
1126 return std::string();
1128 static inline void msleep(
int)
1132 typedef base::threading::internal::NoMutex Mutex;
1133 typedef base::threading::internal::NoScopedLock<base::threading::Mutex> ScopedLock;
1134 #endif // ELPP_THREADING_ENABLED
1139 virtual inline void acquireLock(
void) ELPP_FINAL { m_mutex.lock(); }
1140 virtual inline void releaseLock(
void) ELPP_FINAL { m_mutex.unlock(); }
1141 virtual inline base::threading::Mutex& lock(
void) ELPP_FINAL {
return m_mutex; }
1144 virtual ~ThreadSafe(
void) {}
1146 base::threading::Mutex m_mutex;
1150 class File : base::StaticClass
1155 static base::type::fstream_t* newFileStream(
const std::string& filename)
1157 base::type::fstream_t* fs =
new base::type::fstream_t(filename.c_str(),
1158 base::type::fstream_t::out | base::type::fstream_t::app);
1159 #if defined(ELPP_UNICODE)
1160 std::locale elppUnicodeLocale(
"");
1162 std::locale elppUnicodeLocaleWindows(elppUnicodeLocale,
new std::codecvt_utf8_utf16<wchar_t>);
1163 elppUnicodeLocale = elppUnicodeLocaleWindows;
1165 fs->imbue(elppUnicodeLocale);
1166 #endif // defined(ELPP_UNICODE)
1167 if (fs->is_open()) {
1170 base::utils::safeDelete(fs);
1171 ELPP_INTERNAL_ERROR(
"Bad file [" << filename <<
"]",
true);
1177 static std::size_t getSizeOfFile(base::type::fstream_t* fs)
1179 if (fs ==
nullptr) {
1182 std::streampos currPos = fs->tellg();
1183 fs->seekg(0, fs->end);
1184 std::size_t
size =
static_cast<std::size_t
>(fs->tellg());
1190 static inline bool pathExists(
const char* path,
bool considerFile =
false)
1192 if (path ==
nullptr) {
1196 ELPP_UNUSED(considerFile);
1198 return (stat(path, &st) == 0);
1199 #elif ELPP_OS_WINDOWS
1200 DWORD fileType = GetFileAttributesA(path);
1201 if (fileType == INVALID_FILE_ATTRIBUTES) {
1204 return considerFile ?
true : ((fileType & FILE_ATTRIBUTE_DIRECTORY) == 0 ?
false :
true);
1205 #endif // ELPP_OS_UNIX
1210 static bool createPath(
const std::string& path)
1215 if (base::utils::File::pathExists(path.c_str())) {
1220 char* currPath =
const_cast<char*
>(path.c_str());
1221 std::string builtPath = std::string();
1223 if (path[0] ==
'/') {
1226 currPath = STRTOK(currPath, base::consts::kFilePathSeperator, 0);
1227 #elif ELPP_OS_WINDOWS
1229 char* nextTok_ =
nullptr;
1230 currPath = STRTOK(currPath, base::consts::kFilePathSeperator, &nextTok_);
1231 ELPP_UNUSED(nextTok_);
1232 #endif // ELPP_OS_UNIX
1233 while (currPath !=
nullptr) {
1234 builtPath.append(currPath);
1235 builtPath.append(base::consts::kFilePathSeperator);
1237 status = mkdir(builtPath.c_str(), ELPP_LOG_PERMS);
1238 currPath = STRTOK(
nullptr, base::consts::kFilePathSeperator, 0);
1239 #elif ELPP_OS_WINDOWS
1240 status = _mkdir(builtPath.c_str());
1241 currPath = STRTOK(
nullptr, base::consts::kFilePathSeperator, &nextTok_);
1242 #endif // ELPP_OS_UNIX
1245 ELPP_INTERNAL_ERROR(
"Error while creating path [" << path <<
"]",
true);
1251 static std::string extractPathFromFilename(
const std::string& fullPath,
1252 const char* seperator = base::consts::kFilePathSeperator)
1254 if ((fullPath ==
"") || (fullPath.find(seperator) == std::string::npos)) {
1257 std::size_t lastSlashAt = fullPath.find_last_of(seperator);
1258 if (lastSlashAt == 0) {
1259 return std::string(seperator);
1261 return fullPath.substr(0, lastSlashAt + 1);
1264 static void buildStrippedFilename(
const char* filename,
char buff[],
1265 std::size_t limit = base::consts::kSourceFilenameMaxLength)
1267 std::size_t sizeOfFilename = strlen(filename);
1268 if (sizeOfFilename >= limit) {
1269 filename += (sizeOfFilename - limit);
1270 if (filename[0] !=
'.' && filename[1] !=
'.') {
1272 STRCAT(buff,
"..", limit);
1275 STRCAT(buff, filename, limit);
1278 static void buildBaseFilename(
const std::string& fullPath,
char buff[],
1279 std::size_t limit = base::consts::kSourceFilenameMaxLength,
1280 const char* seperator = base::consts::kFilePathSeperator)
1282 const char* filename = fullPath.c_str();
1283 std::size_t lastSlashAt = fullPath.find_last_of(seperator);
1284 filename += lastSlashAt ? lastSlashAt + 1 : 0;
1285 std::size_t sizeOfFilename = strlen(filename);
1286 if (sizeOfFilename >= limit) {
1287 filename += (sizeOfFilename - limit);
1288 if (filename[0] !=
'.' && filename[1] !=
'.') {
1290 STRCAT(buff,
"..", limit);
1293 STRCAT(buff, filename, limit);
1297 class Str : base::StaticClass
1301 static inline bool isDigit(
char c)
1303 return c >=
'0' && c <=
'9';
1307 static bool wildCardMatch(
const char* str,
const char* pattern)
1318 if (wildCardMatch(str, pattern + 1))
1320 if (*str && wildCardMatch(str + 1, pattern))
1325 if (*str++ != *pattern++)
1330 return !*str && !*pattern;
1335 static inline std::string& ltrim(std::string& str)
1337 str.erase(str.begin(), std::find_if(str.begin(), str.end(), std::not1(std::ptr_fun<int, int>(&std::isspace))));
1343 static inline std::string& rtrim(std::string& str)
1345 str.erase(std::find_if(str.rbegin(), str.rend(), std::not1(std::ptr_fun<int, int>(&std::isspace))).base(), str.end());
1351 static inline std::string& trim(std::string& str)
1353 return ltrim(rtrim(str));
1360 static inline bool startsWith(
const std::string& str,
const std::string& start)
1362 return (str.length() >= start.length()) && (str.compare(0, start.length(), start) == 0);
1369 static inline bool endsWith(
const std::string& str,
const std::string& end)
1371 return (str.length() >= end.length()) && (str.compare(str.length() - end.length(), end.length(), end) == 0);
1379 static inline std::string& replaceAll(std::string& str,
char replaceWhat,
char replaceWith)
1381 std::replace(str.begin(), str.end(), replaceWhat, replaceWith);
1390 static inline std::string& replaceAll(std::string& str,
const std::string& replaceWhat,
1391 const std::string& replaceWith)
1393 if (replaceWhat == replaceWith)
1395 std::size_t foundAt = std::string::npos;
1396 while ((foundAt = str.find(replaceWhat, foundAt + 1)) != std::string::npos) {
1397 str.replace(foundAt, replaceWhat.length(), replaceWith);
1402 static void replaceFirstWithEscape(base::type::string_t& str,
const base::type::string_t& replaceWhat,
1403 const base::type::string_t& replaceWith)
1405 std::size_t foundAt = base::type::string_t::npos;
1406 while ((foundAt = str.find(replaceWhat, foundAt + 1)) != base::type::string_t::npos) {
1407 if (foundAt > 0 && str[foundAt - 1] == base::consts::kFormatSpecifierChar) {
1408 str.erase(foundAt > 0 ? foundAt - 1 : 0, 1);
1411 str.replace(foundAt, replaceWhat.length(), replaceWith);
1416 #if defined(ELPP_UNICODE)
1417 static void replaceFirstWithEscape(base::type::string_t& str,
const base::type::string_t& replaceWhat,
1418 const std::string& replaceWith)
1420 replaceFirstWithEscape(str, replaceWhat, base::type::string_t(replaceWith.begin(), replaceWith.end()));
1422 #endif // defined(ELPP_UNICODE)
1423 static inline std::string& toUpper(std::string& str)
1428 std::transform(str.begin(), str.end(), str.begin(), ::toupper);
1433 static inline bool cStringEq(
const char* s1,
const char* s2)
1435 if (s1 ==
nullptr && s2 ==
nullptr)
return true;
1436 if (s1 ==
nullptr || s2 ==
nullptr)
return false;
1437 return strcmp(s1, s2) == 0;
1442 static bool cStringCaseEq(
const char* s1,
const char* s2)
1444 if (s1 ==
nullptr && s2 ==
nullptr)
return true;
1445 if (s1 ==
nullptr || s2 ==
nullptr)
return false;
1446 if (strlen(s1) != strlen(s2))
return false;
1447 while (*s1 !=
'\0' && *s2 !=
'\0') {
1448 if (::toupper(*s1) != ::toupper(*s2))
return false;
1456 static inline bool contains(
const char* str,
char c)
1458 for (; *str; ++str) {
1465 static inline char* convertAndAddToBuff(std::size_t n,
int len,
char* buf,
const char* bufLim,
bool zeroPadded =
true)
1467 char localBuff[10] =
"";
1468 char* p = localBuff +
sizeof(localBuff) - 2;
1470 for (; n > 0 && p > localBuff && len > 0; n /= 10, --len)
1471 * --p = static_cast<char>(n % 10 +
'0');
1477 while (p > localBuff && len-- > 0) *--p =
static_cast<char>(
'0');
1478 return addToBuff(p, buf, bufLim);
1481 static inline char* addToBuff(
const char* str,
char* buf,
const char* bufLim)
1483 while ((buf < bufLim) && ((*buf = *str++) !=
'\0'))
1488 static inline char* clearBuff(
char buff[], std::size_t lim)
1490 STRCPY(buff,
"", lim);
1497 static char* wcharPtrToCharPtr(
const wchar_t* line)
1499 std::size_t len_ = wcslen(line) + 1;
1500 char* buff_ =
static_cast<char*
>(malloc(len_ + 1));
1501 # if ELPP_OS_UNIX || (ELPP_OS_WINDOWS && !ELPP_CRT_DBG_WARNINGS)
1502 std::wcstombs(buff_, line, len_);
1503 # elif ELPP_OS_WINDOWS
1504 std::size_t convCount_ = 0;
1506 ::memset(static_cast<void*>(&mbState_), 0,
sizeof(mbState_));
1507 wcsrtombs_s(&convCount_, buff_, len_, &line, len_, &mbState_);
1508 # endif // ELPP_OS_UNIX || (ELPP_OS_WINDOWS && !ELPP_CRT_DBG_WARNINGS)
1513 class OS : base::StaticClass
1517 static const char* getWindowsEnvironmentVariable(
const char* varname)
1523 const DWORD bufferLen = 50;
1524 static char buffer[bufferLen];
1525 if (GetEnvironmentVariableA(varname, buffer, bufferLen)) {
1530 #endif // ELPP_OS_WINDOWS
1532 static inline std::string getProperty(
const char* prop)
1535 char propVal[PROP_VALUE_MAX + 1];
1536 int ret = __system_property_get(prop, propVal);
1537 return ret == 0 ? std::string() : std::string(propVal);
1541 static std::string getDeviceName(
void)
1543 std::stringstream ss;
1544 std::string manufacturer = getProperty(
"ro.product.manufacturer");
1545 std::string model = getProperty(
"ro.product.model");
1546 if (manufacturer.empty() || model.empty()) {
1547 return std::string();
1549 ss << manufacturer <<
"-" << model;
1552 #endif // ELPP_OS_ANDROID
1559 static const std::string getBashOutput(
const char* command)
1561 #if (ELPP_OS_UNIX && !ELPP_OS_ANDROID && !ELPP_CYGWIN)
1562 if (command ==
nullptr) {
1563 return std::string();
1565 FILE* proc =
nullptr;
1566 if ((proc = popen(command,
"r")) ==
nullptr) {
1567 ELPP_INTERNAL_ERROR(
"\nUnable to run command [" << command <<
"]",
true);
1568 return std::string();
1571 if (fgets(hBuff,
sizeof(hBuff), proc) !=
nullptr) {
1573 if (hBuff[strlen(hBuff) - 1] ==
'\n') {
1574 hBuff[strlen(hBuff) - 1] =
'\0';
1576 return std::string(hBuff);
1578 return std::string();
1580 ELPP_UNUSED(command);
1581 return std::string();
1582 #endif // (ELPP_OS_UNIX && !ELPP_OS_ANDROID && !ELPP_CYGWIN)
1590 static std::string getEnvironmentVariable(
const char* variableName,
const char* defaultVal,
const char* alternativeBashCommand =
nullptr)
1593 const char* val = getenv(variableName);
1594 #elif ELPP_OS_WINDOWS
1595 const char* val = getWindowsEnvironmentVariable(variableName);
1596 #endif // ELPP_OS_UNIX
1597 if ((val ==
nullptr) || ((strcmp(val,
"") == 0))) {
1598 #if ELPP_OS_UNIX && defined(ELPP_FORCE_ENV_VAR_FROM_BASH)
1600 std::string valBash = base::utils::OS::getBashOutput(alternativeBashCommand);
1601 if (valBash.empty()) {
1602 return std::string(defaultVal);
1606 #elif ELPP_OS_WINDOWS || ELPP_OS_UNIX
1607 ELPP_UNUSED(alternativeBashCommand);
1608 return std::string(defaultVal);
1609 #endif // ELPP_OS_UNIX && defined(ELPP_FORCE_ENV_VAR_FROM_BASH)
1611 return std::string(val);
1614 static inline std::string currentUser(
void)
1616 #if ELPP_OS_UNIX && !ELPP_OS_ANDROID
1617 return getEnvironmentVariable(
"USER", base::consts::kUnknownUser,
"whoami");
1618 #elif ELPP_OS_WINDOWS
1619 return getEnvironmentVariable(
"USERNAME", base::consts::kUnknownUser);
1620 #elif ELPP_OS_ANDROID
1621 ELPP_UNUSED(base::consts::kUnknownUser);
1622 return std::string(
"android");
1624 return std::string();
1625 #endif // ELPP_OS_UNIX && !ELPP_OS_ANDROID
1631 static inline std::string currentHost(
void)
1633 #if ELPP_OS_UNIX && !ELPP_OS_ANDROID
1634 return getEnvironmentVariable(
"HOSTNAME", base::consts::kUnknownHost,
"hostname");
1635 #elif ELPP_OS_WINDOWS
1636 return getEnvironmentVariable(
"COMPUTERNAME", base::consts::kUnknownHost);
1637 #elif ELPP_OS_ANDROID
1638 ELPP_UNUSED(base::consts::kUnknownHost);
1639 return getDeviceName();
1641 return std::string();
1642 #endif // ELPP_OS_UNIX && !ELPP_OS_ANDROID
1645 static inline bool termSupportsColor(
void)
1647 std::string term = getEnvironmentVariable(
"TERM",
"");
1648 return term ==
"xterm" || term ==
"xterm-color" || term ==
"xterm-256color" ||
1649 term ==
"screen" || term ==
"linux" || term ==
"cygwin";
1652 extern std::string s_currentUser;
1653 extern std::string s_currentHost;
1654 extern bool s_termSupportsColor;
1655 #define ELPP_INITI_BASIC_DECLR \
1659 std::string s_currentUser = el::base::utils::OS::currentUser(); \
1660 std::string s_currentHost = el::base::utils::OS::currentHost(); \
1661 bool s_termSupportsColor = el::base::utils::OS::termSupportsColor(); \
1665 class DateTime : base::StaticClass
1673 static void gettimeofday(
struct timeval* tv)
1676 if (tv !=
nullptr) {
1677 # if ELPP_COMPILER_MSVC || defined(_MSC_EXTENSIONS)
1678 const unsigned __int64 delta_ = 11644473600000000Ui64;
1680 const unsigned __int64 delta_ = 11644473600000000ULL;
1681 # endif // ELPP_COMPILER_MSVC || defined(_MSC_EXTENSIONS)
1682 const double secOffSet = 0.000001;
1683 const unsigned long usecOffSet = 1000000;
1685 GetSystemTimeAsFileTime(&fileTime);
1686 unsigned __int64 present = 0;
1687 present |= fileTime.dwHighDateTime;
1688 present = present << 32;
1689 present |= fileTime.dwLowDateTime;
1693 tv->tv_sec =
static_cast<long>(present * secOffSet);
1694 tv->tv_usec =
static_cast<long>(present % usecOffSet);
1697 ::gettimeofday(tv,
nullptr);
1698 #endif // ELPP_OS_WINDOWS
1705 static inline std::string getDateTime(
const char* format,
const base::MillisecondsWidth* msWidth)
1707 struct timeval currTime;
1708 gettimeofday(&currTime);
1709 struct ::tm timeInfo;
1710 buildTimeInfo(&currTime, &timeInfo);
1711 const int kBuffSize = 30;
1712 char buff_[kBuffSize] =
"";
1713 parseFormat(buff_, kBuffSize, format, &timeInfo, static_cast<std::size_t>(currTime.tv_usec / msWidth->m_offset), msWidth);
1714 return std::string(buff_);
1718 static base::type::string_t formatTime(
unsigned long long time, base::TimestampUnit timestampUnit)
1720 double result =
static_cast<double>(time);
1721 base::type::EnumType start =
static_cast<base::type::EnumType
>(timestampUnit);
1722 const base::type::char_t*
unit = base::consts::kTimeFormats[start].unit;
1723 for (base::type::EnumType i = start; i < base::consts::kTimeFormatsCount - 1; ++i) {
1724 if (result <= base::consts::kTimeFormats[i].value) {
1727 result /= base::consts::kTimeFormats[i].value;
1728 unit = base::consts::kTimeFormats[i + 1].unit;
1730 base::type::stringstream_t ss;
1731 ss << result <<
" " <<
unit;
1736 static inline unsigned long long getTimeDifference(
const struct timeval& endTime,
const struct timeval& startTime, base::TimestampUnit timestampUnit)
1738 if (timestampUnit == base::TimestampUnit::Microsecond) {
1739 return static_cast<unsigned long long>(
static_cast<unsigned long long>(1000000 * endTime.tv_sec + endTime.tv_usec) -
1740 static_cast<unsigned long long>(1000000 * startTime.tv_sec + startTime.tv_usec));
1742 return static_cast<unsigned long long>((((endTime.tv_sec - startTime.tv_sec) * 1000000) + (endTime.tv_usec - startTime.tv_usec)) / 1000);
1747 static inline struct ::tm* buildTimeInfo(
struct timeval* currTime, struct ::tm* timeInfo)
1750 time_t rawTime = currTime->tv_sec;
1751 ::localtime_r(&rawTime, timeInfo);
1754 # if ELPP_COMPILER_MSVC
1755 ELPP_UNUSED(currTime);
1758 localtime_s(timeInfo, &t);
1762 time_t rawTime = currTime->tv_sec;
1763 struct tm* tmInf = localtime(&rawTime);
1766 # endif // ELPP_COMPILER_MSVC
1767 #endif // ELPP_OS_UNIX
1769 static char* parseFormat(
char* buf, std::size_t bufSz,
const char* format,
const struct tm* tInfo,
1770 std::size_t msec,
const base::MillisecondsWidth* msWidth)
1772 const char* bufLim = buf + bufSz;
1773 for (; *format; ++format) {
1774 if (*format == base::consts::kFormatSpecifierChar) {
1775 switch (*++format) {
1776 case base::consts::kFormatSpecifierChar:
1782 buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_mday, 2, buf, bufLim);
1785 buf = base::utils::Str::addToBuff(base::consts::kDaysAbbrev[tInfo->tm_wday], buf, bufLim);
1788 buf = base::utils::Str::addToBuff(base::consts::kDays[tInfo->tm_wday], buf, bufLim);
1791 buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_mon + 1, 2, buf, bufLim);
1794 buf = base::utils::Str::addToBuff(base::consts::kMonthsAbbrev[tInfo->tm_mon], buf, bufLim);
1797 buf = base::utils::Str::addToBuff(base::consts::kMonths[tInfo->tm_mon], buf, bufLim);
1800 buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_year + base::consts::kYearBase, 2, buf, bufLim);
1803 buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_year + base::consts::kYearBase, 4, buf, bufLim);
1806 buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_hour % 12, 2, buf, bufLim);
1809 buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_hour, 2, buf, bufLim);
1812 buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_min, 2, buf, bufLim);
1815 buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_sec, 2, buf, bufLim);
1819 buf = base::utils::Str::convertAndAddToBuff(msec, msWidth->m_width, buf, bufLim);
1822 buf = base::utils::Str::addToBuff((tInfo->tm_hour >= 12) ? base::consts::kPm : base::consts::kAm, buf, bufLim);
1828 if (buf == bufLim)
break;
1835 class CommandLineArgs
1838 CommandLineArgs(
void)
1840 setArgs(0, static_cast<char**>(
nullptr));
1842 CommandLineArgs(
int argc,
const char** argv)
1844 setArgs(argc, argv);
1846 CommandLineArgs(
int argc,
char** argv)
1848 setArgs(argc, argv);
1850 virtual ~CommandLineArgs(
void) {}
1852 inline void setArgs(
int argc,
const char** argv)
1854 setArgs(argc, const_cast<char**>(argv));
1857 inline void setArgs(
int argc,
char** argv)
1860 m_paramsWithValue.clear();
1861 if (argc == 0 || argv ==
nullptr) {
1866 for (
int i = 1; i < m_argc; ++i) {
1867 const char* v = (strstr(m_argv[i],
"="));
1868 if (v !=
nullptr && strlen(v) > 0) {
1869 std::string key = std::string(m_argv[i]);
1870 key = key.substr(0, key.find_first_of(
'='));
1871 if (hasParamWithValue(key.c_str())) {
1872 ELPP_INTERNAL_INFO(1,
"Skipping [" << key <<
"] arg since it already has value ["
1873 << getParamValue(key.c_str()) <<
"]");
1875 m_paramsWithValue.insert(std::make_pair(key, std::string(v + 1)));
1879 if (hasParam(m_argv[i])) {
1880 ELPP_INTERNAL_INFO(1,
"Skipping [" << m_argv[i] <<
"] arg since it already exists");
1882 m_params.push_back(std::string(m_argv[i]));
1888 inline bool hasParamWithValue(
const char* paramKey)
const
1890 return m_paramsWithValue.find(std::string(paramKey)) != m_paramsWithValue.end();
1894 inline const char* getParamValue(
const char* paramKey)
const
1896 return m_paramsWithValue.find(std::string(paramKey))->second.c_str();
1899 inline bool hasParam(
const char* paramKey)
const
1901 return std::find(m_params.begin(), m_params.end(), std::string(paramKey)) != m_params.end();
1904 inline bool empty(
void)
const
1906 return m_params.empty() && m_paramsWithValue.empty();
1909 inline std::size_t
size(
void)
const
1911 return m_params.size() + m_paramsWithValue.size();
1913 inline friend base::type::ostream_t&
operator<<(base::type::ostream_t& os,
const CommandLineArgs& c)
1915 for (
int i = 1; i < c.m_argc; ++i) {
1916 os << ELPP_LITERAL(
"[") << c.m_argv[i] << ELPP_LITERAL(
"]");
1917 if (i < c.m_argc - 1) {
1918 os << ELPP_LITERAL(
" ");
1927 std::map<std::string, std::string> m_paramsWithValue;
1928 std::vector<std::string> m_params;
1936 template <
typename T_Ptr,
typename Container>
1937 class AbstractRegistry :
public base::threading::ThreadSafe
1940 typedef typename Container::iterator iterator;
1941 typedef typename Container::const_iterator const_iterator;
1944 AbstractRegistry(
void) {}
1947 AbstractRegistry(AbstractRegistry&& sr)
1953 m_list = std::move(sr.m_list);
1956 bool operator==(
const AbstractRegistry<T_Ptr, Container>& other)
1958 if (
size() != other.size()) {
1961 for (std::size_t i = 0; i < m_list.size(); ++i) {
1962 if (m_list.at(i) != other.m_list.at(i)) {
1969 bool operator!=(
const AbstractRegistry<T_Ptr, Container>& other)
1971 if (
size() != other.size()) {
1974 for (std::size_t i = 0; i < m_list.size(); ++i) {
1975 if (m_list.at(i) != other.m_list.at(i)) {
1983 AbstractRegistry& operator=(AbstractRegistry&& sr)
1989 m_list = std::move(sr.m_list);
1993 virtual ~AbstractRegistry(
void)
1998 virtual inline iterator begin(
void) ELPP_FINAL {
1999 return m_list.begin();
2003 virtual inline iterator end(
void) ELPP_FINAL {
2004 return m_list.end();
2009 virtual inline const_iterator cbegin(
void) const ELPP_FINAL
2011 return m_list.cbegin();
2015 virtual inline const_iterator cend(
void) const ELPP_FINAL
2017 return m_list.cend();
2021 virtual inline bool empty(
void) const ELPP_FINAL
2023 return m_list.empty();
2027 virtual inline std::size_t
size(
void) const ELPP_FINAL
2029 return m_list.size();
2033 virtual inline Container& list(
void) ELPP_FINAL {
2038 virtual inline const Container& list(
void) const ELPP_FINAL
2044 virtual void unregisterAll(
void) = 0;
2047 virtual void deepCopy(
const AbstractRegistry<T_Ptr, Container>&) = 0;
2048 void reinitDeepCopy(
const AbstractRegistry<T_Ptr, Container>& sr)
2063 template <
typename T_Ptr,
typename T_Key = const
char*>
2064 class Registry :
public AbstractRegistry<T_Ptr, std::map<T_Key, T_Ptr*>>
2067 typedef typename Registry<T_Ptr, T_Key>::iterator iterator;
2068 typedef typename Registry<T_Ptr, T_Key>::const_iterator const_iterator;
2073 Registry(
const Registry& sr) : AbstractRegistry<T_Ptr, std::vector<T_Ptr * >>()
2078 this->reinitDeepCopy(sr);
2084 Registry& operator=(
const Registry& sr)
2089 this->reinitDeepCopy(sr);
2093 virtual ~Registry(
void)
2099 virtual inline void unregisterAll(
void) ELPP_FINAL {
2102 for (
auto && curr : this->list()) {
2103 base::utils::safeDelete(curr.second);
2105 this->list().clear();
2110 virtual inline void registerNew(
const T_Key& uniqKey, T_Ptr* ptr) ELPP_FINAL {
2111 unregister(uniqKey);
2112 this->list().insert(std::make_pair(uniqKey, ptr));
2116 inline void unregister(
const T_Key& uniqKey)
2118 T_Ptr* existing =
get(uniqKey);
2119 if (existing !=
nullptr) {
2120 base::utils::safeDelete(existing);
2121 this->list().erase(uniqKey);
2126 inline T_Ptr*
get(
const T_Key& uniqKey)
2128 iterator it = this->list().find(uniqKey);
2129 return it == this->list().end()
2135 virtual inline void deepCopy(
const AbstractRegistry<T_Ptr, std::map<T_Key, T_Ptr*>>& sr) ELPP_FINAL {
2136 for (const_iterator it = sr.cbegin(); it != sr.cend(); ++it)
2138 registerNew(it->first,
new T_Ptr(*it->second));
2147 template <
typename T_Ptr,
typename Pred>
2148 class RegistryWithPred :
public AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>
2151 typedef typename RegistryWithPred<T_Ptr, Pred>::iterator iterator;
2152 typedef typename RegistryWithPred<T_Ptr, Pred>::const_iterator const_iterator;
2154 RegistryWithPred(
void)
2158 virtual ~RegistryWithPred(
void)
2164 RegistryWithPred(
const RegistryWithPred& sr) : AbstractRegistry<T_Ptr, std::vector<T_Ptr * >>()
2169 this->reinitDeepCopy(sr);
2175 RegistryWithPred& operator=(
const RegistryWithPred& sr)
2180 this->reinitDeepCopy(sr);
2184 friend inline base::type::ostream_t&
operator<<(base::type::ostream_t& os,
const RegistryWithPred& sr)
2186 for (const_iterator it = sr.list().begin(); it != sr.list().end(); ++it) {
2187 os << ELPP_LITERAL(
" ") << **it << ELPP_LITERAL(
"\n");
2193 virtual inline void unregisterAll(
void) ELPP_FINAL {
2196 for (
auto && curr : this->list()) {
2197 base::utils::safeDelete(curr);
2199 this->list().clear();
2203 virtual void unregister(T_Ptr*& ptr) ELPP_FINAL {
2206 iterator iter = this->begin();
2207 for (; iter != this->end(); ++iter) {
2212 if (iter != this->end() && *iter !=
nullptr) {
2213 this->list().erase(iter);
2214 base::utils::safeDelete(*iter);
2219 virtual inline void registerNew(T_Ptr* ptr) ELPP_FINAL {
2220 this->list().push_back(ptr);
2225 template <
typename T,
typename T2>
2226 inline T_Ptr*
get(
const T& arg1,
const T2 arg2)
2228 iterator iter = std::find_if(this->list().begin(), this->list().end(), Pred(arg1, arg2));
2229 if (iter != this->list().end() && *iter !=
nullptr) {
2236 virtual inline void deepCopy(
const AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>& sr)
2238 for (const_iterator it = sr.list().begin(); it != sr.list().end(); ++it) {
2239 registerNew(
new T_Ptr(**it));
2252 virtual ~Loggable(
void) {}
2253 virtual void log(el::base::type::ostream_t&)
const = 0;
2255 friend inline el::base::type::ostream_t&
operator<<(el::base::type::ostream_t& os,
const Loggable& loggable)
2263 class LogFormat :
public Loggable
2267 m_level(Level::Unknown),
2268 m_userFormat(base::type::string_t()),
2269 m_format(base::type::string_t()),
2270 m_dateTimeFormat(std::string()),
2275 LogFormat(Level level,
const base::type::string_t& format)
2276 : m_level(level), m_userFormat(format)
2278 parseFromFormat(m_userFormat);
2281 LogFormat(
const LogFormat& logFormat)
2283 m_level = logFormat.m_level;
2284 m_userFormat = logFormat.m_userFormat;
2285 m_format = logFormat.m_format;
2286 m_dateTimeFormat = logFormat.m_dateTimeFormat;
2287 m_flags = logFormat.m_flags;
2290 LogFormat(LogFormat&& logFormat)
2292 m_level = std::move(logFormat.m_level);
2293 m_userFormat = std::move(logFormat.m_userFormat);
2294 m_format = std::move(logFormat.m_format);
2295 m_dateTimeFormat = std::move(logFormat.m_dateTimeFormat);
2296 m_flags = std::move(logFormat.m_flags);
2299 LogFormat& operator=(
const LogFormat& logFormat)
2301 m_level = logFormat.m_level;
2302 m_userFormat = logFormat.m_userFormat;
2303 m_dateTimeFormat = logFormat.m_dateTimeFormat;
2304 m_flags = logFormat.m_flags;
2308 virtual ~LogFormat(
void)
2312 inline bool operator==(
const LogFormat& other)
2314 return m_level == other.m_level && m_userFormat == other.m_userFormat && m_format == other.m_format &&
2315 m_dateTimeFormat == other.m_dateTimeFormat && m_flags == other.m_flags;
2320 void parseFromFormat(
const base::type::string_t& userFormat)
2325 base::type::string_t formatCopy = userFormat;
2327 auto conditionalAddFlag = [&](
const base::type::char_t* specifier, base::FormatFlags flag) {
2328 std::size_t foundAt = base::type::string_t::npos;
2329 while ((foundAt = formatCopy.find(specifier, foundAt + 1)) != base::type::string_t::npos) {
2330 if (foundAt > 0 && formatCopy[foundAt - 1] == base::consts::kFormatSpecifierChar) {
2331 if (hasFlag(flag)) {
2334 formatCopy.erase(foundAt > 0 ? foundAt - 1 : 0, 1);
2338 if (!hasFlag(flag)) addFlag(flag);
2342 conditionalAddFlag(base::consts::kAppNameFormatSpecifier, base::FormatFlags::AppName);
2343 conditionalAddFlag(base::consts::kSeverityLevelFormatSpecifier, base::FormatFlags::Level);
2344 conditionalAddFlag(base::consts::kSeverityLevelShortFormatSpecifier, base::FormatFlags::LevelShort);
2345 conditionalAddFlag(base::consts::kLoggerIdFormatSpecifier, base::FormatFlags::LoggerId);
2346 conditionalAddFlag(base::consts::kThreadIdFormatSpecifier, base::FormatFlags::ThreadId);
2347 conditionalAddFlag(base::consts::kLogFileFormatSpecifier, base::FormatFlags::File);
2348 conditionalAddFlag(base::consts::kLogFileBaseFormatSpecifier, base::FormatFlags::FileBase);
2349 conditionalAddFlag(base::consts::kLogLineFormatSpecifier, base::FormatFlags::Line);
2350 conditionalAddFlag(base::consts::kLogLocationFormatSpecifier, base::FormatFlags::Location);
2351 conditionalAddFlag(base::consts::kLogFunctionFormatSpecifier, base::FormatFlags::Function);
2352 conditionalAddFlag(base::consts::kCurrentUserFormatSpecifier, base::FormatFlags::User);
2353 conditionalAddFlag(base::consts::kCurrentHostFormatSpecifier, base::FormatFlags::Host);
2354 conditionalAddFlag(base::consts::kMessageFormatSpecifier, base::FormatFlags::LogMessage);
2355 conditionalAddFlag(base::consts::kVerboseLevelFormatSpecifier, base::FormatFlags::VerboseLevel);
2357 std::size_t dateIndex = std::string::npos;
2358 if ((dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier)) != std::string::npos) {
2359 while (dateIndex > 0 && formatCopy[dateIndex - 1] == base::consts::kFormatSpecifierChar) {
2360 dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier, dateIndex + 1);
2362 if (dateIndex != std::string::npos) {
2363 addFlag(base::FormatFlags::DateTime);
2364 updateDateFormat(dateIndex, formatCopy);
2367 m_format = formatCopy;
2371 inline Level level(
void)
const
2376 inline const base::type::string_t& userFormat(
void)
const
2378 return m_userFormat;
2381 inline const base::type::string_t& format(
void)
const
2386 inline const std::string& dateTimeFormat(
void)
const
2388 return m_dateTimeFormat;
2391 inline base::type::EnumType flags(
void)
const
2396 inline bool hasFlag(base::FormatFlags flag)
const
2398 return base::utils::hasFlag(flag, m_flags);
2401 virtual void log(el::base::type::ostream_t& os)
const
2410 virtual void updateDateFormat(std::size_t index, base::type::string_t& currFormat) ELPP_FINAL {
2411 if (hasFlag(base::FormatFlags::DateTime))
2413 index += ELPP_STRLEN(base::consts::kDateTimeFormatSpecifier);
2415 const base::type::char_t* ptr = currFormat.c_str() + index;
2416 if ((currFormat.size() > index) && (ptr[0] ==
'{'))
2421 std::stringstream ss;
2422 for (; *ptr; ++ptr, ++count) {
2429 currFormat.erase(index, count);
2430 m_dateTimeFormat = ss.str();
2433 if (hasFlag(base::FormatFlags::DateTime))
2435 m_dateTimeFormat = std::string(base::consts::kDefaultDateTimeFormat);
2441 virtual void updateFormatSpec(
void) ELPP_FINAL {
2443 if (m_level == Level::Debug)
2445 base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier,
2446 base::consts::kDebugLevelLogValue);
2447 base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier,
2448 base::consts::kDebugLevelShortLogValue);
2449 }
else if (m_level == Level::Info)
2451 base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier,
2452 base::consts::kInfoLevelLogValue);
2453 base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier,
2454 base::consts::kInfoLevelShortLogValue);
2455 }
else if (m_level == Level::Warning)
2457 base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier,
2458 base::consts::kWarningLevelLogValue);
2459 base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier,
2460 base::consts::kWarningLevelShortLogValue);
2461 }
else if (m_level == Level::Error)
2463 base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier,
2464 base::consts::kErrorLevelLogValue);
2465 base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier,
2466 base::consts::kErrorLevelShortLogValue);
2467 }
else if (m_level == Level::Fatal)
2469 base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier,
2470 base::consts::kFatalLevelLogValue);
2471 base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier,
2472 base::consts::kFatalLevelShortLogValue);
2473 }
else if (m_level == Level::Verbose)
2475 base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier,
2476 base::consts::kVerboseLevelLogValue);
2477 base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier,
2478 base::consts::kVerboseLevelShortLogValue);
2479 }
else if (m_level == Level::Trace)
2481 base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier,
2482 base::consts::kTraceLevelLogValue);
2483 base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier,
2484 base::consts::kTraceLevelShortLogValue);
2486 if (hasFlag(base::FormatFlags::User))
2488 std::string s = base::utils::s_currentUser;
2489 base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kCurrentUserFormatSpecifier,
2490 base::utils::s_currentUser);
2492 if (hasFlag(base::FormatFlags::Host))
2494 base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kCurrentHostFormatSpecifier,
2495 base::utils::s_currentHost);
2500 inline void addFlag(base::FormatFlags flag)
2502 base::utils::addFlag(flag, &m_flags);
2507 base::type::string_t m_userFormat;
2508 base::type::string_t m_format;
2509 std::string m_dateTimeFormat;
2510 base::type::EnumType m_flags;
2511 friend class el::Logger;
2515 typedef std::function<const char* (void)> FormatSpecifierValueResolver;
2519 class CustomFormatSpecifier
2522 CustomFormatSpecifier(
const char* formatSpecifier,
const FormatSpecifierValueResolver& resolver) :
2523 m_formatSpecifier(formatSpecifier), m_resolver(resolver) {}
2524 inline const char* formatSpecifier(
void)
const {
return m_formatSpecifier; }
2525 inline const FormatSpecifierValueResolver& resolver(
void)
const {
return m_resolver; }
2526 inline bool operator==(
const char* formatSpecifier)
2528 return strcmp(m_formatSpecifier, formatSpecifier) == 0;
2532 const char* m_formatSpecifier;
2533 FormatSpecifierValueResolver m_resolver;
2544 class Configuration :
public Loggable
2547 Configuration(
const Configuration& c) :
2549 m_configurationType(c.m_configurationType),
2554 Configuration& operator=(
const Configuration& c)
2556 m_level = c.m_level;
2557 m_configurationType = c.m_configurationType;
2558 m_value = c.m_value;
2562 virtual ~Configuration(
void)
2567 Configuration(Level level, ConfigurationType configurationType,
const std::string& value) :
2569 m_configurationType(configurationType),
2575 inline Level level(
void)
const
2581 inline ConfigurationType configurationType(
void)
const
2583 return m_configurationType;
2587 inline const std::string& value(
void)
const
2595 inline void setValue(
const std::string& value)
2600 virtual inline void log(el::base::type::ostream_t& os)
const
2602 os << LevelHelper::convertToString(m_level)
2603 << ELPP_LITERAL(
" ") << ConfigurationTypeHelper::convertToString(m_configurationType)
2604 << ELPP_LITERAL(
" = ") << m_value.c_str();
2611 Predicate(Level level, ConfigurationType configurationType) :
2613 m_configurationType(configurationType)
2617 inline bool operator()(
const Configuration* conf)
const
2619 return ((conf !=
nullptr) && (conf->level() == m_level) && (conf->configurationType() == m_configurationType));
2624 ConfigurationType m_configurationType;
2629 ConfigurationType m_configurationType;
2630 std::string m_value;
2636 class Configurations :
public base::utils::RegistryWithPred<Configuration, Configuration::Predicate>
2640 Configurations(
void) :
2641 m_configurationFile(std::string()),
2652 Configurations(
const std::string& configurationFile,
bool useDefaultsForRemaining =
true, Configurations* base =
nullptr) :
2653 m_configurationFile(configurationFile),
2656 parseFromFile(configurationFile, base);
2657 if (useDefaultsForRemaining) {
2658 setRemainingToDefault();
2662 virtual ~Configurations(
void)
2672 inline bool parseFromFile(
const std::string& configurationFile, Configurations* base =
nullptr)
2676 bool assertionPassed =
true;
2677 ELPP_ASSERT((assertionPassed = base::utils::File::pathExists(configurationFile.c_str(),
true)),
2678 "Configuration file [" << configurationFile <<
"] does not exist!");
2679 if (!assertionPassed) {
2682 bool success = Parser::parseFromFile(configurationFile,
this, base);
2683 m_isFromFile = success;
2695 inline bool parseFromText(
const std::string& configurationsString, Configurations* base =
nullptr)
2697 bool success = Parser::parseFromText(configurationsString,
this, base);
2699 m_isFromFile =
false;
2706 inline void setFromBase(Configurations* base)
2708 if (base ==
nullptr || base ==
this) {
2711 base::threading::ScopedLock scopedLock(base->lock());
2712 for (Configuration*& conf : base->list()) {
2721 bool hasConfiguration(ConfigurationType configurationType)
2723 base::type::EnumType lIndex = LevelHelper::kMinValid;
2724 bool result =
false;
2725 LevelHelper::forEachLevel(&lIndex, [&](
void) ->
bool {
2726 if (hasConfiguration(LevelHelper::castFromInt(lIndex), configurationType))
2738 inline bool hasConfiguration(Level level, ConfigurationType configurationType)
2740 base::threading::ScopedLock scopedLock(lock());
2741 #if ELPP_COMPILER_INTEL
2744 return RegistryWithPred::get(level, configurationType) !=
nullptr;
2746 return RegistryWithPred<Configuration, Configuration::Predicate>::get(level, configurationType) !=
nullptr;
2747 #endif // ELPP_COMPILER_INTEL
2762 inline void set(Level level, ConfigurationType configurationType,
const std::string& value)
2764 base::threading::ScopedLock scopedLock(lock());
2765 unsafeSet(level, configurationType, value);
2766 if (level == Level::Global) {
2767 unsafeSetGlobally(configurationType, value,
false);
2773 inline void set(Configuration* conf)
2775 if (conf ==
nullptr) {
2778 set(conf->level(), conf->configurationType(), conf->value());
2781 inline Configuration*
get(Level level, ConfigurationType configurationType)
2783 base::threading::ScopedLock scopedLock(lock());
2784 return RegistryWithPred<Configuration, Configuration::Predicate>::get(level, configurationType);
2791 inline void setGlobally(ConfigurationType configurationType,
const std::string& value)
2793 setGlobally(configurationType, value,
false);
2797 inline void clear(
void)
2799 base::threading::ScopedLock scopedLock(lock());
2806 inline const std::string& configurationFile(
void)
const
2808 return m_configurationFile;
2812 void setToDefault(
void)
2814 setGlobally(ConfigurationType::Enabled, std::string(
"true"),
true);
2815 #if !defined(ELPP_NO_DEFAULT_LOG_FILE)
2816 setGlobally(ConfigurationType::Filename, std::string(base::consts::kDefaultLogFile),
true);
2818 ELPP_UNUSED(base::consts::kDefaultLogFile);
2819 #endif // !defined(ELPP_NO_DEFAULT_LOG_FILE)
2820 setGlobally(ConfigurationType::ToFile, std::string(
"false"),
true);
2821 setGlobally(ConfigurationType::ToStandardOutput, std::string(
"true"),
true);
2822 setGlobally(ConfigurationType::MillisecondsWidth, std::string(
"3"),
true);
2823 setGlobally(ConfigurationType::PerformanceTracking, std::string(
"true"),
true);
2824 setGlobally(ConfigurationType::MaxLogFileSize, std::string(
"10000000"),
true);
2825 setGlobally(ConfigurationType::LogFlushThreshold, std::string(
"0"),
true);
2827 setGlobally(ConfigurationType::Format, std::string(
"%datetime %level [%logger] %msg"),
true);
2828 set(Level::Debug, ConfigurationType::Format, std::string(
"%datetime %level [%logger] [%user@%host] [%func] [%loc] %msg"));
2830 set(Level::Error, ConfigurationType::Format, std::string(
"%datetime %level [%logger] %msg"));
2831 set(Level::Fatal, ConfigurationType::Format, std::string(
"%datetime %level [%logger] %msg"));
2832 set(Level::Verbose, ConfigurationType::Format, std::string(
"%datetime %level-%vlevel [%logger] %msg"));
2833 set(Level::Trace, ConfigurationType::Format, std::string(
"%datetime %level [%logger] [%func] [%loc] %msg"));
2843 void setRemainingToDefault(
void)
2845 base::threading::ScopedLock scopedLock(lock());
2846 unsafeSetIfNotExist(Level::Global, ConfigurationType::Enabled, std::string(
"true"));
2847 #if !defined(ELPP_NO_DEFAULT_LOG_FILE)
2848 unsafeSetIfNotExist(Level::Global, ConfigurationType::Filename, std::string(base::consts::kDefaultLogFile));
2849 #endif // !defined(ELPP_NO_DEFAULT_LOG_FILE)
2850 unsafeSetIfNotExist(Level::Global, ConfigurationType::ToFile, std::string(
"false"));
2851 unsafeSetIfNotExist(Level::Global, ConfigurationType::ToStandardOutput, std::string(
"true"));
2852 unsafeSetIfNotExist(Level::Global, ConfigurationType::MillisecondsWidth, std::string(
"3"));
2853 unsafeSetIfNotExist(Level::Global, ConfigurationType::PerformanceTracking, std::string(
"true"));
2854 unsafeSetIfNotExist(Level::Global, ConfigurationType::MaxLogFileSize, std::string(
"10000000"));
2855 unsafeSetIfNotExist(Level::Global, ConfigurationType::Format, std::string(
"%datetime %level [%logger] %msg"));
2856 unsafeSetIfNotExist(Level::Debug, ConfigurationType::Format,
2857 std::string(
"%datetime %level [%logger] [%user@%host] [%func] [%loc] %msg"));
2859 unsafeSetIfNotExist(Level::Error, ConfigurationType::Format, std::string(
"%datetime %level [%logger] %msg"));
2860 unsafeSetIfNotExist(Level::Fatal, ConfigurationType::Format, std::string(
"%datetime %level [%logger] %msg"));
2861 unsafeSetIfNotExist(Level::Verbose, ConfigurationType::Format, std::string(
"%datetime %level-%vlevel [%logger] %msg"));
2862 unsafeSetIfNotExist(Level::Trace, ConfigurationType::Format, std::string(
"%datetime %level [%logger] [%func] [%loc] %msg"));
2869 class Parser : base::StaticClass
2879 static bool parseFromFile(
const std::string& configurationFile, Configurations* sender, Configurations* base =
nullptr)
2881 sender->setFromBase(base);
2882 std::ifstream fileStream_(configurationFile.c_str(), std::ifstream::in);
2883 ELPP_ASSERT(fileStream_.is_open(),
"Unable to open configuration file [" << configurationFile <<
"] for parsing.");
2884 bool parsedSuccessfully =
false;
2885 std::string line = std::string();
2886 Level currLevel = Level::Unknown;
2887 std::string currConfigStr = std::string();
2888 std::string currLevelStr = std::string();
2889 while (fileStream_.good()) {
2890 std::getline(fileStream_, line);
2891 parsedSuccessfully = parseLine(&line, &currConfigStr, &currLevelStr, &currLevel, sender);
2892 ELPP_ASSERT(parsedSuccessfully,
"Unable to parse configuration line: " << line);
2894 return parsedSuccessfully;
2907 static bool parseFromText(
const std::string& configurationsString, Configurations* sender, Configurations* base =
nullptr)
2909 sender->setFromBase(base);
2910 bool parsedSuccessfully =
false;
2911 std::stringstream ss(configurationsString);
2912 std::string line = std::string();
2913 Level currLevel = Level::Unknown;
2914 std::string currConfigStr = std::string();
2915 std::string currLevelStr = std::string();
2916 while (std::getline(ss, line)) {
2917 parsedSuccessfully = parseLine(&line, &currConfigStr, &currLevelStr, &currLevel, sender);
2918 ELPP_ASSERT(parsedSuccessfully,
"Unable to parse configuration line: " << line);
2920 return parsedSuccessfully;
2924 friend class el::Loggers;
2925 static void ignoreComments(std::string* line)
2927 std::size_t foundAt = 0;
2928 std::size_t quotesStart = line->find(
"\"");
2929 std::size_t quotesEnd = std::string::npos;
2930 if (quotesStart != std::string::npos) {
2931 quotesEnd = line->find(
"\"", quotesStart + 1);
2932 while (quotesEnd != std::string::npos && line->at(quotesEnd - 1) ==
'\\') {
2934 quotesEnd = line->find(
"\"", quotesEnd + 2);
2937 if ((foundAt = line->find(base::consts::kConfigurationComment)) != std::string::npos) {
2938 if (foundAt < quotesEnd) {
2939 foundAt = line->find(base::consts::kConfigurationComment, quotesEnd + 1);
2941 *line = line->substr(0, foundAt);
2944 static inline bool isLevel(
const std::string& line)
2946 return base::utils::Str::startsWith(line, std::string(base::consts::kConfigurationLevel));
2949 static inline bool isComment(
const std::string& line)
2951 return base::utils::Str::startsWith(line, std::string(base::consts::kConfigurationComment));
2954 static inline bool isConfig(
const std::string& line)
2956 std::size_t assignment = line.find(
'=');
2957 return line !=
"" &&
2958 (line[0] >= 65 || line[0] <= 90 || line[0] >= 97 || line[0] <= 122) &&
2959 (assignment != std::string::npos) &&
2960 (line.size() > assignment);
2963 static bool parseLine(std::string* line, std::string* currConfigStr, std::string* currLevelStr, Level* currLevel, Configurations* conf)
2965 ConfigurationType currConfig = ConfigurationType::Unknown;
2966 std::string currValue = std::string();
2967 *line = base::utils::Str::trim(*line);
2968 if (isComment(*line))
return true;
2969 ignoreComments(line);
2970 *line = base::utils::Str::trim(*line);
2971 if (line->empty()) {
2975 if (isLevel(*line)) {
2976 if (line->size() <= 2) {
2979 *currLevelStr = line->substr(1, line->size() - 2);
2980 *currLevelStr = base::utils::Str::toUpper(*currLevelStr);
2981 *currLevelStr = base::utils::Str::trim(*currLevelStr);
2982 *currLevel = LevelHelper::convertFromString(currLevelStr->c_str());
2985 if (isConfig(*line)) {
2986 std::size_t assignment = line->find(
'=');
2987 *currConfigStr = line->substr(0, assignment);
2988 *currConfigStr = base::utils::Str::toUpper(*currConfigStr);
2989 *currConfigStr = base::utils::Str::trim(*currConfigStr);
2990 currConfig = ConfigurationTypeHelper::convertFromString(currConfigStr->c_str());
2991 currValue = line->substr(assignment + 1);
2992 currValue = base::utils::Str::trim(currValue);
2993 std::size_t quotesStart = currValue.find(
"\"", 0);
2994 std::size_t quotesEnd = std::string::npos;
2995 if (quotesStart != std::string::npos) {
2996 quotesEnd = currValue.find(
"\"", quotesStart + 1);
2997 while (quotesEnd != std::string::npos && currValue.at(quotesEnd - 1) ==
'\\') {
2998 currValue = currValue.erase(quotesEnd - 1, 1);
2999 quotesEnd = currValue.find(
"\"", quotesEnd + 2);
3002 if (quotesStart != std::string::npos && quotesEnd != std::string::npos) {
3004 ELPP_ASSERT((quotesStart < quotesEnd),
"Configuration error - No ending quote found in ["
3005 << currConfigStr <<
"]");
3006 ELPP_ASSERT((quotesStart + 1 != quotesEnd),
"Empty configuration value for [" << currConfigStr <<
"]");
3007 if ((quotesStart != quotesEnd) && (quotesStart + 1 != quotesEnd)) {
3009 currValue = currValue.substr(quotesStart + 1, quotesEnd - 1);
3013 ELPP_ASSERT(*currLevel != Level::Unknown,
"Unrecognized severity level [" << *currLevelStr <<
"]");
3014 ELPP_ASSERT(currConfig != ConfigurationType::Unknown,
"Unrecognized configuration [" << *currConfigStr <<
"]");
3015 if (*currLevel == Level::Unknown || currConfig == ConfigurationType::Unknown) {
3018 conf->set(*currLevel, currConfig, currValue);
3024 std::string m_configurationFile;
3026 friend class el::Loggers;
3029 void unsafeSetIfNotExist(Level level, ConfigurationType configurationType,
const std::string& value)
3031 Configuration* conf = RegistryWithPred<Configuration, Configuration::Predicate>::get(level, configurationType);
3032 if (conf ==
nullptr) {
3033 unsafeSet(level, configurationType, value);
3038 void unsafeSet(Level level, ConfigurationType configurationType,
const std::string& value)
3040 Configuration* conf = RegistryWithPred<Configuration, Configuration::Predicate>::get(level, configurationType);
3041 if (conf ==
nullptr) {
3042 registerNew(
new Configuration(level, configurationType, value));
3044 conf->setValue(value);
3046 if (level == Level::Global) {
3047 unsafeSetGlobally(configurationType, value,
false);
3053 void setGlobally(ConfigurationType configurationType,
const std::string& value,
bool includeGlobalLevel)
3055 if (includeGlobalLevel) {
3056 set(Level::Global, configurationType, value);
3058 base::type::EnumType lIndex = LevelHelper::kMinValid;
3059 LevelHelper::forEachLevel(&lIndex, [&](
void) ->
bool {
3060 set(LevelHelper::castFromInt(lIndex), configurationType, value);
3067 void unsafeSetGlobally(ConfigurationType configurationType,
const std::string& value,
bool includeGlobalLevel)
3069 if (includeGlobalLevel) {
3070 unsafeSet(Level::Global, configurationType, value);
3072 base::type::EnumType lIndex = LevelHelper::kMinValid;
3073 LevelHelper::forEachLevel(&lIndex, [&](
void) ->
bool {
3074 unsafeSet(LevelHelper::castFromInt(lIndex), configurationType, value);
3081 typedef std::shared_ptr<base::type::fstream_t> FileStreamPtr;
3082 typedef std::map<std::string, FileStreamPtr> LogStreamsReferenceMap;
3089 class TypedConfigurations :
public base::threading::ThreadSafe
3095 TypedConfigurations(Configurations* configurations, base::LogStreamsReferenceMap* logStreamsReference)
3097 m_configurations = configurations;
3098 m_logStreamsReference = logStreamsReference;
3099 build(m_configurations);
3102 TypedConfigurations(
const TypedConfigurations& other)
3104 this->m_configurations = other.m_configurations;
3105 this->m_logStreamsReference = other.m_logStreamsReference;
3106 build(m_configurations);
3109 virtual ~TypedConfigurations(
void)
3113 const Configurations* configurations(
void)
const
3115 return m_configurations;
3118 inline bool enabled(Level level)
3120 return getConfigByVal<bool>(level, &m_enabledMap,
"enabled");
3123 inline bool toFile(Level level)
3125 return getConfigByVal<bool>(level, &m_toFileMap,
"toFile");
3128 inline const std::string& filename(Level level)
3130 return getConfigByRef<std::string>(level, &m_filenameMap,
"filename");
3133 inline bool toStandardOutput(Level level)
3135 return getConfigByVal<bool>(level, &m_toStandardOutputMap,
"toStandardOutput");
3138 inline const base::LogFormat& logFormat(Level level)
3140 return getConfigByRef<base::LogFormat>(level, &m_logFormatMap,
"logFormat");
3143 inline const base::MillisecondsWidth& millisecondsWidth(Level level = Level::Global)
3145 return getConfigByRef<base::MillisecondsWidth>(level, &m_millisecondsWidthMap,
"millisecondsWidth");
3148 inline bool performanceTracking(Level level = Level::Global)
3150 return getConfigByVal<bool>(level, &m_performanceTrackingMap,
"performanceTracking");
3153 inline base::type::fstream_t* fileStream(Level level)
3155 return getConfigByRef<base::FileStreamPtr>(level, &m_fileStreamMap,
"fileStream").
get();
3158 inline std::size_t maxLogFileSize(Level level)
3160 return getConfigByVal<std::size_t>(level, &m_maxLogFileSizeMap,
"maxLogFileSize");
3163 inline std::size_t logFlushThreshold(Level level)
3165 return getConfigByVal<std::size_t>(level, &m_logFlushThresholdMap,
"logFlushThreshold");
3169 Configurations* m_configurations;
3170 std::map<Level, bool> m_enabledMap;
3171 std::map<Level, bool> m_toFileMap;
3172 std::map<Level, std::string> m_filenameMap;
3173 std::map<Level, bool> m_toStandardOutputMap;
3174 std::map<Level, base::LogFormat> m_logFormatMap;
3175 std::map<Level, base::MillisecondsWidth> m_millisecondsWidthMap;
3176 std::map<Level, bool> m_performanceTrackingMap;
3177 std::map<Level, base::FileStreamPtr> m_fileStreamMap;
3178 std::map<Level, std::size_t> m_maxLogFileSizeMap;
3179 std::map<Level, std::size_t> m_logFlushThresholdMap;
3180 base::LogStreamsReferenceMap* m_logStreamsReference;
3182 friend class el::Helpers;
3183 friend class el::base::MessageBuilder;
3184 friend class el::base::Writer;
3185 friend class el::base::DefaultLogDispatchCallback;
3186 friend class el::base::LogDispatcher;
3188 template <
typename Conf_T>
3189 inline Conf_T getConfigByVal(Level level,
const std::map<Level, Conf_T>* confMap,
const char* confName)
3191 base::threading::ScopedLock scopedLock(lock());
3192 return unsafeGetConfigByVal(level, confMap, confName);
3195 template <
typename Conf_T>
3196 inline Conf_T& getConfigByRef(Level level, std::map<Level, Conf_T>* confMap,
const char* confName)
3198 base::threading::ScopedLock scopedLock(lock());
3199 return unsafeGetConfigByRef(level, confMap, confName);
3202 template <
typename Conf_T>
3203 inline Conf_T unsafeGetConfigByVal(Level level,
const std::map<Level, Conf_T>* confMap,
const char* confName)
3205 ELPP_UNUSED(confName);
3206 typename std::map<Level, Conf_T>::const_iterator it = confMap->find(level);
3207 if (it == confMap->end()) {
3209 return confMap->at(Level::Global);
3211 ELPP_INTERNAL_ERROR(
"Unable to get configuration [" << confName <<
"] for level ["
3212 << LevelHelper::convertToString(level) <<
"]"
3213 << std::endl <<
"Please ensure you have properly configured logger.",
false);
3220 template <
typename Conf_T>
3221 inline Conf_T& unsafeGetConfigByRef(Level level, std::map<Level, Conf_T>* confMap,
const char* confName)
3223 ELPP_UNUSED(confName);
3224 typename std::map<Level, Conf_T>::iterator it = confMap->find(level);
3225 if (it == confMap->end()) {
3227 return confMap->at(Level::Global);
3229 ELPP_INTERNAL_ERROR(
"Unable to get configuration [" << confName <<
"] for level ["
3230 << LevelHelper::convertToString(level) <<
"]"
3231 << std::endl <<
"Please ensure you have properly configured logger.",
false);
3237 template <
typename Conf_T>
3238 void setValue(Level level,
const Conf_T& value, std::map<Level, Conf_T>* confMap,
bool includeGlobalLevel =
true)
3241 if (confMap->empty() && includeGlobalLevel) {
3242 confMap->insert(std::make_pair(Level::Global, value));
3246 typename std::map<Level, Conf_T>::iterator it = confMap->find(Level::Global);
3247 if (it != confMap->end() && it->second == value) {
3251 it = confMap->find(level);
3252 if (it == confMap->end()) {
3254 confMap->insert(std::make_pair(level, value));
3257 confMap->at(level) = value;
3261 void build(Configurations* configurations)
3263 base::threading::ScopedLock scopedLock(lock());
3264 auto getBool = [] (std::string boolStr) ->
bool {
3265 base::utils::Str::trim(boolStr);
3266 return (boolStr ==
"TRUE" || boolStr ==
"true" || boolStr ==
"1");
3268 std::vector<Configuration*> withFileSizeLimit;
3269 for (Configurations::const_iterator it = configurations->begin(); it != configurations->end(); ++it) {
3270 Configuration* conf = *it;
3272 if (conf->configurationType() == ConfigurationType::Enabled) {
3273 setValue(conf->level(), getBool(conf->value()), &m_enabledMap);
3274 }
else if (conf->configurationType() == ConfigurationType::ToFile) {
3275 setValue(conf->level(), getBool(conf->value()), &m_toFileMap);
3276 }
else if (conf->configurationType() == ConfigurationType::ToStandardOutput) {
3277 setValue(conf->level(), getBool(conf->value()), &m_toStandardOutputMap);
3278 }
else if (conf->configurationType() == ConfigurationType::Filename) {
3284 }
else if (conf->configurationType() == ConfigurationType::Format) {
3285 setValue(conf->level(), base::LogFormat(conf->level(),
3286 base::type::string_t(conf->value().begin(), conf->value().end())), &m_logFormatMap);
3287 }
else if (conf->configurationType() == ConfigurationType::MillisecondsWidth) {
3288 setValue(Level::Global,
3289 base::MillisecondsWidth(static_cast<int>(getULong(conf->value()))), &m_millisecondsWidthMap);
3290 }
else if (conf->configurationType() == ConfigurationType::PerformanceTracking) {
3291 setValue(Level::Global, getBool(conf->value()), &m_performanceTrackingMap);
3292 }
else if (conf->configurationType() == ConfigurationType::MaxLogFileSize) {
3293 setValue(conf->level(),
static_cast<std::size_t
>(getULong(conf->value())), &m_maxLogFileSizeMap);
3294 #if !defined(ELPP_NO_DEFAULT_LOG_FILE)
3295 withFileSizeLimit.push_back(conf);
3296 #endif // !defined(ELPP_NO_DEFAULT_LOG_FILE)
3297 }
else if (conf->configurationType() == ConfigurationType::LogFlushThreshold) {
3298 setValue(conf->level(),
static_cast<std::size_t
>(getULong(conf->value())), &m_logFlushThresholdMap);
3302 for (Configurations::const_iterator it = configurations->begin(); it != configurations->end(); ++it) {
3303 Configuration* conf = *it;
3304 if (conf->configurationType() == ConfigurationType::Filename) {
3305 insertFile(conf->level(), conf->value());
3308 for (std::vector<Configuration*>::iterator conf = withFileSizeLimit.begin();
3309 conf != withFileSizeLimit.end(); ++conf) {
3311 unsafeValidateFileRolling((*conf)->level(), base::defaultPreRollOutCallback);
3315 unsigned long getULong(std::string confVal)
3318 base::utils::Str::trim(confVal);
3319 valid = !confVal.empty() && std::find_if(confVal.begin(), confVal.end(),
3320 [](
char c) {
return !base::utils::Str::isDigit(c); }) == confVal.end();
3323 ELPP_ASSERT(valid,
"Configuration value not a valid integer [" << confVal <<
"]");
3326 return atol(confVal.c_str());
3329 std::string resolveFilename(
const std::string& filename)
3331 std::string resultingFilename = filename;
3332 std::size_t dateIndex = std::string::npos;
3333 std::string dateTimeFormatSpecifierStr = std::string(base::consts::kDateTimeFormatSpecifierForFilename);
3334 if ((dateIndex = resultingFilename.find(dateTimeFormatSpecifierStr.c_str())) != std::string::npos) {
3335 while (dateIndex > 0 && resultingFilename[dateIndex - 1] == base::consts::kFormatSpecifierChar) {
3336 dateIndex = resultingFilename.find(dateTimeFormatSpecifierStr.c_str(), dateIndex + 1);
3338 if (dateIndex != std::string::npos) {
3339 const char* ptr = resultingFilename.c_str() + dateIndex;
3341 ptr += dateTimeFormatSpecifierStr.size();
3343 if ((resultingFilename.size() > dateIndex) && (ptr[0] ==
'{')) {
3347 std::stringstream ss;
3348 for (; *ptr; ++ptr, ++count) {
3355 resultingFilename.erase(dateIndex + dateTimeFormatSpecifierStr.size(), count);
3358 fmt = std::string(base::consts::kDefaultDateTimeFormatInFilename);
3360 base::MillisecondsWidth msWidth(3);
3361 std::string now = base::utils::DateTime::getDateTime(fmt.c_str(), &msWidth);
3362 base::utils::Str::replaceAll(now,
'/',
'-');
3363 base::utils::Str::replaceAll(resultingFilename, dateTimeFormatSpecifierStr, now);
3366 return resultingFilename;
3369 void insertFile(Level level,
const std::string& fullFilename)
3371 std::string resolvedFilename = resolveFilename(fullFilename);
3372 if (resolvedFilename.empty()) {
3373 std::cerr <<
"Could not load empty file for logging, please re-check your configurations for level ["
3374 << LevelHelper::convertToString(level) <<
"]";
3376 std::string filePath = base::utils::File::extractPathFromFilename(resolvedFilename, base::consts::kFilePathSeperator);
3377 if (filePath.size() < resolvedFilename.size()) {
3378 base::utils::File::createPath(filePath);
3380 auto create = [&](Level level) {
3381 base::LogStreamsReferenceMap::iterator filestreamIter = m_logStreamsReference->find(resolvedFilename);
3382 base::type::fstream_t* fs =
nullptr;
3383 if (filestreamIter == m_logStreamsReference->end()) {
3385 fs = base::utils::File::newFileStream(resolvedFilename);
3386 m_filenameMap.insert(std::make_pair(level, resolvedFilename));
3387 m_fileStreamMap.insert(std::make_pair(level, base::FileStreamPtr(fs)));
3388 m_logStreamsReference->insert(std::make_pair(resolvedFilename, base::FileStreamPtr(m_fileStreamMap.at(level))));
3391 m_filenameMap.insert(std::make_pair(level, filestreamIter->first));
3392 m_fileStreamMap.insert(std::make_pair(level, base::FileStreamPtr(filestreamIter->second)));
3393 fs = filestreamIter->second.get();
3395 if (fs ==
nullptr) {
3397 ELPP_INTERNAL_ERROR(
"Setting [TO_FILE] of ["
3398 << LevelHelper::convertToString(level) <<
"] to FALSE",
false);
3399 setValue(level,
false, &m_toFileMap);
3404 create(m_filenameMap.empty() && m_fileStreamMap.empty() ? Level::Global : level);
3407 bool unsafeValidateFileRolling(Level level,
const PreRollOutCallback& PreRollOutCallback)
3409 base::type::fstream_t* fs = unsafeGetConfigByRef(level, &m_fileStreamMap,
"fileStream").get();
3410 if (fs ==
nullptr) {
3413 std::size_t maxLogFileSize = unsafeGetConfigByVal(level, &m_maxLogFileSizeMap,
"maxLogFileSize");
3414 std::size_t currFileSize = base::utils::File::getSizeOfFile(fs);
3415 if (maxLogFileSize != 0 && currFileSize >= maxLogFileSize) {
3416 std::string fname = unsafeGetConfigByRef(level, &m_filenameMap,
"filename");
3417 ELPP_INTERNAL_INFO(1,
"Truncating log file [" << fname <<
"] as a result of configurations for level ["
3418 << LevelHelper::convertToString(level) <<
"]");
3420 PreRollOutCallback(fname.c_str(), currFileSize);
3421 fs->open(fname, std::fstream::out | std::fstream::trunc);
3427 bool validateFileRolling(Level level,
const PreRollOutCallback& PreRollOutCallback)
3429 base::threading::ScopedLock scopedLock(lock());
3430 return unsafeValidateFileRolling(level, PreRollOutCallback);
3444 HitCounter(
const char* filename,
unsigned long int lineNumber) :
3445 m_filename(filename),
3446 m_lineNumber(lineNumber),
3451 HitCounter(
const HitCounter& hitCounter) :
3452 m_filename(hitCounter.m_filename),
3453 m_lineNumber(hitCounter.m_lineNumber),
3454 m_hitCounts(hitCounter.m_hitCounts)
3458 HitCounter& operator=(
const HitCounter& hitCounter)
3460 m_filename = hitCounter.m_filename;
3461 m_lineNumber = hitCounter.m_lineNumber;
3462 m_hitCounts = hitCounter.m_hitCounts;
3466 virtual ~HitCounter(
void)
3471 inline void resetLocation(
const char* filename,
unsigned long int lineNumber)
3473 m_filename = filename;
3474 m_lineNumber = lineNumber;
3478 inline void validateHitCounts(std::size_t n)
3480 if (m_hitCounts >= base::consts::kMaxLogPerCounter) {
3481 m_hitCounts = (n >= 1 ? base::consts::kMaxLogPerCounter % n : 0);
3486 inline const char* filename(
void)
const
3491 inline unsigned long int lineNumber(
void)
const
3493 return m_lineNumber;
3496 inline std::size_t hitCounts(
void)
const
3501 inline void increment(
void)
3509 Predicate(
const char* filename,
unsigned long int lineNumber)
3510 : m_filename(filename),
3511 m_lineNumber(lineNumber)
3514 inline bool operator()(
const HitCounter* counter)
3516 return ((counter !=
nullptr) &&
3517 (strcmp(counter->m_filename, m_filename) == 0) &&
3518 (counter->m_lineNumber == m_lineNumber));
3522 const char* m_filename;
3523 unsigned long int m_lineNumber;
3527 const char* m_filename;
3528 unsigned long int m_lineNumber;
3529 std::size_t m_hitCounts;
3532 class RegisteredHitCounters :
public base::utils::RegistryWithPred<base::HitCounter, base::HitCounter::Predicate>
3537 bool validateEveryN(
const char* filename,
unsigned long int lineNumber, std::size_t n)
3539 base::threading::ScopedLock scopedLock(lock());
3540 base::HitCounter* counter =
get(filename, lineNumber);
3541 if (counter ==
nullptr) {
3542 registerNew(counter =
new base::HitCounter(filename, lineNumber));
3544 counter->validateHitCounts(n);
3545 bool result = (n >= 1 && counter->hitCounts() != 0 && counter->hitCounts() % n == 0);
3551 bool validateAfterN(
const char* filename,
unsigned long int lineNumber, std::size_t n)
3553 base::threading::ScopedLock scopedLock(lock());
3554 base::HitCounter* counter =
get(filename, lineNumber);
3555 if (counter ==
nullptr) {
3556 registerNew(counter =
new base::HitCounter(filename, lineNumber));
3561 if (counter->hitCounts() >= n)
3563 counter->increment();
3569 bool validateNTimes(
const char* filename,
unsigned long int lineNumber, std::size_t n)
3571 base::threading::ScopedLock scopedLock(lock());
3572 base::HitCounter* counter =
get(filename, lineNumber);
3573 if (counter ==
nullptr) {
3574 registerNew(counter =
new base::HitCounter(filename, lineNumber));
3576 counter->increment();
3578 if (counter->hitCounts() <= n)
3584 inline const base::HitCounter* getCounter(
const char* filename,
unsigned long int lineNumber)
3586 base::threading::ScopedLock scopedLock(lock());
3587 return get(filename, lineNumber);
3591 enum class DispatchAction : base::type::EnumType {
3592 None = 1, NormalLog = 2, SysLog = 4
3595 template <
typename T>
3596 class Callback :
protected base::threading::ThreadSafe
3599 Callback(
void) : m_enabled(true) {}
3600 inline bool enabled(
void)
const {
return m_enabled; }
3601 inline void setEnabled(
bool enabled)
3603 base::threading::ScopedLock scopedLock(lock());
3604 m_enabled = enabled;
3607 virtual void handle(
const T* handlePtr) = 0;
3611 class LogDispatchData
3614 LogDispatchData() : m_logMessage(nullptr), m_dispatchAction(base::DispatchAction::None) {}
3615 inline const LogMessage* logMessage(
void)
const {
return m_logMessage; }
3616 inline base::DispatchAction dispatchAction(
void)
const {
return m_dispatchAction; }
3618 LogMessage* m_logMessage;
3619 base::DispatchAction m_dispatchAction;
3620 friend class base::LogDispatcher;
3622 inline void setLogMessage(LogMessage* logMessage) { m_logMessage = logMessage; }
3623 inline void setDispatchAction(base::DispatchAction dispatchAction) { m_dispatchAction = dispatchAction; }
3625 class LogDispatchCallback :
public Callback<LogDispatchData>
3628 friend class base::LogDispatcher;
3630 class PerformanceTrackingCallback :
public Callback<PerformanceTrackingData>
3633 friend class base::PerformanceTracker;
3635 class LogBuilder : base::NoCopy
3638 virtual ~LogBuilder(
void) { ELPP_INTERNAL_INFO(3,
"Destroying log builder...")}
3639 virtual base::type::string_t build(
const LogMessage* logMessage,
bool appendNewLine)
const = 0;
3640 void convertToColoredOutput(base::type::string_t* logLine, Level level)
3642 if (!base::utils::s_termSupportsColor)
return;
3643 const base::type::char_t* resetColor = ELPP_LITERAL(
"\x1b[0m");
3644 if (level == Level::Error || level == Level::Fatal)
3645 *logLine = ELPP_LITERAL(
"\x1b[31m") + *logLine + resetColor;
3646 else if (level == Level::Warning)
3647 *logLine = ELPP_LITERAL(
"\x1b[33m") + *logLine + resetColor;
3650 friend class el::base::DefaultLogDispatchCallback;
3652 typedef std::shared_ptr<LogBuilder> LogBuilderPtr;
3656 class Logger :
public base::threading::ThreadSafe,
public Loggable
3659 Logger(
const std::string&
id, base::LogStreamsReferenceMap* logStreamsReference) :
3661 m_typedConfigurations(nullptr),
3662 m_parentApplicationName(std::string()),
3663 m_isConfigured(false),
3664 m_logStreamsReference(logStreamsReference)
3666 initUnflushedCount();
3669 Logger(
const std::string&
id,
const Configurations& configurations, base::LogStreamsReferenceMap* logStreamsReference) :
3671 m_typedConfigurations(nullptr),
3672 m_parentApplicationName(std::string()),
3673 m_isConfigured(false),
3674 m_logStreamsReference(logStreamsReference)
3676 initUnflushedCount();
3677 configure(configurations);
3680 Logger(
const Logger& logger)
3682 base::utils::safeDelete(m_typedConfigurations);
3684 m_typedConfigurations = logger.m_typedConfigurations;
3685 m_parentApplicationName = logger.m_parentApplicationName;
3686 m_isConfigured = logger.m_isConfigured;
3687 m_configurations = logger.m_configurations;
3688 m_unflushedCount = logger.m_unflushedCount;
3689 m_logStreamsReference = logger.m_logStreamsReference;
3692 Logger& operator=(
const Logger& logger)
3694 base::utils::safeDelete(m_typedConfigurations);
3696 m_typedConfigurations = logger.m_typedConfigurations;
3697 m_parentApplicationName = logger.m_parentApplicationName;
3698 m_isConfigured = logger.m_isConfigured;
3699 m_configurations = logger.m_configurations;
3700 m_unflushedCount = logger.m_unflushedCount;
3701 m_logStreamsReference = logger.m_logStreamsReference;
3705 virtual ~Logger(
void)
3707 base::utils::safeDelete(m_typedConfigurations);
3710 virtual inline void log(el::base::type::ostream_t& os)
const
3716 void configure(
const Configurations& configurations)
3718 m_isConfigured =
false;
3719 initUnflushedCount();
3720 if (m_typedConfigurations !=
nullptr) {
3721 Configurations* c =
const_cast<Configurations*
>(m_typedConfigurations->configurations());
3722 if (c->hasConfiguration(Level::Global, ConfigurationType::Filename)) {
3727 base::threading::ScopedLock scopedLock(lock());
3728 if (m_configurations != configurations) {
3729 m_configurations.setFromBase(const_cast<Configurations*>(&configurations));
3731 base::utils::safeDelete(m_typedConfigurations);
3732 m_typedConfigurations =
new base::TypedConfigurations(&m_configurations, m_logStreamsReference);
3733 resolveLoggerFormatSpec();
3734 m_isConfigured =
true;
3738 inline void reconfigure(
void)
3740 ELPP_INTERNAL_INFO(1,
"Reconfiguring logger [" << m_id <<
"]");
3741 configure(m_configurations);
3744 inline const std::string& id(
void)
const
3749 inline const std::string& parentApplicationName(
void)
const
3751 return m_parentApplicationName;
3754 inline void setParentApplicationName(
const std::string& parentApplicationName)
3756 m_parentApplicationName = parentApplicationName;
3759 inline Configurations* configurations(
void)
3761 return &m_configurations;
3764 inline base::TypedConfigurations* typedConfigurations(
void)
3766 return m_typedConfigurations;
3769 static inline bool isValidId(
const std::string&
id)
3771 for (std::string::const_iterator it =
id.begin(); it !=
id.end(); ++it) {
3779 inline void flush(
void)
3781 ELPP_INTERNAL_INFO(3,
"Flushing logger [" << m_id <<
"] all levels");
3782 base::threading::ScopedLock scopedLock(lock());
3783 base::type::EnumType lIndex = LevelHelper::kMinValid;
3784 LevelHelper::forEachLevel(&lIndex, [&](
void) ->
bool {
3785 flush(LevelHelper::castFromInt(lIndex),
nullptr);
3790 inline void flush(Level level, base::type::fstream_t* fs)
3792 if (fs ==
nullptr && m_typedConfigurations->toFile(level)) {
3793 fs = m_typedConfigurations->fileStream(level);
3795 if (fs !=
nullptr) {
3797 m_unflushedCount.find(level)->second = 0;
3801 inline bool isFlushNeeded(Level level)
3803 return ++m_unflushedCount.find(level)->second >= m_typedConfigurations->logFlushThreshold(level);
3806 inline LogBuilder* logBuilder(
void)
const
3808 return m_logBuilder.get();
3811 inline void setLogBuilder(
const LogBuilderPtr& logBuilder)
3813 m_logBuilder = logBuilder;
3816 inline bool enabled(Level level)
const
3818 return m_typedConfigurations->enabled(level);
3821 #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
3822 # define LOGGER_LEVEL_WRITERS_SIGNATURES(FUNCTION_NAME)\
3823 template <typename T, typename... Args>\
3824 inline void FUNCTION_NAME(const char*, const T&, const Args&...);\
3825 template <typename T>\
3826 inline void FUNCTION_NAME(const T&);
3828 template <
typename T,
typename... Args>
3829 inline void verbose(
int,
const char*,
const T&,
const Args& ...);
3831 template <
typename T>
3832 inline void verbose(
int,
const T&);
3834 LOGGER_LEVEL_WRITERS_SIGNATURES(info)
3835 LOGGER_LEVEL_WRITERS_SIGNATURES(debug)
3836 LOGGER_LEVEL_WRITERS_SIGNATURES(warn)
3837 LOGGER_LEVEL_WRITERS_SIGNATURES(error)
3838 LOGGER_LEVEL_WRITERS_SIGNATURES(fatal)
3839 LOGGER_LEVEL_WRITERS_SIGNATURES(
trace)
3840 # undef LOGGER_LEVEL_WRITERS_SIGNATURES
3841 #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
3844 base::TypedConfigurations* m_typedConfigurations;
3845 base::type::stringstream_t m_stream;
3846 std::string m_parentApplicationName;
3847 bool m_isConfigured;
3848 Configurations m_configurations;
3849 std::map<Level, unsigned int> m_unflushedCount;
3850 base::LogStreamsReferenceMap* m_logStreamsReference;
3851 LogBuilderPtr m_logBuilder;
3853 friend class el::LogMessage;
3854 friend class el::Loggers;
3855 friend class el::Helpers;
3856 friend class el::base::RegisteredLoggers;
3857 friend class el::base::DefaultLogDispatchCallback;
3858 friend class el::base::MessageBuilder;
3859 friend class el::base::Writer;
3860 friend class el::base::PErrorWriter;
3861 friend class el::base::Storage;
3862 friend class el::base::PerformanceTracker;
3863 friend class el::base::LogDispatcher;
3867 #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
3868 template <
typename T,
typename... Args>
3869 void log_(Level,
int,
const char*,
const T&,
const Args& ...);
3871 template <
typename T>
3872 inline void log_(Level,
int,
const T&);
3874 template <
typename T,
typename... Args>
3875 void log(Level,
const char*,
const T&,
const Args& ...);
3877 template <
typename T>
3878 inline void log(Level,
const T&);
3879 #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
3881 void initUnflushedCount(
void)
3883 m_unflushedCount.clear();
3884 base::type::EnumType lIndex = LevelHelper::kMinValid;
3885 LevelHelper::forEachLevel(&lIndex, [&](
void) ->
bool {
3886 m_unflushedCount.insert(std::make_pair(LevelHelper::castFromInt(lIndex), 0));
3891 inline base::type::stringstream_t& stream(
void)
3896 void resolveLoggerFormatSpec(
void)
const
3898 base::type::EnumType lIndex = LevelHelper::kMinValid;
3899 LevelHelper::forEachLevel(&lIndex, [&](
void) ->
bool {
3900 base::LogFormat* logFormat =
3901 const_cast<base::LogFormat*
>(&m_typedConfigurations->logFormat(LevelHelper::castFromInt(lIndex)));
3902 base::utils::Str::replaceFirstWithEscape(logFormat->m_format, base::consts::kLoggerIdFormatSpecifier, m_id);
3909 class RegisteredLoggers :
public base::utils::Registry<Logger, std::string>
3912 explicit RegisteredLoggers(
const LogBuilderPtr& defaultLogBuilder) :
3913 m_defaultLogBuilder(defaultLogBuilder)
3915 m_defaultConfigurations.setToDefault();
3918 virtual ~RegisteredLoggers(
void)
3923 inline void setDefaultConfigurations(
const Configurations& configurations)
3925 base::threading::ScopedLock scopedLock(lock());
3926 m_defaultConfigurations.setFromBase(const_cast<Configurations*>(&configurations));
3929 inline Configurations* defaultConfigurations(
void)
3931 return &m_defaultConfigurations;
3934 Logger*
get(
const std::string& id,
bool forceCreation =
true)
3936 base::threading::ScopedLock scopedLock(lock());
3937 Logger* logger_ = base::utils::Registry<Logger, std::string>::get(
id);
3938 if (logger_ ==
nullptr && forceCreation) {
3939 bool validId = Logger::isValidId(
id);
3941 ELPP_ASSERT(validId,
"Invalid logger ID [" <<
id <<
"]. Not registering this logger.");
3944 logger_ =
new Logger(
id, m_defaultConfigurations, &m_logStreamsReference);
3945 logger_->m_logBuilder = m_defaultLogBuilder;
3946 registerNew(
id, logger_);
3951 bool remove(
const std::string& id)
3953 if (
id ==
"default") {
3956 Logger* logger = base::utils::Registry<Logger, std::string>::get(
id);
3957 if (logger !=
nullptr) {
3963 inline bool has(
const std::string&
id)
3965 return get(id,
false) !=
nullptr;
3968 inline void unregister(Logger*& logger)
3970 base::threading::ScopedLock scopedLock(lock());
3971 base::utils::Registry<Logger, std::string>::unregister(logger->id());
3974 inline base::LogStreamsReferenceMap* logStreamsReference(
void)
3976 return &m_logStreamsReference;
3979 inline void flushAll(
void)
3981 ELPP_INTERNAL_INFO(1,
"Flushing all log files");
3982 base::threading::ScopedLock scopedLock(lock());
3983 for (base::LogStreamsReferenceMap::iterator it = m_logStreamsReference.begin();
3984 it != m_logStreamsReference.end(); ++it) {
3985 if (it->second.get() ==
nullptr)
continue;
3986 it->second->flush();
3991 LogBuilderPtr m_defaultLogBuilder;
3992 Configurations m_defaultConfigurations;
3993 base::LogStreamsReferenceMap m_logStreamsReference;
3994 friend class el::base::Storage;
3997 class VRegistry : base::NoCopy,
public base::threading::ThreadSafe
4000 explicit VRegistry(base::type::VerboseLevel level, base::type::EnumType* pFlags) : m_level(level), m_pFlags(pFlags)
4005 inline void setLevel(base::type::VerboseLevel level)
4007 base::threading::ScopedLock scopedLock(lock());
4011 m_level = base::consts::kMaxVerboseLevel;
4016 inline base::type::VerboseLevel level(
void)
const
4021 inline void clearModules(
void)
4023 base::threading::ScopedLock scopedLock(lock());
4027 void setModules(
const char* modules)
4029 base::threading::ScopedLock scopedLock(lock());
4030 auto addSuffix = [](std::stringstream & ss,
const char* sfx,
const char* prev) {
4031 if (prev !=
nullptr && base::utils::Str::endsWith(ss.str(), std::string(prev))) {
4032 std::string chr(ss.str().substr(0, ss.str().size() - strlen(prev)));
4033 ss.str(std::string(
""));
4036 if (base::utils::Str::endsWith(ss.str(), std::string(sfx))) {
4037 std::string chr(ss.str().substr(0, ss.str().size() - strlen(sfx)));
4038 ss.str(std::string(
""));
4043 auto insert = [&](std::stringstream & ss, base::type::VerboseLevel level) {
4044 if (!base::utils::hasFlag(LoggingFlag::DisableVModulesExtensions, *m_pFlags)) {
4045 addSuffix(ss,
".h",
nullptr);
4046 m_modules.insert(std::make_pair(ss.str(), level));
4047 addSuffix(ss,
".c",
".h");
4048 m_modules.insert(std::make_pair(ss.str(), level));
4049 addSuffix(ss,
".cpp",
".c");
4050 m_modules.insert(std::make_pair(ss.str(), level));
4051 addSuffix(ss,
".cc",
".cpp");
4052 m_modules.insert(std::make_pair(ss.str(), level));
4053 addSuffix(ss,
".cxx",
".cc");
4054 m_modules.insert(std::make_pair(ss.str(), level));
4055 addSuffix(ss,
".-inl.h",
".cxx");
4056 m_modules.insert(std::make_pair(ss.str(), level));
4057 addSuffix(ss,
".hxx",
".-inl.h");
4058 m_modules.insert(std::make_pair(ss.str(), level));
4059 addSuffix(ss,
".hpp",
".hxx");
4060 m_modules.insert(std::make_pair(ss.str(), level));
4061 addSuffix(ss,
".hh",
".hpp");
4063 m_modules.insert(std::make_pair(ss.str(), level));
4066 bool isLevel =
false;
4067 std::stringstream ss;
4069 for (; *modules; ++modules) {
4078 if (!ss.str().empty() && level != -1) {
4080 ss.str(std::string(
""));
4087 }
else if (isLevel) {
4088 if (isdigit(*modules)) {
4089 level =
static_cast<base::type::VerboseLevel
>(*modules) - 48;
4095 if (!ss.str().empty() && level != -1) {
4100 bool allowed(base::type::VerboseLevel vlevel,
const char* file)
4102 base::threading::ScopedLock scopedLock(lock());
4103 if (m_modules.empty() || file ==
nullptr) {
4104 return vlevel <= m_level;
4106 std::map<std::string, base::type::VerboseLevel>::iterator it = m_modules.begin();
4107 for (; it != m_modules.end(); ++it) {
4108 if (base::utils::Str::wildCardMatch(file, it->first.c_str())) {
4109 return vlevel <= it->second;
4112 if (base::utils::hasFlag(LoggingFlag::AllowVerboseIfModuleNotSpecified, *m_pFlags)) {
4119 inline const std::map<std::string, base::type::VerboseLevel>& modules(
void)
const
4124 void setFromArgs(
const base::utils::CommandLineArgs* commandLineArgs)
4126 if (commandLineArgs->hasParam(
"-v") || commandLineArgs->hasParam(
"--verbose") ||
4127 commandLineArgs->hasParam(
"-V") || commandLineArgs->hasParam(
"--VERBOSE")) {
4128 setLevel(base::consts::kMaxVerboseLevel);
4129 }
else if (commandLineArgs->hasParamWithValue(
"--v")) {
4130 setLevel(atoi(commandLineArgs->getParamValue(
"--v")));
4131 }
else if (commandLineArgs->hasParamWithValue(
"--V")) {
4132 setLevel(atoi(commandLineArgs->getParamValue(
"--V")));
4133 }
else if ((commandLineArgs->hasParamWithValue(
"-vmodule")) && vModulesEnabled()) {
4134 setModules(commandLineArgs->getParamValue(
"-vmodule"));
4135 }
else if (commandLineArgs->hasParamWithValue(
"-VMODULE") && vModulesEnabled()) {
4136 setModules(commandLineArgs->getParamValue(
"-VMODULE"));
4141 inline bool vModulesEnabled(
void)
4143 return !base::utils::hasFlag(LoggingFlag::DisableVModules, *m_pFlags);
4147 base::type::VerboseLevel m_level;
4148 base::type::EnumType* m_pFlags;
4149 std::map<std::string, base::type::VerboseLevel> m_modules;
4155 LogMessage(Level level,
const std::string& file,
unsigned long int line,
const std::string& func,
4156 base::type::VerboseLevel verboseLevel, Logger* logger) :
4157 m_level(level), m_file(file), m_line(line), m_func(func),
4158 m_verboseLevel(verboseLevel), m_logger(logger), m_message(logger->stream().str())
4161 inline Level level(
void)
const {
return m_level; }
4162 inline const std::string& file(
void)
const {
return m_file; }
4163 inline unsigned long int line(
void)
const {
return m_line; }
4164 inline const std::string& func(
void)
const {
return m_func; }
4165 inline base::type::VerboseLevel verboseLevel(
void)
const {
return m_verboseLevel; }
4166 inline Logger* logger(
void)
const {
return m_logger; }
4167 inline const base::type::string_t& message(
void)
const {
return m_message; }
4171 unsigned long int m_line;
4173 base::type::VerboseLevel m_verboseLevel;
4175 base::type::string_t m_message;
4178 #if ELPP_ASYNC_LOGGING
4182 explicit AsyncLogItem(
const LogMessage& logMessage,
const LogDispatchData& data,
const base::type::string_t& logLine)
4183 : m_logMessage(logMessage), m_dispatchData(data), m_logLine(logLine) {}
4184 virtual ~AsyncLogItem() {}
4185 inline LogMessage* logMessage(
void) {
return &m_logMessage; }
4186 inline LogDispatchData* data(
void) {
return &m_dispatchData; }
4187 inline base::type::string_t logLine(
void) {
return m_logLine; }
4189 LogMessage m_logMessage;
4190 LogDispatchData m_dispatchData;
4191 base::type::string_t m_logLine;
4193 class AsyncLogQueue :
public base::threading::ThreadSafe
4196 virtual ~AsyncLogQueue()
4198 ELPP_INTERNAL_INFO(6,
"~AsyncLogQueue");
4201 inline AsyncLogItem next(
void)
4203 base::threading::ScopedLock scopedLock(lock());
4204 AsyncLogItem result = m_queue.front();
4209 inline void push(
const AsyncLogItem& item)
4211 base::threading::ScopedLock scopedLock(lock());
4214 inline void pop(
void)
4216 base::threading::ScopedLock scopedLock(lock());
4219 inline AsyncLogItem front(
void)
4221 base::threading::ScopedLock scopedLock(lock());
4222 return m_queue.front();
4224 inline bool empty(
void)
4226 base::threading::ScopedLock scopedLock(lock());
4227 return m_queue.empty();
4230 std::queue<AsyncLogItem> m_queue;
4235 virtual ~IWorker() {}
4236 virtual void start() = 0;
4238 #endif // ELPP_ASYNC_LOGGING
4239 class Storage : base::NoCopy,
public base::threading::ThreadSafe
4243 #if ELPP_ASYNC_LOGGING
4244 Storage(
const LogBuilderPtr& defaultLogBuilder, base::IWorker* asyncDispatchWorker) :
4246 explicit Storage(const LogBuilderPtr & defaultLogBuilder) :
4248 m_registeredHitCounters(new base::RegisteredHitCounters()),
4249 m_registeredLoggers(new base::RegisteredLoggers(defaultLogBuilder)),
4251 m_vRegistry(new base::VRegistry(0, &m_flags)),
4252 #if ELPP_ASYNC_LOGGING
4253 m_asyncLogQueue(new base::AsyncLogQueue()),
4254 m_asyncDispatchWorker(asyncDispatchWorker),
4256 m_preRollOutCallback(base::defaultPreRollOutCallback)
4259 m_registeredLoggers->get(std::string(base::consts::kDefaultLoggerId));
4261 Logger* performanceLogger = m_registeredLoggers->get(std::string(base::consts::kPerformanceLoggerId));
4262 performanceLogger->configurations()->setGlobally(ConfigurationType::Format, std::string(
"%datetime %level %msg"));
4263 performanceLogger->reconfigure();
4264 #if defined(ELPP_SYSLOG)
4266 Logger* sysLogLogger = m_registeredLoggers->get(std::string(base::consts::kSysLogLoggerId));
4267 sysLogLogger->configurations()->setGlobally(ConfigurationType::Format, std::string(
"%level: %msg"));
4268 sysLogLogger->reconfigure();
4270 ELPP_UNUSED(base::consts::kSysLogLoggerId);
4271 #endif // defined(ELPP_SYSLOG)
4272 addFlag(LoggingFlag::AllowVerboseIfModuleNotSpecified);
4273 #if ELPP_ASYNC_LOGGING
4274 installLogDispatchCallback<base::AsyncLogDispatchCallback>(std::string(
"AsyncLogDispatchCallback"));
4276 installLogDispatchCallback<base::DefaultLogDispatchCallback>(std::string(
"DefaultLogDispatchCallback"));
4277 #endif // ELPP_ASYNC_LOGGING
4278 installPerformanceTrackingCallback<base::DefaultPerformanceTrackingCallback>(std::string(
"DefaultPerformanceTrackingCallback"));
4279 ELPP_INTERNAL_INFO(1,
"Easylogging++ has been initialized");
4280 #if ELPP_ASYNC_LOGGING
4281 m_asyncDispatchWorker->start();
4282 #endif // ELPP_ASYNC_LOGGING
4285 virtual ~Storage(
void)
4287 ELPP_INTERNAL_INFO(4,
"Destroying storage");
4288 #if ELPP_ASYNC_LOGGING
4289 ELPP_INTERNAL_INFO(5,
"Replacing log dispatch callback to synchronous");
4290 uninstallLogDispatchCallback<base::AsyncLogDispatchCallback>(std::string(
"AsyncLogDispatchCallback"));
4291 installLogDispatchCallback<base::DefaultLogDispatchCallback>(std::string(
"DefaultLogDispatchCallback"));
4292 ELPP_INTERNAL_INFO(5,
"Destroying asyncDispatchWorker");
4293 base::utils::safeDelete(m_asyncDispatchWorker);
4294 ELPP_INTERNAL_INFO(5,
"Destroying asyncLogQueue");
4295 base::utils::safeDelete(m_asyncLogQueue);
4296 #endif // ELPP_ASYNC_LOGGING
4297 ELPP_INTERNAL_INFO(5,
"Destroying registeredHitCounters");
4298 base::utils::safeDelete(m_registeredHitCounters);
4299 ELPP_INTERNAL_INFO(5,
"Destroying registeredLoggers");
4300 base::utils::safeDelete(m_registeredLoggers);
4301 ELPP_INTERNAL_INFO(5,
"Destroying vRegistry");
4302 base::utils::safeDelete(m_vRegistry);
4305 inline bool validateEveryNCounter(
const char* filename,
unsigned long int lineNumber, std::size_t occasion)
4307 return hitCounters()->validateEveryN(filename, lineNumber, occasion);
4310 inline bool validateAfterNCounter(
const char* filename,
unsigned long int lineNumber, std::size_t n)
4312 return hitCounters()->validateAfterN(filename, lineNumber, n);
4315 inline bool validateNTimesCounter(
const char* filename,
unsigned long int lineNumber, std::size_t n)
4317 return hitCounters()->validateNTimes(filename, lineNumber, n);
4320 inline base::RegisteredHitCounters* hitCounters(
void)
const
4322 return m_registeredHitCounters;
4325 inline base::RegisteredLoggers* registeredLoggers(
void)
const
4327 return m_registeredLoggers;
4330 inline base::VRegistry* vRegistry(
void)
const
4335 #if ELPP_ASYNC_LOGGING
4336 inline base::AsyncLogQueue* asyncLogQueue(
void)
const
4338 return m_asyncLogQueue;
4340 #endif // ELPP_ASYNC_LOGGING
4342 inline const base::utils::CommandLineArgs* commandLineArgs(
void)
const
4344 return &m_commandLineArgs;
4347 inline void addFlag(LoggingFlag flag)
4349 base::utils::addFlag(flag, &m_flags);
4352 inline void removeFlag(LoggingFlag flag)
4354 base::utils::removeFlag(flag, &m_flags);
4357 inline bool hasFlag(LoggingFlag flag)
const
4359 return base::utils::hasFlag(flag, m_flags);
4362 inline base::type::EnumType flags(
void)
const
4367 inline void setFlags(base::type::EnumType flags)
4372 inline void setPreRollOutCallback(
const PreRollOutCallback& callback)
4374 m_preRollOutCallback = callback;
4377 inline void unsetPreRollOutCallback(
void)
4379 m_preRollOutCallback = base::defaultPreRollOutCallback;
4382 inline PreRollOutCallback& preRollOutCallback(
void)
4384 return m_preRollOutCallback;
4387 inline bool hasCustomFormatSpecifier(
const char* formatSpecifier)
4389 base::threading::ScopedLock scopedLock(lock());
4390 return std::find(m_customFormatSpecifiers.begin(), m_customFormatSpecifiers.end(),
4391 formatSpecifier) != m_customFormatSpecifiers.end();
4394 inline void installCustomFormatSpecifier(
const CustomFormatSpecifier& customFormatSpecifier)
4396 if (hasCustomFormatSpecifier(customFormatSpecifier.formatSpecifier())) {
4399 base::threading::ScopedLock scopedLock(lock());
4400 m_customFormatSpecifiers.push_back(customFormatSpecifier);
4403 inline bool uninstallCustomFormatSpecifier(
const char* formatSpecifier)
4405 base::threading::ScopedLock scopedLock(lock());
4406 std::vector<CustomFormatSpecifier>::iterator it = std::find(m_customFormatSpecifiers.begin(),
4407 m_customFormatSpecifiers.end(), formatSpecifier);
4408 if (it != m_customFormatSpecifiers.end() && strcmp(formatSpecifier, it->formatSpecifier()) == 0) {
4409 m_customFormatSpecifiers.erase(it);
4415 const std::vector<CustomFormatSpecifier>* customFormatSpecifiers(
void)
const
4417 return &m_customFormatSpecifiers;
4420 inline void setLoggingLevel(Level level)
4422 m_loggingLevel = level;
4425 template <
typename T>
4426 inline bool installLogDispatchCallback(
const std::string&
id)
4428 return installCallback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks);
4431 template <
typename T>
4432 inline void uninstallLogDispatchCallback(
const std::string&
id)
4434 uninstallCallback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks);
4436 template <
typename T>
4437 inline T* logDispatchCallback(
const std::string&
id)
4439 return callback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks);
4442 template <
typename T>
4443 inline bool installPerformanceTrackingCallback(
const std::string&
id)
4445 return installCallback<T, base::type::PerformanceTrackingCallbackPtr>(id, &m_performanceTrackingCallbacks);
4448 template <
typename T>
4449 inline void uninstallPerformanceTrackingCallback(
const std::string&
id)
4451 uninstallCallback<T, base::type::PerformanceTrackingCallbackPtr>(id, &m_performanceTrackingCallbacks);
4454 template <
typename T>
4455 inline T* performanceTrackingCallback(
const std::string&
id)
4457 return callback<T, base::type::PerformanceTrackingCallbackPtr>(id, &m_performanceTrackingCallbacks);
4460 base::RegisteredHitCounters* m_registeredHitCounters;
4461 base::RegisteredLoggers* m_registeredLoggers;
4462 base::type::EnumType m_flags;
4463 base::VRegistry* m_vRegistry;
4464 #if ELPP_ASYNC_LOGGING
4465 base::AsyncLogQueue* m_asyncLogQueue;
4466 base::IWorker* m_asyncDispatchWorker;
4467 #endif // ELPP_ASYNC_LOGGING
4468 base::utils::CommandLineArgs m_commandLineArgs;
4469 PreRollOutCallback m_preRollOutCallback;
4470 std::map<std::string, base::type::LogDispatchCallbackPtr> m_logDispatchCallbacks;
4471 std::map<std::string, base::type::PerformanceTrackingCallbackPtr> m_performanceTrackingCallbacks;
4472 std::vector<CustomFormatSpecifier> m_customFormatSpecifiers;
4473 Level m_loggingLevel;
4475 friend class el::Helpers;
4476 friend class el::base::DefaultLogDispatchCallback;
4477 friend class el::LogBuilder;
4478 friend class el::base::MessageBuilder;
4479 friend class el::base::Writer;
4480 friend class el::base::PerformanceTracker;
4481 friend class el::base::LogDispatcher;
4483 void setApplicationArguments(
int argc,
char** argv)
4485 m_commandLineArgs.setArgs(argc, argv);
4486 m_vRegistry->setFromArgs(commandLineArgs());
4488 #if !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG)
4489 if (m_commandLineArgs.hasParamWithValue(base::consts::kDefaultLogFileParam)) {
4491 c.setGlobally(ConfigurationType::Filename, std::string(m_commandLineArgs.getParamValue(base::consts::kDefaultLogFileParam)));
4492 registeredLoggers()->setDefaultConfigurations(c);
4493 for (base::RegisteredLoggers::iterator it = registeredLoggers()->begin();
4494 it != registeredLoggers()->end(); ++it) {
4495 it->second->configure(c);
4498 #endif // !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG)
4499 #if defined(ELPP_LOGGING_FLAGS_FROM_ARG)
4500 if (m_commandLineArgs.hasParamWithValue(base::consts::kLoggingFlagsParam)) {
4501 m_flags = atoi(m_commandLineArgs.getParamValue(base::consts::kLoggingFlagsParam));
4503 #endif // defined(ELPP_LOGGING_FLAGS_FROM_ARG)
4506 inline void setApplicationArguments(
int argc,
const char** argv)
4508 setApplicationArguments(argc, const_cast<char**>(argv));
4511 template <
typename T,
typename TPtr>
4512 inline bool installCallback(
const std::string&
id, std::map<std::string, TPtr>* mapT)
4514 if (mapT->find(
id) == mapT->end()) {
4515 mapT->insert(std::make_pair(
id, TPtr(
new T())));
4521 template <
typename T,
typename TPtr>
4522 inline void uninstallCallback(
const std::string&
id, std::map<std::string, TPtr>* mapT)
4524 if (mapT->find(
id) != mapT->end()) {
4529 template <
typename T,
typename TPtr>
4530 inline T* callback(
const std::string&
id, std::map<std::string, TPtr>* mapT)
4532 typename std::map<std::string, TPtr>::iterator iter = mapT->find(
id);
4533 if (iter != mapT->end()) {
4534 return static_cast<T*
>(iter->second.get());
4539 extern ELPP_EXPORT base::type::StoragePointer elStorage;
4540 #define ELPP el::base::elStorage
4541 class DefaultLogDispatchCallback :
public LogDispatchCallback
4544 void handle(
const LogDispatchData* data)
4547 dispatch(m_data->logMessage()->logger()->logBuilder()->build(m_data->logMessage(),
4548 m_data->dispatchAction() == base::DispatchAction::NormalLog));
4551 const LogDispatchData* m_data;
4552 void dispatch(base::type::string_t&& logLine)
4554 if (m_data->dispatchAction() == base::DispatchAction::NormalLog) {
4555 if (m_data->logMessage()->logger()->m_typedConfigurations->toFile(m_data->logMessage()->level())) {
4556 base::type::fstream_t* fs = m_data->logMessage()->logger()->m_typedConfigurations->fileStream(m_data->logMessage()->level());
4557 if (fs !=
nullptr) {
4558 fs->write(logLine.c_str(), logLine.size());
4560 ELPP_INTERNAL_ERROR(
"Unable to write log to file ["
4561 << m_data->logMessage()->logger()->m_typedConfigurations->filename(m_data->logMessage()->level()) <<
"].\n"
4562 <<
"Few possible reasons (could be something else):\n" <<
" * Permission denied\n"
4563 <<
" * Disk full\n" <<
" * Disk is not writable",
true);
4565 if (ELPP->hasFlag(LoggingFlag::ImmediateFlush) || (m_data->logMessage()->logger()->isFlushNeeded(m_data->logMessage()->level()))) {
4566 m_data->logMessage()->logger()->flush(m_data->logMessage()->level(), fs);
4570 ELPP_INTERNAL_ERROR(
"Log file for [" << LevelHelper::convertToString(m_data->logMessage()->level()) <<
"] "
4571 <<
"has not been configured but [TO_FILE] is configured to TRUE. [Logger ID: "
4572 << m_data->logMessage()->logger()->id() <<
"]",
false);
4575 if (m_data->logMessage()->logger()->m_typedConfigurations->toStandardOutput(m_data->logMessage()->level())) {
4576 if (ELPP->hasFlag(LoggingFlag::ColoredTerminalOutput))
4577 m_data->logMessage()->logger()->logBuilder()->convertToColoredOutput(&logLine, m_data->logMessage()->level());
4578 ELPP_COUT << ELPP_COUT_LINE(logLine);
4581 #if defined(ELPP_SYSLOG)
4582 else if (m_data->dispatchAction() == base::DispatchAction::SysLog) {
4584 int sysLogPriority = 0;
4585 if (m_data->logMessage()->level() == Level::Fatal)
4586 sysLogPriority = LOG_EMERG;
4587 else if (m_data->logMessage()->level() == Level::Error)
4588 sysLogPriority = LOG_ERR;
4589 else if (m_data->logMessage()->level() == Level::Warning)
4590 sysLogPriority = LOG_WARNING;
4591 else if (m_data->logMessage()->level() == Level::Info)
4592 sysLogPriority = LOG_INFO;
4593 else if (m_data->logMessage()->level() == Level::Debug)
4594 sysLogPriority = LOG_DEBUG;
4596 sysLogPriority = LOG_NOTICE;
4597 # if defined(ELPP_UNICODE)
4598 char* line = base::utils::Str::wcharPtrToCharPtr(logLine.c_str());
4599 syslog(sysLogPriority,
"%s", line);
4602 syslog(sysLogPriority,
"%s", logLine.c_str());
4605 #endif // defined(ELPP_SYSLOG)
4608 #if ELPP_ASYNC_LOGGING
4609 class AsyncLogDispatchCallback :
public LogDispatchCallback
4612 void handle(
const LogDispatchData* data)
4614 base::type::string_t logLine = data->logMessage()->logger()->logBuilder()->build(data->logMessage(), data->dispatchAction() == base::DispatchAction::NormalLog);
4615 if (data->dispatchAction() == base::DispatchAction::NormalLog && data->logMessage()->logger()->typedConfigurations()->toStandardOutput(data->logMessage()->level())) {
4616 if (ELPP->hasFlag(LoggingFlag::ColoredTerminalOutput))
4617 data->logMessage()->logger()->logBuilder()->convertToColoredOutput(&logLine, data->logMessage()->level());
4618 ELPP_COUT << ELPP_COUT_LINE(logLine);
4621 if (data->logMessage()->logger()->typedConfigurations()->toFile(data->logMessage()->level())) {
4622 ELPP->asyncLogQueue()->push(AsyncLogItem(*(data->logMessage()), *data, logLine));
4626 class AsyncDispatchWorker :
public base::IWorker,
public base::threading::ThreadSafe
4629 AsyncDispatchWorker()
4631 setContinueRunning(
false);
4634 virtual ~AsyncDispatchWorker()
4636 setContinueRunning(
false);
4637 ELPP_INTERNAL_INFO(6,
"Stopping dispatch worker - Cleaning log queue");
4639 ELPP_INTERNAL_INFO(6,
"Log queue cleaned");
4645 std::unique_lock<std::mutex> lk(m);
4646 cv.wait(lk, [] {
return !ELPP->asyncLogQueue()->empty(); });
4650 return ELPP->asyncLogQueue()->empty();
4653 inline void emptyQueue()
4655 while (!ELPP->asyncLogQueue()->empty()) {
4656 AsyncLogItem data = ELPP->asyncLogQueue()->next();
4658 base::threading::msleep(100);
4662 virtual inline void start()
4664 base::threading::msleep(5000);
4665 setContinueRunning(
true);
4666 std::thread t1(&AsyncDispatchWorker::runner,
this);
4670 void handle(AsyncLogItem* logItem)
4672 LogDispatchData* data = logItem->data();
4673 LogMessage* logMessage = logItem->logMessage();
4674 Logger* logger = logMessage->logger();
4675 base::TypedConfigurations* conf = logger->typedConfigurations();
4676 base::type::string_t logLine = logItem->logLine();
4677 if (data->dispatchAction() == base::DispatchAction::NormalLog) {
4678 if (conf->toFile(logMessage->level())) {
4679 base::type::fstream_t* fs = conf->fileStream(logMessage->level());
4680 if (fs !=
nullptr) {
4681 fs->write(logLine.c_str(), logLine.size());
4683 ELPP_INTERNAL_ERROR(
"Unable to write log to file ["
4684 << conf->filename(logMessage->level()) <<
"].\n"
4685 <<
"Few possible reasons (could be something else):\n" <<
" * Permission denied\n"
4686 <<
" * Disk full\n" <<
" * Disk is not writable",
true);
4688 if (ELPP->hasFlag(LoggingFlag::ImmediateFlush) || (logger->isFlushNeeded(logMessage->level()))) {
4689 logger->flush(logMessage->level(), fs);
4693 ELPP_INTERNAL_ERROR(
"Log file for [" << LevelHelper::convertToString(logMessage->level()) <<
"] "
4694 <<
"has not been configured but [TO_FILE] is configured to TRUE. [Logger ID: " << logger->id() <<
"]",
false);
4698 # if defined(ELPP_SYSLOG)
4699 else if (data->dispatchAction() == base::DispatchAction::SysLog) {
4701 int sysLogPriority = 0;
4702 if (logMessage->level() == Level::Fatal)
4703 sysLogPriority = LOG_EMERG;
4704 else if (logMessage->level() == Level::Error)
4705 sysLogPriority = LOG_ERR;
4706 else if (logMessage->level() == Level::Warning)
4707 sysLogPriority = LOG_WARNING;
4708 else if (logMessage->level() == Level::Info)
4709 sysLogPriority = LOG_INFO;
4710 else if (logMessage->level() == Level::Debug)
4711 sysLogPriority = LOG_DEBUG;
4713 sysLogPriority = LOG_NOTICE;
4714 # if defined(ELPP_UNICODE)
4715 char* line = base::utils::Str::wcharPtrToCharPtr(logLine.c_str());
4716 syslog(sysLogPriority,
"%s", line);
4719 syslog(sysLogPriority,
"%s", logLine.c_str());
4722 # endif // defined(ELPP_SYSLOG)
4727 while (continueRunning()) {
4729 base::threading::msleep(10);
4733 static void* runner(
void* context)
4735 static_cast<AsyncDispatchWorker*
>(context)->run();
4739 void setContinueRunning(
bool value)
4741 base::threading::ScopedLock scopedLock(m_continueRunningMutex);
4742 m_continueRunning = value;
4744 bool continueRunning(
void)
4746 return m_continueRunning;
4749 std::condition_variable cv;
4750 bool m_continueRunning;
4751 base::threading::Mutex m_continueRunningMutex;
4753 #endif // ELPP_ASYNC_LOGGING
4756 class DefaultLogBuilder :
public LogBuilder
4759 base::type::string_t build(
const LogMessage* logMessage,
bool appendNewLine)
const
4761 base::TypedConfigurations* tc = logMessage->logger()->typedConfigurations();
4762 const base::LogFormat* logFormat = &tc->logFormat(logMessage->level());
4763 base::type::string_t logLine = logFormat->format();
4764 char buff[base::consts::kSourceFilenameMaxLength + base::consts::kSourceLineMaxLength] =
"";
4765 const char* bufLim = buff +
sizeof(buff);
4766 if (logFormat->hasFlag(base::FormatFlags::AppName)) {
4768 base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kAppNameFormatSpecifier,
4769 logMessage->logger()->parentApplicationName());
4771 if (logFormat->hasFlag(base::FormatFlags::ThreadId)) {
4773 base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kThreadIdFormatSpecifier,
4774 base::threading::getCurrentThreadId());
4776 if (logFormat->hasFlag(base::FormatFlags::DateTime)) {
4778 base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kDateTimeFormatSpecifier,
4779 base::utils::DateTime::getDateTime(logFormat->dateTimeFormat().c_str(),
4780 &tc->millisecondsWidth(logMessage->level())));
4782 if (logFormat->hasFlag(base::FormatFlags::Function)) {
4784 base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogFunctionFormatSpecifier, logMessage->func());
4786 if (logFormat->hasFlag(base::FormatFlags::File)) {
4788 char* buf = base::utils::Str::clearBuff(buff, base::consts::kSourceFilenameMaxLength);
4789 base::utils::File::buildStrippedFilename(logMessage->file().c_str(), buff);
4790 buf = base::utils::Str::addToBuff(buff, buf, bufLim);
4791 base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogFileFormatSpecifier, std::string(buff));
4793 if (logFormat->hasFlag(base::FormatFlags::FileBase)) {
4795 char* buf = base::utils::Str::clearBuff(buff, base::consts::kSourceFilenameMaxLength);
4796 base::utils::File::buildBaseFilename(logMessage->file(), buff);
4797 buf = base::utils::Str::addToBuff(buff, buf, bufLim);
4798 base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogFileBaseFormatSpecifier, std::string(buff));
4800 if (logFormat->hasFlag(base::FormatFlags::Line)) {
4802 char* buf = base::utils::Str::clearBuff(buff, base::consts::kSourceLineMaxLength);
4803 buf = base::utils::Str::convertAndAddToBuff(logMessage->line(),
4804 base::consts::kSourceLineMaxLength, buf, bufLim,
false);
4805 base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogLineFormatSpecifier, std::string(buff));
4807 if (logFormat->hasFlag(base::FormatFlags::Location)) {
4809 char* buf = base::utils::Str::clearBuff(buff,
4810 base::consts::kSourceFilenameMaxLength + base::consts::kSourceLineMaxLength);
4811 base::utils::File::buildStrippedFilename(logMessage->file().c_str(), buff);
4812 buf = base::utils::Str::addToBuff(buff, buf, bufLim);
4813 buf = base::utils::Str::addToBuff(
":", buf, bufLim);
4814 buf = base::utils::Str::convertAndAddToBuff(logMessage->line(),
4815 base::consts::kSourceLineMaxLength, buf, bufLim,
false);
4816 base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogLocationFormatSpecifier, std::string(buff));
4818 if (logMessage->level() == Level::Verbose && logFormat->hasFlag(base::FormatFlags::VerboseLevel)) {
4820 char* buf = base::utils::Str::clearBuff(buff, 1);
4821 buf = base::utils::Str::convertAndAddToBuff(logMessage->verboseLevel(), 1, buf, bufLim,
false);
4822 base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kVerboseLevelFormatSpecifier, std::string(buff));
4824 if (logFormat->hasFlag(base::FormatFlags::LogMessage)) {
4826 base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kMessageFormatSpecifier, logMessage->message());
4828 #if !defined(ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS)
4829 for (std::vector<CustomFormatSpecifier>::const_iterator it = ELPP->customFormatSpecifiers()->begin();
4830 it != ELPP->customFormatSpecifiers()->end(); ++it) {
4831 std::string fs(it->formatSpecifier());
4832 base::type::string_t wcsFormatSpecifier(fs.begin(), fs.end());
4833 base::utils::Str::replaceFirstWithEscape(logLine, wcsFormatSpecifier, std::string(it->resolver()()));
4835 #endif // !defined(ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS)
4836 if (appendNewLine) logLine += ELPP_LITERAL(
"\n");
4841 class LogDispatcher : base::NoCopy
4844 LogDispatcher(
bool proceed, LogMessage&& logMessage, base::DispatchAction dispatchAction) :
4846 m_logMessage(std::move(logMessage)),
4847 m_dispatchAction(std::move(dispatchAction))
4853 if (m_proceed && m_dispatchAction == base::DispatchAction::None) {
4860 base::threading::ScopedLock scopedLock(ELPP->lock());
4861 base::TypedConfigurations* tc = m_logMessage.logger()->m_typedConfigurations;
4862 if (ELPP->hasFlag(LoggingFlag::StrictLogFileSizeCheck)) {
4863 tc->validateFileRolling(m_logMessage.level(), ELPP->preRollOutCallback());
4865 LogDispatchCallback* callback =
nullptr;
4866 LogDispatchData data;
4867 for (
const std::pair<std::string, base::type::LogDispatchCallbackPtr>& h
4868 : ELPP->m_logDispatchCallbacks) {
4869 callback = h.second.get();
4870 if (callback !=
nullptr && callback->enabled()) {
4871 data.setLogMessage(&m_logMessage);
4872 data.setDispatchAction(m_dispatchAction);
4873 callback->acquireLock();
4874 callback->handle(&data);
4875 callback->releaseLock();
4882 LogMessage m_logMessage;
4883 base::DispatchAction m_dispatchAction;
4885 #if defined(ELPP_STL_LOGGING)
4886 namespace workarounds {
4894 template <
typename T,
typename Container>
4895 class IterableContainer
4898 typedef typename Container::iterator iterator;
4899 typedef typename Container::const_iterator const_iterator;
4900 IterableContainer(
void) {}
4901 virtual ~IterableContainer(
void) {}
4902 iterator begin(
void) {
return getContainer().begin(); }
4903 iterator end(
void) {
return getContainer().end(); }
4905 virtual Container& getContainer(
void) = 0;
4908 template<
typename T,
typename Container = std::vector<T>,
typename Comparator = std::less<
typename Container::value_type>>
4909 class IterablePriorityQueue :
public IterableContainer<T, Container>,
public std::priority_queue<T, Container, Comparator>
4912 IterablePriorityQueue(std::priority_queue<T, Container, Comparator> queue_)
4914 std::size_t count_ = 0;
4915 while (++count_ < base::consts::kMaxLogPerContainer && !queue_.empty()) {
4916 this->push(queue_.top());
4921 inline Container& getContainer(
void)
4927 template<
typename T,
typename Container = std::deque<T>>
4928 class IterableQueue :
public IterableContainer<T, Container>,
public std::queue<T, Container>
4931 IterableQueue(std::queue<T, Container> queue_)
4933 std::size_t count_ = 0;
4934 while (++count_ < base::consts::kMaxLogPerContainer && !queue_.empty()) {
4935 this->push(queue_.front());
4940 inline Container& getContainer(
void)
4946 template<
typename T,
typename Container = std::deque<T>>
4947 class IterableStack :
public IterableContainer<T, Container>,
public std::stack<T, Container>
4950 IterableStack(std::stack<T, Container> stack_)
4952 std::size_t count_ = 0;
4953 while (++count_ < base::consts::kMaxLogPerContainer && !stack_.empty()) {
4954 this->push(stack_.top());
4959 inline Container& getContainer(
void)
4965 #endif // defined(ELPP_STL_LOGGING)
4967 class MessageBuilder
4970 MessageBuilder(
void) : m_logger(nullptr), m_containerLogSeperator(ELPP_LITERAL(
"")) {}
4971 void initialize(Logger* logger)
4974 m_containerLogSeperator = ELPP->hasFlag(LoggingFlag::NewLineForContainer) ?
4975 ELPP_LITERAL(
"\n ") : ELPP_LITERAL(
", ");
4978 # define ELPP_SIMPLE_LOG(LOG_TYPE)\
4979 inline MessageBuilder& operator<<(LOG_TYPE msg) {\
4980 m_logger->stream() << msg;\
4981 if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) {\
4982 m_logger->stream() << " ";\
4987 inline MessageBuilder&
operator<<(
const std::string& msg)
4991 ELPP_SIMPLE_LOG(
char)
4992 ELPP_SIMPLE_LOG(
bool)
4993 ELPP_SIMPLE_LOG(
signed short)
4994 ELPP_SIMPLE_LOG(
unsigned short)
4995 ELPP_SIMPLE_LOG(
signed int)
4996 ELPP_SIMPLE_LOG(
unsigned int)
4997 ELPP_SIMPLE_LOG(
signed long)
4998 ELPP_SIMPLE_LOG(
unsigned long)
4999 ELPP_SIMPLE_LOG(
float)
5000 ELPP_SIMPLE_LOG(
double)
5001 ELPP_SIMPLE_LOG(
char*)
5002 ELPP_SIMPLE_LOG(const
char*)
5003 ELPP_SIMPLE_LOG(const
void*)
5004 ELPP_SIMPLE_LOG(
long double)
5005 inline MessageBuilder& operator<<(const std::wstring& msg)
5009 inline MessageBuilder&
operator<<(
const wchar_t* msg)
5011 if (msg ==
nullptr) {
5012 m_logger->stream() << base::consts::kNullPointer;
5015 # if defined(ELPP_UNICODE)
5016 m_logger->stream() << msg;
5018 char* buff_ = base::utils::Str::wcharPtrToCharPtr(msg);
5019 m_logger->stream() << buff_;
5022 if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) {
5023 m_logger->stream() <<
" ";
5028 inline MessageBuilder&
operator<<(std::ostream & (*OStreamMani)(std::ostream&))
5030 m_logger->stream() << OStreamMani;
5033 #define ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(temp) \
5034 template <typename T> \
5035 inline MessageBuilder& operator<<(const temp<T>& template_inst) { \
5036 return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
5038 #define ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(temp) \
5039 template <typename T1, typename T2> \
5040 inline MessageBuilder& operator<<(const temp<T1, T2>& template_inst) { \
5041 return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
5043 #define ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(temp) \
5044 template <typename T1, typename T2, typename T3> \
5045 inline MessageBuilder& operator<<(const temp<T1, T2, T3>& template_inst) { \
5046 return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
5048 #define ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(temp) \
5049 template <typename T1, typename T2, typename T3, typename T4> \
5050 inline MessageBuilder& operator<<(const temp<T1, T2, T3, T4>& template_inst) { \
5051 return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
5053 #define ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(temp) \
5054 template <typename T1, typename T2, typename T3, typename T4, typename T5> \
5055 inline MessageBuilder& operator<<(const temp<T1, T2, T3, T4, T5>& template_inst) { \
5056 return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
5059 #if defined(ELPP_STL_LOGGING)
5060 ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::vector)
5061 ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::list)
5062 ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::deque)
5063 ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(std::set)
5064 ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(std::multiset)
5065 ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::map)
5066 ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::multimap)
5067 template <class T, class Container>
5068 inline MessageBuilder& operator<<(const std::queue<T, Container>& queue_)
5070 base::workarounds::IterableQueue<T, Container> iterableQueue_ =
5071 static_cast<base::workarounds::IterableQueue<T, Container>
>(queue_);
5072 return writeIterator(iterableQueue_.begin(), iterableQueue_.end(), iterableQueue_.size());
5074 template <
class T,
class Container>
5075 inline MessageBuilder& operator<<(const std::stack<T, Container>& stack_)
5077 base::workarounds::IterableStack<T, Container> iterableStack_ =
5078 static_cast<base::workarounds::IterableStack<T, Container>
>(stack_);
5079 return writeIterator(iterableStack_.begin(), iterableStack_.end(), iterableStack_.size());
5081 template <
class T,
class Container,
class Comparator>
5082 inline MessageBuilder& operator<<(const std::priority_queue<T, Container, Comparator>& priorityQueue_)
5084 base::workarounds::IterablePriorityQueue<T, Container, Comparator> iterablePriorityQueue_ =
5085 static_cast<base::workarounds::IterablePriorityQueue<T, Container, Comparator>
>(priorityQueue_);
5086 return writeIterator(iterablePriorityQueue_.begin(), iterablePriorityQueue_.end(), iterablePriorityQueue_.size());
5088 template <
class First,
class Second>
5089 inline MessageBuilder& operator<<(const std::pair<First, Second>& pair_)
5091 m_logger->stream() << ELPP_LITERAL(
"(");
5092 operator << (static_cast<First>(pair_.first));
5093 m_logger->stream() << ELPP_LITERAL(
", ");
5094 operator << (static_cast<Second>(pair_.second));
5095 m_logger->stream() << ELPP_LITERAL(
")");
5098 template <std::
size_t Size>
5099 inline MessageBuilder& operator<<(const std::bitset<Size>& bitset_)
5101 m_logger->stream() << ELPP_LITERAL(
"[");
5103 m_logger->stream() << ELPP_LITERAL(
"]");
5106 # if defined(ELPP_LOG_STD_ARRAY)
5107 template <
class T, std::
size_t Size>
5108 inline MessageBuilder& operator<<(const std::array<T, Size>& array)
5110 return writeIterator(array.begin(), array.end(), array.size());
5112 # endif // defined(ELPP_LOG_STD_ARRAY)
5113 # if defined(ELPP_LOG_UNORDERED_MAP)
5114 ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(std::unordered_map)
5115 ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(std::unordered_multimap)
5116 # endif // defined(ELPP_LOG_UNORDERED_MAP)
5117 # if defined(ELPP_LOG_UNORDERED_SET)
5118 ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::unordered_set)
5119 ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::unordered_multiset)
5120 # endif // defined(ELPP_LOG_UNORDERED_SET)
5121 #endif // defined(ELPP_STL_LOGGING)
5122 #if defined(ELPP_QT_LOGGING)
5123 inline MessageBuilder&
operator<<(
const QString& msg)
5125 # if defined(ELPP_UNICODE)
5126 m_logger->stream() << msg.toStdWString();
5128 m_logger->stream() << msg.toStdString();
5129 # endif // defined(ELPP_UNICODE)
5132 inline MessageBuilder&
operator<<(
const QByteArray& msg)
5136 inline MessageBuilder&
operator<<(
const QStringRef& msg)
5140 inline MessageBuilder&
operator<<(qint64 msg)
5142 # if defined(ELPP_UNICODE)
5143 m_logger->stream() << QString::number(msg).toStdWString();
5145 m_logger->stream() << QString::number(msg).toStdString();
5146 # endif // defined(ELPP_UNICODE)
5149 inline MessageBuilder&
operator<<(quint64 msg)
5151 # if defined(ELPP_UNICODE)
5152 m_logger->stream() << QString::number(msg).toStdWString();
5154 m_logger->stream() << QString::number(msg).toStdString();
5155 # endif // defined(ELPP_UNICODE)
5160 m_logger->stream() << msg.toLatin1();
5163 inline MessageBuilder&
operator<<(
const QLatin1String& msg)
5165 m_logger->stream() << msg.latin1();
5168 ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QList)
5169 ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QVector)
5170 ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QQueue)
5171 ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QSet)
5172 ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QLinkedList)
5173 ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QStack)
5174 template <typename First, typename Second>
5175 inline MessageBuilder& operator<<(const QPair<First, Second>& pair_)
5177 m_logger->stream() << ELPP_LITERAL(
"(");
5178 operator << (static_cast<First>(pair_.first));
5179 m_logger->stream() << ELPP_LITERAL(
", ");
5180 operator << (static_cast<Second>(pair_.second));
5181 m_logger->stream() << ELPP_LITERAL(
")");
5184 template <
typename K,
typename V>
5185 inline MessageBuilder& operator<<(const QMap<K, V>& map_)
5187 m_logger->stream() << ELPP_LITERAL(
"[");
5188 QList<K> keys = map_.keys();
5189 typename QList<K>::const_iterator begin = keys.begin();
5190 typename QList<K>::const_iterator end = keys.end();
5191 int max_ =
static_cast<int>(base::consts::kMaxLogPerContainer);
5192 for (
int index_ = 0; begin != end && index_ < max_; ++index_, ++begin) {
5193 m_logger->stream() << ELPP_LITERAL(
"(");
5194 operator << (static_cast<K>(*begin));
5195 m_logger->stream() << ELPP_LITERAL(
", ");
5196 operator << (static_cast<V>(map_.value(*begin)));
5197 m_logger->stream() << ELPP_LITERAL(
")");
5198 m_logger->stream() << ((index_ < keys.size() - 1) ? m_containerLogSeperator : ELPP_LITERAL(
""));
5201 m_logger->stream() << ELPP_LITERAL(
"...");
5203 m_logger->stream() << ELPP_LITERAL(
"]");
5206 template <
typename K,
typename V>
5207 inline MessageBuilder& operator<<(const QMultiMap<K, V>& map_)
5209 operator << (static_cast<QMap<K, V>>(map_));
5212 template <
typename K,
typename V>
5213 inline MessageBuilder& operator<<(const QHash<K, V>& hash_)
5215 m_logger->stream() << ELPP_LITERAL(
"[");
5216 QList<K> keys = hash_.keys();
5217 typename QList<K>::const_iterator begin = keys.begin();
5218 typename QList<K>::const_iterator end = keys.end();
5219 int max_ =
static_cast<int>(base::consts::kMaxLogPerContainer);
5220 for (
int index_ = 0; begin != end && index_ < max_; ++index_, ++begin) {
5221 m_logger->stream() << ELPP_LITERAL(
"(");
5222 operator << (static_cast<K>(*begin));
5223 m_logger->stream() << ELPP_LITERAL(
", ");
5224 operator << (static_cast<V>(hash_.value(*begin)));
5225 m_logger->stream() << ELPP_LITERAL(
")");
5226 m_logger->stream() << ((index_ < keys.size() - 1) ? m_containerLogSeperator : ELPP_LITERAL(
""));
5229 m_logger->stream() << ELPP_LITERAL(
"...");
5231 m_logger->stream() << ELPP_LITERAL(
"]");
5234 template <
typename K,
typename V>
5235 inline MessageBuilder& operator<<(const QMultiHash<K, V>& multiHash_)
5237 operator << (static_cast<QHash<K, V>>(multiHash_));
5240 #endif // defined(ELPP_QT_LOGGING)
5241 #if defined(ELPP_BOOST_LOGGING)
5242 ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::vector)
5243 ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::stable_vector)
5244 ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::list)
5245 ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::deque)
5246 ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(boost::container::map)
5247 ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(boost::container::flat_map)
5248 ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(boost::container::set)
5249 ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(boost::container::flat_set)
5250 #endif // defined(ELPP_BOOST_LOGGING)
5260 #define MAKE_CONTAINERELPP_FRIENDLY(ContainerType, SizeMethod, ElementInstance) \
5261 el::base::type::ostream_t& operator<<(el::base::type::ostream_t& ss, const ContainerType& container) {\
5262 const el::base::type::char_t* sep = ELPP->hasFlag(el::LoggingFlag::NewLineForContainer) ? \
5263 ELPP_LITERAL("\n ") : ELPP_LITERAL(", ");\
5264 ContainerType::const_iterator elem = container.begin();\
5265 ContainerType::const_iterator endElem = container.end();\
5266 std::size_t size_ = container.SizeMethod; \
5267 ss << ELPP_LITERAL("[");\
5268 for (std::size_t i = 0; elem != endElem && i < el::base::consts::kMaxLogPerContainer; ++i, ++elem) { \
5269 ss << ElementInstance;\
5270 ss << ((i < size_ - 1) ? sep : ELPP_LITERAL(""));\
5272 if (elem != endElem) {\
5273 ss << ELPP_LITERAL("...");\
5275 ss << ELPP_LITERAL("]");\
5278 #if defined(ELPP_WXWIDGETS_LOGGING)
5279 ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(wxVector)
5280 # define ELPP_WX_PTR_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), *(*elem))
5281 # define ELPP_WX_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), (*elem))
5282 # define ELPP_WX_HASH_MAP_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), \
5283 ELPP_LITERAL("(") << elem->first << ELPP_LITERAL(", ") << elem->second << ELPP_LITERAL(")")
5285 # define ELPP_WX_PTR_ENABLED(ContainerType)
5286 # define ELPP_WX_ENABLED(ContainerType)
5287 # define ELPP_WX_HASH_MAP_ENABLED(ContainerType)
5288 #endif // defined(ELPP_WXWIDGETS_LOGGING)
5290 template <
class Class>
5291 ELPP_SIMPLE_LOG(
const Class&)
5292 #undef ELPP_SIMPLE_LOG
5293 #undef ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG
5294 #undef ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG
5295 #undef ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG
5296 #undef ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG
5297 #undef ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG
5300 const base::type::char_t* m_containerLogSeperator;
5302 template<
class Iterator>
5303 inline MessageBuilder& writeIterator(Iterator begin_, Iterator end_, std::size_t size_)
5305 m_logger->stream() << ELPP_LITERAL(
"[");
5306 for (std::size_t i = 0; begin_ != end_ && i < base::consts::kMaxLogPerContainer; ++i, ++begin_) {
5308 m_logger->stream() << ((i < size_ - 1) ? m_containerLogSeperator : ELPP_LITERAL(
""));
5310 if (begin_ != end_) {
5311 m_logger->stream() << ELPP_LITERAL(
"...");
5313 m_logger->stream() << ELPP_LITERAL(
"]");
5314 if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) {
5315 m_logger->stream() <<
" ";
5321 class NullWriter : base::NoCopy
5327 inline NullWriter&
operator<<(std::ostream & (*)(std::ostream&))
5332 template <
typename T>
5339 class Writer : base::NoCopy
5342 Writer(Level level,
const char* file,
unsigned long int line,
5343 const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog,
5344 base::type::VerboseLevel verboseLevel = 0) :
5345 m_level(level), m_file(file), m_line(line), m_func(func), m_verboseLevel(verboseLevel),
5346 m_proceed(false), m_dispatchAction(dispatchAction)
5350 virtual ~Writer(
void)
5355 template <
typename T>
5358 #if ELPP_LOGGING_ENABLED
5360 m_messageBuilder << log;
5362 #endif // ELPP_LOGGING_ENABLED
5366 inline Writer&
operator<<(std::ostream & (*log)(std::ostream&))
5368 #if ELPP_LOGGING_ENABLED
5370 m_messageBuilder << log;
5372 #endif // ELPP_LOGGING_ENABLED
5376 Writer& construct(Logger* logger,
bool needLock =
true)
5379 initializeLogger(logger->id(),
false, needLock);
5380 m_messageBuilder.initialize(m_logger);
5384 Writer& construct(
int count,
const char* loggerIds, ...)
5386 if (ELPP->hasFlag(LoggingFlag::MultiLoggerSupport)) {
5387 va_list loggersList;
5388 va_start(loggersList, loggerIds);
5389 const char*
id = loggerIds;
5390 for (
int i = 0; i < count; ++i) {
5391 m_loggerIds.push_back(std::string(
id));
5392 id = va_arg(loggersList,
const char*);
5394 va_end(loggersList);
5395 initializeLogger(m_loggerIds.at(0));
5397 initializeLogger(std::string(loggerIds));
5399 m_messageBuilder.initialize(m_logger);
5405 const unsigned long int m_line;
5407 base::type::VerboseLevel m_verboseLevel;
5410 base::MessageBuilder m_messageBuilder;
5411 base::DispatchAction m_dispatchAction;
5412 std::vector<std::string> m_loggerIds;
5413 friend class el::Helpers;
5415 void initializeLogger(
const std::string& loggerId,
bool lookup =
true,
bool needLock =
true)
5418 m_logger = ELPP->registeredLoggers()->get(loggerId, ELPP->hasFlag(LoggingFlag::CreateLoggerAutomatically));
5420 if (m_logger ==
nullptr) {
5421 ELPP->acquireLock();
5422 if (!ELPP->registeredLoggers()->has(std::string(base::consts::kDefaultLoggerId))) {
5424 ELPP->registeredLoggers()->get(std::string(base::consts::kDefaultLoggerId));
5426 ELPP->releaseLock();
5427 Writer(Level::Debug, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId)
5428 <<
"Logger [" << loggerId <<
"] is not registered yet!";
5432 m_logger->acquireLock();
5435 if (ELPP->hasFlag(LoggingFlag::HierarchicalLogging)) {
5436 m_proceed = m_level == Level::Verbose ? m_logger->enabled(m_level) :
5437 LevelHelper::castToInt(m_level) >= LevelHelper::castToInt(ELPP->m_loggingLevel);
5439 m_proceed = m_logger->enabled(m_level);
5444 void processDispatch()
5446 #if ELPP_LOGGING_ENABLED
5447 if (ELPP->hasFlag(LoggingFlag::MultiLoggerSupport)) {
5448 bool firstDispatched =
false;
5449 base::type::string_t logMessage;
5453 if (firstDispatched) {
5454 m_logger->stream() << logMessage;
5456 firstDispatched =
true;
5457 if (m_loggerIds.size() > 1) {
5458 logMessage = m_logger->stream().str();
5462 }
else if (m_logger !=
nullptr) {
5463 m_logger->stream().str(ELPP_LITERAL(
""));
5464 m_logger->releaseLock();
5466 if (i + 1 < m_loggerIds.size()) {
5467 initializeLogger(m_loggerIds.at(i + 1));
5469 }
while (++i < m_loggerIds.size());
5473 }
else if (m_logger !=
nullptr) {
5474 m_logger->stream().str(ELPP_LITERAL(
""));
5475 m_logger->releaseLock();
5479 if (m_logger !=
nullptr) {
5480 m_logger->stream().str(ELPP_LITERAL(
""));
5481 m_logger->releaseLock();
5483 #endif // ELPP_LOGGING_ENABLED
5486 void triggerDispatch(
void)
5489 base::LogDispatcher(m_proceed, LogMessage(m_level, m_file, m_line, m_func, m_verboseLevel,
5490 m_logger), m_dispatchAction).dispatch();
5492 if (m_logger !=
nullptr) {
5493 m_logger->stream().str(ELPP_LITERAL(
""));
5494 m_logger->releaseLock();
5496 if (m_proceed && m_level == Level::Fatal
5497 && !ELPP->hasFlag(LoggingFlag::DisableApplicationAbortOnFatalLog)) {
5498 base::Writer(Level::Warning, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId)
5499 <<
"Aborting application. Reason: Fatal log at [" << m_file <<
":" << m_line <<
"]";
5500 std::stringstream reasonStream;
5501 reasonStream <<
"Fatal log at [" << m_file <<
":" << m_line <<
"]"
5502 <<
" If you wish to disable 'abort on fatal log' please use "
5503 <<
"el::Helpers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog)";
5504 base::utils::abort(1, reasonStream.str());
5509 class PErrorWriter :
public base::Writer
5512 PErrorWriter(Level level,
const char* file,
unsigned long int line,
5513 const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog,
5514 base::type::VerboseLevel verboseLevel = 0) :
5515 base::Writer(level, file, line, func, dispatchAction, verboseLevel)
5519 virtual ~PErrorWriter(
void)
5522 #if ELPP_COMPILER_MSVC
5524 strerror_s(buff, 256, errno);
5525 m_logger->stream() <<
": " << buff <<
" [" << errno <<
"]";
5527 m_logger->stream() <<
": " << strerror(errno) <<
" [" << errno <<
"]";
5534 #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
5535 template <
typename T,
typename... Args>
5536 void Logger::log_(Level level,
int vlevel,
const char* s,
const T& value,
const Args& ... args)
5538 base::MessageBuilder b;
5541 if (*s == base::consts::kFormatSpecifierChar) {
5542 if (*(s + 1) == base::consts::kFormatSpecifierChar) {
5545 if (*(s + 1) == base::consts::kFormatSpecifierCharValue) {
5548 log_(level, vlevel, ++s, args...);
5555 ELPP_INTERNAL_ERROR(
"Too many arguments provided. Unable to handle. Please provide more format specifiers",
false);
5557 template <
typename T>
5558 inline void Logger::log_(Level level,
int vlevel,
const T& log)
5560 if (level == Level::Verbose) {
5561 if (ELPP->vRegistry()->allowed(vlevel, __FILE__)) {
5562 base::Writer(Level::Verbose,
"FILE", 0,
"FUNCTION",
5563 base::DispatchAction::NormalLog, vlevel).construct(
this,
false) << log;
5565 stream().str(ELPP_LITERAL(
""));
5568 base::Writer(level,
"FILE", 0,
"FUNCTION").construct(
this,
false) << log;
5571 template <
typename T,
typename... Args>
5572 void Logger::log(Level level,
const char* s,
const T& value,
const Args& ... args)
5574 base::threading::ScopedLock scopedLock(lock());
5575 log_(level, 0, s, value, args...);
5577 template <
typename T>
5578 inline void Logger::log(Level level,
const T& log)
5580 base::threading::ScopedLock scopedLock(lock());
5581 log_(level, 0, log);
5583 # if ELPP_VERBOSE_LOG
5584 template <
typename T,
typename... Args>
5585 inline void Logger::verbose(
int vlevel,
const char* s,
const T& value,
const Args& ... args)
5587 base::threading::ScopedLock scopedLock(lock());
5588 log_(el::Level::Verbose, vlevel, s, value, args...);
5590 template <
typename T>
5591 inline void Logger::verbose(
int vlevel,
const T& log)
5593 base::threading::ScopedLock scopedLock(lock());
5594 log_(el::Level::Verbose, vlevel, log);
5597 template <
typename T,
typename... Args>
5598 inline void Logger::verbose(
int,
const char*,
const T&,
const Args& ...)
5602 template <
typename T>
5603 inline void Logger::verbose(
int,
const T&)
5607 # endif // ELPP_VERBOSE_LOG
5608 # define LOGGER_LEVEL_WRITERS(FUNCTION_NAME, LOG_LEVEL)\
5609 template <typename T, typename... Args>\
5610 inline void Logger::FUNCTION_NAME(const char* s, const T& value, const Args&... args) {\
5611 log(LOG_LEVEL, s, value, args...);\
5613 template <typename T>\
5614 inline void Logger::FUNCTION_NAME(const T& value) {\
5615 log(LOG_LEVEL, value);\
5617 # define LOGGER_LEVEL_WRITERS_DISABLED(FUNCTION_NAME, LOG_LEVEL)\
5618 template <typename T, typename... Args>\
5619 inline void Logger::FUNCTION_NAME(const char*, const T&, const Args&...) {\
5622 template <typename T>\
5623 inline void Logger::FUNCTION_NAME(const T&) {\
5628 LOGGER_LEVEL_WRITERS(info, Level::Info)
5630 LOGGER_LEVEL_WRITERS_DISABLED(info, Level::Info)
5631 # endif // ELPP_INFO_LOG
5633 LOGGER_LEVEL_WRITERS(debug, Level::Debug)
5635 LOGGER_LEVEL_WRITERS_DISABLED(debug, Level::Debug)
5636 # endif // ELPP_DEBUG_LOG
5637 # if ELPP_WARNING_LOG
5638 LOGGER_LEVEL_WRITERS(warn, Level::Warning)
5640 LOGGER_LEVEL_WRITERS_DISABLED(warn, Level::Warning)
5641 # endif // ELPP_WARNING_LOG
5643 LOGGER_LEVEL_WRITERS(error, Level::Error)
5645 LOGGER_LEVEL_WRITERS_DISABLED(error, Level::Error)
5646 # endif // ELPP_ERROR_LOG
5648 LOGGER_LEVEL_WRITERS(fatal, Level::Fatal)
5650 LOGGER_LEVEL_WRITERS_DISABLED(fatal, Level::Fatal)
5651 # endif // ELPP_FATAL_LOG
5653 LOGGER_LEVEL_WRITERS(
trace, Level::Trace)
5655 LOGGER_LEVEL_WRITERS_DISABLED(
trace, Level::Trace)
5656 # endif // ELPP_TRACE_LOG
5657 # undef LOGGER_LEVEL_WRITERS
5658 # undef LOGGER_LEVEL_WRITERS_DISABLED
5659 #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
5660 #if ELPP_COMPILER_MSVC
5661 # define ELPP_VARIADIC_FUNC_MSVC(variadicFunction, variadicArgs) variadicFunction variadicArgs
5662 # define ELPP_VARIADIC_FUNC_MSVC_RUN(variadicFunction, ...) ELPP_VARIADIC_FUNC_MSVC(variadicFunction, (__VA_ARGS__))
5663 # define el_getVALength(...) ELPP_VARIADIC_FUNC_MSVC_RUN(el_resolveVALength, 0, ## __VA_ARGS__,\
5664 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
5666 # if ELPP_COMPILER_CLANG
5667 # define el_getVALength(...) el_resolveVALength(0, __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
5669 # define el_getVALength(...) el_resolveVALength(0, ## __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
5670 # endif // ELPP_COMPILER_CLANG
5671 #endif // ELPP_COMPILER_MSVC
5672 #define el_resolveVALength(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
5673 #define ELPP_WRITE_LOG(writer, level, dispatchAction, ...) \
5674 writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
5675 #define ELPP_WRITE_LOG_IF(writer, condition, level, dispatchAction, ...) if (condition) \
5676 writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
5677 #define ELPP_WRITE_LOG_EVERY_N(writer, occasion, level, dispatchAction, ...) \
5678 if (ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion)) \
5679 writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
5680 #define ELPP_WRITE_LOG_AFTER_N(writer, n, level, dispatchAction, ...) \
5681 if (ELPP->validateAfterNCounter(__FILE__, __LINE__, n)) \
5682 writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
5683 #define ELPP_WRITE_LOG_N_TIMES(writer, n, level, dispatchAction, ...) \
5684 if (ELPP->validateNTimesCounter(__FILE__, __LINE__, n)) \
5685 writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
5686 #undef ELPP_CURR_FILE_PERFORMANCE_LOGGER
5687 #if defined(ELPP_PERFORMANCE_LOGGER)
5688 # define ELPP_CURR_FILE_PERFORMANCE_LOGGER ELPP_PERFORMANCE_LOGGER
5690 # define ELPP_CURR_FILE_PERFORMANCE_LOGGER el::base::consts::kPerformanceLoggerId
5692 class PerformanceTrackingData
5695 enum class DataType : base::type::EnumType {
5696 Checkpoint = 1, Complete = 2
5699 explicit PerformanceTrackingData(DataType dataType) : m_performanceTracker(nullptr),
5700 m_dataType(dataType), m_file(
""), m_line(0), m_func(
"") {}
5701 inline const std::string* blockName(
void)
const;
5702 inline const struct timeval* startTime(
void)
const;
5703 inline const struct timeval* endTime(
void)
const;
5704 inline const struct timeval* lastCheckpointTime(
void)
const;
5705 inline const base::PerformanceTracker* performanceTracker(
void)
const {
return m_performanceTracker; }
5706 inline PerformanceTrackingData::DataType dataType(
void)
const {
return m_dataType; }
5707 inline bool firstCheckpoint(
void)
const {
return m_firstCheckpoint; }
5708 inline std::string checkpointId(
void)
const {
return m_checkpointId; }
5709 inline const char* file(
void)
const {
return m_file; }
5710 inline unsigned long int line(
void)
const {
return m_line; }
5711 inline const char* func(
void)
const {
return m_func; }
5712 inline const base::type::string_t* formattedTimeTaken()
const {
return &m_formattedTimeTaken; }
5713 inline const std::string& loggerId(
void)
const;
5715 base::PerformanceTracker* m_performanceTracker;
5716 base::type::string_t m_formattedTimeTaken;
5717 PerformanceTrackingData::DataType m_dataType;
5718 bool m_firstCheckpoint;
5719 std::string m_checkpointId;
5721 unsigned long int m_line;
5723 inline void init(base::PerformanceTracker* performanceTracker,
bool firstCheckpoint =
false)
5725 m_performanceTracker = performanceTracker;
5726 m_firstCheckpoint = firstCheckpoint;
5729 friend class el::base::PerformanceTracker;
5734 class PerformanceTracker :
public base::threading::ThreadSafe,
public Loggable
5737 PerformanceTracker(
const std::string& blockName,
5738 base::TimestampUnit timestampUnit = base::TimestampUnit::Millisecond,
5739 const std::string& loggerId = std::string(ELPP_CURR_FILE_PERFORMANCE_LOGGER),
5740 bool scopedLog =
true, Level level = base::consts::kPerformanceTrackerDefaultLevel) :
5741 m_blockName(blockName), m_timestampUnit(timestampUnit), m_loggerId(loggerId), m_scopedLog(scopedLog),
5742 m_level(level), m_hasChecked(false), m_lastCheckpointId(std::string()), m_enabled(false)
5744 #if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED
5747 el::Logger* loggerPtr = ELPP->registeredLoggers()->get(loggerId,
false);
5748 m_enabled = loggerPtr !=
nullptr && loggerPtr->m_typedConfigurations->performanceTracking(m_level);
5750 base::utils::DateTime::gettimeofday(&m_startTime);
5752 #endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED
5755 PerformanceTracker(
const PerformanceTracker& t) :
5756 m_blockName(t.m_blockName), m_timestampUnit(t.m_timestampUnit), m_loggerId(t.m_loggerId), m_scopedLog(t.m_scopedLog),
5757 m_level(t.m_level), m_hasChecked(t.m_hasChecked), m_lastCheckpointId(t.m_lastCheckpointId), m_enabled(t.m_enabled),
5758 m_startTime(t.m_startTime), m_endTime(t.m_endTime), m_lastCheckpointTime(t.m_lastCheckpointTime)
5761 virtual ~PerformanceTracker(
void)
5763 #if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED
5765 base::threading::ScopedLock scopedLock(lock());
5767 base::utils::DateTime::gettimeofday(&m_endTime);
5768 base::type::string_t formattedTime = getFormattedTimeTaken();
5769 PerformanceTrackingData data(PerformanceTrackingData::DataType::Complete);
5771 data.m_formattedTimeTaken = formattedTime;
5772 PerformanceTrackingCallback* callback =
nullptr;
5773 for (
const std::pair<std::string, base::type::PerformanceTrackingCallbackPtr>& h
5774 : ELPP->m_performanceTrackingCallbacks) {
5775 callback = h.second.get();
5776 if (callback !=
nullptr && callback->enabled()) {
5777 callback->acquireLock();
5778 callback->handle(&data);
5779 callback->releaseLock();
5784 #endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING)
5787 void checkpoint(
const std::string&
id = std::string(),
const char* file = __FILE__,
unsigned long int line = __LINE__,
const char* func =
"")
5789 #if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED
5791 base::threading::ScopedLock scopedLock(lock());
5792 base::utils::DateTime::gettimeofday(&m_endTime);
5793 base::type::string_t formattedTime = m_hasChecked ? getFormattedTimeTaken(m_lastCheckpointTime) : ELPP_LITERAL(
"");
5794 PerformanceTrackingData data(PerformanceTrackingData::DataType::Checkpoint);
5796 data.m_checkpointId = id;
5800 data.m_formattedTimeTaken = formattedTime;
5801 PerformanceTrackingCallback* callback =
nullptr;
5802 for (
const std::pair<std::string, base::type::PerformanceTrackingCallbackPtr>& h
5803 : ELPP->m_performanceTrackingCallbacks) {
5804 callback = h.second.get();
5805 if (callback !=
nullptr && callback->enabled()) {
5806 callback->acquireLock();
5807 callback->handle(&data);
5808 callback->releaseLock();
5811 base::utils::DateTime::gettimeofday(&m_lastCheckpointTime);
5812 m_hasChecked =
true;
5813 m_lastCheckpointId = id;
5815 #endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED
5821 inline Level level(
void)
const {
return m_level; }
5823 std::string m_blockName;
5824 base::TimestampUnit m_timestampUnit;
5825 std::string m_loggerId;
5829 std::string m_lastCheckpointId;
5831 struct timeval m_startTime, m_endTime, m_lastCheckpointTime;
5833 PerformanceTracker(
void);
5835 friend class el::PerformanceTrackingData;
5836 friend class base::DefaultPerformanceTrackingCallback;
5838 const inline base::type::string_t getFormattedTimeTaken()
const
5840 return getFormattedTimeTaken(m_startTime);
5843 const base::type::string_t getFormattedTimeTaken(
struct timeval startTime)
const
5845 if (ELPP->hasFlag(LoggingFlag::FixedTimeFormat)) {
5846 base::type::stringstream_t ss;
5847 ss << base::utils::DateTime::getTimeDifference(m_endTime,
5848 startTime, m_timestampUnit) <<
" " << base::consts::kTimeFormats[
static_cast<base::type::EnumType
>(m_timestampUnit)].unit;
5851 return base::utils::DateTime::formatTime(base::utils::DateTime::getTimeDifference(m_endTime,
5852 startTime, m_timestampUnit), m_timestampUnit);
5855 virtual inline void log(el::base::type::ostream_t& os)
const
5857 os << getFormattedTimeTaken();
5860 class DefaultPerformanceTrackingCallback :
public PerformanceTrackingCallback
5863 void handle(
const PerformanceTrackingData* data)
5866 base::type::stringstream_t ss;
5867 if (m_data->dataType() == PerformanceTrackingData::DataType::Complete) {
5868 ss << ELPP_LITERAL(
"Executed [") << m_data->blockName()->c_str() << ELPP_LITERAL(
"] in [") << *m_data->formattedTimeTaken() << ELPP_LITERAL(
"]");
5870 ss << ELPP_LITERAL(
"Performance checkpoint");
5871 if (!m_data->checkpointId().empty()) {
5872 ss << ELPP_LITERAL(
" [") << m_data->checkpointId().c_str() << ELPP_LITERAL(
"]");
5874 ss << ELPP_LITERAL(
" for block [") << m_data->blockName()->c_str() << ELPP_LITERAL(
"] : [") << *m_data->performanceTracker();
5875 if (!ELPP->hasFlag(LoggingFlag::DisablePerformanceTrackingCheckpointComparison) && m_data->performanceTracker()->m_hasChecked) {
5876 ss << ELPP_LITERAL(
" ([") << *m_data->formattedTimeTaken() << ELPP_LITERAL(
"] from ");
5877 if (m_data->performanceTracker()->m_lastCheckpointId.empty()) {
5878 ss << ELPP_LITERAL(
"last checkpoint");
5880 ss << ELPP_LITERAL(
"checkpoint '") << m_data->performanceTracker()->m_lastCheckpointId.c_str() << ELPP_LITERAL(
"'");
5882 ss << ELPP_LITERAL(
")]");
5884 ss << ELPP_LITERAL(
"]");
5887 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();
5890 const PerformanceTrackingData* m_data;
5893 inline const std::string* PerformanceTrackingData::blockName()
const
5895 return const_cast<const std::string*
>(&m_performanceTracker->m_blockName);
5897 inline const struct timeval* PerformanceTrackingData::startTime()
const {
5898 return const_cast<const struct timeval*
>(&m_performanceTracker->m_startTime);
5900 inline const struct timeval* PerformanceTrackingData::endTime()
const {
5901 return const_cast<const struct timeval*
>(&m_performanceTracker->m_endTime);
5903 inline const struct timeval* PerformanceTrackingData::lastCheckpointTime()
const {
5904 return const_cast<const struct timeval*
>(&m_performanceTracker->m_lastCheckpointTime);
5906 inline const std::string& PerformanceTrackingData::loggerId(
void)
const {
return m_performanceTracker->m_loggerId; }
5910 class StackTrace : base::NoCopy
5913 static const std::size_t kMaxStack = 64;
5914 static const std::size_t kStackStart = 2;
5915 class StackTraceEntry
5918 StackTraceEntry(std::size_t index,
const char* loc,
const char* demang,
const char* hex,
const char* addr)
5921 m_location = std::string(loc);
5922 m_demangled = std::string(demang);
5923 m_hex = std::string(hex);
5924 m_addr = std::string(addr);
5926 StackTraceEntry(std::size_t index,
char* loc)
5929 m_location = std::string(loc);
5931 std::size_t m_index;
5932 std::string m_location;
5933 std::string m_demangled;
5936 friend std::ostream&
operator<<(std::ostream& ss,
const StackTraceEntry& si)
5938 ss <<
"[" << si.m_index <<
"] " << si.m_location << (si.m_demangled.empty() ?
"" :
":") << si.m_demangled
5939 << (si.m_hex.empty() ?
"" :
"+") << si.m_hex << si.m_addr;
5944 StackTraceEntry(
void);
5952 virtual ~StackTrace(
void)
5956 inline std::vector<StackTraceEntry>& getLatestStack(
void)
5961 friend inline std::ostream&
operator<<(std::ostream& os,
const StackTrace& st)
5963 std::vector<StackTraceEntry>::const_iterator it = st.m_stack.begin();
5964 while (it != st.m_stack.end()) {
5965 os <<
" " << *it++ <<
"\n";
5971 std::vector<StackTraceEntry> m_stack;
5973 void generateNew(
void)
5977 void* stack[kMaxStack];
5978 std::size_t size = backtrace(stack, kMaxStack);
5979 char** strings = backtrace_symbols(stack, size);
5980 if (size > kStackStart) {
5981 for (std::size_t i = kStackStart; i <
size; ++i) {
5982 char* mangName =
nullptr;
5983 char* hex =
nullptr;
5984 char* addr =
nullptr;
5985 for (
char* c = strings[i]; *c; ++c) {
5999 if (mangName !=
nullptr && hex !=
nullptr && addr !=
nullptr && mangName < hex) {
6004 char* demangName = abi::__cxa_demangle(mangName, 0, 0, &status);
6008 StackTraceEntry entry(i - 1, strings[i], demangName, hex, addr);
6009 m_stack.push_back(entry);
6012 StackTraceEntry entry(i - 1, strings[i], mangName, hex, addr);
6013 m_stack.push_back(entry);
6017 StackTraceEntry entry(i - 1, strings[i]);
6018 m_stack.push_back(entry);
6024 ELPP_INTERNAL_INFO(1,
"Stacktrace generation not supported for selected compiler");
6025 #endif // ELPP_STACKTRACE
6028 static std::string crashReason(
int sig)
6030 std::stringstream ss;
6031 bool foundReason =
false;
6032 for (
int i = 0; i < base::consts::kCrashSignalsCount; ++i) {
6033 if (base::consts::kCrashSignals[i].numb == sig) {
6034 ss <<
"Application has crashed due to [" << base::consts::kCrashSignals[i].name <<
"] signal";
6035 if (ELPP->hasFlag(el::LoggingFlag::LogDetailedCrashReason)) {
6037 " " << base::consts::kCrashSignals[i].brief << std::endl <<
6038 " " << base::consts::kCrashSignals[i].detail;
6044 ss <<
"Application has crashed due to unknown signal [" << sig <<
"]";
6049 static void logCrashReason(
int sig,
bool stackTraceIfAvailable, Level level,
const char* logger)
6051 std::stringstream ss;
6052 ss <<
"CRASH HANDLED; ";
6053 ss << crashReason(sig);
6055 if (stackTraceIfAvailable) {
6056 ss << std::endl <<
" ======= Backtrace: =========" << std::endl << base::debug::StackTrace();
6059 ELPP_UNUSED(stackTraceIfAvailable);
6060 #endif // ELPP_STACKTRACE
6061 ELPP_WRITE_LOG(el::base::Writer, level, base::DispatchAction::NormalLog, logger) << ss.str();
6063 static inline void crashAbort(
int sig)
6065 base::utils::abort(sig);
6070 static inline void defaultCrashHandler(
int sig)
6072 base::debug::logCrashReason(sig,
true, Level::Fatal, base::consts::kDefaultLoggerId);
6073 base::debug::crashAbort(sig);
6076 class CrashHandler : base::NoCopy
6079 typedef void (*Handler)(int);
6081 explicit CrashHandler(
bool useDefault)
6084 setHandler(defaultCrashHandler);
6087 explicit CrashHandler(
const Handler& cHandler)
6089 setHandler(cHandler);
6091 void setHandler(
const Handler& cHandler)
6093 m_handler = cHandler;
6094 #if defined(ELPP_HANDLE_SIGABRT)
6098 #endif // defined(ELPP_HANDLE_SIGABRT)
6099 for (; i < base::consts::kCrashSignalsCount; ++i) {
6100 m_handler = signal(base::consts::kCrashSignals[i].numb, cHandler);
6109 extern base::debug::CrashHandler elCrashHandler;
6110 #define MAKE_LOGGABLE(ClassType, ClassInstance, OutputStreamInstance) \
6111 el::base::type::ostream_t& operator<<(el::base::type::ostream_t& OutputStreamInstance, const ClassType& ClassInstance)
6112 class SysLogInitializer
6116 SysLogInitializer(
const char* processIdent,
int options = 0,
int facility = 0)
6118 #if defined(ELPP_SYSLOG)
6119 openlog(processIdent, options, facility);
6121 ELPP_UNUSED(processIdent);
6122 ELPP_UNUSED(options);
6123 ELPP_UNUSED(facility);
6124 #endif // defined(ELPP_SYSLOG)
6126 virtual ~SysLogInitializer(
void)
6128 #if defined(ELPP_SYSLOG)
6130 #endif // defined(ELPP_SYSLOG)
6133 #define ELPP_INITIALIZE_SYSLOG(id, opt, fac) el::SysLogInitializer elSyslogInit(id, opt, fac)
6134 class Helpers : base::StaticClass
6139 static inline void setStorage(base::type::StoragePointer storage)
6144 static inline base::type::StoragePointer storage()
6149 static inline void setArgs(
int argc,
char** argv)
6151 ELPP->setApplicationArguments(argc, argv);
6154 static inline void setArgs(
int argc,
const char** argv)
6156 ELPP->setApplicationArguments(argc, const_cast<char**>(argv));
6161 static inline void setCrashHandler(
const el::base::debug::CrashHandler::Handler& crashHandler)
6163 el::elCrashHandler.setHandler(crashHandler);
6167 static inline void crashAbort(
int sig,
const char* sourceFile =
"",
unsigned int long line = 0)
6169 std::stringstream ss;
6170 ss << base::debug::crashReason(sig).c_str();
6171 ss <<
" - [Called el::Helpers::crashAbort(" << sig <<
")]";
6172 if (sourceFile !=
nullptr && strlen(sourceFile) > 0) {
6173 ss <<
" - Source: " << sourceFile;
6177 ss <<
" (line number not specified)";
6179 base::utils::abort(sig, ss.str());
6186 static inline void logCrashReason(
int sig,
bool stackTraceIfAvailable =
false,
6187 Level level = Level::Fatal,
const char* logger = base::consts::kDefaultLoggerId)
6189 el::base::debug::logCrashReason(sig, stackTraceIfAvailable, level, logger);
6193 static inline void installPreRollOutCallback(
const PreRollOutCallback& callback)
6195 ELPP->setPreRollOutCallback(callback);
6198 static inline void uninstallPreRollOutCallback(
void)
6200 ELPP->unsetPreRollOutCallback();
6203 template <
typename T>
6204 static inline bool installLogDispatchCallback(
const std::string&
id)
6206 return ELPP->installLogDispatchCallback<T>(id);
6209 template <
typename T>
6210 static inline void uninstallLogDispatchCallback(
const std::string&
id)
6212 ELPP->uninstallLogDispatchCallback<T>(id);
6214 template <
typename T>
6215 static inline T* logDispatchCallback(
const std::string&
id)
6217 return ELPP->logDispatchCallback<T>(id);
6220 template <
typename T>
6221 static inline bool installPerformanceTrackingCallback(
const std::string&
id)
6223 return ELPP->installPerformanceTrackingCallback<T>(id);
6226 template <
typename T>
6227 static inline void uninstallPerformanceTrackingCallback(
const std::string&
id)
6229 ELPP->uninstallPerformanceTrackingCallback<T>(id);
6231 template <
typename T>
6232 static inline T* performanceTrackingCallback(
const std::string&
id)
6234 return ELPP->performanceTrackingCallback<T>(id);
6237 template <
typename T>
6238 static std::string convertTemplateToStdString(
const T& templ)
6240 el::Logger* logger =
6241 ELPP->registeredLoggers()->get(el::base::consts::kDefaultLoggerId);
6242 if (logger ==
nullptr) {
6243 return std::string();
6245 base::MessageBuilder b;
6246 b.initialize(logger);
6247 logger->acquireLock();
6249 #if defined(ELPP_UNICODE)
6250 std::string s = std::string(logger->stream().str().begin(), logger->stream().str().end());
6252 std::string s = logger->stream().str();
6253 #endif // defined(ELPP_UNICODE)
6254 logger->stream().str(ELPP_LITERAL(
""));
6255 logger->releaseLock();
6259 static inline const el::base::utils::CommandLineArgs* commandLineArgs(
void)
6261 return ELPP->commandLineArgs();
6264 static inline void installCustomFormatSpecifier(
const CustomFormatSpecifier& customFormatSpecifier)
6266 ELPP->installCustomFormatSpecifier(customFormatSpecifier);
6269 static inline bool uninstallCustomFormatSpecifier(
const char* formatSpecifier)
6271 return ELPP->uninstallCustomFormatSpecifier(formatSpecifier);
6274 static inline bool hasCustomFormatSpecifier(
const char* formatSpecifier)
6276 return ELPP->hasCustomFormatSpecifier(formatSpecifier);
6278 static inline void validateFileRolling(Logger* logger, Level level)
6280 if (logger ==
nullptr)
return;
6281 logger->m_typedConfigurations->validateFileRolling(level, ELPP->preRollOutCallback());
6285 class Loggers : base::StaticClass
6289 static inline Logger* getLogger(
const std::string& identity,
bool registerIfNotAvailable =
true)
6291 base::threading::ScopedLock scopedLock(ELPP->lock());
6292 return ELPP->registeredLoggers()->get(identity, registerIfNotAvailable);
6296 static inline bool unregisterLogger(
const std::string& identity)
6298 base::threading::ScopedLock scopedLock(ELPP->lock());
6299 return ELPP->registeredLoggers()->remove(identity);
6302 static inline bool hasLogger(
const std::string& identity)
6304 base::threading::ScopedLock scopedLock(ELPP->lock());
6305 return ELPP->registeredLoggers()->has(identity);
6308 static inline Logger* reconfigureLogger(Logger* logger,
const Configurations& configurations)
6310 if (!logger)
return nullptr;
6311 logger->configure(configurations);
6315 static inline Logger* reconfigureLogger(
const std::string& identity,
const Configurations& configurations)
6317 return Loggers::reconfigureLogger(Loggers::getLogger(identity), configurations);
6320 static inline Logger* reconfigureLogger(
const std::string& identity, ConfigurationType configurationType,
6321 const std::string& value)
6323 Logger* logger = Loggers::getLogger(identity);
6324 if (logger ==
nullptr) {
6327 logger->configurations()->set(Level::Global, configurationType, value);
6328 logger->reconfigure();
6332 static inline void reconfigureAllLoggers(
const Configurations& configurations)
6334 for (base::RegisteredLoggers::iterator it = ELPP->registeredLoggers()->begin();
6335 it != ELPP->registeredLoggers()->end(); ++it) {
6336 Loggers::reconfigureLogger(it->second, configurations);
6340 static inline void reconfigureAllLoggers(ConfigurationType configurationType,
const std::string& value)
6342 reconfigureAllLoggers(Level::Global, configurationType, value);
6345 static inline void reconfigureAllLoggers(Level level, ConfigurationType configurationType,
6346 const std::string& value)
6348 for (base::RegisteredLoggers::iterator it = ELPP->registeredLoggers()->begin();
6349 it != ELPP->registeredLoggers()->end(); ++it) {
6350 Logger* logger = it->second;
6351 logger->configurations()->set(level, configurationType, value);
6352 logger->reconfigure();
6356 static inline void setDefaultConfigurations(
const Configurations& configurations,
bool reconfigureExistingLoggers =
false)
6358 ELPP->registeredLoggers()->setDefaultConfigurations(configurations);
6359 if (reconfigureExistingLoggers) {
6360 Loggers::reconfigureAllLoggers(configurations);
6364 static inline const Configurations* defaultConfigurations(
void)
6366 return ELPP->registeredLoggers()->defaultConfigurations();
6369 static inline const base::LogStreamsReferenceMap* logStreamsReference(
void)
6371 return ELPP->registeredLoggers()->logStreamsReference();
6374 static base::TypedConfigurations defaultTypedConfigurations(
void)
6376 return base::TypedConfigurations(
6377 ELPP->registeredLoggers()->defaultConfigurations(),
6378 ELPP->registeredLoggers()->logStreamsReference());
6382 static inline std::vector<std::string>* populateAllLoggerIds(std::vector<std::string>* targetList)
6384 targetList->clear();
6385 for (base::RegisteredLoggers::iterator it = ELPP->registeredLoggers()->list().begin();
6386 it != ELPP->registeredLoggers()->list().end(); ++it) {
6387 targetList->push_back(it->first);
6392 static void configureFromGlobal(
const char* globalConfigurationFilePath)
6394 std::ifstream gcfStream(globalConfigurationFilePath, std::ifstream::in);
6395 ELPP_ASSERT(gcfStream.is_open(),
"Unable to open global configuration file [" << globalConfigurationFilePath
6396 <<
"] for parsing.");
6397 std::string line = std::string();
6398 std::stringstream ss;
6399 Logger* logger =
nullptr;
6400 auto configure = [&](void) {
6401 ELPP_INTERNAL_INFO(8,
"Configuring logger: '" << logger->id() <<
"' with configurations \n" << ss.str()
6402 <<
"\n--------------");
6404 c.parseFromText(ss.str());
6405 logger->configure(c);
6407 while (gcfStream.good()) {
6408 std::getline(gcfStream, line);
6409 ELPP_INTERNAL_INFO(1,
"Parsing line: " << line);
6410 base::utils::Str::trim(line);
6411 if (Configurations::Parser::isComment(line))
continue;
6412 Configurations::Parser::ignoreComments(&line);
6413 base::utils::Str::trim(line);
6414 if (line.size() > 2 && base::utils::Str::startsWith(line, std::string(base::consts::kConfigurationLoggerId))) {
6415 if (!ss.str().empty() && logger !=
nullptr) {
6418 ss.str(std::string(
""));
6419 line = line.substr(2);
6420 base::utils::Str::trim(line);
6421 if (line.size() > 1) {
6422 ELPP_INTERNAL_INFO(1,
"Getting logger: '" << line <<
"'");
6423 logger = getLogger(line);
6429 if (!ss.str().empty() && logger !=
nullptr) {
6437 static inline bool configureFromArg(
const char* argKey)
6439 #if defined(ELPP_DISABLE_CONFIGURATION_FROM_PROGRAM_ARGS)
6440 ELPP_UNUSED(argKey);
6442 if (!Helpers::commandLineArgs()->hasParamWithValue(argKey)) {
6445 configureFromGlobal(Helpers::commandLineArgs()->getParamValue(argKey));
6446 #endif // defined(ELPP_DISABLE_CONFIGURATION_FROM_PROGRAM_ARGS)
6450 static inline void flushAll(
void)
6452 ELPP->registeredLoggers()->flushAll();
6455 static inline void addFlag(LoggingFlag flag)
6457 ELPP->addFlag(flag);
6460 static inline void removeFlag(LoggingFlag flag)
6462 ELPP->removeFlag(flag);
6465 static inline bool hasFlag(LoggingFlag flag)
6467 return ELPP->hasFlag(flag);
6473 ScopedAddFlag(LoggingFlag flag) : m_flag(flag) { Loggers::addFlag(m_flag); }
6474 ~ScopedAddFlag(
void) { Loggers::removeFlag(m_flag); }
6479 class ScopedRemoveFlag
6482 ScopedRemoveFlag(LoggingFlag flag) : m_flag(flag) { Loggers::removeFlag(m_flag); }
6483 ~ScopedRemoveFlag(
void) { Loggers::addFlag(m_flag); }
6488 static inline void setLoggingLevel(Level level)
6490 ELPP->setLoggingLevel(level);
6493 static inline void setVerboseLevel(base::type::VerboseLevel level)
6495 ELPP->vRegistry()->setLevel(level);
6498 static inline base::type::VerboseLevel verboseLevel(
void)
6500 return ELPP->vRegistry()->level();
6503 static inline void setVModules(
const char* modules)
6505 if (ELPP->vRegistry()->vModulesEnabled()) {
6506 ELPP->vRegistry()->setModules(modules);
6510 static inline void clearVModules(
void)
6512 ELPP->vRegistry()->clearModules();
6515 class VersionInfo : base::StaticClass
6519 static inline const std::string version(
void) {
return std::string(
"9.80"); }
6521 static inline const std::string releaseDate(
void) {
return std::string(
"08-01-2015 0850hrs"); }
6525 #define VLOG_IS_ON(verboseLevel) (ELPP->vRegistry()->allowed(verboseLevel, __FILE__))
6530 #undef ELPP_MIN_UNIT
6531 #if defined(ELPP_PERFORMANCE_MICROSECONDS)
6532 # define ELPP_MIN_UNIT el::base::TimestampUnit::Microsecond
6534 # define ELPP_MIN_UNIT el::base::TimestampUnit::Millisecond
6535 #endif // (defined(ELPP_PERFORMANCE_MICROSECONDS))
6543 #define TIMED_SCOPE(obj, blockname) el::base::PerformanceTracker obj(blockname, ELPP_MIN_UNIT)
6544 #define TIMED_BLOCK(obj, blockName) for (struct { int i; el::base::PerformanceTracker timer; } obj = { 0, \
6545 el::base::PerformanceTracker(blockName, ELPP_MIN_UNIT) }; obj.i < 1; ++obj.i)
6546 #define TIMED_FUNC(obj) TIMED_SCOPE(obj, ELPP_FUNC)
6553 #undef PERFORMANCE_CHECKPOINT
6554 #undef PERFORMANCE_CHECKPOINT_WITH_ID
6555 #define PERFORMANCE_CHECKPOINT(obj) obj.checkpoint(std::string(), __FILE__, __LINE__, ELPP_FUNC)
6556 #define PERFORMANCE_CHECKPOINT_WITH_ID(obj, id) obj.checkpoint(id, __FILE__, __LINE__, ELPP_FUNC)
6558 #undef ELPP_COUNTER_POS
6559 #define ELPP_COUNTER (ELPP->hitCounters()->getCounter(__FILE__, __LINE__))
6561 #define ELPP_COUNTER_POS (ELPP_COUNTER == nullptr ? -1 : ELPP_COUNTER->hitCounts())
6586 #undef CINFO_EVERY_N
6587 #undef CWARNING_EVERY_N
6588 #undef CDEBUG_EVERY_N
6589 #undef CERROR_EVERY_N
6590 #undef CFATAL_EVERY_N
6591 #undef CTRACE_EVERY_N
6592 #undef CVERBOSE_EVERY_N
6593 #undef CINFO_AFTER_N
6594 #undef CWARNING_AFTER_N
6595 #undef CDEBUG_AFTER_N
6596 #undef CERROR_AFTER_N
6597 #undef CFATAL_AFTER_N
6598 #undef CTRACE_AFTER_N
6599 #undef CVERBOSE_AFTER_N
6600 #undef CINFO_N_TIMES
6601 #undef CWARNING_N_TIMES
6602 #undef CDEBUG_N_TIMES
6603 #undef CERROR_N_TIMES
6604 #undef CFATAL_N_TIMES
6605 #undef CTRACE_N_TIMES
6606 #undef CVERBOSE_N_TIMES
6609 # define CINFO(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Info, dispatchAction, __VA_ARGS__)
6611 # define CINFO(writer, dispatchAction, ...) el::base::NullWriter()
6612 #endif // ELPP_INFO_LOG
6613 #if ELPP_WARNING_LOG
6614 # define CWARNING(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Warning, dispatchAction, __VA_ARGS__)
6616 # define CWARNING(writer, dispatchAction, ...) el::base::NullWriter()
6617 #endif // ELPP_WARNING_LOG
6619 # define CDEBUG(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Debug, dispatchAction, __VA_ARGS__)
6621 # define CDEBUG(writer, dispatchAction, ...) el::base::NullWriter()
6622 #endif // ELPP_DEBUG_LOG
6624 # define CERROR(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Error, dispatchAction, __VA_ARGS__)
6626 # define CERROR(writer, dispatchAction, ...) el::base::NullWriter()
6627 #endif // ELPP_ERROR_LOG
6629 # define CFATAL(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Fatal, dispatchAction, __VA_ARGS__)
6631 # define CFATAL(writer, dispatchAction, ...) el::base::NullWriter()
6632 #endif // ELPP_FATAL_LOG
6634 # define CTRACE(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Trace, dispatchAction, __VA_ARGS__)
6636 # define CTRACE(writer, dispatchAction, ...) el::base::NullWriter()
6637 #endif // ELPP_TRACE_LOG
6638 #if ELPP_VERBOSE_LOG
6639 # define CVERBOSE(writer, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel)) writer(\
6640 el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
6642 # define CVERBOSE(writer, vlevel, dispatchAction, ...) el::base::NullWriter()
6643 #endif // ELPP_VERBOSE_LOG
6646 # define CINFO_IF(writer, condition_, dispatchAction, ...) \
6647 ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Info, dispatchAction, __VA_ARGS__)
6649 # define CINFO_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
6650 #endif // ELPP_INFO_LOG
6651 #if ELPP_WARNING_LOG
6652 # define CWARNING_IF(writer, condition_, dispatchAction, ...)\
6653 ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Warning, dispatchAction, __VA_ARGS__)
6655 # define CWARNING_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
6656 #endif // ELPP_WARNING_LOG
6658 # define CDEBUG_IF(writer, condition_, dispatchAction, ...)\
6659 ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Debug, dispatchAction, __VA_ARGS__)
6661 # define CDEBUG_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
6662 #endif // ELPP_DEBUG_LOG
6664 # define CERROR_IF(writer, condition_, dispatchAction, ...)\
6665 ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Error, dispatchAction, __VA_ARGS__)
6667 # define CERROR_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
6668 #endif // ELPP_ERROR_LOG
6670 # define CFATAL_IF(writer, condition_, dispatchAction, ...)\
6671 ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Fatal, dispatchAction, __VA_ARGS__)
6673 # define CFATAL_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
6674 #endif // ELPP_FATAL_LOG
6676 # define CTRACE_IF(writer, condition_, dispatchAction, ...)\
6677 ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Trace, dispatchAction, __VA_ARGS__)
6679 # define CTRACE_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
6680 #endif // ELPP_TRACE_LOG
6681 #if ELPP_VERBOSE_LOG
6682 # define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel) && (condition_)) writer( \
6683 el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
6685 # define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) el::base::NullWriter()
6686 #endif // ELPP_VERBOSE_LOG
6689 # define CINFO_EVERY_N(writer, occasion, dispatchAction, ...)\
6690 ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Info, dispatchAction, __VA_ARGS__)
6692 # define CINFO_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
6693 #endif // ELPP_INFO_LOG
6694 #if ELPP_WARNING_LOG
6695 # define CWARNING_EVERY_N(writer, occasion, dispatchAction, ...)\
6696 ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Warning, dispatchAction, __VA_ARGS__)
6698 # define CWARNING_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
6699 #endif // ELPP_WARNING_LOG
6701 # define CDEBUG_EVERY_N(writer, occasion, dispatchAction, ...)\
6702 ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Debug, dispatchAction, __VA_ARGS__)
6704 # define CDEBUG_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
6705 #endif // ELPP_DEBUG_LOG
6707 # define CERROR_EVERY_N(writer, occasion, dispatchAction, ...)\
6708 ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Error, dispatchAction, __VA_ARGS__)
6710 # define CERROR_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
6711 #endif // ELPP_ERROR_LOG
6713 # define CFATAL_EVERY_N(writer, occasion, dispatchAction, ...)\
6714 ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Fatal, dispatchAction, __VA_ARGS__)
6716 # define CFATAL_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
6717 #endif // ELPP_FATAL_LOG
6719 # define CTRACE_EVERY_N(writer, occasion, dispatchAction, ...)\
6720 ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Trace, dispatchAction, __VA_ARGS__)
6722 # define CTRACE_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
6723 #endif // ELPP_TRACE_LOG
6724 #if ELPP_VERBOSE_LOG
6725 # define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...)\
6726 CVERBOSE_IF(writer, ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion), vlevel, dispatchAction, __VA_ARGS__)
6728 # define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...) el::base::NullWriter()
6729 #endif // ELPP_VERBOSE_LOG
6732 # define CINFO_AFTER_N(writer, n, dispatchAction, ...)\
6733 ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Info, dispatchAction, __VA_ARGS__)
6735 # define CINFO_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
6736 #endif // ELPP_INFO_LOG
6737 #if ELPP_WARNING_LOG
6738 # define CWARNING_AFTER_N(writer, n, dispatchAction, ...)\
6739 ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Warning, dispatchAction, __VA_ARGS__)
6741 # define CWARNING_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
6742 #endif // ELPP_WARNING_LOG
6744 # define CDEBUG_AFTER_N(writer, n, dispatchAction, ...)\
6745 ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Debug, dispatchAction, __VA_ARGS__)
6747 # define CDEBUG_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
6748 #endif // ELPP_DEBUG_LOG
6750 # define CERROR_AFTER_N(writer, n, dispatchAction, ...)\
6751 ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Error, dispatchAction, __VA_ARGS__)
6753 # define CERROR_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
6754 #endif // ELPP_ERROR_LOG
6756 # define CFATAL_AFTER_N(writer, n, dispatchAction, ...)\
6757 ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Fatal, dispatchAction, __VA_ARGS__)
6759 # define CFATAL_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
6760 #endif // ELPP_FATAL_LOG
6762 # define CTRACE_AFTER_N(writer, n, dispatchAction, ...)\
6763 ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Trace, dispatchAction, __VA_ARGS__)
6765 # define CTRACE_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
6766 #endif // ELPP_TRACE_LOG
6767 #if ELPP_VERBOSE_LOG
6768 # define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...)\
6769 CVERBOSE_IF(writer, ELPP->validateAfterNCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__)
6771 # define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter()
6772 #endif // ELPP_VERBOSE_LOG
6775 # define CINFO_N_TIMES(writer, n, dispatchAction, ...)\
6776 ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Info, dispatchAction, __VA_ARGS__)
6778 # define CINFO_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
6779 #endif // ELPP_INFO_LOG
6780 #if ELPP_WARNING_LOG
6781 # define CWARNING_N_TIMES(writer, n, dispatchAction, ...)\
6782 ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Warning, dispatchAction, __VA_ARGS__)
6784 # define CWARNING_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
6785 #endif // ELPP_WARNING_LOG
6787 # define CDEBUG_N_TIMES(writer, n, dispatchAction, ...)\
6788 ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Debug, dispatchAction, __VA_ARGS__)
6790 # define CDEBUG_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
6791 #endif // ELPP_DEBUG_LOG
6793 # define CERROR_N_TIMES(writer, n, dispatchAction, ...)\
6794 ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Error, dispatchAction, __VA_ARGS__)
6796 # define CERROR_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
6797 #endif // ELPP_ERROR_LOG
6799 # define CFATAL_N_TIMES(writer, n, dispatchAction, ...)\
6800 ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Fatal, dispatchAction, __VA_ARGS__)
6802 # define CFATAL_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
6803 #endif // ELPP_FATAL_LOG
6805 # define CTRACE_N_TIMES(writer, n, dispatchAction, ...)\
6806 ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Trace, dispatchAction, __VA_ARGS__)
6808 # define CTRACE_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
6809 #endif // ELPP_TRACE_LOG
6810 #if ELPP_VERBOSE_LOG
6811 # define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...)\
6812 CVERBOSE_IF(writer, ELPP->validateNTimesCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__)
6814 # define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter()
6815 #endif // ELPP_VERBOSE_LOG
6824 #undef CLOG_VERBOSE_IF
6827 #undef CVLOG_EVERY_N
6829 #undef CVLOG_AFTER_N
6831 #undef CVLOG_N_TIMES
6833 #define CLOG(LEVEL, ...)\
6834 C##LEVEL(el::base::Writer, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6835 #define CVLOG(vlevel, ...) CVERBOSE(el::base::Writer, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6837 #define CLOG_IF(condition, LEVEL, ...)\
6838 C##LEVEL##_IF(el::base::Writer, condition, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6839 #define CVLOG_IF(condition, vlevel, ...)\
6840 CVERBOSE_IF(el::base::Writer, condition, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6842 #define CLOG_EVERY_N(n, LEVEL, ...)\
6843 C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6844 #define CVLOG_EVERY_N(n, vlevel, ...)\
6845 CVERBOSE_EVERY_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6846 #define CLOG_AFTER_N(n, LEVEL, ...)\
6847 C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6848 #define CVLOG_AFTER_N(n, vlevel, ...)\
6849 CVERBOSE_AFTER_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6850 #define CLOG_N_TIMES(n, LEVEL, ...)\
6851 C##LEVEL##_N_TIMES(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6852 #define CVLOG_N_TIMES(n, vlevel, ...)\
6853 CVERBOSE_N_TIMES(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6868 #undef ELPP_CURR_FILE_LOGGER_ID
6869 #if defined(ELPP_DEFAULT_LOGGER)
6870 # define ELPP_CURR_FILE_LOGGER_ID ELPP_DEFAULT_LOGGER
6872 # define ELPP_CURR_FILE_LOGGER_ID el::base::consts::kDefaultLoggerId
6875 #define ELPP_TRACE CLOG(TRACE, ELPP_CURR_FILE_LOGGER_ID)
6877 #define LOG(LEVEL) CLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6878 #define VLOG(vlevel) CVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID)
6880 #define LOG_IF(condition, LEVEL) CLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6881 #define VLOG_IF(condition, vlevel) CVLOG_IF(condition, vlevel, ELPP_CURR_FILE_LOGGER_ID)
6883 #define LOG_EVERY_N(n, LEVEL) CLOG_EVERY_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6884 #define VLOG_EVERY_N(n, vlevel) CVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
6885 #define LOG_AFTER_N(n, LEVEL) CLOG_AFTER_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6886 #define VLOG_AFTER_N(n, vlevel) CVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
6887 #define LOG_N_TIMES(n, LEVEL) CLOG_N_TIMES(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6888 #define VLOG_N_TIMES(n, vlevel) CVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
6898 #define CPLOG(LEVEL, ...)\
6899 C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6900 #define CPLOG_IF(condition, LEVEL, ...)\
6901 C##LEVEL##_IF(el::base::PErrorWriter, condition, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6902 #define DCPLOG(LEVEL, ...)\
6903 if (ELPP_DEBUG_LOG) C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6904 #define DCPLOG_IF(condition, LEVEL, ...)\
6905 C##LEVEL##_IF(el::base::PErrorWriter, (ELPP_DEBUG_LOG) && (condition), el::base::DispatchAction::NormalLog, __VA_ARGS__)
6906 #define PLOG(LEVEL) CPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6907 #define PLOG_IF(condition, LEVEL) CPLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6908 #define DPLOG(LEVEL) DCPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6909 #define DPLOG_IF(condition, LEVEL) DCPLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6913 #undef CSYSLOG_EVERY_N
6914 #undef CSYSLOG_AFTER_N
6915 #undef CSYSLOG_N_TIMES
6918 #undef SYSLOG_EVERY_N
6919 #undef SYSLOG_AFTER_N
6920 #undef SYSLOG_N_TIMES
6923 #undef DCSYSLOG_EVERY_N
6924 #undef DCSYSLOG_AFTER_N
6925 #undef DCSYSLOG_N_TIMES
6928 #undef DSYSLOG_EVERY_N
6929 #undef DSYSLOG_AFTER_N
6930 #undef DSYSLOG_N_TIMES
6931 #if defined(ELPP_SYSLOG)
6932 # define CSYSLOG(LEVEL, ...)\
6933 C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__)
6934 # define CSYSLOG_IF(condition, LEVEL, ...)\
6935 C##LEVEL##_IF(el::base::Writer, condition, el::base::DispatchAction::SysLog, __VA_ARGS__)
6936 # define CSYSLOG_EVERY_N(n, LEVEL, ...) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
6937 # define CSYSLOG_AFTER_N(n, LEVEL, ...) C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
6938 # define CSYSLOG_N_TIMES(n, LEVEL, ...) C##LEVEL##_N_TIMES(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
6939 # define SYSLOG(LEVEL) CSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId)
6940 # define SYSLOG_IF(condition, LEVEL) CSYSLOG_IF(condition, LEVEL, el::base::consts::kSysLogLoggerId)
6941 # define SYSLOG_EVERY_N(n, LEVEL) CSYSLOG_EVERY_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
6942 # define SYSLOG_AFTER_N(n, LEVEL) CSYSLOG_AFTER_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
6943 # define SYSLOG_N_TIMES(n, LEVEL) CSYSLOG_N_TIMES(n, LEVEL, el::base::consts::kSysLogLoggerId)
6944 # define DCSYSLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__)
6945 # define DCSYSLOG_IF(condition, LEVEL, ...)\
6946 C##LEVEL##_IF(el::base::Writer, (ELPP_DEBUG_LOG) && (condition), el::base::DispatchAction::SysLog, __VA_ARGS__)
6947 # define DCSYSLOG_EVERY_N(n, LEVEL, ...)\
6948 if (ELPP_DEBUG_LOG) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
6949 # define DCSYSLOG_AFTER_N(n, LEVEL, ...)\
6950 if (ELPP_DEBUG_LOG) C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
6951 # define DCSYSLOG_N_TIMES(n, LEVEL, ...)\
6952 if (ELPP_DEBUG_LOG) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
6953 # define DSYSLOG(LEVEL) DCSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId)
6954 # define DSYSLOG_IF(condition, LEVEL) DCSYSLOG_IF(condition, LEVEL, el::base::consts::kSysLogLoggerId)
6955 # define DSYSLOG_EVERY_N(n, LEVEL) DCSYSLOG_EVERY_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
6956 # define DSYSLOG_AFTER_N(n, LEVEL) DCSYSLOG_AFTER_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
6957 # define DSYSLOG_N_TIMES(n, LEVEL) DCSYSLOG_N_TIMES(n, LEVEL, el::base::consts::kSysLogLoggerId)
6959 # define CSYSLOG(LEVEL, ...) el::base::NullWriter()
6960 # define CSYSLOG_IF(condition, LEVEL, ...) el::base::NullWriter()
6961 # define CSYSLOG_EVERY_N(n, LEVEL, ...) el::base::NullWriter()
6962 # define CSYSLOG_AFTER_N(n, LEVEL, ...) el::base::NullWriter()
6963 # define CSYSLOG_N_TIMES(n, LEVEL, ...) el::base::NullWriter()
6964 # define SYSLOG(LEVEL) el::base::NullWriter()
6965 # define SYSLOG_IF(condition, LEVEL) el::base::NullWriter()
6966 # define SYSLOG_EVERY_N(n, LEVEL) el::base::NullWriter()
6967 # define SYSLOG_AFTER_N(n, LEVEL) el::base::NullWriter()
6968 # define SYSLOG_N_TIMES(n, LEVEL) el::base::NullWriter()
6969 # define DCSYSLOG(LEVEL, ...) el::base::NullWriter()
6970 # define DCSYSLOG_IF(condition, LEVEL, ...) el::base::NullWriter()
6971 # define DCSYSLOG_EVERY_N(n, LEVEL, ...) el::base::NullWriter()
6972 # define DCSYSLOG_AFTER_N(n, LEVEL, ...) el::base::NullWriter()
6973 # define DCSYSLOG_N_TIMES(n, LEVEL, ...) el::base::NullWriter()
6974 # define DSYSLOG(LEVEL) el::base::NullWriter()
6975 # define DSYSLOG_IF(condition, LEVEL) el::base::NullWriter()
6976 # define DSYSLOG_EVERY_N(n, LEVEL) el::base::NullWriter()
6977 # define DSYSLOG_AFTER_N(n, LEVEL) el::base::NullWriter()
6978 # define DSYSLOG_N_TIMES(n, LEVEL) el::base::NullWriter()
6979 #endif // defined(ELPP_SYSLOG)
6988 #undef DCLOG_EVERY_N
6989 #undef DCVLOG_EVERY_N
6990 #undef DCLOG_AFTER_N
6991 #undef DCVLOG_AFTER_N
6992 #undef DCLOG_N_TIMES
6993 #undef DCVLOG_N_TIMES
6995 #define DCLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG(LEVEL, __VA_ARGS__)
6996 #define DCLOG_VERBOSE(vlevel, ...) if (ELPP_DEBUG_LOG) CLOG_VERBOSE(vlevel, __VA_ARGS__)
6997 #define DCVLOG(vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG(vlevel, __VA_ARGS__)
6999 #define DCLOG_IF(condition, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_IF(condition, LEVEL, __VA_ARGS__)
7000 #define DCVLOG_IF(condition, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_IF(condition, vlevel, __VA_ARGS__)
7002 #define DCLOG_EVERY_N(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_EVERY_N(n, LEVEL, __VA_ARGS__)
7003 #define DCVLOG_EVERY_N(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_EVERY_N(n, vlevel, __VA_ARGS__)
7004 #define DCLOG_AFTER_N(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_AFTER_N(n, LEVEL, __VA_ARGS__)
7005 #define DCVLOG_AFTER_N(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_AFTER_N(n, vlevel, __VA_ARGS__)
7006 #define DCLOG_N_TIMES(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_N_TIMES(n, LEVEL, __VA_ARGS__)
7007 #define DCVLOG_N_TIMES(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_N_TIMES(n, vlevel, __VA_ARGS__)
7017 #undef DVLOG_EVERY_N
7019 #undef DVLOG_AFTER_N
7021 #undef DVLOG_N_TIMES
7023 #define DLOG(LEVEL) DCLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
7024 #define DVLOG(vlevel) DCVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID)
7026 #define DLOG_IF(condition, LEVEL) DCLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
7027 #define DVLOG_IF(condition, vlevel) DCVLOG_IF(condition, vlevel, ELPP_CURR_FILE_LOGGER_ID)
7029 #define DLOG_EVERY_N(n, LEVEL) DCLOG_EVERY_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
7030 #define DVLOG_EVERY_N(n, vlevel) DCVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
7031 #define DLOG_AFTER_N(n, LEVEL) DCLOG_AFTER_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
7032 #define DVLOG_AFTER_N(n, vlevel) DCVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
7033 #define DLOG_N_TIMES(n, LEVEL) DCLOG_N_TIMES(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
7034 #define DVLOG_N_TIMES(n, vlevel) DCVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
7044 #undef CCHECK_BOUNDS
7045 #undef CCHECK_NOTNULL
7046 #undef CCHECK_STRCASEEQ
7047 #undef CCHECK_STRCASENE
7057 #undef CHECK_NOTNULL
7058 #undef CHECK_STRCASEEQ
7059 #undef CHECK_STRCASENE
7060 #define CCHECK(condition, ...) CLOG_IF(!(condition), FATAL, __VA_ARGS__) << "Check failed: [" << #condition << "] "
7061 #define CPCHECK(condition, ...) CPLOG_IF(!(condition), FATAL, __VA_ARGS__) << "Check failed: [" << #condition << "] "
7062 #define CHECK(condition) CCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
7063 #define PCHECK(condition) CPCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
7064 #define CCHECK_EQ(a, b, ...) CCHECK(a == b, __VA_ARGS__)
7065 #define CCHECK_NE(a, b, ...) CCHECK(a != b, __VA_ARGS__)
7066 #define CCHECK_LT(a, b, ...) CCHECK(a < b, __VA_ARGS__)
7067 #define CCHECK_GT(a, b, ...) CCHECK(a > b, __VA_ARGS__)
7068 #define CCHECK_LE(a, b, ...) CCHECK(a <= b, __VA_ARGS__)
7069 #define CCHECK_GE(a, b, ...) CCHECK(a >= b, __VA_ARGS__)
7070 #define CCHECK_BOUNDS(val, min, max, ...) CCHECK(val >= min && val <= max, __VA_ARGS__)
7071 #define CHECK_EQ(a, b) CCHECK_EQ(a, b, ELPP_CURR_FILE_LOGGER_ID)
7072 #define CHECK_NE(a, b) CCHECK_NE(a, b, ELPP_CURR_FILE_LOGGER_ID)
7073 #define CHECK_LT(a, b) CCHECK_LT(a, b, ELPP_CURR_FILE_LOGGER_ID)
7074 #define CHECK_GT(a, b) CCHECK_GT(a, b, ELPP_CURR_FILE_LOGGER_ID)
7075 #define CHECK_LE(a, b) CCHECK_LE(a, b, ELPP_CURR_FILE_LOGGER_ID)
7076 #define CHECK_GE(a, b) CCHECK_GE(a, b, ELPP_CURR_FILE_LOGGER_ID)
7077 #define CHECK_BOUNDS(val, min, max) CCHECK_BOUNDS(val, min, max, ELPP_CURR_FILE_LOGGER_ID)
7081 template <
typename T>
7082 static T* checkNotNull(T* ptr,
const char* name,
const char* loggers, ...)
7084 CLOG_IF(ptr ==
nullptr, FATAL, loggers) <<
"Check failed: [" << name <<
" != nullptr]";
7090 #define CCHECK_NOTNULL(ptr, ...) el::base::utils::checkNotNull(ptr, #ptr, __VA_ARGS__)
7091 #define CCHECK_STREQ(str1, str2, ...) CLOG_IF(!el::base::utils::Str::cStringEq(str1, str2), FATAL, __VA_ARGS__) \
7092 << "Check failed: [" << #str1 << " == " << #str2 << "] "
7093 #define CCHECK_STRNE(str1, str2, ...) CLOG_IF(el::base::utils::Str::cStringEq(str1, str2), FATAL, __VA_ARGS__) \
7094 << "Check failed: [" << #str1 << " != " << #str2 << "] "
7095 #define CCHECK_STRCASEEQ(str1, str2, ...) CLOG_IF(!el::base::utils::Str::cStringCaseEq(str1, str2), FATAL, __VA_ARGS__) \
7096 << "Check failed: [" << #str1 << " == " << #str2 << "] "
7097 #define CCHECK_STRCASENE(str1, str2, ...) CLOG_IF(el::base::utils::Str::cStringCaseEq(str1, str2), FATAL, __VA_ARGS__) \
7098 << "Check failed: [" << #str1 << " != " << #str2 << "] "
7099 #define CHECK_NOTNULL(ptr) CCHECK_NOTNULL(ptr, ELPP_CURR_FILE_LOGGER_ID)
7100 #define CHECK_STREQ(str1, str2) CCHECK_STREQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
7101 #define CHECK_STRNE(str1, str2) CCHECK_STRNE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
7102 #define CHECK_STRCASEEQ(str1, str2) CCHECK_STRCASEEQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
7103 #define CHECK_STRCASENE(str1, str2) CCHECK_STRCASENE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
7111 #undef DCCHECK_BOUNDS
7112 #undef DCCHECK_NOTNULL
7113 #undef DCCHECK_STRCASEEQ
7114 #undef DCCHECK_STRCASENE
7123 #undef DCHECK_BOUNDS_
7124 #undef DCHECK_NOTNULL
7125 #undef DCHECK_STRCASEEQ
7126 #undef DCHECK_STRCASENE
7128 #define DCCHECK(condition, ...) if (ELPP_DEBUG_LOG) CCHECK(condition, __VA_ARGS__)
7129 #define DCCHECK_EQ(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_EQ(a, b, __VA_ARGS__)
7130 #define DCCHECK_NE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_NE(a, b, __VA_ARGS__)
7131 #define DCCHECK_LT(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_LT(a, b, __VA_ARGS__)
7132 #define DCCHECK_GT(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_GT(a, b, __VA_ARGS__)
7133 #define DCCHECK_LE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_LE(a, b, __VA_ARGS__)
7134 #define DCCHECK_GE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_GE(a, b, __VA_ARGS__)
7135 #define DCCHECK_BOUNDS(val, min, max, ...) if (ELPP_DEBUG_LOG) CCHECK_BOUNDS(val, min, max, __VA_ARGS__)
7136 #define DCCHECK_NOTNULL(ptr, ...) if (ELPP_DEBUG_LOG) CCHECK_NOTNULL(ptr, __VA_ARGS__)
7137 #define DCCHECK_STREQ(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STREQ(str1, str2, __VA_ARGS__)
7138 #define DCCHECK_STRNE(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRNE(str1, str2, __VA_ARGS__)
7139 #define DCCHECK_STRCASEEQ(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRCASEEQ(str1, str2, __VA_ARGS__)
7140 #define DCCHECK_STRCASENE(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRCASENE(str1, str2, __VA_ARGS__)
7141 #define DCPCHECK(condition, ...) if (ELPP_DEBUG_LOG) CPCHECK(condition, __VA_ARGS__)
7142 #define DCHECK(condition) DCCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
7143 #define DCHECK_EQ(a, b) DCCHECK_EQ(a, b, ELPP_CURR_FILE_LOGGER_ID)
7144 #define DCHECK_NE(a, b) DCCHECK_NE(a, b, ELPP_CURR_FILE_LOGGER_ID)
7145 #define DCHECK_LT(a, b) DCCHECK_LT(a, b, ELPP_CURR_FILE_LOGGER_ID)
7146 #define DCHECK_GT(a, b) DCCHECK_GT(a, b, ELPP_CURR_FILE_LOGGER_ID)
7147 #define DCHECK_LE(a, b) DCCHECK_LE(a, b, ELPP_CURR_FILE_LOGGER_ID)
7148 #define DCHECK_GE(a, b) DCCHECK_GE(a, b, ELPP_CURR_FILE_LOGGER_ID)
7149 #define DCHECK_BOUNDS(val, min, max) DCCHECK_BOUNDS(val, min, max, ELPP_CURR_FILE_LOGGER_ID)
7150 #define DCHECK_NOTNULL(ptr) DCCHECK_NOTNULL(ptr, ELPP_CURR_FILE_LOGGER_ID)
7151 #define DCHECK_STREQ(str1, str2) DCCHECK_STREQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
7152 #define DCHECK_STRNE(str1, str2) DCCHECK_STRNE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
7153 #define DCHECK_STRCASEEQ(str1, str2) DCCHECK_STRCASEEQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
7154 #define DCHECK_STRCASENE(str1, str2) DCCHECK_STRCASENE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
7155 #define DPCHECK(condition) DCPCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
7156 #if defined(ELPP_DISABLE_DEFAULT_CRASH_HANDLING)
7157 # define ELPP_USE_DEF_CRASH_HANDLER false
7159 # define ELPP_USE_DEF_CRASH_HANDLER true
7160 #endif // defined(ELPP_DISABLE_DEFAULT_CRASH_HANDLING)
7161 #define ELPP_CRASH_HANDLER_INIT
7162 #define ELPP_INIT_EASYLOGGINGPP(val)\
7163 ELPP_INITI_BASIC_DECLR\
7166 el::base::type::StoragePointer elStorage(val);\
7168 el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\
7171 #if ELPP_ASYNC_LOGGING
7172 # define INITIALIZE_EASYLOGGINGPP\
7173 ELPP_INIT_EASYLOGGINGPP(new el::base::Storage(el::LogBuilderPtr(new el::base::DefaultLogBuilder()),\
7174 new el::base::AsyncDispatchWorker()))\
7177 # define INITIALIZE_EASYLOGGINGPP\
7178 ELPP_INIT_EASYLOGGINGPP(new el::base::Storage(el::LogBuilderPtr(new el::base::DefaultLogBuilder())))
7179 #endif // ELPP_ASYNC_LOGGING
7180 #define INITIALIZE_NULL_EASYLOGGINGPP\
7181 ELPP_INITI_BASIC_DECLR\
7184 el::base::type::StoragePointer elStorage;\
7186 el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\
7189 #define SHARE_EASYLOGGINGPP(initializedStorage)\
7192 el::base::type::StoragePointer elStorage(initializedStorage);\
7194 el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\
7197 #if defined(ELPP_UNICODE)
7198 # define START_EASYLOGGINGPP(argc, argv) el::Helpers::setArgs(argc, argv); std::locale::global(std::locale(""))
7200 # define START_EASYLOGGINGPP(argc, argv) el::Helpers::setArgs(argc, argv)
7201 #endif // defined(ELPP_UNICODE)
7202 #endif // EASYLOGGINGPP_H
bool contains(InputIt1 first_haystack, InputIt1 last_haystack, InputIt2 first_needle, InputIt2 last_needle, BinaryPredicate p)
Definition: container_utils.h:49
bool operator==(const CachedValue::Status &S, const CalculationStatus &s)
equality operator for checking the CalculationStatus
Definition: CachedValue.h:153
bool operator!=(const CachedValue::Status &S, const CalculationStatus &s)
inequality operator for checking the CalculationStatus
Definition: CachedValue.h:157
const size_t size(const ParameterVector &V)
Definition: Parameter.h:283
std::ostream & operator<<(std::ostream &os, const DecayChannel &dc)
<< operator
Definition: DecayChannel.h:127
const CoordinateSystem< T, N > unit(const CoordinateSystem< T, N > &C)
Definition: CoordinateSystem.h:52
const T trace(const SquareMatrix< T, N > &M)
trace
Definition: Matrix.h:340