RDFS
The Rice Comp413 2017 class' continuation on the work of the 2016 RDFS.
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
easylogging++.h
1 //
2 // Bismillah ar-Rahmaan ar-Raheem
3 //
4 // Easylogging++ v9.95.3
5 // Single-header only, cross-platform logging library for C++ applications
6 //
7 // Copyright (c) 2017 muflihun.com
8 //
9 // This library is released under the MIT Licence.
10 // http://labs.muflihun.com/easyloggingpp/licence.php
11 //
12 // https://github.com/muflihun/easyloggingpp
13 // https://muflihun.github.io/easyloggingpp
14 // http://muflihun.com
15 //
16 #ifndef EASYLOGGINGPP_H
17 #define EASYLOGGINGPP_H
18 // Compilers and C++0x/C++11 Evaluation
19 #if __cplusplus >= 201103L
20 # define ELPP_CXX11 1
21 #endif // __cplusplus >= 201103L
22 #if (defined(__GNUC__))
23 # define ELPP_COMPILER_GCC 1
24 #else
25 # define ELPP_COMPILER_GCC 0
26 #endif
27 #if ELPP_COMPILER_GCC
28 # define ELPP_GCC_VERSION (__GNUC__ * 10000 \
29 + __GNUC_MINOR__ * 100 \
30 + __GNUC_PATCHLEVEL__)
31 # if defined(__GXX_EXPERIMENTAL_CXX0X__)
32 # define ELPP_CXX0X 1
33 # endif
34 #endif
35 // Visual C++
36 #if defined(_MSC_VER)
37 # define ELPP_COMPILER_MSVC 1
38 #else
39 # define ELPP_COMPILER_MSVC 0
40 #endif
41 #define ELPP_CRT_DBG_WARNINGS ELPP_COMPILER_MSVC
42 #if ELPP_COMPILER_MSVC
43 # if (_MSC_VER == 1600)
44 # define ELPP_CXX0X 1
45 # elif(_MSC_VER >= 1700)
46 # define ELPP_CXX11 1
47 # endif
48 #endif
49 // Clang++
50 #if (defined(__clang__) && (__clang__ == 1))
51 # define ELPP_COMPILER_CLANG 1
52 #else
53 # define ELPP_COMPILER_CLANG 0
54 #endif
55 #if ELPP_COMPILER_CLANG
56 # if __has_include(<thread>)
57 # include <cstddef> // Make __GLIBCXX__ defined when using libstdc++
58 # if !defined(__GLIBCXX__) || __GLIBCXX__ >= 20150426
59 # define ELPP_CLANG_SUPPORTS_THREAD
60 # endif // !defined(__GLIBCXX__) || __GLIBCXX__ >= 20150426
61 # endif // __has_include(<thread>)
62 #endif
63 #if (defined(__MINGW32__) || defined(__MINGW64__))
64 # define ELPP_MINGW 1
65 #else
66 # define ELPP_MINGW 0
67 #endif
68 #if (defined(__CYGWIN__) && (__CYGWIN__ == 1))
69 # define ELPP_CYGWIN 1
70 #else
71 # define ELPP_CYGWIN 0
72 #endif
73 #if (defined(__INTEL_COMPILER))
74 # define ELPP_COMPILER_INTEL 1
75 #else
76 # define ELPP_COMPILER_INTEL 0
77 #endif
78 // Operating System Evaluation
79 // Windows
80 #if (defined(_WIN32) || defined(_WIN64))
81 # define ELPP_OS_WINDOWS 1
82 #else
83 # define ELPP_OS_WINDOWS 0
84 #endif
85 // Linux
86 #if (defined(__linux) || defined(__linux__))
87 # define ELPP_OS_LINUX 1
88 #else
89 # define ELPP_OS_LINUX 0
90 #endif
91 #if (defined(__APPLE__))
92 # define ELPP_OS_MAC 1
93 #else
94 # define ELPP_OS_MAC 0
95 #endif
96 #if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
97 # define ELPP_OS_FREEBSD 1
98 #else
99 # define ELPP_OS_FREEBSD 0
100 #endif
101 #if (defined(__sun))
102 # define ELPP_OS_SOLARIS 1
103 #else
104 # define ELPP_OS_SOLARIS 0
105 #endif
106 #if (defined(_AIX))
107 # define ELPP_OS_AIX 1
108 #else
109 # define ELPP_OS_AIX 0
110 #endif
111 #if (defined(__NetBSD__))
112 # define ELPP_OS_NETBSD 1
113 #else
114 # define ELPP_OS_NETBSD 0
115 #endif
116 // Unix
117 #if ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_NETBSD || ELPP_OS_SOLARIS || ELPP_OS_AIX) && (!ELPP_OS_WINDOWS))
118 # define ELPP_OS_UNIX 1
119 #else
120 # define ELPP_OS_UNIX 0
121 #endif
122 #if (defined(__ANDROID__))
123 # define ELPP_OS_ANDROID 1
124 #else
125 # define ELPP_OS_ANDROID 0
126 #endif
127 // Evaluating Cygwin as *nix OS
128 #if !ELPP_OS_UNIX && !ELPP_OS_WINDOWS && ELPP_CYGWIN
129 # undef ELPP_OS_UNIX
130 # undef ELPP_OS_LINUX
131 # define ELPP_OS_UNIX 1
132 # define ELPP_OS_LINUX 1
133 #endif // !ELPP_OS_UNIX && !ELPP_OS_WINDOWS && ELPP_CYGWIN
134 #if !defined(ELPP_INTERNAL_DEBUGGING_OUT_INFO)
135 # define ELPP_INTERNAL_DEBUGGING_OUT_INFO std::cout
136 #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
137 #if !defined(ELPP_INTERNAL_DEBUGGING_OUT_ERROR)
138 # define ELPP_INTERNAL_DEBUGGING_OUT_ERROR std::cerr
139 #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
140 #if !defined(ELPP_INTERNAL_DEBUGGING_ENDL)
141 # define ELPP_INTERNAL_DEBUGGING_ENDL std::endl
142 #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
143 #if !defined(ELPP_INTERNAL_DEBUGGING_MSG)
144 # define ELPP_INTERNAL_DEBUGGING_MSG(msg) msg
145 #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
146 // Internal Assertions and errors
147 #if !defined(ELPP_DISABLE_ASSERT)
148 # if (defined(ELPP_DEBUG_ASSERT_FAILURE))
149 # define ELPP_ASSERT(expr, msg) if (!(expr)) { \
150 std::stringstream internalInfoStream; internalInfoStream << msg; \
151 ELPP_INTERNAL_DEBUGGING_OUT_ERROR \
152 << "EASYLOGGING++ ASSERTION FAILED (LINE: " << __LINE__ << ") [" #expr << "] WITH MESSAGE \"" \
153 << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << "\"" << ELPP_INTERNAL_DEBUGGING_ENDL; base::utils::abort(1, \
154 "ELPP Assertion failure, please define ELPP_DEBUG_ASSERT_FAILURE"); }
155 # else
156 # define ELPP_ASSERT(expr, msg) if (!(expr)) { \
157 std::stringstream internalInfoStream; internalInfoStream << msg; \
158 ELPP_INTERNAL_DEBUGGING_OUT_ERROR\
159 << "ASSERTION FAILURE FROM EASYLOGGING++ (LINE: " \
160 << __LINE__ << ") [" #expr << "] WITH MESSAGE \"" << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << "\"" \
161 << ELPP_INTERNAL_DEBUGGING_ENDL; }
162 # endif // (defined(ELPP_DEBUG_ASSERT_FAILURE))
163 #else
164 # define ELPP_ASSERT(x, y)
165 #endif //(!defined(ELPP_DISABLE_ASSERT)
166 #if ELPP_COMPILER_MSVC
167 # define ELPP_INTERNAL_DEBUGGING_WRITE_PERROR \
168 { char buff[256]; strerror_s(buff, 256, errno); \
169 ELPP_INTERNAL_DEBUGGING_OUT_ERROR << ": " << buff << " [" << errno << "]";} (void)0
170 #else
171 # define ELPP_INTERNAL_DEBUGGING_WRITE_PERROR \
172 ELPP_INTERNAL_DEBUGGING_OUT_ERROR << ": " << strerror(errno) << " [" << errno << "]"; (void)0
173 #endif // ELPP_COMPILER_MSVC
174 #if defined(ELPP_DEBUG_ERRORS)
175 # if !defined(ELPP_INTERNAL_ERROR)
176 # define ELPP_INTERNAL_ERROR(msg, pe) { \
177 std::stringstream internalInfoStream; internalInfoStream << "<ERROR> " << msg; \
178 ELPP_INTERNAL_DEBUGGING_OUT_ERROR \
179 << "ERROR FROM EASYLOGGING++ (LINE: " << __LINE__ << ") " \
180 << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << ELPP_INTERNAL_DEBUGGING_ENDL; \
181 if (pe) { ELPP_INTERNAL_DEBUGGING_OUT_ERROR << " "; ELPP_INTERNAL_DEBUGGING_WRITE_PERROR; }} (void)0
182 # endif
183 #else
184 # undef ELPP_INTERNAL_INFO
185 # define ELPP_INTERNAL_ERROR(msg, pe)
186 #endif // defined(ELPP_DEBUG_ERRORS)
187 #if (defined(ELPP_DEBUG_INFO))
188 # if !(defined(ELPP_INTERNAL_INFO_LEVEL))
189 # define ELPP_INTERNAL_INFO_LEVEL 9
190 # endif // !(defined(ELPP_INTERNAL_INFO_LEVEL))
191 # if !defined(ELPP_INTERNAL_INFO)
192 # define ELPP_INTERNAL_INFO(lvl, msg) { if (lvl <= ELPP_INTERNAL_INFO_LEVEL) { \
193 std::stringstream internalInfoStream; internalInfoStream << "<INFO> " << msg; \
194 ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) \
195 << ELPP_INTERNAL_DEBUGGING_ENDL; }}
196 # endif
197 #else
198 # undef ELPP_INTERNAL_INFO
199 # define ELPP_INTERNAL_INFO(lvl, msg)
200 #endif // (defined(ELPP_DEBUG_INFO))
201 #if (defined(ELPP_FEATURE_ALL)) || (defined(ELPP_FEATURE_CRASH_LOG))
202 # if (ELPP_COMPILER_GCC && !ELPP_MINGW && !ELPP_OS_ANDROID)
203 # define ELPP_STACKTRACE 1
204 # else
205 # if ELPP_COMPILER_MSVC
206 # pragma message("Stack trace not available for this compiler")
207 # else
208 # warning "Stack trace not available for this compiler";
209 # endif // ELPP_COMPILER_MSVC
210 # define ELPP_STACKTRACE 0
211 # endif // ELPP_COMPILER_GCC
212 #else
213 # define ELPP_STACKTRACE 0
214 #endif // (defined(ELPP_FEATURE_ALL)) || (defined(ELPP_FEATURE_CRASH_LOG))
215 // Miscellaneous macros
216 #define ELPP_UNUSED(x) (void)x
217 #if ELPP_OS_UNIX
218 // Log file permissions for unix-based systems
219 # define ELPP_LOG_PERMS S_IRUSR | S_IWUSR | S_IXUSR | S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IXOTH
220 #endif // ELPP_OS_UNIX
221 #if defined(ELPP_AS_DLL) && ELPP_COMPILER_MSVC
222 # if defined(ELPP_EXPORT_SYMBOLS)
223 # define ELPP_EXPORT __declspec(dllexport)
224 # else
225 # define ELPP_EXPORT __declspec(dllimport)
226 # endif // defined(ELPP_EXPORT_SYMBOLS)
227 #else
228 # define ELPP_EXPORT
229 #endif // defined(ELPP_AS_DLL) && ELPP_COMPILER_MSVC
230 // Some special functions that are VC++ specific
231 #undef STRTOK
232 #undef STRERROR
233 #undef STRCAT
234 #undef STRCPY
235 #if ELPP_CRT_DBG_WARNINGS
236 # define STRTOK(a, b, c) strtok_s(a, b, c)
237 # define STRERROR(a, b, c) strerror_s(a, b, c)
238 # define STRCAT(a, b, len) strcat_s(a, len, b)
239 # define STRCPY(a, b, len) strcpy_s(a, len, b)
240 #else
241 # define STRTOK(a, b, c) strtok(a, b)
242 # define STRERROR(a, b, c) strerror(c)
243 # define STRCAT(a, b, len) strcat(a, b)
244 # define STRCPY(a, b, len) strcpy(a, b)
245 #endif
246 // Compiler specific support evaluations
247 #if (ELPP_MINGW && !defined(ELPP_FORCE_USE_STD_THREAD))
248 # define ELPP_USE_STD_THREADING 0
249 #else
250 # if ((ELPP_COMPILER_CLANG && defined(ELPP_CLANG_SUPPORTS_THREAD)) || \
251  (!ELPP_COMPILER_CLANG && defined(ELPP_CXX11)) || \
252  defined(ELPP_FORCE_USE_STD_THREAD))
253 # define ELPP_USE_STD_THREADING 1
254 # else
255 # define ELPP_USE_STD_THREADING 0
256 # endif
257 #endif
258 #undef ELPP_FINAL
259 #if ELPP_COMPILER_INTEL || (ELPP_GCC_VERSION < 40702)
260 # define ELPP_FINAL
261 #else
262 # define ELPP_FINAL final
263 #endif // ELPP_COMPILER_INTEL || (ELPP_GCC_VERSION < 40702)
264 #if defined(ELPP_EXPERIMENTAL_ASYNC)
265 # define ELPP_ASYNC_LOGGING 1
266 #else
267 # define ELPP_ASYNC_LOGGING 0
268 #endif // defined(ELPP_EXPERIMENTAL_ASYNC)
269 #if defined(ELPP_THREAD_SAFE) || ELPP_ASYNC_LOGGING
270 # define ELPP_THREADING_ENABLED 1
271 #else
272 # define ELPP_THREADING_ENABLED 0
273 #endif // defined(ELPP_THREAD_SAFE) || ELPP_ASYNC_LOGGING
274 // Function macro ELPP_FUNC
275 #undef ELPP_FUNC
276 #if ELPP_COMPILER_MSVC // Visual C++
277 # define ELPP_FUNC __FUNCSIG__
278 #elif ELPP_COMPILER_GCC // GCC
279 # define ELPP_FUNC __PRETTY_FUNCTION__
280 #elif ELPP_COMPILER_INTEL // Intel C++
281 # define ELPP_FUNC __PRETTY_FUNCTION__
282 #elif ELPP_COMPILER_CLANG // Clang++
283 # define ELPP_FUNC __PRETTY_FUNCTION__
284 #else
285 # if defined(__func__)
286 # define ELPP_FUNC __func__
287 # else
288 # define ELPP_FUNC ""
289 # endif // defined(__func__)
290 #endif // defined(_MSC_VER)
291 #undef ELPP_VARIADIC_TEMPLATES_SUPPORTED
292 // Keep following line commented until features are fixed
293 #define ELPP_VARIADIC_TEMPLATES_SUPPORTED \
294 (ELPP_COMPILER_GCC || ELPP_COMPILER_CLANG || ELPP_COMPILER_INTEL || (ELPP_COMPILER_MSVC && _MSC_VER >= 1800))
295 // Logging Enable/Disable macros
296 #if defined(ELPP_DISABLE_LOGS)
297 #define ELPP_LOGGING_ENABLED 0
298 #else
299 #define ELPP_LOGGING_ENABLED 1
300 #endif
301 #if (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED))
302 # define ELPP_DEBUG_LOG 1
303 #else
304 # define ELPP_DEBUG_LOG 0
305 #endif // (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED))
306 #if (!defined(ELPP_DISABLE_INFO_LOGS) && (ELPP_LOGGING_ENABLED))
307 # define ELPP_INFO_LOG 1
308 #else
309 # define ELPP_INFO_LOG 0
310 #endif // (!defined(ELPP_DISABLE_INFO_LOGS) && (ELPP_LOGGING_ENABLED))
311 #if (!defined(ELPP_DISABLE_WARNING_LOGS) && (ELPP_LOGGING_ENABLED))
312 # define ELPP_WARNING_LOG 1
313 #else
314 # define ELPP_WARNING_LOG 0
315 #endif // (!defined(ELPP_DISABLE_WARNING_LOGS) && (ELPP_LOGGING_ENABLED))
316 #if (!defined(ELPP_DISABLE_ERROR_LOGS) && (ELPP_LOGGING_ENABLED))
317 # define ELPP_ERROR_LOG 1
318 #else
319 # define ELPP_ERROR_LOG 0
320 #endif // (!defined(ELPP_DISABLE_ERROR_LOGS) && (ELPP_LOGGING_ENABLED))
321 #if (!defined(ELPP_DISABLE_FATAL_LOGS) && (ELPP_LOGGING_ENABLED))
322 # define ELPP_FATAL_LOG 1
323 #else
324 # define ELPP_FATAL_LOG 0
325 #endif // (!defined(ELPP_DISABLE_FATAL_LOGS) && (ELPP_LOGGING_ENABLED))
326 #if (!defined(ELPP_DISABLE_TRACE_LOGS) && (ELPP_LOGGING_ENABLED))
327 # define ELPP_TRACE_LOG 1
328 #else
329 # define ELPP_TRACE_LOG 0
330 #endif // (!defined(ELPP_DISABLE_TRACE_LOGS) && (ELPP_LOGGING_ENABLED))
331 #if (!defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED))
332 # define ELPP_VERBOSE_LOG 1
333 #else
334 # define ELPP_VERBOSE_LOG 0
335 #endif // (!defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED))
336 #if (!(ELPP_CXX0X || ELPP_CXX11))
337 # error "C++0x (or higher) support not detected! (Is `-std=c++11' missing?)"
338 #endif // (!(ELPP_CXX0X || ELPP_CXX11))
339 // Headers
340 #if defined(ELPP_SYSLOG)
341 # include <syslog.h>
342 #endif // defined(ELPP_SYSLOG)
343 #include <ctime>
344 #include <cstring>
345 #include <cstdlib>
346 #include <cctype>
347 #include <cwchar>
348 #include <csignal>
349 #include <cerrno>
350 #include <cstdarg>
351 #if defined(ELPP_UNICODE)
352 # include <locale>
353 # if ELPP_OS_WINDOWS
354 # include <codecvt>
355 # endif // ELPP_OS_WINDOWS
356 #endif // defined(ELPP_UNICODE)
357 #if ELPP_STACKTRACE
358 # include <cxxabi.h>
359 # include <execinfo.h>
360 #endif // ELPP_STACKTRACE
361 #if ELPP_OS_ANDROID
362 # include <sys/system_properties.h>
363 #endif // ELPP_OS_ANDROID
364 #if ELPP_OS_UNIX
365 # include <sys/stat.h>
366 # include <sys/time.h>
367 #elif ELPP_OS_WINDOWS
368 # include <direct.h>
369 # include <windows.h>
370 # if defined(WIN32_LEAN_AND_MEAN)
371 # if defined(ELPP_WINSOCK2)
372 # include <winsock2.h>
373 # else
374 # include <winsock.h>
375 # endif // defined(ELPP_WINSOCK2)
376 # endif // defined(WIN32_LEAN_AND_MEAN)
377 #endif // ELPP_OS_UNIX
378 #include <string>
379 #include <vector>
380 #include <map>
381 #include <utility>
382 #include <functional>
383 #include <algorithm>
384 #include <fstream>
385 #include <iostream>
386 #include <sstream>
387 #include <memory>
388 #include <type_traits>
389 #if ELPP_THREADING_ENABLED
390 # if ELPP_USE_STD_THREADING
391 # include <mutex>
392 # include <thread>
393 # else
394 # if ELPP_OS_UNIX
395 # include <pthread.h>
396 # endif // ELPP_OS_UNIX
397 # endif // ELPP_USE_STD_THREADING
398 #endif // ELPP_THREADING_ENABLED
399 #if ELPP_ASYNC_LOGGING
400 # if defined(ELPP_NO_SLEEP_FOR)
401 # include <unistd.h>
402 # endif // defined(ELPP_NO_SLEEP_FOR)
403 # include <thread>
404 # include <queue>
405 # include <condition_variable>
406 #endif // ELPP_ASYNC_LOGGING
407 #if defined(ELPP_STL_LOGGING)
408 // For logging STL based templates
409 # include <list>
410 # include <queue>
411 # include <deque>
412 # include <set>
413 # include <bitset>
414 # include <stack>
415 # if defined(ELPP_LOG_STD_ARRAY)
416 # include <array>
417 # endif // defined(ELPP_LOG_STD_ARRAY)
418 # if defined(ELPP_LOG_UNORDERED_MAP)
419 # include <unordered_map>
420 # endif // defined(ELPP_LOG_UNORDERED_MAP)
421 # if defined(ELPP_LOG_UNORDERED_SET)
422 # include <unordered_set>
423 # endif // defined(ELPP_UNORDERED_SET)
424 #endif // defined(ELPP_STL_LOGGING)
425 #if defined(ELPP_QT_LOGGING)
426 // For logging Qt based classes & templates
427 # include <QString>
428 # include <QByteArray>
429 # include <QVector>
430 # include <QList>
431 # include <QPair>
432 # include <QMap>
433 # include <QQueue>
434 # include <QSet>
435 # include <QLinkedList>
436 # include <QHash>
437 # include <QMultiHash>
438 # include <QStack>
439 #endif // defined(ELPP_QT_LOGGING)
440 #if defined(ELPP_BOOST_LOGGING)
441 // For logging boost based classes & templates
442 # include <boost/container/vector.hpp>
443 # include <boost/container/stable_vector.hpp>
444 # include <boost/container/list.hpp>
445 # include <boost/container/deque.hpp>
446 # include <boost/container/map.hpp>
447 # include <boost/container/flat_map.hpp>
448 # include <boost/container/set.hpp>
449 # include <boost/container/flat_set.hpp>
450 #endif // defined(ELPP_BOOST_LOGGING)
451 #if defined(ELPP_WXWIDGETS_LOGGING)
452 // For logging wxWidgets based classes & templates
453 # include <wx/vector.h>
454 #endif // defined(ELPP_WXWIDGETS_LOGGING)
455 #if defined(ELPP_UTC_DATETIME)
456 # define elpptime_r gmtime_r
457 # define elpptime_s gmtime_s
458 # define elpptime gmtime
459 #else
460 # define elpptime_r localtime_r
461 # define elpptime_s localtime_s
462 # define elpptime localtime
463 #endif // defined(ELPP_UTC_DATETIME)
464 // Forward declarations
465 namespace el {
466 class Logger;
467 class LogMessage;
468 class PerformanceTrackingData;
469 class Loggers;
470 class Helpers;
471 template <typename T> class Callback;
472 class LogDispatchCallback;
475 class LogDispatchData;
476 namespace base {
477 class Storage;
478 class RegisteredLoggers;
479 class PerformanceTracker;
480 class MessageBuilder;
481 class Writer;
482 class PErrorWriter;
483 class LogDispatcher;
484 class DefaultLogBuilder;
485 class DefaultLogDispatchCallback;
486 #if ELPP_ASYNC_LOGGING
487 class AsyncLogDispatchCallback;
488 class AsyncDispatchWorker;
489 #endif // ELPP_ASYNC_LOGGING
490 class DefaultPerformanceTrackingCallback;
491 } // namespace base
492 } // namespace el
494 namespace el {
496 namespace base {
498 namespace type {
499 #undef ELPP_LITERAL
500 #undef ELPP_STRLEN
501 #undef ELPP_COUT
502 #if defined(ELPP_UNICODE)
503 # define ELPP_LITERAL(txt) L##txt
504 # define ELPP_STRLEN wcslen
505 # if defined ELPP_CUSTOM_COUT
506 # define ELPP_COUT ELPP_CUSTOM_COUT
507 # else
508 # define ELPP_COUT std::wcout
509 # endif // defined ELPP_CUSTOM_COUT
510 typedef wchar_t char_t;
511 typedef std::wstring string_t;
512 typedef std::wstringstream stringstream_t;
513 typedef std::wfstream fstream_t;
514 typedef std::wostream ostream_t;
515 #else
516 # define ELPP_LITERAL(txt) txt
517 # define ELPP_STRLEN strlen
518 # if defined ELPP_CUSTOM_COUT
519 # define ELPP_COUT ELPP_CUSTOM_COUT
520 # else
521 # define ELPP_COUT std::cout
522 # endif // defined ELPP_CUSTOM_COUT
523 typedef char char_t;
524 typedef std::string string_t;
525 typedef std::stringstream stringstream_t;
526 typedef std::fstream fstream_t;
527 typedef std::ostream ostream_t;
528 #endif // defined(ELPP_UNICODE)
529 #if defined(ELPP_CUSTOM_COUT_LINE)
530 # define ELPP_COUT_LINE(logLine) ELPP_CUSTOM_COUT_LINE(logLine)
531 #else
532 # define ELPP_COUT_LINE(logLine) logLine << std::flush
533 #endif // defined(ELPP_CUSTOM_COUT_LINE)
534 
535 #define CI_LOG_CONF "/home/vagrant/rdfs/config/ci-log-conf.conf"
536 
537 typedef unsigned int EnumType;
538 typedef unsigned short VerboseLevel;
539 typedef unsigned long int LineNumber;
540 
541 typedef std::shared_ptr<base::Storage> StoragePointer;
542 typedef std::shared_ptr<LogDispatchCallback> LogDispatchCallbackPtr;
543 typedef std::shared_ptr<PerformanceTrackingCallback> PerformanceTrackingCallbackPtr;
544 typedef std::shared_ptr<LoggerRegistrationCallback> LoggerRegistrationCallbackPtr;
545 typedef std::unique_ptr<el::base::PerformanceTracker> PerformanceTrackerPtr;
546 } // namespace type
550 class NoCopy {
551  protected:
552  NoCopy(void) {}
553  private:
554  NoCopy(const NoCopy&);
555  NoCopy& operator=(const NoCopy&);
556 };
561 class StaticClass {
562  private:
563  StaticClass(void);
564  StaticClass(const StaticClass&);
565  StaticClass& operator=(const StaticClass&);
566 };
567 } // namespace base
572 enum class Level : base::type::EnumType {
574  Global = 1,
576  Trace = 2,
578  Debug = 4,
580  Fatal = 8,
582  Error = 16,
584  Warning = 32,
586  Verbose = 64,
588  Info = 128,
590  Unknown = 1010
591 };
594  public:
596  static const base::type::EnumType kMinValid = static_cast<base::type::EnumType>(Level::Trace);
598  static const base::type::EnumType kMaxValid = static_cast<base::type::EnumType>(Level::Info);
600  static base::type::EnumType castToInt(Level level) {
601  return static_cast<base::type::EnumType>(level);
602  }
604  static Level castFromInt(base::type::EnumType l) {
605  return static_cast<Level>(l);
606  }
609  static const char* convertToString(Level level);
613  static Level convertFromString(const char* levelStr);
618  static void forEachLevel(base::type::EnumType* startIndex, const std::function<bool(void)>& fn);
619 };
622 enum class ConfigurationType : base::type::EnumType {
625  Enabled = 1,
627  ToFile = 2,
630  ToStandardOutput = 4,
632  Format = 8,
634  Filename = 16,
636  SubsecondPrecision = 32,
642  PerformanceTracking = 64,
647  MaxLogFileSize = 128,
649  LogFlushThreshold = 256,
651  Unknown = 1010
652 };
655  public:
657  static const base::type::EnumType kMinValid = static_cast<base::type::EnumType>(ConfigurationType::Enabled);
659  static const base::type::EnumType kMaxValid = static_cast<base::type::EnumType>(ConfigurationType::MaxLogFileSize);
661  static base::type::EnumType castToInt(ConfigurationType configurationType) {
662  return static_cast<base::type::EnumType>(configurationType);
663  }
665  static ConfigurationType castFromInt(base::type::EnumType c) {
666  return static_cast<ConfigurationType>(c);
667  }
670  static const char* convertToString(ConfigurationType configurationType);
674  static ConfigurationType convertFromString(const char* configStr);
680  static inline void forEachConfigType(base::type::EnumType* startIndex, const std::function<bool(void)>& fn);
681 };
683 enum class LoggingFlag : base::type::EnumType {
694  ImmediateFlush = 16,
700  MultiLoggerSupport = 128,
704  DisableVModules = 512,
708  HierarchicalLogging = 2048,
712  AutoSpacing = 8192,
714  FixedTimeFormat = 16384
715 };
716 namespace base {
718 namespace consts {
719 #if defined(__GNUC__) && !defined(__clang__)
720 #pragma GCC diagnostic push
721 #pragma GCC diagnostic ignored "-Wunused-variable"
722 #endif
723 // Level log values - These are values that are replaced in place of %level format specifier
724 // Extra spaces after format specifiers are only for readability purposes in log files
725 static const base::type::char_t* kInfoLevelLogValue = ELPP_LITERAL("INFO");
726 static const base::type::char_t* kDebugLevelLogValue = ELPP_LITERAL("DEBUG");
727 static const base::type::char_t* kWarningLevelLogValue = ELPP_LITERAL("WARNING");
728 static const base::type::char_t* kErrorLevelLogValue = ELPP_LITERAL("ERROR");
729 static const base::type::char_t* kFatalLevelLogValue = ELPP_LITERAL("FATAL");
730 static const base::type::char_t* kVerboseLevelLogValue =
731  ELPP_LITERAL("VERBOSE"); // will become VERBOSE-x where x = verbose level
732 static const base::type::char_t* kTraceLevelLogValue = ELPP_LITERAL("TRACE");
733 static const base::type::char_t* kInfoLevelShortLogValue = ELPP_LITERAL("I");
734 static const base::type::char_t* kDebugLevelShortLogValue = ELPP_LITERAL("D");
735 static const base::type::char_t* kWarningLevelShortLogValue = ELPP_LITERAL("W");
736 static const base::type::char_t* kErrorLevelShortLogValue = ELPP_LITERAL("E");
737 static const base::type::char_t* kFatalLevelShortLogValue = ELPP_LITERAL("F");
738 static const base::type::char_t* kVerboseLevelShortLogValue = ELPP_LITERAL("V");
739 static const base::type::char_t* kTraceLevelShortLogValue = ELPP_LITERAL("T");
740 // Format specifiers - These are used to define log format
741 static const base::type::char_t* kAppNameFormatSpecifier = ELPP_LITERAL("%app");
742 static const base::type::char_t* kLoggerIdFormatSpecifier = ELPP_LITERAL("%logger");
743 static const base::type::char_t* kThreadIdFormatSpecifier = ELPP_LITERAL("%thread");
744 static const base::type::char_t* kSeverityLevelFormatSpecifier = ELPP_LITERAL("%level");
745 static const base::type::char_t* kSeverityLevelShortFormatSpecifier = ELPP_LITERAL("%levshort");
746 static const base::type::char_t* kDateTimeFormatSpecifier = ELPP_LITERAL("%datetime");
747 static const base::type::char_t* kLogFileFormatSpecifier = ELPP_LITERAL("%file");
748 static const base::type::char_t* kLogFileBaseFormatSpecifier = ELPP_LITERAL("%fbase");
749 static const base::type::char_t* kLogLineFormatSpecifier = ELPP_LITERAL("%line");
750 static const base::type::char_t* kLogLocationFormatSpecifier = ELPP_LITERAL("%loc");
751 static const base::type::char_t* kLogFunctionFormatSpecifier = ELPP_LITERAL("%func");
752 static const base::type::char_t* kCurrentUserFormatSpecifier = ELPP_LITERAL("%user");
753 static const base::type::char_t* kCurrentHostFormatSpecifier = ELPP_LITERAL("%host");
754 static const base::type::char_t* kMessageFormatSpecifier = ELPP_LITERAL("%msg");
755 static const base::type::char_t* kVerboseLevelFormatSpecifier = ELPP_LITERAL("%vlevel");
756 static const char* kDateTimeFormatSpecifierForFilename = "%datetime";
757 // Date/time
758 static const char* kDays[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
759 static const char* kDaysAbbrev[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
760 static const char* kMonths[12] = { "January", "February", "March", "Apri", "May", "June", "July", "August",
761  "September", "October", "November", "December"
762  };
763 static const char* kMonthsAbbrev[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
764 static const char* kDefaultDateTimeFormat = "%Y-%M-%d %H:%m:%s,%g";
765 static const char* kDefaultDateTimeFormatInFilename = "%Y-%M-%d_%H-%m";
766 static const int kYearBase = 1900;
767 static const char* kAm = "AM";
768 static const char* kPm = "PM";
769 // Miscellaneous constants
770 #ifdef ELPP_DEFAULT_LOGGER
771 static const char* kDefaultLoggerId = ELPP_DEFAULT_LOGGER;
772 #else
773 static const char* kDefaultLoggerId = "default";
774 #endif
775 #ifdef ELPP_DEFAULT_PERFORMANCE_LOGGER
776 static const char* kPerformanceLoggerId = ELPP_DEFAULT_PERFORMANCE_LOGGER;
777 #else
778 static const char* kPerformanceLoggerId = "performance";
779 #endif
780 #if defined(ELPP_SYSLOG)
781 static const char* kSysLogLoggerId = "syslog";
782 #endif // defined(ELPP_SYSLOG)
783 static const char* kNullPointer = "nullptr";
784 static const char kFormatSpecifierChar = '%';
785 #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
786 static const char kFormatSpecifierCharValue = 'v';
787 #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
788 static const unsigned int kMaxLogPerContainer = 100;
789 static const unsigned int kMaxLogPerCounter = 100000;
790 static const unsigned int kDefaultSubsecondPrecision = 3;
791 static const base::type::VerboseLevel kMaxVerboseLevel = 9;
792 static const char* kUnknownUser = "user";
793 static const char* kUnknownHost = "unknown-host";
794 #if defined(ELPP_DEFAULT_LOG_FILE)
795 static const char* kDefaultLogFile = ELPP_DEFAULT_LOG_FILE;
796 #else
797 # if ELPP_OS_UNIX
798 # if ELPP_OS_ANDROID
799 static const char* kDefaultLogFile = "logs/myeasylog.log";
800 # else
801 static const char* kDefaultLogFile = "logs/myeasylog.log";
802 # endif // ELPP_OS_ANDROID
803 # elif ELPP_OS_WINDOWS
804 static const char* kDefaultLogFile = "logs\\myeasylog.log";
805 # endif // ELPP_OS_UNIX
806 #endif // defined(ELPP_DEFAULT_LOG_FILE)
807 #if !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG)
808 static const char* kDefaultLogFileParam = "--default-log-file";
809 #endif // !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG)
810 #if defined(ELPP_LOGGING_FLAGS_FROM_ARG)
811 static const char* kLoggingFlagsParam = "--logging-flags";
812 #endif // defined(ELPP_LOGGING_FLAGS_FROM_ARG)
813 #if ELPP_OS_WINDOWS
814 static const char* kFilePathSeperator = "\\";
815 #else
816 static const char* kFilePathSeperator = "/";
817 #endif // ELPP_OS_WINDOWS
818 static const char* kValidLoggerIdSymbols =
819  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._";
820 static const char* kConfigurationComment = "##";
821 static const char* kConfigurationLevel = "*";
822 static const char* kConfigurationLoggerId = "--";
823 static const std::size_t kSourceFilenameMaxLength = 100;
824 static const std::size_t kSourceLineMaxLength = 10;
825 static const Level kPerformanceTrackerDefaultLevel = Level::Info;
826 const struct {
827  double value;
828  const base::type::char_t* unit;
829 } kTimeFormats[] = {
830  { 1000.0f, ELPP_LITERAL("us") },
831  { 1000.0f, ELPP_LITERAL("ms") },
832  { 60.0f, ELPP_LITERAL("seconds") },
833  { 60.0f, ELPP_LITERAL("minutes") },
834  { 24.0f, ELPP_LITERAL("hours") },
835  { 7.0f, ELPP_LITERAL("days") }
836 };
837 static const int kTimeFormatsCount = sizeof(kTimeFormats) / sizeof(kTimeFormats[0]);
838 const struct {
839  int numb;
840  const char* name;
841  const char* brief;
842  const char* detail;
843 } kCrashSignals[] = {
844  // NOTE: Do not re-order, if you do please check CrashHandler(bool) constructor and CrashHandler::setHandler(..)
845  {
846  SIGABRT, "SIGABRT", "Abnormal termination",
847  "Program was abnormally terminated."
848  },
849  {
850  SIGFPE, "SIGFPE", "Erroneous arithmetic operation",
851  "Arithemetic operation issue such as division by zero or operation resulting in overflow."
852  },
853  {
854  SIGILL, "SIGILL", "Illegal instruction",
855  "Generally due to a corruption in the code or to an attempt to execute data."
856  },
857  {
858  SIGSEGV, "SIGSEGV", "Invalid access to memory",
859  "Program is trying to read an invalid (unallocated, deleted or corrupted) or inaccessible memory."
860  },
861  {
862  SIGINT, "SIGINT", "Interactive attention signal",
863  "Interruption generated (generally) by user or operating system."
864  },
865 };
866 static const int kCrashSignalsCount = sizeof(kCrashSignals) / sizeof(kCrashSignals[0]);
867 #if defined(__GNUC__) && !defined(__clang__)
868 #pragma GCC diagnostic pop
869 #endif
870 } // namespace consts
871 } // namespace base
872 typedef std::function<void(const char*, std::size_t)> PreRollOutCallback;
873 namespace base {
874 static inline void defaultPreRollOutCallback(const char*, std::size_t) {}
876 enum class TimestampUnit : base::type::EnumType {
877  Microsecond = 0, Millisecond = 1, Second = 2, Minute = 3, Hour = 4, Day = 5
878 };
880 enum class FormatFlags : base::type::EnumType {
881  DateTime = 1 << 1,
882  LoggerId = 1 << 2,
883  File = 1 << 3,
884  Line = 1 << 4,
885  Location = 1 << 5,
886  Function = 1 << 6,
887  User = 1 << 7,
888  Host = 1 << 8,
889  LogMessage = 1 << 9,
890  VerboseLevel = 1 << 10,
891  AppName = 1 << 11,
892  ThreadId = 1 << 12,
893  Level = 1 << 13,
894  FileBase = 1 << 14,
895  LevelShort = 1 << 15
896 };
899  public:
900  SubsecondPrecision(void) {
901  init(base::consts::kDefaultSubsecondPrecision);
902  }
903  explicit SubsecondPrecision(int width) {
904  init(width);
905  }
906  bool operator==(const SubsecondPrecision& ssPrec) {
907  return m_width == ssPrec.m_width && m_offset == ssPrec.m_offset;
908  }
909  int m_width;
910  unsigned int m_offset;
911  private:
912  void init(int width);
913 };
917 namespace utils {
919 template <typename T>
920 static
921 typename std::enable_if<std::is_pointer<T*>::value, void>::type
922 safeDelete(T*& pointer) {
923  if (pointer == nullptr)
924  return;
925  delete pointer;
926  pointer = nullptr;
927 }
930 namespace bitwise {
931 template <typename Enum>
932 static inline base::type::EnumType And(Enum e, base::type::EnumType flag) {
933  return static_cast<base::type::EnumType>(flag) & static_cast<base::type::EnumType>(e);
934 }
935 template <typename Enum>
936 static inline base::type::EnumType Not(Enum e, base::type::EnumType flag) {
937  return static_cast<base::type::EnumType>(flag) & ~(static_cast<base::type::EnumType>(e));
938 }
939 template <typename Enum>
940 static inline base::type::EnumType Or(Enum e, base::type::EnumType flag) {
941  return static_cast<base::type::EnumType>(flag) | static_cast<base::type::EnumType>(e);
942 }
943 } // namespace bitwise
944 template <typename Enum>
945 static inline void addFlag(Enum e, base::type::EnumType* flag) {
946  *flag = base::utils::bitwise::Or<Enum>(e, *flag);
947 }
948 template <typename Enum>
949 static inline void removeFlag(Enum e, base::type::EnumType* flag) {
950  *flag = base::utils::bitwise::Not<Enum>(e, *flag);
951 }
952 template <typename Enum>
953 static inline bool hasFlag(Enum e, base::type::EnumType flag) {
954  return base::utils::bitwise::And<Enum>(e, flag) > 0x0;
955 }
956 } // namespace utils
957 namespace threading {
958 #if ELPP_THREADING_ENABLED
959 # if !ELPP_USE_STD_THREADING
960 namespace internal {
962 class Mutex : base::NoCopy {
963  public:
964  Mutex(void) {
965 # if ELPP_OS_UNIX
966  pthread_mutexattr_t attr;
967  pthread_mutexattr_init(&attr);
968  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
969  pthread_mutex_init(&m_underlyingMutex, &attr);
970  pthread_mutexattr_destroy(&attr);
971 # elif ELPP_OS_WINDOWS
972  InitializeCriticalSection(&m_underlyingMutex);
973 # endif // ELPP_OS_UNIX
974  }
975 
976  virtual ~Mutex(void) {
977 # if ELPP_OS_UNIX
978  pthread_mutex_destroy(&m_underlyingMutex);
979 # elif ELPP_OS_WINDOWS
980  DeleteCriticalSection(&m_underlyingMutex);
981 # endif // ELPP_OS_UNIX
982  }
983 
984  inline void lock(void) {
985 # if ELPP_OS_UNIX
986  pthread_mutex_lock(&m_underlyingMutex);
987 # elif ELPP_OS_WINDOWS
988  EnterCriticalSection(&m_underlyingMutex);
989 # endif // ELPP_OS_UNIX
990  }
991 
992  inline bool try_lock(void) {
993 # if ELPP_OS_UNIX
994  return (pthread_mutex_trylock(&m_underlyingMutex) == 0);
995 # elif ELPP_OS_WINDOWS
996  return TryEnterCriticalSection(&m_underlyingMutex);
997 # endif // ELPP_OS_UNIX
998  }
999 
1000  inline void unlock(void) {
1001 # if ELPP_OS_UNIX
1002  pthread_mutex_unlock(&m_underlyingMutex);
1003 # elif ELPP_OS_WINDOWS
1004  LeaveCriticalSection(&m_underlyingMutex);
1005 # endif // ELPP_OS_UNIX
1006  }
1007 
1008  private:
1009 # if ELPP_OS_UNIX
1010  pthread_mutex_t m_underlyingMutex;
1011 # elif ELPP_OS_WINDOWS
1012  CRITICAL_SECTION m_underlyingMutex;
1013 # endif // ELPP_OS_UNIX
1014 };
1016 template <typename M>
1017 class ScopedLock : base::NoCopy {
1018  public:
1019  explicit ScopedLock(M& mutex) {
1020  m_mutex = &mutex;
1021  m_mutex->lock();
1022  }
1023 
1024  virtual ~ScopedLock(void) {
1025  m_mutex->unlock();
1026  }
1027  private:
1028  M* m_mutex;
1029  ScopedLock(void);
1030 };
1031 } // namespace internal
1032 typedef base::threading::internal::Mutex Mutex;
1033 typedef base::threading::internal::ScopedLock<base::threading::Mutex> ScopedLock;
1034 # else
1035 typedef std::recursive_mutex Mutex;
1036 typedef std::lock_guard<base::threading::Mutex> ScopedLock;
1037 # endif // !ELPP_USE_STD_THREADING
1038 #else
1039 namespace internal {
1042  public:
1043  NoMutex(void) {}
1044  inline void lock(void) {}
1045  inline bool try_lock(void) {
1046  return true;
1047  }
1048  inline void unlock(void) {}
1049 };
1051 template <typename Mutex>
1053  public:
1054  explicit NoScopedLock(Mutex&) {
1055  }
1056  virtual ~NoScopedLock(void) {
1057  }
1058  private:
1059  NoScopedLock(void);
1060 };
1061 } // namespace internal
1064 #endif // ELPP_THREADING_ENABLED
1065 class ThreadSafe {
1067  public:
1068  virtual inline void acquireLock(void) ELPP_FINAL { m_mutex.lock(); }
1069  virtual inline void releaseLock(void) ELPP_FINAL { m_mutex.unlock(); }
1070  virtual inline base::threading::Mutex& lock(void) ELPP_FINAL { return m_mutex; }
1071  protected:
1072  ThreadSafe(void) {}
1073  virtual ~ThreadSafe(void) {}
1074  private:
1075  base::threading::Mutex m_mutex;
1076 };
1077 
1078 #if ELPP_THREADING_ENABLED
1079 # if !ELPP_USE_STD_THREADING
1080 static std::string getCurrentThreadId(void) {
1082  std::stringstream ss;
1083 # if (ELPP_OS_WINDOWS)
1084  ss << GetCurrentThreadId();
1085 # endif // (ELPP_OS_WINDOWS)
1086  return ss.str();
1087 }
1088 # else
1089 static std::string getCurrentThreadId(void) {
1091  std::stringstream ss;
1092  ss << std::this_thread::get_id();
1093  return ss.str();
1094 }
1095 # endif // !ELPP_USE_STD_THREADING
1096 #else
1097 static inline std::string getCurrentThreadId(void) {
1098  return std::string();
1099 }
1100 #endif // ELPP_THREADING_ENABLED
1101 } // namespace threading
1102 namespace utils {
1104  public:
1107  static base::type::fstream_t* newFileStream(const std::string& filename);
1108 
1110  static std::size_t getSizeOfFile(base::type::fstream_t* fs);
1111 
1113  static bool pathExists(const char* path, bool considerFile = false);
1114 
1117  static bool createPath(const std::string& path);
1119  static std::string extractPathFromFilename(const std::string& fullPath,
1120  const char* seperator = base::consts::kFilePathSeperator);
1122  static void buildStrippedFilename(const char* filename, char buff[],
1123  std::size_t limit = base::consts::kSourceFilenameMaxLength);
1125  static void buildBaseFilename(const std::string& fullPath, char buff[],
1126  std::size_t limit = base::consts::kSourceFilenameMaxLength,
1127  const char* seperator = base::consts::kFilePathSeperator);
1128 };
1131  public:
1133  static inline bool isDigit(char c) {
1134  return c >= '0' && c <= '9';
1135  }
1136 
1138  static bool wildCardMatch(const char* str, const char* pattern);
1139 
1140  static std::string& ltrim(std::string& str);
1141  static std::string& rtrim(std::string& str);
1142  static std::string& trim(std::string& str);
1143 
1148  static bool startsWith(const std::string& str, const std::string& start);
1149 
1154  static bool endsWith(const std::string& str, const std::string& end);
1155 
1161  static std::string& replaceAll(std::string& str, char replaceWhat, char replaceWith);
1162 
1168  static std::string& replaceAll(std::string& str, const std::string& replaceWhat,
1169  const std::string& replaceWith);
1170 
1171  static void replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat,
1172  const base::type::string_t& replaceWith);
1173 #if defined(ELPP_UNICODE)
1174  static void replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat,
1175  const std::string& replaceWith);
1176 #endif // defined(ELPP_UNICODE)
1177  static std::string& toUpper(std::string& str);
1181 
1183  static bool cStringEq(const char* s1, const char* s2);
1184 
1187  static bool cStringCaseEq(const char* s1, const char* s2);
1188 
1190  static bool contains(const char* str, char c);
1191 
1192  static char* convertAndAddToBuff(std::size_t n, int len, char* buf, const char* bufLim, bool zeroPadded = true);
1193  static char* addToBuff(const char* str, char* buf, const char* bufLim);
1194  static char* clearBuff(char buff[], std::size_t lim);
1195 
1198  static char* wcharPtrToCharPtr(const wchar_t* line);
1199 };
1202  public:
1203 #if ELPP_OS_WINDOWS
1204  static const char* getWindowsEnvironmentVariable(const char* varname);
1209 #endif // ELPP_OS_WINDOWS
1210 #if ELPP_OS_ANDROID
1211  static std::string getProperty(const char* prop);
1213 
1215  static std::string getDeviceName(void);
1216 #endif // ELPP_OS_ANDROID
1217 
1223  static const std::string getBashOutput(const char* command);
1224 
1230  static std::string getEnvironmentVariable(const char* variableName, const char* defaultVal,
1231  const char* alternativeBashCommand = nullptr);
1233  static std::string currentUser(void);
1234 
1238  static std::string currentHost(void);
1240  static bool termSupportsColor(void);
1241 };
1244  public:
1249  static void gettimeofday(struct timeval* tv);
1250 
1255  static std::string getDateTime(const char* format, const base::SubsecondPrecision* ssPrec);
1256 
1258  static std::string timevalToString(struct timeval tval, const char* format,
1259  const el::base::SubsecondPrecision* ssPrec);
1260 
1262  static base::type::string_t formatTime(unsigned long long time, base::TimestampUnit timestampUnit);
1263 
1265  static unsigned long long getTimeDifference(const struct timeval& endTime, const struct timeval& startTime,
1266  base::TimestampUnit timestampUnit);
1267 
1268 
1269  private:
1270  static struct ::tm* buildTimeInfo(struct timeval* currTime, struct ::tm* timeInfo);
1271  static char* parseFormat(char* buf, std::size_t bufSz, const char* format, const struct tm* tInfo,
1272  std::size_t msec, const base::SubsecondPrecision* ssPrec);
1273 };
1276  public:
1277  CommandLineArgs(void) {
1278  setArgs(0, static_cast<char**>(nullptr));
1279  }
1280  CommandLineArgs(int argc, const char** argv) {
1281  setArgs(argc, argv);
1282  }
1283  CommandLineArgs(int argc, char** argv) {
1284  setArgs(argc, argv);
1285  }
1286  virtual ~CommandLineArgs(void) {}
1288  inline void setArgs(int argc, const char** argv) {
1289  setArgs(argc, const_cast<char**>(argv));
1290  }
1292  void setArgs(int argc, char** argv);
1294  bool hasParamWithValue(const char* paramKey) const;
1297  const char* getParamValue(const char* paramKey) const;
1299  bool hasParam(const char* paramKey) const;
1301  bool empty(void) const;
1303  std::size_t size(void) const;
1304  friend base::type::ostream_t& operator<<(base::type::ostream_t& os, const CommandLineArgs& c);
1305 
1306  private:
1307  int m_argc;
1308  char** m_argv;
1309  std::map<std::string, std::string> m_paramsWithValue;
1310  std::vector<std::string> m_params;
1311 };
1318 template <typename T_Ptr, typename Container>
1320  public:
1321  typedef typename Container::iterator iterator;
1322  typedef typename Container::const_iterator const_iterator;
1323 
1326 
1329  if (this == &sr) {
1330  return;
1331  }
1332  unregisterAll();
1333  m_list = std::move(sr.m_list);
1334  }
1335 
1336  bool operator==(const AbstractRegistry<T_Ptr, Container>& other) {
1337  if (size() != other.size()) {
1338  return false;
1339  }
1340  for (std::size_t i = 0; i < m_list.size(); ++i) {
1341  if (m_list.at(i) != other.m_list.at(i)) {
1342  return false;
1343  }
1344  }
1345  return true;
1346  }
1347 
1348  bool operator!=(const AbstractRegistry<T_Ptr, Container>& other) {
1349  if (size() != other.size()) {
1350  return true;
1351  }
1352  for (std::size_t i = 0; i < m_list.size(); ++i) {
1353  if (m_list.at(i) != other.m_list.at(i)) {
1354  return true;
1355  }
1356  }
1357  return false;
1358  }
1359 
1362  if (this == &sr) {
1363  return *this;
1364  }
1365  unregisterAll();
1366  m_list = std::move(sr.m_list);
1367  return *this;
1368  }
1369 
1370  virtual ~AbstractRegistry(void) {
1371  }
1372 
1374  virtual inline iterator begin(void) ELPP_FINAL {
1375  return m_list.begin();
1376  }
1377 
1379  virtual inline iterator end(void) ELPP_FINAL {
1380  return m_list.end();
1381  }
1382 
1383 
1385  virtual inline const_iterator cbegin(void) const ELPP_FINAL {
1386  return m_list.cbegin();
1387  }
1388 
1390  virtual inline const_iterator cend(void) const ELPP_FINAL {
1391  return m_list.cend();
1392  }
1393 
1395  virtual inline bool empty(void) const ELPP_FINAL {
1396  return m_list.empty();
1397  }
1398 
1400  virtual inline std::size_t size(void) const ELPP_FINAL {
1401  return m_list.size();
1402  }
1403 
1405  virtual inline Container& list(void) ELPP_FINAL {
1406  return m_list;
1407  }
1408 
1410  virtual inline const Container& list(void) const ELPP_FINAL {
1411  return m_list;
1412  }
1413 
1415  virtual void unregisterAll(void) = 0;
1416 
1417  protected:
1418  virtual void deepCopy(const AbstractRegistry<T_Ptr, Container>&) = 0;
1419  void reinitDeepCopy(const AbstractRegistry<T_Ptr, Container>& sr) {
1420  unregisterAll();
1421  deepCopy(sr);
1422  }
1423 
1424  private:
1425  Container m_list;
1426 };
1427 
1433 template <typename T_Ptr, typename T_Key = const char*>
1434 class Registry : public AbstractRegistry<T_Ptr, std::map<T_Key, T_Ptr*>> {
1435  public:
1436  typedef typename Registry<T_Ptr, T_Key>::iterator iterator;
1437  typedef typename Registry<T_Ptr, T_Key>::const_iterator const_iterator;
1438 
1439  Registry(void) {}
1440 
1442  Registry(const Registry& sr) : AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>() {
1443  if (this == &sr) {
1444  return;
1445  }
1446  this->reinitDeepCopy(sr);
1447  }
1448 
1453  if (this == &sr) {
1454  return *this;
1455  }
1456  this->reinitDeepCopy(sr);
1457  return *this;
1458  }
1459 
1460  virtual ~Registry(void) {
1461  unregisterAll();
1462  }
1463 
1464  protected:
1465  virtual void unregisterAll(void) ELPP_FINAL {
1466  if (!this->empty()) {
1467  for (auto&& curr : this->list()) {
1468  base::utils::safeDelete(curr.second);
1469  }
1470  this->list().clear();
1471  }
1472  }
1473 
1475  virtual void registerNew(const T_Key& uniqKey, T_Ptr* ptr) ELPP_FINAL {
1476  unregister(uniqKey);
1477  this->list().insert(std::make_pair(uniqKey, ptr));
1478  }
1479 
1481  void unregister(const T_Key& uniqKey) {
1482  T_Ptr* existing = get(uniqKey);
1483  if (existing != nullptr) {
1484  this->list().erase(uniqKey);
1485  base::utils::safeDelete(existing);
1486  }
1487  }
1488 
1490  T_Ptr* get(const T_Key& uniqKey) {
1491  iterator it = this->list().find(uniqKey);
1492  return it == this->list().end()
1493  ? nullptr
1494  : it->second;
1495  }
1496 
1497  private:
1498  virtual void deepCopy(const AbstractRegistry<T_Ptr, std::map<T_Key, T_Ptr*>>& sr) ELPP_FINAL {
1499  for (const_iterator it = sr.cbegin(); it != sr.cend(); ++it) {
1500  registerNew(it->first, new T_Ptr(*it->second));
1501  }
1502  }
1503 };
1504 
1509 template <typename T_Ptr, typename Pred>
1510 class RegistryWithPred : public AbstractRegistry<T_Ptr, std::vector<T_Ptr*>> {
1511  public:
1512  typedef typename RegistryWithPred<T_Ptr, Pred>::iterator iterator;
1513  typedef typename RegistryWithPred<T_Ptr, Pred>::const_iterator const_iterator;
1514 
1515  RegistryWithPred(void) {
1516  }
1517 
1518  virtual ~RegistryWithPred(void) {
1519  unregisterAll();
1520  }
1521 
1523  RegistryWithPred(const RegistryWithPred& sr) : AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>() {
1524  if (this == &sr) {
1525  return;
1526  }
1527  this->reinitDeepCopy(sr);
1528  }
1529 
1534  if (this == &sr) {
1535  return *this;
1536  }
1537  this->reinitDeepCopy(sr);
1538  return *this;
1539  }
1540 
1541  friend base::type::ostream_t& operator<<(base::type::ostream_t& os, const RegistryWithPred& sr) {
1542  for (const_iterator it = sr.list().begin(); it != sr.list().end(); ++it) {
1543  os << ELPP_LITERAL(" ") << **it << ELPP_LITERAL("\n");
1544  }
1545  return os;
1546  }
1547 
1548  protected:
1549  virtual void unregisterAll(void) ELPP_FINAL {
1550  if (!this->empty()) {
1551  for (auto&& curr : this->list()) {
1552  base::utils::safeDelete(curr);
1553  }
1554  this->list().clear();
1555  }
1556  }
1557 
1558  virtual void unregister(T_Ptr*& ptr) ELPP_FINAL {
1559  if (ptr) {
1560  iterator iter = this->begin();
1561  for (; iter != this->end(); ++iter) {
1562  if (ptr == *iter) {
1563  break;
1564  }
1565  }
1566  if (iter != this->end() && *iter != nullptr) {
1567  this->list().erase(iter);
1568  base::utils::safeDelete(*iter);
1569  }
1570  }
1571  }
1572 
1573  virtual inline void registerNew(T_Ptr* ptr) ELPP_FINAL {
1574  this->list().push_back(ptr);
1575  }
1576 
1579  template <typename T, typename T2>
1580  T_Ptr* get(const T& arg1, const T2 arg2) {
1581  iterator iter = std::find_if(this->list().begin(), this->list().end(), Pred(arg1, arg2));
1582  if (iter != this->list().end() && *iter != nullptr) {
1583  return *iter;
1584  }
1585  return nullptr;
1586  }
1587 
1588  private:
1589  virtual void deepCopy(const AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>& sr) {
1590  for (const_iterator it = sr.list().begin(); it != sr.list().end(); ++it) {
1591  registerNew(new T_Ptr(**it));
1592  }
1593  }
1594 };
1595 class Utils {
1596  public:
1597  template <typename T, typename TPtr>
1598  static bool installCallback(const std::string& id, std::map<std::string, TPtr>* mapT) {
1599  if (mapT->find(id) == mapT->end()) {
1600  mapT->insert(std::make_pair(id, TPtr(new T())));
1601  return true;
1602  }
1603  return false;
1604  }
1605 
1606  template <typename T, typename TPtr>
1607  static void uninstallCallback(const std::string& id, std::map<std::string, TPtr>* mapT) {
1608  if (mapT->find(id) != mapT->end()) {
1609  mapT->erase(id);
1610  }
1611  }
1612 
1613  template <typename T, typename TPtr>
1614  static T* callback(const std::string& id, std::map<std::string, TPtr>* mapT) {
1615  typename std::map<std::string, TPtr>::iterator iter = mapT->find(id);
1616  if (iter != mapT->end()) {
1617  return static_cast<T*>(iter->second.get());
1618  }
1619  return nullptr;
1620  }
1621 };
1622 } // namespace utils
1623 } // namespace base
1627 class Loggable {
1628  public:
1629  virtual ~Loggable(void) {}
1630  virtual void log(el::base::type::ostream_t&) const = 0;
1631  private:
1632  friend inline el::base::type::ostream_t& operator<<(el::base::type::ostream_t& os, const Loggable& loggable) {
1633  loggable.log(os);
1634  return os;
1635  }
1636 };
1637 namespace base {
1639 class LogFormat : public Loggable {
1640  public:
1641  LogFormat(void);
1642  LogFormat(Level level, const base::type::string_t& format);
1643  LogFormat(const LogFormat& logFormat);
1644  LogFormat(LogFormat&& logFormat);
1645  LogFormat& operator=(const LogFormat& logFormat);
1646  virtual ~LogFormat(void) {}
1647  bool operator==(const LogFormat& other);
1648 
1651  void parseFromFormat(const base::type::string_t& userFormat);
1652 
1653  inline Level level(void) const {
1654  return m_level;
1655  }
1656 
1657  inline const base::type::string_t& userFormat(void) const {
1658  return m_userFormat;
1659  }
1660 
1661  inline const base::type::string_t& format(void) const {
1662  return m_format;
1663  }
1664 
1665  inline const std::string& dateTimeFormat(void) const {
1666  return m_dateTimeFormat;
1667  }
1668 
1669  inline base::type::EnumType flags(void) const {
1670  return m_flags;
1671  }
1672 
1673  inline bool hasFlag(base::FormatFlags flag) const {
1674  return base::utils::hasFlag(flag, m_flags);
1675  }
1676 
1677  virtual void log(el::base::type::ostream_t& os) const {
1678  os << m_format;
1679  }
1680 
1681  protected:
1685  virtual void updateDateFormat(std::size_t index, base::type::string_t& currFormat) ELPP_FINAL;
1686 
1688  virtual void updateFormatSpec(void) ELPP_FINAL;
1689 
1690  inline void addFlag(base::FormatFlags flag) {
1691  base::utils::addFlag(flag, &m_flags);
1692  }
1693 
1694  private:
1695  Level m_level;
1696  base::type::string_t m_userFormat;
1697  base::type::string_t m_format;
1698  std::string m_dateTimeFormat;
1699  base::type::EnumType m_flags;
1700  std::string m_currentUser;
1701  std::string m_currentHost;
1702  friend class el::Logger; // To resolve loggerId format specifier easily
1703 };
1704 } // namespace base
1706 typedef std::function<std::string(const LogMessage*)> FormatSpecifierValueResolver;
1711  public:
1712  CustomFormatSpecifier(const char* formatSpecifier, const FormatSpecifierValueResolver& resolver) :
1713  m_formatSpecifier(formatSpecifier), m_resolver(resolver) {}
1714  inline const char* formatSpecifier(void) const {
1715  return m_formatSpecifier;
1716  }
1717  inline const FormatSpecifierValueResolver& resolver(void) const {
1718  return m_resolver;
1719  }
1720  inline bool operator==(const char* formatSpecifier) {
1721  return strcmp(m_formatSpecifier, formatSpecifier) == 0;
1722  }
1723 
1724  private:
1725  const char* m_formatSpecifier;
1726  FormatSpecifierValueResolver m_resolver;
1727 };
1737 class Configuration : public Loggable {
1738  public:
1739  Configuration(const Configuration& c);
1740  Configuration& operator=(const Configuration& c);
1741 
1742  virtual ~Configuration(void) {
1743  }
1744 
1747 
1749  inline Level level(void) const {
1750  return m_level;
1751  }
1752 
1755  return m_configurationType;
1756  }
1757 
1759  inline const std::string& value(void) const {
1760  return m_value;
1761  }
1762 
1766  inline void setValue(const std::string& value) {
1767  m_value = value;
1768  }
1769 
1770  virtual void log(el::base::type::ostream_t& os) const;
1771 
1773  class Predicate {
1774  public:
1775  Predicate(Level level, ConfigurationType configurationType);
1776 
1777  bool operator()(const Configuration* conf) const;
1778 
1779  private:
1780  Level m_level;
1781  ConfigurationType m_configurationType;
1782  };
1783 
1784  private:
1785  Level m_level;
1786  ConfigurationType m_configurationType;
1787  std::string m_value;
1788 };
1789 
1793 class Configurations : public base::utils::RegistryWithPred<Configuration, Configuration::Predicate> {
1794  public:
1796  Configurations(void);
1797 
1804  Configurations(const std::string &configurationFile,
1805  bool useDefaultsForRemaining = true,
1806  Configurations *base = nullptr);
1807 
1808  virtual ~Configurations(void) {
1809  }
1810 
1817  bool parseFromFile(const std::string& configurationFile, Configurations* base = nullptr);
1818 
1827  bool parseFromText(const std::string& configurationsString, Configurations* base = nullptr);
1828 
1831  void setFromBase(Configurations* base);
1832 
1837  bool hasConfiguration(ConfigurationType configurationType);
1838 
1842  bool hasConfiguration(Level level, ConfigurationType configurationType);
1843 
1856  void set(Level level, ConfigurationType configurationType, const std::string& value);
1857 
1860  void set(Configuration* conf);
1861 
1862  inline Configuration* get(Level level, ConfigurationType configurationType) {
1863  base::threading::ScopedLock scopedLock(lock());
1864  return RegistryWithPred<Configuration, Configuration::Predicate>::get(level, configurationType);
1865  }
1866 
1871  inline void setGlobally(ConfigurationType configurationType, const std::string& value) {
1872  setGlobally(configurationType, value, false);
1873  }
1874 
1876  inline void clear(void) {
1877  base::threading::ScopedLock scopedLock(lock());
1878  unregisterAll();
1879  }
1880 
1884  inline const std::string& configurationFile(void) const {
1885  return m_configurationFile;
1886  }
1887 
1889  void setToDefault(void);
1890 
1898  void setRemainingToDefault(void);
1899 
1905  public:
1913  static bool parseFromFile(const std::string& configurationFile, Configurations* sender,
1914  Configurations* base = nullptr);
1915 
1926  static bool parseFromText(const std::string& configurationsString, Configurations* sender,
1927  Configurations* base = nullptr);
1928 
1929  private:
1930  friend class el::Loggers;
1931  static void ignoreComments(std::string* line);
1932  static bool isLevel(const std::string& line);
1933  static bool isComment(const std::string& line);
1934  static inline bool isConfig(const std::string& line);
1935  static bool parseLine(std::string* line, std::string* currConfigStr, std::string* currLevelStr, Level* currLevel,
1936  Configurations* conf);
1937  };
1938 
1939  private:
1940  std::string m_configurationFile;
1941  bool m_isFromFile;
1942  friend class el::Loggers;
1943 
1945  void unsafeSetIfNotExist(Level level, ConfigurationType configurationType, const std::string& value);
1946 
1948  void unsafeSet(Level level, ConfigurationType configurationType, const std::string& value);
1949 
1952  void setGlobally(ConfigurationType configurationType, const std::string& value, bool includeGlobalLevel);
1953 
1956  void unsafeSetGlobally(ConfigurationType configurationType, const std::string& value, bool includeGlobalLevel);
1957 };
1958 
1959 namespace base {
1960 typedef std::shared_ptr<base::type::fstream_t> FileStreamPtr;
1961 typedef std::map<std::string, FileStreamPtr> LogStreamsReferenceMap;
1969  public:
1973  TypedConfigurations(Configurations* configurations, base::LogStreamsReferenceMap* logStreamsReference);
1974 
1976 
1977  virtual ~TypedConfigurations(void) {
1978  }
1979 
1980  const Configurations* configurations(void) const {
1981  return m_configurations;
1982  }
1983 
1984  bool enabled(Level level);
1985  bool toFile(Level level);
1986  const std::string& filename(Level level);
1987  bool toStandardOutput(Level level);
1988  const base::LogFormat& logFormat(Level level);
1989  const base::SubsecondPrecision& subsecondPrecision(Level level = Level::Global);
1990  const base::MillisecondsWidth& millisecondsWidth(Level level = Level::Global);
1991  bool performanceTracking(Level level = Level::Global);
1992  base::type::fstream_t* fileStream(Level level);
1993  std::size_t maxLogFileSize(Level level);
1994  std::size_t logFlushThreshold(Level level);
1995 
1996  private:
1997  Configurations* m_configurations;
1998  std::map<Level, bool> m_enabledMap;
1999  std::map<Level, bool> m_toFileMap;
2000  std::map<Level, std::string> m_filenameMap;
2001  std::map<Level, bool> m_toStandardOutputMap;
2002  std::map<Level, base::LogFormat> m_logFormatMap;
2003  std::map<Level, base::SubsecondPrecision> m_subsecondPrecisionMap;
2004  std::map<Level, bool> m_performanceTrackingMap;
2005  std::map<Level, base::FileStreamPtr> m_fileStreamMap;
2006  std::map<Level, std::size_t> m_maxLogFileSizeMap;
2007  std::map<Level, std::size_t> m_logFlushThresholdMap;
2008  base::LogStreamsReferenceMap* m_logStreamsReference;
2009 
2010  friend class el::Helpers;
2011  friend class el::base::MessageBuilder;
2012  friend class el::base::Writer;
2014  friend class el::base::LogDispatcher;
2015 
2016  template <typename Conf_T>
2017  inline Conf_T getConfigByVal(Level level, const std::map<Level, Conf_T>* confMap, const char* confName) {
2018  base::threading::ScopedLock scopedLock(lock());
2019  return unsafeGetConfigByVal(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope
2020  }
2021 
2022  template <typename Conf_T>
2023  inline Conf_T& getConfigByRef(Level level, std::map<Level, Conf_T>* confMap, const char* confName) {
2024  base::threading::ScopedLock scopedLock(lock());
2025  return unsafeGetConfigByRef(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope
2026  }
2027 
2028  template <typename Conf_T>
2029  Conf_T unsafeGetConfigByVal(Level level, const std::map<Level, Conf_T>* confMap, const char* confName) {
2030  ELPP_UNUSED(confName);
2031  typename std::map<Level, Conf_T>::const_iterator it = confMap->find(level);
2032  if (it == confMap->end()) {
2033  try {
2034  return confMap->at(Level::Global);
2035  } catch (...) {
2036  ELPP_INTERNAL_ERROR("Unable to get configuration [" << confName << "] for level ["
2037  << LevelHelper::convertToString(level) << "]"
2038  << std::endl << "Please ensure you have properly configured logger.", false);
2039  return Conf_T();
2040  }
2041  }
2042  return it->second;
2043  }
2044 
2045  template <typename Conf_T>
2046  Conf_T& unsafeGetConfigByRef(Level level, std::map<Level, Conf_T>* confMap, const char* confName) {
2047  ELPP_UNUSED(confName);
2048  typename std::map<Level, Conf_T>::iterator it = confMap->find(level);
2049  if (it == confMap->end()) {
2050  try {
2051  return confMap->at(Level::Global);
2052  } catch (...) {
2053  ELPP_INTERNAL_ERROR("Unable to get configuration [" << confName << "] for level ["
2054  << LevelHelper::convertToString(level) << "]"
2055  << std::endl << "Please ensure you have properly configured logger.", false);
2056  }
2057  }
2058  return it->second;
2059  }
2060 
2061  template <typename Conf_T>
2062  void setValue(Level level, const Conf_T& value, std::map<Level, Conf_T>* confMap, bool includeGlobalLevel = true) {
2063  // If map is empty and we are allowed to add into generic level (Level::Global), do it!
2064  if (confMap->empty() && includeGlobalLevel) {
2065  confMap->insert(std::make_pair(Level::Global, value));
2066  return;
2067  }
2068  // If same value exist in generic level already, dont add it to explicit level
2069  typename std::map<Level, Conf_T>::iterator it = confMap->find(Level::Global);
2070  if (it != confMap->end() && it->second == value) {
2071  return;
2072  }
2073  // Now make sure we dont double up values if we really need to add it to explicit level
2074  it = confMap->find(level);
2075  if (it == confMap->end()) {
2076  // Value not found for level, add new
2077  confMap->insert(std::make_pair(level, value));
2078  } else {
2079  // Value found, just update value
2080  confMap->at(level) = value;
2081  }
2082  }
2083 
2084  void build(Configurations* configurations);
2085  unsigned long getULong(std::string confVal);
2086  std::string resolveFilename(const std::string& filename);
2087  void insertFile(Level level, const std::string& fullFilename);
2088  bool unsafeValidateFileRolling(Level level, const PreRollOutCallback& preRollOutCallback);
2089 
2090  inline bool validateFileRolling(Level level, const PreRollOutCallback& preRollOutCallback) {
2091  base::threading::ScopedLock scopedLock(lock());
2092  return unsafeValidateFileRolling(level, preRollOutCallback);
2093  }
2094 };
2096 class HitCounter {
2097  public:
2098  HitCounter(void) :
2099  m_filename(""),
2100  m_lineNumber(0),
2101  m_hitCounts(0) {
2102  }
2103 
2104  HitCounter(const char* filename, base::type::LineNumber lineNumber) :
2105  m_filename(filename),
2106  m_lineNumber(lineNumber),
2107  m_hitCounts(0) {
2108  }
2109 
2110  HitCounter(const HitCounter& hitCounter) :
2111  m_filename(hitCounter.m_filename),
2112  m_lineNumber(hitCounter.m_lineNumber),
2113  m_hitCounts(hitCounter.m_hitCounts) {
2114  }
2115 
2116  HitCounter& operator=(const HitCounter& hitCounter) {
2117  if (&hitCounter != this) {
2118  m_filename = hitCounter.m_filename;
2119  m_lineNumber = hitCounter.m_lineNumber;
2120  m_hitCounts = hitCounter.m_hitCounts;
2121  }
2122  return *this;
2123  }
2124 
2125  virtual ~HitCounter(void) {
2126  }
2127 
2129  inline void resetLocation(const char* filename, base::type::LineNumber lineNumber) {
2130  m_filename = filename;
2131  m_lineNumber = lineNumber;
2132  }
2133 
2135  inline void validateHitCounts(std::size_t n) {
2136  if (m_hitCounts >= base::consts::kMaxLogPerCounter) {
2137  m_hitCounts = (n >= 1 ? base::consts::kMaxLogPerCounter % n : 0);
2138  }
2139  ++m_hitCounts;
2140  }
2141 
2142  inline const char* filename(void) const {
2143  return m_filename;
2144  }
2145 
2146  inline base::type::LineNumber lineNumber(void) const {
2147  return m_lineNumber;
2148  }
2149 
2150  inline std::size_t hitCounts(void) const {
2151  return m_hitCounts;
2152  }
2153 
2154  inline void increment(void) {
2155  ++m_hitCounts;
2156  }
2157 
2158  class Predicate {
2159  public:
2160  Predicate(const char* filename, base::type::LineNumber lineNumber)
2161  : m_filename(filename),
2162  m_lineNumber(lineNumber) {
2163  }
2164  inline bool operator()(const HitCounter* counter) {
2165  return ((counter != nullptr) &&
2166  (strcmp(counter->m_filename, m_filename) == 0) &&
2167  (counter->m_lineNumber == m_lineNumber));
2168  }
2169 
2170  private:
2171  const char* m_filename;
2172  base::type::LineNumber m_lineNumber;
2173  };
2174 
2175  private:
2176  const char* m_filename;
2177  base::type::LineNumber m_lineNumber;
2178  std::size_t m_hitCounts;
2179 };
2181 class RegisteredHitCounters : public base::utils::RegistryWithPred<base::HitCounter, base::HitCounter::Predicate> {
2182  public:
2185  bool validateEveryN(const char* filename, base::type::LineNumber lineNumber, std::size_t n);
2186 
2189  bool validateAfterN(const char* filename, base::type::LineNumber lineNumber, std::size_t n);
2190 
2193  bool validateNTimes(const char* filename, base::type::LineNumber lineNumber, std::size_t n);
2194 
2196  inline const base::HitCounter* getCounter(const char* filename, base::type::LineNumber lineNumber) {
2197  base::threading::ScopedLock scopedLock(lock());
2198  return get(filename, lineNumber);
2199  }
2200 };
2202 enum class DispatchAction : base::type::EnumType {
2203  None = 1, NormalLog = 2, SysLog = 4
2204 };
2205 } // namespace base
2206 template <typename T>
2207 class Callback : protected base::threading::ThreadSafe {
2208  public:
2209  Callback(void) : m_enabled(true) {}
2210  inline bool enabled(void) const {
2211  return m_enabled;
2212  }
2213  inline void setEnabled(bool enabled) {
2214  base::threading::ScopedLock scopedLock(lock());
2215  m_enabled = enabled;
2216  }
2217  protected:
2218  virtual void handle(const T* handlePtr) = 0;
2219  private:
2220  bool m_enabled;
2221 };
2223  public:
2224  LogDispatchData() : m_logMessage(nullptr), m_dispatchAction(base::DispatchAction::None) {}
2225  inline const LogMessage* logMessage(void) const {
2226  return m_logMessage;
2227  }
2228  inline base::DispatchAction dispatchAction(void) const {
2229  return m_dispatchAction;
2230  }
2231  private:
2232  LogMessage* m_logMessage;
2233  base::DispatchAction m_dispatchAction;
2234  friend class base::LogDispatcher;
2235 
2236  inline void setLogMessage(LogMessage* logMessage) {
2237  m_logMessage = logMessage;
2238  }
2239  inline void setDispatchAction(base::DispatchAction dispatchAction) {
2240  m_dispatchAction = dispatchAction;
2241  }
2242 };
2243 class LogDispatchCallback : public Callback<LogDispatchData> {
2244  private:
2245  friend class base::LogDispatcher;
2246 };
2247 class PerformanceTrackingCallback : public Callback<PerformanceTrackingData> {
2248  private:
2249  friend class base::PerformanceTracker;
2250 };
2251 class LoggerRegistrationCallback : public Callback<Logger> {
2252  private:
2253  friend class base::RegisteredLoggers;
2254 };
2256  public:
2257  LogBuilder() : m_termSupportsColor(base::utils::OS::termSupportsColor()) {}
2258  virtual ~LogBuilder(void) {
2259  ELPP_INTERNAL_INFO(3, "Destroying log builder...")
2260  }
2261  virtual base::type::string_t build(const LogMessage* logMessage, bool appendNewLine) const = 0;
2262  void convertToColoredOutput(base::type::string_t* logLine, Level level);
2263  private:
2264  bool m_termSupportsColor;
2266 };
2267 typedef std::shared_ptr<LogBuilder> LogBuilderPtr;
2272  public:
2273  Logger(const std::string& id, base::LogStreamsReferenceMap* logStreamsReference);
2274  Logger(const std::string& id, const Configurations& configurations, base::LogStreamsReferenceMap* logStreamsReference);
2275  Logger(const Logger& logger);
2276  Logger& operator=(const Logger& logger);
2277 
2278  virtual ~Logger(void) {
2279  base::utils::safeDelete(m_typedConfigurations);
2280  }
2281 
2282  virtual inline void log(el::base::type::ostream_t& os) const {
2283  os << m_id.c_str();
2284  }
2285 
2287  void configure(const Configurations& configurations);
2288 
2290  void reconfigure(void);
2291 
2292  inline const std::string& id(void) const {
2293  return m_id;
2294  }
2295 
2296  inline const std::string& parentApplicationName(void) const {
2297  return m_parentApplicationName;
2298  }
2299 
2300  inline void setParentApplicationName(const std::string& parentApplicationName) {
2301  m_parentApplicationName = parentApplicationName;
2302  }
2303 
2304  inline Configurations* configurations(void) {
2305  return &m_configurations;
2306  }
2307 
2308  inline base::TypedConfigurations* typedConfigurations(void) {
2309  return m_typedConfigurations;
2310  }
2311 
2312  static bool isValidId(const std::string& id);
2313 
2315  void flush(void);
2316 
2317  void flush(Level level, base::type::fstream_t* fs);
2318 
2319  inline bool isFlushNeeded(Level level) {
2320  return ++m_unflushedCount.find(level)->second >= m_typedConfigurations->logFlushThreshold(level);
2321  }
2322 
2323  inline LogBuilder* logBuilder(void) const {
2324  return m_logBuilder.get();
2325  }
2326 
2327  inline void setLogBuilder(const LogBuilderPtr& logBuilder) {
2328  m_logBuilder = logBuilder;
2329  }
2330 
2331  inline bool enabled(Level level) const {
2332  return m_typedConfigurations->enabled(level);
2333  }
2334 
2335 #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
2336 # define LOGGER_LEVEL_WRITERS_SIGNATURES(FUNCTION_NAME)\
2337 template <typename T, typename... Args>\
2338 inline void FUNCTION_NAME(const char*, const T&, const Args&...);\
2339 template <typename T>\
2340 inline void FUNCTION_NAME(const T&);
2341 
2342  template <typename T, typename... Args>
2343  inline void verbose(int, const char*, const T&, const Args&...);
2344 
2345  template <typename T>
2346  inline void verbose(int, const T&);
2347 
2348  LOGGER_LEVEL_WRITERS_SIGNATURES(info)
2349  LOGGER_LEVEL_WRITERS_SIGNATURES(debug)
2350  LOGGER_LEVEL_WRITERS_SIGNATURES(warn)
2351  LOGGER_LEVEL_WRITERS_SIGNATURES(error)
2352  LOGGER_LEVEL_WRITERS_SIGNATURES(fatal)
2353  LOGGER_LEVEL_WRITERS_SIGNATURES(trace)
2354 # undef LOGGER_LEVEL_WRITERS_SIGNATURES
2355 #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
2356  private:
2357  std::string m_id;
2358  base::TypedConfigurations* m_typedConfigurations;
2359  base::type::stringstream_t m_stream;
2360  std::string m_parentApplicationName;
2361  bool m_isConfigured;
2362  Configurations m_configurations;
2363  std::map<Level, unsigned int> m_unflushedCount;
2364  base::LogStreamsReferenceMap* m_logStreamsReference;
2365  LogBuilderPtr m_logBuilder;
2366 
2367  friend class el::LogMessage;
2368  friend class el::Loggers;
2369  friend class el::Helpers;
2370  friend class el::base::RegisteredLoggers;
2372  friend class el::base::MessageBuilder;
2373  friend class el::base::Writer;
2374  friend class el::base::PErrorWriter;
2375  friend class el::base::Storage;
2376  friend class el::base::PerformanceTracker;
2377  friend class el::base::LogDispatcher;
2378 
2379  Logger(void);
2380 
2381 #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
2382  template <typename T, typename... Args>
2383  void log_(Level, int, const char*, const T&, const Args&...);
2384 
2385  template <typename T>
2386  inline void log_(Level, int, const T&);
2387 
2388  template <typename T, typename... Args>
2389  void log(Level, const char*, const T&, const Args&...);
2390 
2391  template <typename T>
2392  inline void log(Level, const T&);
2393 #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
2394 
2395  void initUnflushedCount(void);
2396 
2397  inline base::type::stringstream_t& stream(void) {
2398  return m_stream;
2399  }
2400 
2401  void resolveLoggerFormatSpec(void) const;
2402 };
2403 namespace base {
2405 class RegisteredLoggers : public base::utils::Registry<Logger, std::string> {
2406  public:
2407  explicit RegisteredLoggers(const LogBuilderPtr& defaultLogBuilder);
2408 
2409  virtual ~RegisteredLoggers(void) {
2410  unsafeFlushAll();
2411  }
2412 
2413  inline void setDefaultConfigurations(const Configurations& configurations) {
2414  base::threading::ScopedLock scopedLock(lock());
2415  m_defaultConfigurations.setFromBase(const_cast<Configurations*>(&configurations));
2416  }
2417 
2418  inline Configurations* defaultConfigurations(void) {
2419  return &m_defaultConfigurations;
2420  }
2421 
2422  Logger* get(const std::string& id, bool forceCreation = true);
2423 
2424  template <typename T>
2425  inline bool installLoggerRegistrationCallback(const std::string& id) {
2426  return base::utils::Utils::installCallback<T, base::type::LoggerRegistrationCallbackPtr>(id,
2427  &m_loggerRegistrationCallbacks);
2428  }
2429 
2430  template <typename T>
2431  inline void uninstallLoggerRegistrationCallback(const std::string& id) {
2432  base::utils::Utils::uninstallCallback<T, base::type::LoggerRegistrationCallbackPtr>(id, &m_loggerRegistrationCallbacks);
2433  }
2434 
2435  template <typename T>
2436  inline T* loggerRegistrationCallback(const std::string& id) {
2437  return base::utils::Utils::callback<T, base::type::LoggerRegistrationCallbackPtr>(id, &m_loggerRegistrationCallbacks);
2438  }
2439 
2440  bool remove(const std::string& id);
2441 
2442  inline bool has(const std::string& id) {
2443  return get(id, false) != nullptr;
2444  }
2445 
2446  inline void unregister(Logger*& logger) {
2447  base::threading::ScopedLock scopedLock(lock());
2449  }
2450 
2451  inline base::LogStreamsReferenceMap* logStreamsReference(void) {
2452  return &m_logStreamsReference;
2453  }
2454 
2455  inline void flushAll(void) {
2456  base::threading::ScopedLock scopedLock(lock());
2457  unsafeFlushAll();
2458  }
2459 
2460  inline void setDefaultLogBuilder(LogBuilderPtr& logBuilderPtr) {
2461  base::threading::ScopedLock scopedLock(lock());
2462  m_defaultLogBuilder = logBuilderPtr;
2463  }
2464 
2465  private:
2466  LogBuilderPtr m_defaultLogBuilder;
2467  Configurations m_defaultConfigurations;
2468  base::LogStreamsReferenceMap m_logStreamsReference;
2469  std::map<std::string, base::type::LoggerRegistrationCallbackPtr> m_loggerRegistrationCallbacks;
2470  friend class el::base::Storage;
2471 
2472  void unsafeFlushAll(void);
2473 };
2476  public:
2477  explicit VRegistry(base::type::VerboseLevel level, base::type::EnumType* pFlags);
2478 
2480  void setLevel(base::type::VerboseLevel level);
2481 
2482  inline base::type::VerboseLevel level(void) const {
2483  return m_level;
2484  }
2485 
2486  inline void clearModules(void) {
2487  base::threading::ScopedLock scopedLock(lock());
2488  m_modules.clear();
2489  }
2490 
2491  void setModules(const char* modules);
2492 
2493  bool allowed(base::type::VerboseLevel vlevel, const char* file);
2494 
2495  inline const std::map<std::string, base::type::VerboseLevel>& modules(void) const {
2496  return m_modules;
2497  }
2498 
2499  void setFromArgs(const base::utils::CommandLineArgs* commandLineArgs);
2500 
2502  inline bool vModulesEnabled(void) {
2503  return !base::utils::hasFlag(LoggingFlag::DisableVModules, *m_pFlags);
2504  }
2505 
2506  private:
2507  base::type::VerboseLevel m_level;
2508  base::type::EnumType* m_pFlags;
2509  std::map<std::string, base::type::VerboseLevel> m_modules;
2510 };
2511 } // namespace base
2512 class LogMessage {
2513  public:
2514  LogMessage(Level level, const std::string& file, base::type::LineNumber line, const std::string& func,
2515  base::type::VerboseLevel verboseLevel, Logger* logger) :
2516  m_level(level), m_file(file), m_line(line), m_func(func),
2517  m_verboseLevel(verboseLevel), m_logger(logger), m_message(logger->stream().str()) {
2518  }
2519  inline Level level(void) const {
2520  return m_level;
2521  }
2522  inline const std::string& file(void) const {
2523  return m_file;
2524  }
2525  inline base::type::LineNumber line(void) const {
2526  return m_line;
2527  }
2528  inline const std::string& func(void) const {
2529  return m_func;
2530  }
2531  inline base::type::VerboseLevel verboseLevel(void) const {
2532  return m_verboseLevel;
2533  }
2534  inline Logger* logger(void) const {
2535  return m_logger;
2536  }
2537  inline const base::type::string_t& message(void) const {
2538  return m_message;
2539  }
2540  private:
2541  Level m_level;
2542  std::string m_file;
2543  base::type::LineNumber m_line;
2544  std::string m_func;
2545  base::type::VerboseLevel m_verboseLevel;
2546  Logger* m_logger;
2547  base::type::string_t m_message;
2548 };
2549 namespace base {
2550 #if ELPP_ASYNC_LOGGING
2551 class AsyncLogItem {
2552  public:
2553  explicit AsyncLogItem(const LogMessage& logMessage, const LogDispatchData& data, const base::type::string_t& logLine)
2554  : m_logMessage(logMessage), m_dispatchData(data), m_logLine(logLine) {}
2555  virtual ~AsyncLogItem() {}
2556  inline LogMessage* logMessage(void) {
2557  return &m_logMessage;
2558  }
2559  inline LogDispatchData* data(void) {
2560  return &m_dispatchData;
2561  }
2562  inline base::type::string_t logLine(void) {
2563  return m_logLine;
2564  }
2565  private:
2566  LogMessage m_logMessage;
2567  LogDispatchData m_dispatchData;
2568  base::type::string_t m_logLine;
2569 };
2570 class AsyncLogQueue : public base::threading::ThreadSafe {
2571  public:
2572  virtual ~AsyncLogQueue() {
2573  ELPP_INTERNAL_INFO(6, "~AsyncLogQueue");
2574  }
2575 
2576  inline AsyncLogItem next(void) {
2577  base::threading::ScopedLock scopedLock(lock());
2578  AsyncLogItem result = m_queue.front();
2579  m_queue.pop();
2580  return result;
2581  }
2582 
2583  inline void push(const AsyncLogItem& item) {
2584  base::threading::ScopedLock scopedLock(lock());
2585  m_queue.push(item);
2586  }
2587  inline void pop(void) {
2588  base::threading::ScopedLock scopedLock(lock());
2589  m_queue.pop();
2590  }
2591  inline AsyncLogItem front(void) {
2592  base::threading::ScopedLock scopedLock(lock());
2593  return m_queue.front();
2594  }
2595  inline bool empty(void) {
2596  base::threading::ScopedLock scopedLock(lock());
2597  return m_queue.empty();
2598  }
2599  private:
2600  std::queue<AsyncLogItem> m_queue;
2601 };
2602 class IWorker {
2603  public:
2604  virtual ~IWorker() {}
2605  virtual void start() = 0;
2606 };
2607 #endif // ELPP_ASYNC_LOGGING
2608 class Storage : base::NoCopy, public base::threading::ThreadSafe {
2610  public:
2611 #if ELPP_ASYNC_LOGGING
2612  Storage(const LogBuilderPtr& defaultLogBuilder, base::IWorker* asyncDispatchWorker);
2613 #else
2614  explicit Storage(const LogBuilderPtr& defaultLogBuilder);
2615 #endif // ELPP_ASYNC_LOGGING
2616 
2617  virtual ~Storage(void);
2618 
2619  inline bool validateEveryNCounter(const char* filename, base::type::LineNumber lineNumber, std::size_t occasion) {
2620  return hitCounters()->validateEveryN(filename, lineNumber, occasion);
2621  }
2622 
2623  inline bool validateAfterNCounter(const char* filename, base::type::LineNumber lineNumber, std::size_t n) {
2624  return hitCounters()->validateAfterN(filename, lineNumber, n);
2625  }
2626 
2627  inline bool validateNTimesCounter(const char* filename, base::type::LineNumber lineNumber, std::size_t n) {
2628  return hitCounters()->validateNTimes(filename, lineNumber, n);
2629  }
2630 
2631  inline base::RegisteredHitCounters* hitCounters(void) const {
2632  return m_registeredHitCounters;
2633  }
2634 
2635  inline base::RegisteredLoggers* registeredLoggers(void) const {
2636  return m_registeredLoggers;
2637  }
2638 
2639  inline base::VRegistry* vRegistry(void) const {
2640  return m_vRegistry;
2641  }
2642 
2643 #if ELPP_ASYNC_LOGGING
2644  inline base::AsyncLogQueue* asyncLogQueue(void) const {
2645  return m_asyncLogQueue;
2646  }
2647 #endif // ELPP_ASYNC_LOGGING
2648 
2649  inline const base::utils::CommandLineArgs* commandLineArgs(void) const {
2650  return &m_commandLineArgs;
2651  }
2652 
2653  inline void addFlag(LoggingFlag flag) {
2654  base::utils::addFlag(flag, &m_flags);
2655  }
2656 
2657  inline void removeFlag(LoggingFlag flag) {
2658  base::utils::removeFlag(flag, &m_flags);
2659  }
2660 
2661  inline bool hasFlag(LoggingFlag flag) const {
2662  return base::utils::hasFlag(flag, m_flags);
2663  }
2664 
2665  inline base::type::EnumType flags(void) const {
2666  return m_flags;
2667  }
2668 
2669  inline void setFlags(base::type::EnumType flags) {
2670  m_flags = flags;
2671  }
2672 
2673  inline void setPreRollOutCallback(const PreRollOutCallback& callback) {
2674  m_preRollOutCallback = callback;
2675  }
2676 
2677  inline void unsetPreRollOutCallback(void) {
2678  m_preRollOutCallback = base::defaultPreRollOutCallback;
2679  }
2680 
2681  inline PreRollOutCallback& preRollOutCallback(void) {
2682  return m_preRollOutCallback;
2683  }
2684 
2685  bool hasCustomFormatSpecifier(const char* formatSpecifier);
2686  void installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier);
2687  bool uninstallCustomFormatSpecifier(const char* formatSpecifier);
2688 
2689  const std::vector<CustomFormatSpecifier>* customFormatSpecifiers(void) const {
2690  return &m_customFormatSpecifiers;
2691  }
2692 
2693  inline void setLoggingLevel(Level level) {
2694  m_loggingLevel = level;
2695  }
2696 
2697  template <typename T>
2698  inline bool installLogDispatchCallback(const std::string& id) {
2699  return base::utils::Utils::installCallback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks);
2700  }
2701 
2702  template <typename T>
2703  inline void uninstallLogDispatchCallback(const std::string& id) {
2704  base::utils::Utils::uninstallCallback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks);
2705  }
2706  template <typename T>
2707  inline T* logDispatchCallback(const std::string& id) {
2708  return base::utils::Utils::callback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks);
2709  }
2710 
2711 #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
2712  template <typename T>
2713  inline bool installPerformanceTrackingCallback(const std::string& id) {
2714  return base::utils::Utils::installCallback<T, base::type::PerformanceTrackingCallbackPtr>(id,
2715  &m_performanceTrackingCallbacks);
2716  }
2717 
2718  template <typename T>
2719  inline void uninstallPerformanceTrackingCallback(const std::string& id) {
2720  base::utils::Utils::uninstallCallback<T, base::type::PerformanceTrackingCallbackPtr>(id,
2721  &m_performanceTrackingCallbacks);
2722  }
2723 
2724  template <typename T>
2725  inline T* performanceTrackingCallback(const std::string& id) {
2726  return base::utils::Utils::callback<T, base::type::PerformanceTrackingCallbackPtr>(id, &m_performanceTrackingCallbacks);
2727  }
2728 #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
2729 
2731  inline void setThreadName(const std::string& name) {
2732  if (name.empty()) return;
2733  base::threading::ScopedLock scopedLock(lock());
2734  m_threadNames[base::threading::getCurrentThreadId()] = name;
2735  }
2736 
2737  inline std::string getThreadName(const std::string& threadId) {
2738  std::map<std::string, std::string>::const_iterator it = m_threadNames.find(threadId);
2739  if (it == m_threadNames.end()) {
2740  return threadId;
2741  }
2742  return it->second;
2743  }
2744  private:
2745  base::RegisteredHitCounters* m_registeredHitCounters;
2746  base::RegisteredLoggers* m_registeredLoggers;
2747  base::type::EnumType m_flags;
2748  base::VRegistry* m_vRegistry;
2749 #if ELPP_ASYNC_LOGGING
2750  base::AsyncLogQueue* m_asyncLogQueue;
2751  base::IWorker* m_asyncDispatchWorker;
2752 #endif // ELPP_ASYNC_LOGGING
2753  base::utils::CommandLineArgs m_commandLineArgs;
2754  PreRollOutCallback m_preRollOutCallback;
2755  std::map<std::string, base::type::LogDispatchCallbackPtr> m_logDispatchCallbacks;
2756  std::map<std::string, base::type::PerformanceTrackingCallbackPtr> m_performanceTrackingCallbacks;
2757  std::map<std::string, std::string> m_threadNames;
2758  std::vector<CustomFormatSpecifier> m_customFormatSpecifiers;
2759  Level m_loggingLevel;
2760 
2761  friend class el::Helpers;
2763  friend class el::LogBuilder;
2764  friend class el::base::MessageBuilder;
2765  friend class el::base::Writer;
2766  friend class el::base::PerformanceTracker;
2767  friend class el::base::LogDispatcher;
2768 
2769  void setApplicationArguments(int argc, char** argv);
2770 
2771  inline void setApplicationArguments(int argc, const char** argv) {
2772  setApplicationArguments(argc, const_cast<char**>(argv));
2773  }
2774 };
2775 extern ELPP_EXPORT base::type::StoragePointer elStorage;
2776 #define ELPP el::base::elStorage
2778  protected:
2779  void handle(const LogDispatchData* data);
2780  private:
2781  const LogDispatchData* m_data;
2782  void dispatch(base::type::string_t&& logLine);
2783 };
2784 #if ELPP_ASYNC_LOGGING
2785 class AsyncLogDispatchCallback : public LogDispatchCallback {
2786  protected:
2787  void handle(const LogDispatchData* data);
2788 };
2789 class AsyncDispatchWorker : public base::IWorker, public base::threading::ThreadSafe {
2790  public:
2791  AsyncDispatchWorker();
2792  virtual ~AsyncDispatchWorker();
2793 
2794  bool clean(void);
2795  void emptyQueue(void);
2796  virtual void start(void);
2797  void handle(AsyncLogItem* logItem);
2798  void run(void);
2799 
2800  void setContinueRunning(bool value) {
2801  base::threading::ScopedLock scopedLock(m_continueRunningMutex);
2802  m_continueRunning = value;
2803  }
2804 
2805  bool continueRunning(void) const {
2806  return m_continueRunning;
2807  }
2808  private:
2809  std::condition_variable cv;
2810  bool m_continueRunning;
2811  base::threading::Mutex m_continueRunningMutex;
2812 };
2813 #endif // ELPP_ASYNC_LOGGING
2814 } // namespace base
2815 namespace base {
2817  public:
2818  base::type::string_t build(const LogMessage* logMessage, bool appendNewLine) const;
2819 };
2822  public:
2823  LogDispatcher(bool proceed, LogMessage&& logMessage, base::DispatchAction dispatchAction) :
2824  m_proceed(proceed),
2825  m_logMessage(std::move(logMessage)),
2826  m_dispatchAction(std::move(dispatchAction)) {
2827  }
2828 
2829  void dispatch(void);
2830 
2831  private:
2832  bool m_proceed;
2833  LogMessage m_logMessage;
2834  base::DispatchAction m_dispatchAction;
2835 };
2836 #if defined(ELPP_STL_LOGGING)
2837 namespace workarounds {
2845 template <typename T, typename Container>
2846 class IterableContainer {
2847  public:
2848  typedef typename Container::iterator iterator;
2849  typedef typename Container::const_iterator const_iterator;
2850  IterableContainer(void) {}
2851  virtual ~IterableContainer(void) {}
2852  iterator begin(void) {
2853  return getContainer().begin();
2854  }
2855  iterator end(void) {
2856  return getContainer().end();
2857  }
2858  private:
2859  virtual Container& getContainer(void) = 0;
2860 };
2862 template<typename T, typename Container = std::vector<T>, typename Comparator = std::less<typename Container::value_type>>
2863 class IterablePriorityQueue : public IterableContainer<T, Container>,
2864  public std::priority_queue<T, Container, Comparator> {
2865  public:
2866  IterablePriorityQueue(std::priority_queue<T, Container, Comparator> queue_) {
2867  std::size_t count_ = 0;
2868  while (++count_ < base::consts::kMaxLogPerContainer && !queue_.empty()) {
2869  this->push(queue_.top());
2870  queue_.pop();
2871  }
2872  }
2873  private:
2874  inline Container& getContainer(void) {
2875  return this->c;
2876  }
2877 };
2879 template<typename T, typename Container = std::deque<T>>
2880 class IterableQueue : public IterableContainer<T, Container>, public std::queue<T, Container> {
2881  public:
2882  IterableQueue(std::queue<T, Container> queue_) {
2883  std::size_t count_ = 0;
2884  while (++count_ < base::consts::kMaxLogPerContainer && !queue_.empty()) {
2885  this->push(queue_.front());
2886  queue_.pop();
2887  }
2888  }
2889  private:
2890  inline Container& getContainer(void) {
2891  return this->c;
2892  }
2893 };
2895 template<typename T, typename Container = std::deque<T>>
2896 class IterableStack : public IterableContainer<T, Container>, public std::stack<T, Container> {
2897  public:
2898  IterableStack(std::stack<T, Container> stack_) {
2899  std::size_t count_ = 0;
2900  while (++count_ < base::consts::kMaxLogPerContainer && !stack_.empty()) {
2901  this->push(stack_.top());
2902  stack_.pop();
2903  }
2904  }
2905  private:
2906  inline Container& getContainer(void) {
2907  return this->c;
2908  }
2909 };
2910 } // namespace workarounds
2911 #endif // defined(ELPP_STL_LOGGING)
2912 // Log message builder
2914  public:
2915  MessageBuilder(void) : m_logger(nullptr), m_containerLogSeperator(ELPP_LITERAL("")) {}
2916  void initialize(Logger* logger);
2917 
2918 # define ELPP_SIMPLE_LOG(LOG_TYPE)\
2919 MessageBuilder& operator<<(LOG_TYPE msg) {\
2920 m_logger->stream() << msg;\
2921 if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) {\
2922 m_logger->stream() << " ";\
2923 }\
2924 return *this;\
2925 }
2926 
2927  inline MessageBuilder& operator<<(const std::string& msg) {
2928  return operator<<(msg.c_str());
2929  }
2930  ELPP_SIMPLE_LOG(char)
2931  ELPP_SIMPLE_LOG(bool)
2932  ELPP_SIMPLE_LOG(signed short)
2933  ELPP_SIMPLE_LOG(unsigned short)
2934  ELPP_SIMPLE_LOG(signed int)
2935  ELPP_SIMPLE_LOG(unsigned int)
2936  ELPP_SIMPLE_LOG(signed long)
2937  ELPP_SIMPLE_LOG(unsigned long)
2938  ELPP_SIMPLE_LOG(float)
2939  ELPP_SIMPLE_LOG(double)
2940  ELPP_SIMPLE_LOG(char*)
2941  ELPP_SIMPLE_LOG(const char*)
2942  ELPP_SIMPLE_LOG(const void*)
2943  ELPP_SIMPLE_LOG(long double)
2944  inline MessageBuilder& operator<<(const std::wstring& msg) {
2945  return operator<<(msg.c_str());
2946  }
2947  MessageBuilder& operator<<(const wchar_t* msg);
2948  // ostream manipulators
2949  inline MessageBuilder& operator<<(std::ostream& (*OStreamMani)(std::ostream&)) {
2950  m_logger->stream() << OStreamMani;
2951  return *this;
2952  }
2953 #define ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(temp) \
2954 template <typename T> \
2955 inline MessageBuilder& operator<<(const temp<T>& template_inst) { \
2956 return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
2957 }
2958 #define ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(temp) \
2959 template <typename T1, typename T2> \
2960 inline MessageBuilder& operator<<(const temp<T1, T2>& template_inst) { \
2961 return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
2962 }
2963 #define ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(temp) \
2964 template <typename T1, typename T2, typename T3> \
2965 inline MessageBuilder& operator<<(const temp<T1, T2, T3>& template_inst) { \
2966 return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
2967 }
2968 #define ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(temp) \
2969 template <typename T1, typename T2, typename T3, typename T4> \
2970 inline MessageBuilder& operator<<(const temp<T1, T2, T3, T4>& template_inst) { \
2971 return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
2972 }
2973 #define ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(temp) \
2974 template <typename T1, typename T2, typename T3, typename T4, typename T5> \
2975 inline MessageBuilder& operator<<(const temp<T1, T2, T3, T4, T5>& template_inst) { \
2976 return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
2977 }
2978 
2979 #if defined(ELPP_STL_LOGGING)
2980  ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::vector)
2981  ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::list)
2982  ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::deque)
2983  ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(std::set)
2984  ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(std::multiset)
2985  ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::map)
2986  ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::multimap)
2987  template <class T, class Container>
2988  inline MessageBuilder& operator<<(const std::queue<T, Container>& queue_) {
2989  base::workarounds::IterableQueue<T, Container> iterableQueue_ =
2990  static_cast<base::workarounds::IterableQueue<T, Container> >(queue_);
2991  return writeIterator(iterableQueue_.begin(), iterableQueue_.end(), iterableQueue_.size());
2992  }
2993  template <class T, class Container>
2994  inline MessageBuilder& operator<<(const std::stack<T, Container>& stack_) {
2995  base::workarounds::IterableStack<T, Container> iterableStack_ =
2996  static_cast<base::workarounds::IterableStack<T, Container> >(stack_);
2997  return writeIterator(iterableStack_.begin(), iterableStack_.end(), iterableStack_.size());
2998  }
2999  template <class T, class Container, class Comparator>
3000  inline MessageBuilder& operator<<(const std::priority_queue<T, Container, Comparator>& priorityQueue_) {
3001  base::workarounds::IterablePriorityQueue<T, Container, Comparator> iterablePriorityQueue_ =
3002  static_cast<base::workarounds::IterablePriorityQueue<T, Container, Comparator> >(priorityQueue_);
3003  return writeIterator(iterablePriorityQueue_.begin(), iterablePriorityQueue_.end(), iterablePriorityQueue_.size());
3004  }
3005  template <class First, class Second>
3006  MessageBuilder& operator<<(const std::pair<First, Second>& pair_) {
3007  m_logger->stream() << ELPP_LITERAL("(");
3008  operator << (static_cast<First>(pair_.first));
3009  m_logger->stream() << ELPP_LITERAL(", ");
3010  operator << (static_cast<Second>(pair_.second));
3011  m_logger->stream() << ELPP_LITERAL(")");
3012  return *this;
3013  }
3014  template <std::size_t Size>
3015  MessageBuilder& operator<<(const std::bitset<Size>& bitset_) {
3016  m_logger->stream() << ELPP_LITERAL("[");
3017  operator << (bitset_.to_string());
3018  m_logger->stream() << ELPP_LITERAL("]");
3019  return *this;
3020  }
3021 # if defined(ELPP_LOG_STD_ARRAY)
3022  template <class T, std::size_t Size>
3023  inline MessageBuilder& operator<<(const std::array<T, Size>& array) {
3024  return writeIterator(array.begin(), array.end(), array.size());
3025  }
3026 # endif // defined(ELPP_LOG_STD_ARRAY)
3027 # if defined(ELPP_LOG_UNORDERED_MAP)
3028  ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(std::unordered_map)
3029  ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(std::unordered_multimap)
3030 # endif // defined(ELPP_LOG_UNORDERED_MAP)
3031 # if defined(ELPP_LOG_UNORDERED_SET)
3032  ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::unordered_set)
3033  ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::unordered_multiset)
3034 # endif // defined(ELPP_LOG_UNORDERED_SET)
3035 #endif // defined(ELPP_STL_LOGGING)
3036 #if defined(ELPP_QT_LOGGING)
3037  inline MessageBuilder& operator<<(const QString& msg) {
3038 # if defined(ELPP_UNICODE)
3039  m_logger->stream() << msg.toStdWString();
3040 # else
3041  m_logger->stream() << msg.toStdString();
3042 # endif // defined(ELPP_UNICODE)
3043  return *this;
3044  }
3045  inline MessageBuilder& operator<<(const QByteArray& msg) {
3046  return operator << (QString(msg));
3047  }
3048  inline MessageBuilder& operator<<(const QStringRef& msg) {
3049  return operator<<(msg.toString());
3050  }
3051  inline MessageBuilder& operator<<(qint64 msg) {
3052 # if defined(ELPP_UNICODE)
3053  m_logger->stream() << QString::number(msg).toStdWString();
3054 # else
3055  m_logger->stream() << QString::number(msg).toStdString();
3056 # endif // defined(ELPP_UNICODE)
3057  return *this;
3058  }
3059  inline MessageBuilder& operator<<(quint64 msg) {
3060 # if defined(ELPP_UNICODE)
3061  m_logger->stream() << QString::number(msg).toStdWString();
3062 # else
3063  m_logger->stream() << QString::number(msg).toStdString();
3064 # endif // defined(ELPP_UNICODE)
3065  return *this;
3066  }
3067  inline MessageBuilder& operator<<(QChar msg) {
3068  m_logger->stream() << msg.toLatin1();
3069  return *this;
3070  }
3071  inline MessageBuilder& operator<<(const QLatin1String& msg) {
3072  m_logger->stream() << msg.latin1();
3073  return *this;
3074  }
3075  ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QList)
3076  ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QVector)
3077  ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QQueue)
3078  ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QSet)
3079  ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QLinkedList)
3080  ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QStack)
3081  template <typename First, typename Second>
3082  MessageBuilder& operator<<(const QPair<First, Second>& pair_) {
3083  m_logger->stream() << ELPP_LITERAL("(");
3084  operator << (static_cast<First>(pair_.first));
3085  m_logger->stream() << ELPP_LITERAL(", ");
3086  operator << (static_cast<Second>(pair_.second));
3087  m_logger->stream() << ELPP_LITERAL(")");
3088  return *this;
3089  }
3090  template <typename K, typename V>
3091  MessageBuilder& operator<<(const QMap<K, V>& map_) {
3092  m_logger->stream() << ELPP_LITERAL("[");
3093  QList<K> keys = map_.keys();
3094  typename QList<K>::const_iterator begin = keys.begin();
3095  typename QList<K>::const_iterator end = keys.end();
3096  int max_ = static_cast<int>(base::consts::kMaxLogPerContainer); // to prevent warning
3097  for (int index_ = 0; begin != end && index_ < max_; ++index_, ++begin) {
3098  m_logger->stream() << ELPP_LITERAL("(");
3099  operator << (static_cast<K>(*begin));
3100  m_logger->stream() << ELPP_LITERAL(", ");
3101  operator << (static_cast<V>(map_.value(*begin)));
3102  m_logger->stream() << ELPP_LITERAL(")");
3103  m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL(""));
3104  }
3105  if (begin != end) {
3106  m_logger->stream() << ELPP_LITERAL("...");
3107  }
3108  m_logger->stream() << ELPP_LITERAL("]");
3109  return *this;
3110  }
3111  template <typename K, typename V>
3112  inline MessageBuilder& operator<<(const QMultiMap<K, V>& map_) {
3113  operator << (static_cast<QMap<K, V>>(map_));
3114  return *this;
3115  }
3116  template <typename K, typename V>
3117  MessageBuilder& operator<<(const QHash<K, V>& hash_) {
3118  m_logger->stream() << ELPP_LITERAL("[");
3119  QList<K> keys = hash_.keys();
3120  typename QList<K>::const_iterator begin = keys.begin();
3121  typename QList<K>::const_iterator end = keys.end();
3122  int max_ = static_cast<int>(base::consts::kMaxLogPerContainer); // prevent type warning
3123  for (int index_ = 0; begin != end && index_ < max_; ++index_, ++begin) {
3124  m_logger->stream() << ELPP_LITERAL("(");
3125  operator << (static_cast<K>(*begin));
3126  m_logger->stream() << ELPP_LITERAL(", ");
3127  operator << (static_cast<V>(hash_.value(*begin)));
3128  m_logger->stream() << ELPP_LITERAL(")");
3129  m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL(""));
3130  }
3131  if (begin != end) {
3132  m_logger->stream() << ELPP_LITERAL("...");
3133  }
3134  m_logger->stream() << ELPP_LITERAL("]");
3135  return *this;
3136  }
3137  template <typename K, typename V>
3138  inline MessageBuilder& operator<<(const QMultiHash<K, V>& multiHash_) {
3139  operator << (static_cast<QHash<K, V>>(multiHash_));
3140  return *this;
3141  }
3142 #endif // defined(ELPP_QT_LOGGING)
3143 #if defined(ELPP_BOOST_LOGGING)
3144  ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::vector)
3145  ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::stable_vector)
3146  ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::list)
3147  ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::deque)
3148  ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(boost::container::map)
3149  ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(boost::container::flat_map)
3150  ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(boost::container::set)
3151  ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(boost::container::flat_set)
3152 #endif // defined(ELPP_BOOST_LOGGING)
3153 
3162 #define MAKE_CONTAINERELPP_FRIENDLY(ContainerType, SizeMethod, ElementInstance) \
3163 el::base::type::ostream_t& operator<<(el::base::type::ostream_t& ss, const ContainerType& container) {\
3164 const el::base::type::char_t* sep = ELPP->hasFlag(el::LoggingFlag::NewLineForContainer) ? \
3165 ELPP_LITERAL("\n ") : ELPP_LITERAL(", ");\
3166 ContainerType::const_iterator elem = container.begin();\
3167 ContainerType::const_iterator endElem = container.end();\
3168 std::size_t size_ = container.SizeMethod; \
3169 ss << ELPP_LITERAL("[");\
3170 for (std::size_t i = 0; elem != endElem && i < el::base::consts::kMaxLogPerContainer; ++i, ++elem) { \
3171 ss << ElementInstance;\
3172 ss << ((i < size_ - 1) ? sep : ELPP_LITERAL(""));\
3173 }\
3174 if (elem != endElem) {\
3175 ss << ELPP_LITERAL("...");\
3176 }\
3177 ss << ELPP_LITERAL("]");\
3178 return ss;\
3179 }
3180 #if defined(ELPP_WXWIDGETS_LOGGING)
3181  ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(wxVector)
3182 # define ELPP_WX_PTR_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), *(*elem))
3183 # define ELPP_WX_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), (*elem))
3184 # define ELPP_WX_HASH_MAP_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), \
3185 ELPP_LITERAL("(") << elem->first << ELPP_LITERAL(", ") << elem->second << ELPP_LITERAL(")")
3186 #else
3187 # define ELPP_WX_PTR_ENABLED(ContainerType)
3188 # define ELPP_WX_ENABLED(ContainerType)
3189 # define ELPP_WX_HASH_MAP_ENABLED(ContainerType)
3190 #endif // defined(ELPP_WXWIDGETS_LOGGING)
3191  // Other classes
3192  template <class Class>
3193  ELPP_SIMPLE_LOG(const Class&)
3194 #undef ELPP_SIMPLE_LOG
3195 #undef ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG
3196 #undef ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG
3197 #undef ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG
3198 #undef ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG
3199 #undef ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG
3200  private:
3201  Logger* m_logger;
3202  const base::type::char_t* m_containerLogSeperator;
3203 
3204  template<class Iterator>
3205  MessageBuilder& writeIterator(Iterator begin_, Iterator end_, std::size_t size_) {
3206  m_logger->stream() << ELPP_LITERAL("[");
3207  for (std::size_t i = 0; begin_ != end_ && i < base::consts::kMaxLogPerContainer; ++i, ++begin_) {
3208  operator << (*begin_);
3209  m_logger->stream() << ((i < size_ - 1) ? m_containerLogSeperator : ELPP_LITERAL(""));
3210  }
3211  if (begin_ != end_) {
3212  m_logger->stream() << ELPP_LITERAL("...");
3213  }
3214  m_logger->stream() << ELPP_LITERAL("]");
3215  if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) {
3216  m_logger->stream() << " ";
3217  }
3218  return *this;
3219  }
3220 };
3223  public:
3224  NullWriter(void) {}
3225 
3226  // Null manipulator
3227  inline NullWriter& operator<<(std::ostream& (*)(std::ostream&)) {
3228  return *this;
3229  }
3230 
3231  template <typename T>
3232  inline NullWriter& operator<<(const T&) {
3233  return *this;
3234  }
3235 
3236  inline operator bool() {
3237  return true;
3238  }
3239 };
3242  public:
3243  Writer(Level level, const char* file, base::type::LineNumber line,
3244  const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog,
3245  base::type::VerboseLevel verboseLevel = 0) :
3246  m_level(level), m_file(file), m_line(line), m_func(func), m_verboseLevel(verboseLevel),
3247  m_logger(nullptr), m_proceed(false), m_dispatchAction(dispatchAction) {
3248  }
3249 
3250  virtual ~Writer(void) {
3251  processDispatch();
3252  }
3253 
3254  template <typename T>
3255  inline Writer& operator<<(const T& log) {
3256 #if ELPP_LOGGING_ENABLED
3257  if (m_proceed) {
3258  m_messageBuilder << log;
3259  }
3260 #endif // ELPP_LOGGING_ENABLED
3261  return *this;
3262  }
3263 
3264  inline Writer& operator<<(std::ostream& (*log)(std::ostream&)) {
3265 #if ELPP_LOGGING_ENABLED
3266  if (m_proceed) {
3267  m_messageBuilder << log;
3268  }
3269 #endif // ELPP_LOGGING_ENABLED
3270  return *this;
3271  }
3272 
3273  inline operator bool() {
3274  return true;
3275  }
3276 
3277  Writer& construct(Logger* logger, bool needLock = true);
3278  Writer& construct(int count, const char* loggerIds, ...);
3279  protected:
3280  Level m_level;
3281  const char* m_file;
3282  const base::type::LineNumber m_line;
3283  const char* m_func;
3284  base::type::VerboseLevel m_verboseLevel;
3285  Logger* m_logger;
3286  bool m_proceed;
3287  base::MessageBuilder m_messageBuilder;
3288  base::DispatchAction m_dispatchAction;
3289  std::vector<std::string> m_loggerIds;
3290  friend class el::Helpers;
3291 
3292  void initializeLogger(const std::string& loggerId, bool lookup = true, bool needLock = true);
3293  void processDispatch();
3294  void triggerDispatch(void);
3295 };
3296 class PErrorWriter : public base::Writer {
3297  public:
3298  PErrorWriter(Level level, const char* file, base::type::LineNumber line,
3299  const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog,
3300  base::type::VerboseLevel verboseLevel = 0) :
3301  base::Writer(level, file, line, func, dispatchAction, verboseLevel) {
3302  }
3303 
3304  virtual ~PErrorWriter(void);
3305 };
3306 } // namespace base
3307 // Logging from Logger class. Why this is here? Because we have Storage and Writer class available
3308 #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
3309 template <typename T, typename... Args>
3310 void Logger::log_(Level level, int vlevel, const char* s, const T& value, const Args&... args) {
3312  b.initialize(this);
3313  while (*s) {
3314  if (*s == base::consts::kFormatSpecifierChar) {
3315  if (*(s + 1) == base::consts::kFormatSpecifierChar) {
3316  ++s;
3317  } else {
3318  if (*(s + 1) == base::consts::kFormatSpecifierCharValue) {
3319  ++s;
3320  b << value;
3321  log_(level, vlevel, ++s, args...);
3322  return;
3323  }
3324  }
3325  }
3326  b << *s++;
3327  }
3328  ELPP_INTERNAL_ERROR("Too many arguments provided. Unable to handle. Please provide more format specifiers", false);
3329 }
3330 template <typename T>
3331 void Logger::log_(Level level, int vlevel, const T& log) {
3332  if (level == Level::Verbose) {
3333  if (ELPP->vRegistry()->allowed(vlevel, __FILE__)) {
3334  base::Writer(Level::Verbose, "FILE", 0, "FUNCTION",
3335  base::DispatchAction::NormalLog, vlevel).construct(this, false) << log;
3336  } else {
3337  stream().str(ELPP_LITERAL(""));
3338  releaseLock();
3339  }
3340  } else {
3341  base::Writer(level, "FILE", 0, "FUNCTION").construct(this, false) << log;
3342  }
3343 }
3344 template <typename T, typename... Args>
3345 inline void Logger::log(Level level, const char* s, const T& value, const Args&... args) {
3346  acquireLock(); // released in Writer!
3347  log_(level, 0, s, value, args...);
3348 }
3349 template <typename T>
3350 inline void Logger::log(Level level, const T& log) {
3351  acquireLock(); // released in Writer!
3352  log_(level, 0, log);
3353 }
3354 # if ELPP_VERBOSE_LOG
3355 template <typename T, typename... Args>
3356 inline void Logger::verbose(int vlevel, const char* s, const T& value, const Args&... args) {
3357  acquireLock(); // released in Writer!
3358  log_(el::Level::Verbose, vlevel, s, value, args...);
3359 }
3360 template <typename T>
3361 inline void Logger::verbose(int vlevel, const T& log) {
3362  acquireLock(); // released in Writer!
3363  log_(el::Level::Verbose, vlevel, log);
3364 }
3365 # else
3366 template <typename T, typename... Args>
3367 inline void Logger::verbose(int, const char*, const T&, const Args&...) {
3368  return;
3369 }
3370 template <typename T>
3371 inline void Logger::verbose(int, const T&) {
3372  return;
3373 }
3374 # endif // ELPP_VERBOSE_LOG
3375 # define LOGGER_LEVEL_WRITERS(FUNCTION_NAME, LOG_LEVEL)\
3376 template <typename T, typename... Args>\
3377 inline void Logger::FUNCTION_NAME(const char* s, const T& value, const Args&... args) {\
3378 log(LOG_LEVEL, s, value, args...);\
3379 }\
3380 template <typename T>\
3381 inline void Logger::FUNCTION_NAME(const T& value) {\
3382 log(LOG_LEVEL, value);\
3383 }
3384 # define LOGGER_LEVEL_WRITERS_DISABLED(FUNCTION_NAME, LOG_LEVEL)\
3385 template <typename T, typename... Args>\
3386 inline void Logger::FUNCTION_NAME(const char*, const T&, const Args&...) {\
3387 return;\
3388 }\
3389 template <typename T>\
3390 inline void Logger::FUNCTION_NAME(const T&) {\
3391 return;\
3392 }
3393 
3394 # if ELPP_INFO_LOG
3395 LOGGER_LEVEL_WRITERS(info, Level::Info)
3396 # else
3397 LOGGER_LEVEL_WRITERS_DISABLED(info, Level::Info)
3398 # endif // ELPP_INFO_LOG
3399 # if ELPP_DEBUG_LOG
3400 LOGGER_LEVEL_WRITERS(debug, Level::Debug)
3401 # else
3402 LOGGER_LEVEL_WRITERS_DISABLED(debug, Level::Debug)
3403 # endif // ELPP_DEBUG_LOG
3404 # if ELPP_WARNING_LOG
3405 LOGGER_LEVEL_WRITERS(warn, Level::Warning)
3406 # else
3407 LOGGER_LEVEL_WRITERS_DISABLED(warn, Level::Warning)
3408 # endif // ELPP_WARNING_LOG
3409 # if ELPP_ERROR_LOG
3410 LOGGER_LEVEL_WRITERS(error, Level::Error)
3411 # else
3412 LOGGER_LEVEL_WRITERS_DISABLED(error, Level::Error)
3413 # endif // ELPP_ERROR_LOG
3414 # if ELPP_FATAL_LOG
3415 LOGGER_LEVEL_WRITERS(fatal, Level::Fatal)
3416 # else
3417 LOGGER_LEVEL_WRITERS_DISABLED(fatal, Level::Fatal)
3418 # endif // ELPP_FATAL_LOG
3419 # if ELPP_TRACE_LOG
3420 LOGGER_LEVEL_WRITERS(trace, Level::Trace)
3421 # else
3422 LOGGER_LEVEL_WRITERS_DISABLED(trace, Level::Trace)
3423 # endif // ELPP_TRACE_LOG
3424 # undef LOGGER_LEVEL_WRITERS
3425 # undef LOGGER_LEVEL_WRITERS_DISABLED
3426 #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
3427 #if ELPP_COMPILER_MSVC
3428 # define ELPP_VARIADIC_FUNC_MSVC(variadicFunction, variadicArgs) variadicFunction variadicArgs
3429 # define ELPP_VARIADIC_FUNC_MSVC_RUN(variadicFunction, ...) ELPP_VARIADIC_FUNC_MSVC(variadicFunction, (__VA_ARGS__))
3430 # define el_getVALength(...) ELPP_VARIADIC_FUNC_MSVC_RUN(el_resolveVALength, 0, ## __VA_ARGS__,\
3431 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
3432 #else
3433 # if ELPP_COMPILER_CLANG
3434 # define el_getVALength(...) el_resolveVALength(0, __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
3435 # else
3436 # define el_getVALength(...) el_resolveVALength(0, ## __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
3437 # endif // ELPP_COMPILER_CLANG
3438 #endif // ELPP_COMPILER_MSVC
3439 #define el_resolveVALength(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
3440 #define ELPP_WRITE_LOG(writer, level, dispatchAction, ...) \
3441 writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
3442 #define ELPP_WRITE_LOG_IF(writer, condition, level, dispatchAction, ...) if (condition) \
3443 writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
3444 #define ELPP_WRITE_LOG_EVERY_N(writer, occasion, level, dispatchAction, ...) \
3445 ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion) && \
3446 writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
3447 #define ELPP_WRITE_LOG_AFTER_N(writer, n, level, dispatchAction, ...) \
3448 ELPP->validateAfterNCounter(__FILE__, __LINE__, n) && \
3449 writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
3450 #define ELPP_WRITE_LOG_N_TIMES(writer, n, level, dispatchAction, ...) \
3451 ELPP->validateNTimesCounter(__FILE__, __LINE__, n) && \
3452 writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
3453 #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
3454 class PerformanceTrackingData {
3455  public:
3456  enum class DataType : base::type::EnumType {
3457  Checkpoint = 1, Complete = 2
3458  };
3459  // Do not use constructor, will run into multiple definition error, use init(PerformanceTracker*)
3460  explicit PerformanceTrackingData(DataType dataType) : m_performanceTracker(nullptr),
3461  m_dataType(dataType), m_firstCheckpoint(false), m_file(""), m_line(0), m_func("") {}
3462  inline const std::string* blockName(void) const;
3463  inline const struct timeval* startTime(void) const;
3464  inline const struct timeval* endTime(void) const;
3465  inline const struct timeval* lastCheckpointTime(void) const;
3466  inline const base::PerformanceTracker* performanceTracker(void) const {
3467  return m_performanceTracker;
3468  }
3469  inline PerformanceTrackingData::DataType dataType(void) const {
3470  return m_dataType;
3471  }
3472  inline bool firstCheckpoint(void) const {
3473  return m_firstCheckpoint;
3474  }
3475  inline std::string checkpointId(void) const {
3476  return m_checkpointId;
3477  }
3478  inline const char* file(void) const {
3479  return m_file;
3480  }
3481  inline base::type::LineNumber line(void) const {
3482  return m_line;
3483  }
3484  inline const char* func(void) const {
3485  return m_func;
3486  }
3487  inline const base::type::string_t* formattedTimeTaken() const {
3488  return &m_formattedTimeTaken;
3489  }
3490  inline const std::string& loggerId(void) const;
3491  private:
3492  base::PerformanceTracker* m_performanceTracker;
3493  base::type::string_t m_formattedTimeTaken;
3494  PerformanceTrackingData::DataType m_dataType;
3495  bool m_firstCheckpoint;
3496  std::string m_checkpointId;
3497  const char* m_file;
3498  base::type::LineNumber m_line;
3499  const char* m_func;
3500  inline void init(base::PerformanceTracker* performanceTracker, bool firstCheckpoint = false) {
3501  m_performanceTracker = performanceTracker;
3502  m_firstCheckpoint = firstCheckpoint;
3503  }
3504 
3505  friend class el::base::PerformanceTracker;
3506 };
3507 namespace base {
3510 class PerformanceTracker : public base::threading::ThreadSafe, public Loggable {
3511  public:
3512  PerformanceTracker(const std::string& blockName,
3513  base::TimestampUnit timestampUnit = base::TimestampUnit::Millisecond,
3514  const std::string& loggerId = std::string(el::base::consts::kPerformanceLoggerId),
3515  bool scopedLog = true, Level level = base::consts::kPerformanceTrackerDefaultLevel);
3517  PerformanceTracker(const PerformanceTracker& t) :
3518  m_blockName(t.m_blockName), m_timestampUnit(t.m_timestampUnit), m_loggerId(t.m_loggerId), m_scopedLog(t.m_scopedLog),
3519  m_level(t.m_level), m_hasChecked(t.m_hasChecked), m_lastCheckpointId(t.m_lastCheckpointId), m_enabled(t.m_enabled),
3520  m_startTime(t.m_startTime), m_endTime(t.m_endTime), m_lastCheckpointTime(t.m_lastCheckpointTime) {
3521  }
3522  virtual ~PerformanceTracker(void);
3524  void checkpoint(const std::string& id = std::string(), const char* file = __FILE__,
3525  base::type::LineNumber line = __LINE__,
3526  const char* func = "");
3527  inline Level level(void) const {
3528  return m_level;
3529  }
3530  private:
3531  std::string m_blockName;
3532  base::TimestampUnit m_timestampUnit;
3533  std::string m_loggerId;
3534  bool m_scopedLog;
3535  Level m_level;
3536  bool m_hasChecked;
3537  std::string m_lastCheckpointId;
3538  bool m_enabled;
3539  struct timeval m_startTime, m_endTime, m_lastCheckpointTime;
3540 
3541  PerformanceTracker(void);
3542 
3543  friend class el::PerformanceTrackingData;
3544  friend class base::DefaultPerformanceTrackingCallback;
3545 
3546  const inline base::type::string_t getFormattedTimeTaken() const {
3547  return getFormattedTimeTaken(m_startTime);
3548  }
3549 
3550  const base::type::string_t getFormattedTimeTaken(struct timeval startTime) const;
3551 
3552  virtual inline void log(el::base::type::ostream_t& os) const {
3553  os << getFormattedTimeTaken();
3554  }
3555 };
3556 class DefaultPerformanceTrackingCallback : public PerformanceTrackingCallback {
3557  protected:
3558  void handle(const PerformanceTrackingData* data) {
3559  m_data = data;
3560  base::type::stringstream_t ss;
3561  if (m_data->dataType() == PerformanceTrackingData::DataType::Complete) {
3562  ss << ELPP_LITERAL("Executed [") << m_data->blockName()->c_str() << ELPP_LITERAL("] in [") <<
3563  *m_data->formattedTimeTaken() << ELPP_LITERAL("]");
3564  } else {
3565  ss << ELPP_LITERAL("Performance checkpoint");
3566  if (!m_data->checkpointId().empty()) {
3567  ss << ELPP_LITERAL(" [") << m_data->checkpointId().c_str() << ELPP_LITERAL("]");
3568  }
3569  ss << ELPP_LITERAL(" for block [") << m_data->blockName()->c_str() << ELPP_LITERAL("] : [") <<
3570  *m_data->performanceTracker();
3572  && m_data->performanceTracker()->m_hasChecked) {
3573  ss << ELPP_LITERAL(" ([") << *m_data->formattedTimeTaken() << ELPP_LITERAL("] from ");
3574  if (m_data->performanceTracker()->m_lastCheckpointId.empty()) {
3575  ss << ELPP_LITERAL("last checkpoint");
3576  } else {
3577  ss << ELPP_LITERAL("checkpoint '") << m_data->performanceTracker()->m_lastCheckpointId.c_str() << ELPP_LITERAL("'");
3578  }
3579  ss << ELPP_LITERAL(")]");
3580  } else {
3581  ss << ELPP_LITERAL("]");
3582  }
3583  }
3584  el::base::Writer(m_data->performanceTracker()->level(), m_data->file(), m_data->line(), m_data->func()).construct(1,
3585  m_data->loggerId().c_str()) << ss.str();
3586  }
3587  private:
3588  const PerformanceTrackingData* m_data;
3589 };
3590 } // namespace base
3591 inline const std::string* PerformanceTrackingData::blockName() const {
3592  return const_cast<const std::string*>(&m_performanceTracker->m_blockName);
3593 }
3594 inline const struct timeval* PerformanceTrackingData::startTime() const {
3595  return const_cast<const struct timeval*>(&m_performanceTracker->m_startTime);
3596 }
3597 inline const struct timeval* PerformanceTrackingData::endTime() const {
3598  return const_cast<const struct timeval*>(&m_performanceTracker->m_endTime);
3599 }
3600 inline const struct timeval* PerformanceTrackingData::lastCheckpointTime() const {
3601  return const_cast<const struct timeval*>(&m_performanceTracker->m_lastCheckpointTime);
3602 }
3603 inline const std::string& PerformanceTrackingData::loggerId(void) const {
3604  return m_performanceTracker->m_loggerId;
3605 }
3606 #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
3607 namespace base {
3609 namespace debug {
3610 #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG)
3611 class StackTrace : base::NoCopy {
3612  public:
3613  static const unsigned int kMaxStack = 64;
3614  static const unsigned int kStackStart = 2; // We want to skip c'tor and StackTrace::generateNew()
3615  class StackTraceEntry {
3616  public:
3617  StackTraceEntry(std::size_t index, const char* loc, const char* demang, const char* hex, const char* addr);
3618  StackTraceEntry(std::size_t index, char* loc) :
3619  m_index(index),
3620  m_location(loc) {
3621  }
3622  std::size_t m_index;
3623  std::string m_location;
3624  std::string m_demangled;
3625  std::string m_hex;
3626  std::string m_addr;
3627  friend std::ostream& operator<<(std::ostream& ss, const StackTraceEntry& si);
3628 
3629  private:
3630  StackTraceEntry(void);
3631  };
3632 
3633  StackTrace(void) {
3634  generateNew();
3635  }
3636 
3637  virtual ~StackTrace(void) {
3638  }
3639 
3640  inline std::vector<StackTraceEntry>& getLatestStack(void) {
3641  return m_stack;
3642  }
3643 
3644  friend std::ostream& operator<<(std::ostream& os, const StackTrace& st);
3645 
3646  private:
3647  std::vector<StackTraceEntry> m_stack;
3648 
3649  void generateNew(void);
3650 };
3652 class CrashHandler : base::NoCopy {
3653  public:
3654  typedef void (*Handler)(int);
3655 
3656  explicit CrashHandler(bool useDefault);
3657  explicit CrashHandler(const Handler& cHandler) {
3658  setHandler(cHandler);
3659  }
3660  void setHandler(const Handler& cHandler);
3661 
3662  private:
3663  Handler m_handler;
3664 };
3665 #else
3667  public:
3668  explicit CrashHandler(bool) {}
3669 };
3670 #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG)
3671 } // namespace debug
3672 } // namespace base
3673 extern base::debug::CrashHandler elCrashHandler;
3674 #define MAKE_LOGGABLE(ClassType, ClassInstance, OutputStreamInstance) \
3675 el::base::type::ostream_t& operator<<(el::base::type::ostream_t& OutputStreamInstance, const ClassType& ClassInstance)
3676 class SysLogInitializer {
3678  public:
3679  SysLogInitializer(const char* processIdent, int options = 0, int facility = 0) {
3680 #if defined(ELPP_SYSLOG)
3681  openlog(processIdent, options, facility);
3682 #else
3683  ELPP_UNUSED(processIdent);
3684  ELPP_UNUSED(options);
3685  ELPP_UNUSED(facility);
3686 #endif // defined(ELPP_SYSLOG)
3687  }
3688  virtual ~SysLogInitializer(void) {
3689 #if defined(ELPP_SYSLOG)
3690  closelog();
3691 #endif // defined(ELPP_SYSLOG)
3692  }
3693 };
3694 #define ELPP_INITIALIZE_SYSLOG(id, opt, fac) el::SysLogInitializer elSyslogInit(id, opt, fac)
3695 class Helpers : base::StaticClass {
3697  public:
3699  static inline void setStorage(base::type::StoragePointer storage) {
3700  ELPP = storage;
3701  }
3703  static inline base::type::StoragePointer storage() {
3704  return ELPP;
3705  }
3707  static inline void setArgs(int argc, char** argv) {
3708  ELPP->setApplicationArguments(argc, argv);
3709  }
3711  static inline void setArgs(int argc, const char** argv) {
3712  ELPP->setApplicationArguments(argc, const_cast<char**>(argv));
3713  }
3715  static inline void setThreadName(const std::string& name) {
3716  ELPP->setThreadName(name);
3717  }
3718  static inline std::string getThreadName() {
3719  return ELPP->getThreadName(base::threading::getCurrentThreadId());
3720  }
3721 #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG)
3722  static inline void setCrashHandler(const el::base::debug::CrashHandler::Handler& crashHandler) {
3726  el::elCrashHandler.setHandler(crashHandler);
3727  }
3730  static void crashAbort(int sig, const char* sourceFile = "", unsigned int long line = 0);
3736  static void logCrashReason(int sig, bool stackTraceIfAvailable = false,
3737  Level level = Level::Fatal, const char* logger = base::consts::kDefaultLoggerId);
3738 #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG)
3739  static inline void installPreRollOutCallback(const PreRollOutCallback& callback) {
3742  ELPP->setPreRollOutCallback(callback);
3743  }
3745  static inline void uninstallPreRollOutCallback(void) {
3746  ELPP->unsetPreRollOutCallback();
3747  }
3749  template <typename T>
3750  static inline bool installLogDispatchCallback(const std::string& id) {
3751  return ELPP->installLogDispatchCallback<T>(id);
3752  }
3754  template <typename T>
3755  static inline void uninstallLogDispatchCallback(const std::string& id) {
3756  ELPP->uninstallLogDispatchCallback<T>(id);
3757  }
3758  template <typename T>
3759  static inline T* logDispatchCallback(const std::string& id) {
3760  return ELPP->logDispatchCallback<T>(id);
3761  }
3762 #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
3763  template <typename T>
3765  static inline bool installPerformanceTrackingCallback(const std::string& id) {
3766  return ELPP->installPerformanceTrackingCallback<T>(id);
3767  }
3769  template <typename T>
3770  static inline void uninstallPerformanceTrackingCallback(const std::string& id) {
3771  ELPP->uninstallPerformanceTrackingCallback<T>(id);
3772  }
3773  template <typename T>
3774  static inline T* performanceTrackingCallback(const std::string& id) {
3775  return ELPP->performanceTrackingCallback<T>(id);
3776  }
3777 #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
3778  template <typename T>
3780  static std::string convertTemplateToStdString(const T& templ) {
3781  el::Logger* logger =
3782  ELPP->registeredLoggers()->get(el::base::consts::kDefaultLoggerId);
3783  if (logger == nullptr) {
3784  return std::string();
3785  }
3787  b.initialize(logger);
3788  logger->acquireLock();
3789  b << templ;
3790 #if defined(ELPP_UNICODE)
3791  std::string s = std::string(logger->stream().str().begin(), logger->stream().str().end());
3792 #else
3793  std::string s = logger->stream().str();
3794 #endif // defined(ELPP_UNICODE)
3795  logger->stream().str(ELPP_LITERAL(""));
3796  logger->releaseLock();
3797  return s;
3798  }
3801  return ELPP->commandLineArgs();
3802  }
3804  static inline void installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier) {
3805  ELPP->installCustomFormatSpecifier(customFormatSpecifier);
3806  }
3808  static inline bool uninstallCustomFormatSpecifier(const char* formatSpecifier) {
3809  return ELPP->uninstallCustomFormatSpecifier(formatSpecifier);
3810  }
3812  static inline bool hasCustomFormatSpecifier(const char* formatSpecifier) {
3813  return ELPP->hasCustomFormatSpecifier(formatSpecifier);
3814  }
3815  static inline void validateFileRolling(Logger* logger, Level level) {
3816  if (logger == nullptr) return;
3817  logger->m_typedConfigurations->validateFileRolling(level, ELPP->preRollOutCallback());
3818  }
3819 };
3822  public:
3824  static Logger* getLogger(const std::string& identity, bool registerIfNotAvailable = true);
3826  static void setDefaultLogBuilder(el::LogBuilderPtr& logBuilderPtr);
3828  template <typename T>
3829  static inline bool installLoggerRegistrationCallback(const std::string& id) {
3830  return ELPP->registeredLoggers()->installLoggerRegistrationCallback<T>(id);
3831  }
3833  template <typename T>
3834  static inline void uninstallLoggerRegistrationCallback(const std::string& id) {
3835  ELPP->registeredLoggers()->uninstallLoggerRegistrationCallback<T>(id);
3836  }
3837  template <typename T>
3838  static inline T* loggerRegistrationCallback(const std::string& id) {
3839  return ELPP->registeredLoggers()->loggerRegistrationCallback<T>(id);
3840  }
3843  static bool unregisterLogger(const std::string& identity);
3845  static bool hasLogger(const std::string& identity);
3847  static Logger* reconfigureLogger(Logger* logger, const Configurations& configurations);
3849  static Logger* reconfigureLogger(const std::string& identity, const Configurations& configurations);
3851  static Logger* reconfigureLogger(const std::string& identity, ConfigurationType configurationType,
3852  const std::string& value);
3854  static void reconfigureAllLoggers(const Configurations& configurations);
3856  static inline void reconfigureAllLoggers(ConfigurationType configurationType, const std::string& value) {
3857  reconfigureAllLoggers(Level::Global, configurationType, value);
3858  }
3860  static void reconfigureAllLoggers(Level level, ConfigurationType configurationType,
3861  const std::string& value);
3863  static void setDefaultConfigurations(const Configurations& configurations,
3864  bool reconfigureExistingLoggers = false);
3866  static const Configurations* defaultConfigurations(void);
3868  static const base::LogStreamsReferenceMap* logStreamsReference(void);
3873  static std::vector<std::string>* populateAllLoggerIds(std::vector<std::string>* targetList);
3875  static void configureFromGlobal(const char* globalConfigurationFilePath);
3880  static bool configureFromArg(const char* argKey);
3882  static void flushAll(void);
3884  static inline void addFlag(LoggingFlag flag) {
3885  ELPP->addFlag(flag);
3886  }
3888  static inline void removeFlag(LoggingFlag flag) {
3889  ELPP->removeFlag(flag);
3890  }
3892  static inline bool hasFlag(LoggingFlag flag) {
3893  return ELPP->hasFlag(flag);
3894  }
3897  public:
3898  ScopedAddFlag(LoggingFlag flag) : m_flag(flag) {
3899  Loggers::addFlag(m_flag);
3900  }
3901  ~ScopedAddFlag(void) {
3902  Loggers::removeFlag(m_flag);
3903  }
3904  private:
3905  LoggingFlag m_flag;
3906  };
3909  public:
3910  ScopedRemoveFlag(LoggingFlag flag) : m_flag(flag) {
3911  Loggers::removeFlag(m_flag);
3912  }
3913  ~ScopedRemoveFlag(void) {
3914  Loggers::addFlag(m_flag);
3915  }
3916  private:
3917  LoggingFlag m_flag;
3918  };
3920  static void setLoggingLevel(Level level) {
3921  ELPP->setLoggingLevel(level);
3922  }
3924  static void setVerboseLevel(base::type::VerboseLevel level);
3926  static base::type::VerboseLevel verboseLevel(void);
3928  static void setVModules(const char* modules);
3930  static void clearVModules(void);
3931 };
3933  public:
3935  static const std::string version(void);
3936 
3938  static const std::string releaseDate(void);
3939 };
3940 } // namespace el
3941 #undef VLOG_IS_ON
3942 #define VLOG_IS_ON(verboseLevel) (ELPP->vRegistry()->allowed(verboseLevel, __FILE__))
3944 #undef TIMED_BLOCK
3945 #undef TIMED_SCOPE
3946 #undef TIMED_SCOPE_IF
3947 #undef TIMED_FUNC
3948 #undef TIMED_FUNC_IF
3949 #undef ELPP_MIN_UNIT
3950 #if defined(ELPP_PERFORMANCE_MICROSECONDS)
3951 # define ELPP_MIN_UNIT el::base::TimestampUnit::Microsecond
3952 #else
3953 # define ELPP_MIN_UNIT el::base::TimestampUnit::Millisecond
3954 #endif // (defined(ELPP_PERFORMANCE_MICROSECONDS))
3955 // Note: Do not surround this definition with null macro because of obj instance
3962 #define TIMED_SCOPE_IF(obj, blockname, condition) el::base::type::PerformanceTrackerPtr obj( condition ? \
3963  new el::base::PerformanceTracker(blockname, ELPP_MIN_UNIT) : nullptr )
3964 #define TIMED_SCOPE(obj, blockname) TIMED_SCOPE_IF(obj, blockname, true)
3965 #define TIMED_BLOCK(obj, blockName) for (struct { int i; el::base::type::PerformanceTrackerPtr timer; } obj = { 0, \
3966  el::base::type::PerformanceTrackerPtr(new el::base::PerformanceTracker(blockName, ELPP_MIN_UNIT)) }; obj.i < 1; ++obj.i)
3967 #define TIMED_FUNC_IF(obj,condition) TIMED_SCOPE_IF(obj, ELPP_FUNC, condition)
3974 #define TIMED_FUNC(obj) TIMED_SCOPE(obj, ELPP_FUNC)
3975 #undef PERFORMANCE_CHECKPOINT
3976 #undef PERFORMANCE_CHECKPOINT_WITH_ID
3977 #define PERFORMANCE_CHECKPOINT(obj) obj->checkpoint(std::string(), __FILE__, __LINE__, ELPP_FUNC)
3978 #define PERFORMANCE_CHECKPOINT_WITH_ID(obj, id) obj->checkpoint(id, __FILE__, __LINE__, ELPP_FUNC)
3979 #undef ELPP_COUNTER
3980 #undef ELPP_COUNTER_POS
3981 #define ELPP_COUNTER (ELPP->hitCounters()->getCounter(__FILE__, __LINE__))
3983 #define ELPP_COUNTER_POS (ELPP_COUNTER == nullptr ? -1 : ELPP_COUNTER->hitCounts())
3985 // Undef levels to support LOG(LEVEL)
3986 #undef INFO
3987 #undef WARNING
3988 #undef DEBUG
3989 #undef ERROR
3990 #undef FATAL
3991 #undef TRACE
3992 #undef VERBOSE
3993 // Undef existing
3994 #undef CINFO
3995 #undef CWARNING
3996 #undef CDEBUG
3997 #undef CFATAL
3998 #undef CERROR
3999 #undef CTRACE
4000 #undef CVERBOSE
4001 #undef CINFO_IF
4002 #undef CWARNING_IF
4003 #undef CDEBUG_IF
4004 #undef CERROR_IF
4005 #undef CFATAL_IF
4006 #undef CTRACE_IF
4007 #undef CVERBOSE_IF
4008 #undef CINFO_EVERY_N
4009 #undef CWARNING_EVERY_N
4010 #undef CDEBUG_EVERY_N
4011 #undef CERROR_EVERY_N
4012 #undef CFATAL_EVERY_N
4013 #undef CTRACE_EVERY_N
4014 #undef CVERBOSE_EVERY_N
4015 #undef CINFO_AFTER_N
4016 #undef CWARNING_AFTER_N
4017 #undef CDEBUG_AFTER_N
4018 #undef CERROR_AFTER_N
4019 #undef CFATAL_AFTER_N
4020 #undef CTRACE_AFTER_N
4021 #undef CVERBOSE_AFTER_N
4022 #undef CINFO_N_TIMES
4023 #undef CWARNING_N_TIMES
4024 #undef CDEBUG_N_TIMES
4025 #undef CERROR_N_TIMES
4026 #undef CFATAL_N_TIMES
4027 #undef CTRACE_N_TIMES
4028 #undef CVERBOSE_N_TIMES
4029 // Normal logs
4030 #if ELPP_INFO_LOG
4031 # define CINFO(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Info, dispatchAction, __VA_ARGS__)
4032 #else
4033 # define CINFO(writer, dispatchAction, ...) el::base::NullWriter()
4034 #endif // ELPP_INFO_LOG
4035 #if ELPP_WARNING_LOG
4036 # define CWARNING(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Warning, dispatchAction, __VA_ARGS__)
4037 #else
4038 # define CWARNING(writer, dispatchAction, ...) el::base::NullWriter()
4039 #endif // ELPP_WARNING_LOG
4040 #if ELPP_DEBUG_LOG
4041 # define CDEBUG(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Debug, dispatchAction, __VA_ARGS__)
4042 #else
4043 # define CDEBUG(writer, dispatchAction, ...) el::base::NullWriter()
4044 #endif // ELPP_DEBUG_LOG
4045 #if ELPP_ERROR_LOG
4046 # define CERROR(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Error, dispatchAction, __VA_ARGS__)
4047 #else
4048 # define CERROR(writer, dispatchAction, ...) el::base::NullWriter()
4049 #endif // ELPP_ERROR_LOG
4050 #if ELPP_FATAL_LOG
4051 # define CFATAL(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Fatal, dispatchAction, __VA_ARGS__)
4052 #else
4053 # define CFATAL(writer, dispatchAction, ...) el::base::NullWriter()
4054 #endif // ELPP_FATAL_LOG
4055 #if ELPP_TRACE_LOG
4056 # define CTRACE(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Trace, dispatchAction, __VA_ARGS__)
4057 #else
4058 # define CTRACE(writer, dispatchAction, ...) el::base::NullWriter()
4059 #endif // ELPP_TRACE_LOG
4060 #if ELPP_VERBOSE_LOG
4061 # define CVERBOSE(writer, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel)) writer(\
4062 el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
4063 #else
4064 # define CVERBOSE(writer, vlevel, dispatchAction, ...) el::base::NullWriter()
4065 #endif // ELPP_VERBOSE_LOG
4066 // Conditional logs
4067 #if ELPP_INFO_LOG
4068 # define CINFO_IF(writer, condition_, dispatchAction, ...) \
4069 ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Info, dispatchAction, __VA_ARGS__)
4070 #else
4071 # define CINFO_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
4072 #endif // ELPP_INFO_LOG
4073 #if ELPP_WARNING_LOG
4074 # define CWARNING_IF(writer, condition_, dispatchAction, ...)\
4075 ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Warning, dispatchAction, __VA_ARGS__)
4076 #else
4077 # define CWARNING_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
4078 #endif // ELPP_WARNING_LOG
4079 #if ELPP_DEBUG_LOG
4080 # define CDEBUG_IF(writer, condition_, dispatchAction, ...)\
4081 ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Debug, dispatchAction, __VA_ARGS__)
4082 #else
4083 # define CDEBUG_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
4084 #endif // ELPP_DEBUG_LOG
4085 #if ELPP_ERROR_LOG
4086 # define CERROR_IF(writer, condition_, dispatchAction, ...)\
4087 ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Error, dispatchAction, __VA_ARGS__)
4088 #else
4089 # define CERROR_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
4090 #endif // ELPP_ERROR_LOG
4091 #if ELPP_FATAL_LOG
4092 # define CFATAL_IF(writer, condition_, dispatchAction, ...)\
4093 ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Fatal, dispatchAction, __VA_ARGS__)
4094 #else
4095 # define CFATAL_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
4096 #endif // ELPP_FATAL_LOG
4097 #if ELPP_TRACE_LOG
4098 # define CTRACE_IF(writer, condition_, dispatchAction, ...)\
4099 ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Trace, dispatchAction, __VA_ARGS__)
4100 #else
4101 # define CTRACE_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
4102 #endif // ELPP_TRACE_LOG
4103 #if ELPP_VERBOSE_LOG
4104 # define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel) && (condition_)) writer( \
4105 el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
4106 #else
4107 # define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) el::base::NullWriter()
4108 #endif // ELPP_VERBOSE_LOG
4109 // Occasional logs
4110 #if ELPP_INFO_LOG
4111 # define CINFO_EVERY_N(writer, occasion, dispatchAction, ...)\
4112 ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Info, dispatchAction, __VA_ARGS__)
4113 #else
4114 # define CINFO_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
4115 #endif // ELPP_INFO_LOG
4116 #if ELPP_WARNING_LOG
4117 # define CWARNING_EVERY_N(writer, occasion, dispatchAction, ...)\
4118 ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Warning, dispatchAction, __VA_ARGS__)
4119 #else
4120 # define CWARNING_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
4121 #endif // ELPP_WARNING_LOG
4122 #if ELPP_DEBUG_LOG
4123 # define CDEBUG_EVERY_N(writer, occasion, dispatchAction, ...)\
4124 ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Debug, dispatchAction, __VA_ARGS__)
4125 #else
4126 # define CDEBUG_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
4127 #endif // ELPP_DEBUG_LOG
4128 #if ELPP_ERROR_LOG
4129 # define CERROR_EVERY_N(writer, occasion, dispatchAction, ...)\
4130 ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Error, dispatchAction, __VA_ARGS__)
4131 #else
4132 # define CERROR_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
4133 #endif // ELPP_ERROR_LOG
4134 #if ELPP_FATAL_LOG
4135 # define CFATAL_EVERY_N(writer, occasion, dispatchAction, ...)\
4136 ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Fatal, dispatchAction, __VA_ARGS__)
4137 #else
4138 # define CFATAL_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
4139 #endif // ELPP_FATAL_LOG
4140 #if ELPP_TRACE_LOG
4141 # define CTRACE_EVERY_N(writer, occasion, dispatchAction, ...)\
4142 ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Trace, dispatchAction, __VA_ARGS__)
4143 #else
4144 # define CTRACE_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
4145 #endif // ELPP_TRACE_LOG
4146 #if ELPP_VERBOSE_LOG
4147 # define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...)\
4148 CVERBOSE_IF(writer, ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion), vlevel, dispatchAction, __VA_ARGS__)
4149 #else
4150 # define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...) el::base::NullWriter()
4151 #endif // ELPP_VERBOSE_LOG
4152 // After N logs
4153 #if ELPP_INFO_LOG
4154 # define CINFO_AFTER_N(writer, n, dispatchAction, ...)\
4155 ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Info, dispatchAction, __VA_ARGS__)
4156 #else
4157 # define CINFO_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
4158 #endif // ELPP_INFO_LOG
4159 #if ELPP_WARNING_LOG
4160 # define CWARNING_AFTER_N(writer, n, dispatchAction, ...)\
4161 ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Warning, dispatchAction, __VA_ARGS__)
4162 #else
4163 # define CWARNING_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
4164 #endif // ELPP_WARNING_LOG
4165 #if ELPP_DEBUG_LOG
4166 # define CDEBUG_AFTER_N(writer, n, dispatchAction, ...)\
4167 ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Debug, dispatchAction, __VA_ARGS__)
4168 #else
4169 # define CDEBUG_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
4170 #endif // ELPP_DEBUG_LOG
4171 #if ELPP_ERROR_LOG
4172 # define CERROR_AFTER_N(writer, n, dispatchAction, ...)\
4173 ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Error, dispatchAction, __VA_ARGS__)
4174 #else
4175 # define CERROR_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
4176 #endif // ELPP_ERROR_LOG
4177 #if ELPP_FATAL_LOG
4178 # define CFATAL_AFTER_N(writer, n, dispatchAction, ...)\
4179 ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Fatal, dispatchAction, __VA_ARGS__)
4180 #else
4181 # define CFATAL_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
4182 #endif // ELPP_FATAL_LOG
4183 #if ELPP_TRACE_LOG
4184 # define CTRACE_AFTER_N(writer, n, dispatchAction, ...)\
4185 ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Trace, dispatchAction, __VA_ARGS__)
4186 #else
4187 # define CTRACE_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
4188 #endif // ELPP_TRACE_LOG
4189 #if ELPP_VERBOSE_LOG
4190 # define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...)\
4191 CVERBOSE_IF(writer, ELPP->validateAfterNCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__)
4192 #else
4193 # define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter()
4194 #endif // ELPP_VERBOSE_LOG
4195 // N Times logs
4196 #if ELPP_INFO_LOG
4197 # define CINFO_N_TIMES(writer, n, dispatchAction, ...)\
4198 ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Info, dispatchAction, __VA_ARGS__)
4199 #else
4200 # define CINFO_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
4201 #endif // ELPP_INFO_LOG
4202 #if ELPP_WARNING_LOG
4203 # define CWARNING_N_TIMES(writer, n, dispatchAction, ...)\
4204 ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Warning, dispatchAction, __VA_ARGS__)
4205 #else
4206 # define CWARNING_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
4207 #endif // ELPP_WARNING_LOG
4208 #if ELPP_DEBUG_LOG
4209 # define CDEBUG_N_TIMES(writer, n, dispatchAction, ...)\
4210 ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Debug, dispatchAction, __VA_ARGS__)
4211 #else
4212 # define CDEBUG_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
4213 #endif // ELPP_DEBUG_LOG
4214 #if ELPP_ERROR_LOG
4215 # define CERROR_N_TIMES(writer, n, dispatchAction, ...)\
4216 ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Error, dispatchAction, __VA_ARGS__)
4217 #else
4218 # define CERROR_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
4219 #endif // ELPP_ERROR_LOG
4220 #if ELPP_FATAL_LOG
4221 # define CFATAL_N_TIMES(writer, n, dispatchAction, ...)\
4222 ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Fatal, dispatchAction, __VA_ARGS__)
4223 #else
4224 # define CFATAL_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
4225 #endif // ELPP_FATAL_LOG
4226 #if ELPP_TRACE_LOG
4227 # define CTRACE_N_TIMES(writer, n, dispatchAction, ...)\
4228 ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Trace, dispatchAction, __VA_ARGS__)
4229 #else
4230 # define CTRACE_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
4231 #endif // ELPP_TRACE_LOG
4232 #if ELPP_VERBOSE_LOG
4233 # define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...)\
4234 CVERBOSE_IF(writer, ELPP->validateNTimesCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__)
4235 #else
4236 # define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter()
4237 #endif // ELPP_VERBOSE_LOG
4238 //
4239 // Custom Loggers - Requires (level, dispatchAction, loggerId/s)
4240 //
4241 // undef existing
4242 #undef CLOG
4243 #undef CLOG_VERBOSE
4244 #undef CVLOG
4245 #undef CLOG_IF
4246 #undef CLOG_VERBOSE_IF
4247 #undef CVLOG_IF
4248 #undef CLOG_EVERY_N
4249 #undef CVLOG_EVERY_N
4250 #undef CLOG_AFTER_N
4251 #undef CVLOG_AFTER_N
4252 #undef CLOG_N_TIMES
4253 #undef CVLOG_N_TIMES
4254 // Normal logs
4255 #define CLOG(LEVEL, ...)\
4256 C##LEVEL(el::base::Writer, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4257 #define CVLOG(vlevel, ...) CVERBOSE(el::base::Writer, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4258 // Conditional logs
4259 #define CLOG_IF(condition, LEVEL, ...)\
4260 C##LEVEL##_IF(el::base::Writer, condition, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4261 #define CVLOG_IF(condition, vlevel, ...)\
4262 CVERBOSE_IF(el::base::Writer, condition, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4263 // Hit counts based logs
4264 #define CLOG_EVERY_N(n, LEVEL, ...)\
4265 C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4266 #define CVLOG_EVERY_N(n, vlevel, ...)\
4267 CVERBOSE_EVERY_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4268 #define CLOG_AFTER_N(n, LEVEL, ...)\
4269 C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4270 #define CVLOG_AFTER_N(n, vlevel, ...)\
4271 CVERBOSE_AFTER_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4272 #define CLOG_N_TIMES(n, LEVEL, ...)\
4273 C##LEVEL##_N_TIMES(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4274 #define CVLOG_N_TIMES(n, vlevel, ...)\
4275 CVERBOSE_N_TIMES(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4276 //
4277 // Default Loggers macro using CLOG(), CLOG_VERBOSE() and CVLOG() macros
4278 //
4279 // undef existing
4280 #undef LOG
4281 #undef VLOG
4282 #undef LOG_IF
4283 #undef VLOG_IF
4284 #undef LOG_EVERY_N
4285 #undef VLOG_EVERY_N
4286 #undef LOG_AFTER_N
4287 #undef VLOG_AFTER_N
4288 #undef LOG_N_TIMES
4289 #undef VLOG_N_TIMES
4290 #undef ELPP_CURR_FILE_LOGGER_ID
4291 #if defined(ELPP_DEFAULT_LOGGER)
4292 # define ELPP_CURR_FILE_LOGGER_ID ELPP_DEFAULT_LOGGER
4293 #else
4294 # define ELPP_CURR_FILE_LOGGER_ID el::base::consts::kDefaultLoggerId
4295 #endif
4296 #undef ELPP_TRACE
4297 #define ELPP_TRACE CLOG(TRACE, ELPP_CURR_FILE_LOGGER_ID)
4298 // Normal logs
4299 #define LOG(LEVEL) CLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4300 #define VLOG(vlevel) CVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID)
4301 // Conditional logs
4302 #define LOG_IF(condition, LEVEL) CLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4303 #define VLOG_IF(condition, vlevel) CVLOG_IF(condition, vlevel, ELPP_CURR_FILE_LOGGER_ID)
4304 // Hit counts based logs
4305 #define LOG_EVERY_N(n, LEVEL) CLOG_EVERY_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4306 #define VLOG_EVERY_N(n, vlevel) CVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
4307 #define LOG_AFTER_N(n, LEVEL) CLOG_AFTER_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4308 #define VLOG_AFTER_N(n, vlevel) CVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
4309 #define LOG_N_TIMES(n, LEVEL) CLOG_N_TIMES(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4310 #define VLOG_N_TIMES(n, vlevel) CVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
4311 // Generic PLOG()
4312 #undef CPLOG
4313 #undef CPLOG_IF
4314 #undef PLOG
4315 #undef PLOG_IF
4316 #undef DCPLOG
4317 #undef DCPLOG_IF
4318 #undef DPLOG
4319 #undef DPLOG_IF
4320 #define CPLOG(LEVEL, ...)\
4321 C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4322 #define CPLOG_IF(condition, LEVEL, ...)\
4323 C##LEVEL##_IF(el::base::PErrorWriter, condition, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4324 #define DCPLOG(LEVEL, ...)\
4325 if (ELPP_DEBUG_LOG) C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4326 #define DCPLOG_IF(condition, LEVEL, ...)\
4327 C##LEVEL##_IF(el::base::PErrorWriter, (ELPP_DEBUG_LOG) && (condition), el::base::DispatchAction::NormalLog, __VA_ARGS__)
4328 #define PLOG(LEVEL) CPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4329 #define PLOG_IF(condition, LEVEL) CPLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4330 #define DPLOG(LEVEL) DCPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4331 #define DPLOG_IF(condition, LEVEL) DCPLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4332 // Generic SYSLOG()
4333 #undef CSYSLOG
4334 #undef CSYSLOG_IF
4335 #undef CSYSLOG_EVERY_N
4336 #undef CSYSLOG_AFTER_N
4337 #undef CSYSLOG_N_TIMES
4338 #undef SYSLOG
4339 #undef SYSLOG_IF
4340 #undef SYSLOG_EVERY_N
4341 #undef SYSLOG_AFTER_N
4342 #undef SYSLOG_N_TIMES
4343 #undef DCSYSLOG
4344 #undef DCSYSLOG_IF
4345 #undef DCSYSLOG_EVERY_N
4346 #undef DCSYSLOG_AFTER_N
4347 #undef DCSYSLOG_N_TIMES
4348 #undef DSYSLOG
4349 #undef DSYSLOG_IF
4350 #undef DSYSLOG_EVERY_N
4351 #undef DSYSLOG_AFTER_N
4352 #undef DSYSLOG_N_TIMES
4353 #if defined(ELPP_SYSLOG)
4354 # define CSYSLOG(LEVEL, ...)\
4355 C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__)
4356 # define CSYSLOG_IF(condition, LEVEL, ...)\
4357 C##LEVEL##_IF(el::base::Writer, condition, el::base::DispatchAction::SysLog, __VA_ARGS__)
4358 # define CSYSLOG_EVERY_N(n, LEVEL, ...) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
4359 # define CSYSLOG_AFTER_N(n, LEVEL, ...) C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
4360 # define CSYSLOG_N_TIMES(n, LEVEL, ...) C##LEVEL##_N_TIMES(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
4361 # define SYSLOG(LEVEL) CSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId)
4362 # define SYSLOG_IF(condition, LEVEL) CSYSLOG_IF(condition, LEVEL, el::base::consts::kSysLogLoggerId)
4363 # define SYSLOG_EVERY_N(n, LEVEL) CSYSLOG_EVERY_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
4364 # define SYSLOG_AFTER_N(n, LEVEL) CSYSLOG_AFTER_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
4365 # define SYSLOG_N_TIMES(n, LEVEL) CSYSLOG_N_TIMES(n, LEVEL, el::base::consts::kSysLogLoggerId)
4366 # define DCSYSLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__)
4367 # define DCSYSLOG_IF(condition, LEVEL, ...)\
4368 C##LEVEL##_IF(el::base::Writer, (ELPP_DEBUG_LOG) && (condition), el::base::DispatchAction::SysLog, __VA_ARGS__)
4369 # define DCSYSLOG_EVERY_N(n, LEVEL, ...)\
4370 if (ELPP_DEBUG_LOG) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
4371 # define DCSYSLOG_AFTER_N(n, LEVEL, ...)\
4372 if (ELPP_DEBUG_LOG) C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
4373 # define DCSYSLOG_N_TIMES(n, LEVEL, ...)\
4374 if (ELPP_DEBUG_LOG) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
4375 # define DSYSLOG(LEVEL) DCSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId)
4376 # define DSYSLOG_IF(condition, LEVEL) DCSYSLOG_IF(condition, LEVEL, el::base::consts::kSysLogLoggerId)
4377 # define DSYSLOG_EVERY_N(n, LEVEL) DCSYSLOG_EVERY_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
4378 # define DSYSLOG_AFTER_N(n, LEVEL) DCSYSLOG_AFTER_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
4379 # define DSYSLOG_N_TIMES(n, LEVEL) DCSYSLOG_N_TIMES(n, LEVEL, el::base::consts::kSysLogLoggerId)
4380 #else
4381 # define CSYSLOG(LEVEL, ...) el::base::NullWriter()
4382 # define CSYSLOG_IF(condition, LEVEL, ...) el::base::NullWriter()
4383 # define CSYSLOG_EVERY_N(n, LEVEL, ...) el::base::NullWriter()
4384 # define CSYSLOG_AFTER_N(n, LEVEL, ...) el::base::NullWriter()
4385 # define CSYSLOG_N_TIMES(n, LEVEL, ...) el::base::NullWriter()
4386 # define SYSLOG(LEVEL) el::base::NullWriter()
4387 # define SYSLOG_IF(condition, LEVEL) el::base::NullWriter()
4388 # define SYSLOG_EVERY_N(n, LEVEL) el::base::NullWriter()
4389 # define SYSLOG_AFTER_N(n, LEVEL) el::base::NullWriter()
4390 # define SYSLOG_N_TIMES(n, LEVEL) el::base::NullWriter()
4391 # define DCSYSLOG(LEVEL, ...) el::base::NullWriter()
4392 # define DCSYSLOG_IF(condition, LEVEL, ...) el::base::NullWriter()
4393 # define DCSYSLOG_EVERY_N(n, LEVEL, ...) el::base::NullWriter()
4394 # define DCSYSLOG_AFTER_N(n, LEVEL, ...) el::base::NullWriter()
4395 # define DCSYSLOG_N_TIMES(n, LEVEL, ...) el::base::NullWriter()
4396 # define DSYSLOG(LEVEL) el::base::NullWriter()
4397 # define DSYSLOG_IF(condition, LEVEL) el::base::NullWriter()
4398 # define DSYSLOG_EVERY_N(n, LEVEL) el::base::NullWriter()
4399 # define DSYSLOG_AFTER_N(n, LEVEL) el::base::NullWriter()
4400 # define DSYSLOG_N_TIMES(n, LEVEL) el::base::NullWriter()
4401 #endif // defined(ELPP_SYSLOG)
4402 //
4403 // Custom Debug Only Loggers - Requires (level, loggerId/s)
4404 //
4405 // undef existing
4406 #undef DCLOG
4407 #undef DCVLOG
4408 #undef DCLOG_IF
4409 #undef DCVLOG_IF
4410 #undef DCLOG_EVERY_N
4411 #undef DCVLOG_EVERY_N
4412 #undef DCLOG_AFTER_N
4413 #undef DCVLOG_AFTER_N
4414 #undef DCLOG_N_TIMES
4415 #undef DCVLOG_N_TIMES
4416 // Normal logs
4417 #define DCLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG(LEVEL, __VA_ARGS__)
4418 #define DCLOG_VERBOSE(vlevel, ...) if (ELPP_DEBUG_LOG) CLOG_VERBOSE(vlevel, __VA_ARGS__)
4419 #define DCVLOG(vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG(vlevel, __VA_ARGS__)
4420 // Conditional logs
4421 #define DCLOG_IF(condition, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_IF(condition, LEVEL, __VA_ARGS__)
4422 #define DCVLOG_IF(condition, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_IF(condition, vlevel, __VA_ARGS__)
4423 // Hit counts based logs
4424 #define DCLOG_EVERY_N(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_EVERY_N(n, LEVEL, __VA_ARGS__)
4425 #define DCVLOG_EVERY_N(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_EVERY_N(n, vlevel, __VA_ARGS__)
4426 #define DCLOG_AFTER_N(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_AFTER_N(n, LEVEL, __VA_ARGS__)
4427 #define DCVLOG_AFTER_N(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_AFTER_N(n, vlevel, __VA_ARGS__)
4428 #define DCLOG_N_TIMES(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_N_TIMES(n, LEVEL, __VA_ARGS__)
4429 #define DCVLOG_N_TIMES(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_N_TIMES(n, vlevel, __VA_ARGS__)
4430 //
4431 // Default Debug Only Loggers macro using CLOG(), CLOG_VERBOSE() and CVLOG() macros
4432 //
4433 #if !defined(ELPP_NO_DEBUG_MACROS)
4434 // undef existing
4435 #undef DLOG
4436 #undef DVLOG
4437 #undef DLOG_IF
4438 #undef DVLOG_IF
4439 #undef DLOG_EVERY_N
4440 #undef DVLOG_EVERY_N
4441 #undef DLOG_AFTER_N
4442 #undef DVLOG_AFTER_N
4443 #undef DLOG_N_TIMES
4444 #undef DVLOG_N_TIMES
4445 // Normal logs
4446 #define DLOG(LEVEL) DCLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4447 #define DVLOG(vlevel) DCVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID)
4448 // Conditional logs
4449 #define DLOG_IF(condition, LEVEL) DCLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4450 #define DVLOG_IF(condition, vlevel) DCVLOG_IF(condition, vlevel, ELPP_CURR_FILE_LOGGER_ID)
4451 // Hit counts based logs
4452 #define DLOG_EVERY_N(n, LEVEL) DCLOG_EVERY_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4453 #define DVLOG_EVERY_N(n, vlevel) DCVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
4454 #define DLOG_AFTER_N(n, LEVEL) DCLOG_AFTER_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4455 #define DVLOG_AFTER_N(n, vlevel) DCVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
4456 #define DLOG_N_TIMES(n, LEVEL) DCLOG_N_TIMES(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4457 #define DVLOG_N_TIMES(n, vlevel) DCVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
4458 #endif // defined(ELPP_NO_DEBUG_MACROS)
4459 #if !defined(ELPP_NO_CHECK_MACROS)
4460 // Check macros
4461 #undef CCHECK
4462 #undef CPCHECK
4463 #undef CCHECK_EQ
4464 #undef CCHECK_NE
4465 #undef CCHECK_LT
4466 #undef CCHECK_GT
4467 #undef CCHECK_LE
4468 #undef CCHECK_GE
4469 #undef CCHECK_BOUNDS
4470 #undef CCHECK_NOTNULL
4471 #undef CCHECK_STRCASEEQ
4472 #undef CCHECK_STRCASENE
4473 #undef CHECK
4474 #undef PCHECK
4475 #undef CHECK_EQ
4476 #undef CHECK_NE
4477 #undef CHECK_LT
4478 #undef CHECK_GT
4479 #undef CHECK_LE
4480 #undef CHECK_GE
4481 #undef CHECK_BOUNDS
4482 #undef CHECK_NOTNULL
4483 #undef CHECK_STRCASEEQ
4484 #undef CHECK_STRCASENE
4485 #define CCHECK(condition, ...) CLOG_IF(!(condition), FATAL, __VA_ARGS__) << "Check failed: [" << #condition << "] "
4486 #define CPCHECK(condition, ...) CPLOG_IF(!(condition), FATAL, __VA_ARGS__) << "Check failed: [" << #condition << "] "
4487 #define CHECK(condition) CCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
4488 #define PCHECK(condition) CPCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
4489 #define CCHECK_EQ(a, b, ...) CCHECK(a == b, __VA_ARGS__)
4490 #define CCHECK_NE(a, b, ...) CCHECK(a != b, __VA_ARGS__)
4491 #define CCHECK_LT(a, b, ...) CCHECK(a < b, __VA_ARGS__)
4492 #define CCHECK_GT(a, b, ...) CCHECK(a > b, __VA_ARGS__)
4493 #define CCHECK_LE(a, b, ...) CCHECK(a <= b, __VA_ARGS__)
4494 #define CCHECK_GE(a, b, ...) CCHECK(a >= b, __VA_ARGS__)
4495 #define CCHECK_BOUNDS(val, min, max, ...) CCHECK(val >= min && val <= max, __VA_ARGS__)
4496 #define CHECK_EQ(a, b) CCHECK_EQ(a, b, ELPP_CURR_FILE_LOGGER_ID)
4497 #define CHECK_NE(a, b) CCHECK_NE(a, b, ELPP_CURR_FILE_LOGGER_ID)
4498 #define CHECK_LT(a, b) CCHECK_LT(a, b, ELPP_CURR_FILE_LOGGER_ID)
4499 #define CHECK_GT(a, b) CCHECK_GT(a, b, ELPP_CURR_FILE_LOGGER_ID)
4500 #define CHECK_LE(a, b) CCHECK_LE(a, b, ELPP_CURR_FILE_LOGGER_ID)
4501 #define CHECK_GE(a, b) CCHECK_GE(a, b, ELPP_CURR_FILE_LOGGER_ID)
4502 #define CHECK_BOUNDS(val, min, max) CCHECK_BOUNDS(val, min, max, ELPP_CURR_FILE_LOGGER_ID)
4503 #define CCHECK_NOTNULL(ptr, ...) CCHECK((ptr) != nullptr, __VA_ARGS__)
4504 #define CCHECK_STREQ(str1, str2, ...) CLOG_IF(!el::base::utils::Str::cStringEq(str1, str2), FATAL, __VA_ARGS__) \
4505 << "Check failed: [" << #str1 << " == " << #str2 << "] "
4506 #define CCHECK_STRNE(str1, str2, ...) CLOG_IF(el::base::utils::Str::cStringEq(str1, str2), FATAL, __VA_ARGS__) \
4507 << "Check failed: [" << #str1 << " != " << #str2 << "] "
4508 #define CCHECK_STRCASEEQ(str1, str2, ...) CLOG_IF(!el::base::utils::Str::cStringCaseEq(str1, str2), FATAL, __VA_ARGS__) \
4509 << "Check failed: [" << #str1 << " == " << #str2 << "] "
4510 #define CCHECK_STRCASENE(str1, str2, ...) CLOG_IF(el::base::utils::Str::cStringCaseEq(str1, str2), FATAL, __VA_ARGS__) \
4511 << "Check failed: [" << #str1 << " != " << #str2 << "] "
4512 #define CHECK_NOTNULL(ptr) CCHECK_NOTNULL((ptr), ELPP_CURR_FILE_LOGGER_ID)
4513 #define CHECK_STREQ(str1, str2) CCHECK_STREQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
4514 #define CHECK_STRNE(str1, str2) CCHECK_STRNE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
4515 #define CHECK_STRCASEEQ(str1, str2) CCHECK_STRCASEEQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
4516 #define CHECK_STRCASENE(str1, str2) CCHECK_STRCASENE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
4517 #undef DCCHECK
4518 #undef DCCHECK_EQ
4519 #undef DCCHECK_NE
4520 #undef DCCHECK_LT
4521 #undef DCCHECK_GT
4522 #undef DCCHECK_LE
4523 #undef DCCHECK_GE
4524 #undef DCCHECK_BOUNDS
4525 #undef DCCHECK_NOTNULL
4526 #undef DCCHECK_STRCASEEQ
4527 #undef DCCHECK_STRCASENE
4528 #undef DCPCHECK
4529 #undef DCHECK
4530 #undef DCHECK_EQ
4531 #undef DCHECK_NE
4532 #undef DCHECK_LT
4533 #undef DCHECK_GT
4534 #undef DCHECK_LE
4535 #undef DCHECK_GE
4536 #undef DCHECK_BOUNDS_
4537 #undef DCHECK_NOTNULL
4538 #undef DCHECK_STRCASEEQ
4539 #undef DCHECK_STRCASENE
4540 #undef DPCHECK
4541 #define DCCHECK(condition, ...) if (ELPP_DEBUG_LOG) CCHECK(condition, __VA_ARGS__)
4542 #define DCCHECK_EQ(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_EQ(a, b, __VA_ARGS__)
4543 #define DCCHECK_NE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_NE(a, b, __VA_ARGS__)
4544 #define DCCHECK_LT(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_LT(a, b, __VA_ARGS__)
4545 #define DCCHECK_GT(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_GT(a, b, __VA_ARGS__)
4546 #define DCCHECK_LE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_LE(a, b, __VA_ARGS__)
4547 #define DCCHECK_GE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_GE(a, b, __VA_ARGS__)
4548 #define DCCHECK_BOUNDS(val, min, max, ...) if (ELPP_DEBUG_LOG) CCHECK_BOUNDS(val, min, max, __VA_ARGS__)
4549 #define DCCHECK_NOTNULL(ptr, ...) if (ELPP_DEBUG_LOG) CCHECK_NOTNULL((ptr), __VA_ARGS__)
4550 #define DCCHECK_STREQ(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STREQ(str1, str2, __VA_ARGS__)
4551 #define DCCHECK_STRNE(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRNE(str1, str2, __VA_ARGS__)
4552 #define DCCHECK_STRCASEEQ(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRCASEEQ(str1, str2, __VA_ARGS__)
4553 #define DCCHECK_STRCASENE(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRCASENE(str1, str2, __VA_ARGS__)
4554 #define DCPCHECK(condition, ...) if (ELPP_DEBUG_LOG) CPCHECK(condition, __VA_ARGS__)
4555 #define DCHECK(condition) DCCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
4556 #define DCHECK_EQ(a, b) DCCHECK_EQ(a, b, ELPP_CURR_FILE_LOGGER_ID)
4557 #define DCHECK_NE(a, b) DCCHECK_NE(a, b, ELPP_CURR_FILE_LOGGER_ID)
4558 #define DCHECK_LT(a, b) DCCHECK_LT(a, b, ELPP_CURR_FILE_LOGGER_ID)
4559 #define DCHECK_GT(a, b) DCCHECK_GT(a, b, ELPP_CURR_FILE_LOGGER_ID)
4560 #define DCHECK_LE(a, b) DCCHECK_LE(a, b, ELPP_CURR_FILE_LOGGER_ID)
4561 #define DCHECK_GE(a, b) DCCHECK_GE(a, b, ELPP_CURR_FILE_LOGGER_ID)
4562 #define DCHECK_BOUNDS(val, min, max) DCCHECK_BOUNDS(val, min, max, ELPP_CURR_FILE_LOGGER_ID)
4563 #define DCHECK_NOTNULL(ptr) DCCHECK_NOTNULL((ptr), ELPP_CURR_FILE_LOGGER_ID)
4564 #define DCHECK_STREQ(str1, str2) DCCHECK_STREQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
4565 #define DCHECK_STRNE(str1, str2) DCCHECK_STRNE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
4566 #define DCHECK_STRCASEEQ(str1, str2) DCCHECK_STRCASEEQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
4567 #define DCHECK_STRCASENE(str1, str2) DCCHECK_STRCASENE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
4568 #define DPCHECK(condition) DCPCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
4569 #endif // defined(ELPP_NO_CHECK_MACROS)
4570 #if defined(ELPP_DISABLE_DEFAULT_CRASH_HANDLING)
4571 # define ELPP_USE_DEF_CRASH_HANDLER false
4572 #else
4573 # define ELPP_USE_DEF_CRASH_HANDLER true
4574 #endif // defined(ELPP_DISABLE_DEFAULT_CRASH_HANDLING)
4575 #define ELPP_CRASH_HANDLER_INIT
4576 #define ELPP_INIT_EASYLOGGINGPP(val) \
4577 namespace el { \
4578 namespace base { \
4579 el::base::type::StoragePointer elStorage(val); \
4580 } \
4581 el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER); \
4582 }
4583 
4584 #if ELPP_ASYNC_LOGGING
4585 # define INITIALIZE_EASYLOGGINGPP ELPP_INIT_EASYLOGGINGPP(new el::base::Storage(el::LogBuilderPtr(new el::base::DefaultLogBuilder()),\
4586 new el::base::AsyncDispatchWorker()))
4587 #else
4588 # define INITIALIZE_EASYLOGGINGPP ELPP_INIT_EASYLOGGINGPP(new el::base::Storage(el::LogBuilderPtr(new el::base::DefaultLogBuilder())))
4589 #endif // ELPP_ASYNC_LOGGING
4590 #define INITIALIZE_NULL_EASYLOGGINGPP \
4591 namespace el {\
4592 namespace base {\
4593 el::base::type::StoragePointer elStorage;\
4594 }\
4595 el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\
4596 }
4597 #define SHARE_EASYLOGGINGPP(initializedStorage)\
4598 namespace el {\
4599 namespace base {\
4600 el::base::type::StoragePointer elStorage(initializedStorage);\
4601 }\
4602 el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\
4603 }
4604 
4605 #if defined(ELPP_UNICODE)
4606 # define START_EASYLOGGINGPP(argc, argv) el::Helpers::setArgs(argc, argv); std::locale::global(std::locale(""))
4607 #else
4608 # define START_EASYLOGGINGPP(argc, argv) el::Helpers::setArgs(argc, argv)
4609 #endif // defined(ELPP_UNICODE)
4610 #endif // EASYLOGGINGPP_H
RegistryWithPred(const RegistryWithPred &sr)
Copy constructor that is useful for base classes. Try to avoid this constructor, use move constructor...
Definition: easylogging++.h:1523
static void removeFlag(LoggingFlag flag)
Removes logging flag used internally.
Definition: easylogging++.h:3888
Specifies precision of the subsecond part. It should be within range (1-6).
static const std::string version(void)
Current version number.
Definition: easylogging++.cc:2992
bool parseFromFile(const std::string &configurationFile, Configurations *base=nullptr)
Parses configuration from file.
Definition: easylogging++.cc:211
static const char * convertToString(ConfigurationType configurationType)
Converts configuration type to associated const char*.
Definition: easylogging++.cc:99
virtual const_iterator cbegin(void) const ELPP_FINAL
Definition: easylogging++.h:1385
static bool parseFromFile(const std::string &configurationFile, Configurations *sender, Configurations *base=nullptr)
Parses configuration from file.
Definition: easylogging++.cc:334
static std::string extractPathFromFilename(const std::string &fullPath, const char *seperator=base::consts::kFilePathSeperator)
Extracts path of filename with leading slash.
Definition: easylogging++.cc:746
virtual Container & list(void) ELPP_FINAL
Returns underlying container by reference.
Definition: easylogging++.h:1405
Level level(void) const
Gets level of current configuration.
Definition: easylogging++.h:1749
Definition: easylogging++.h:1595
Determines whether or not corresponding level and logger of logging is enabled You may disable all lo...
A subsecond precision class containing actual width and offset of the subsecond part.
Definition: easylogging++.h:898
Definition: easylogging++.h:3666
Static helpers for developers.
Definition: easylogging++.h:3696
static void setThreadName(const std::string &name)
Sets thread name for current thread. Requires std::thread.
Definition: easylogging++.h:3715
virtual iterator end(void) ELPP_FINAL
Definition: easylogging++.h:1379
Determines whether or not performance tracking is enabled.
Creates logger automatically when not available.
AbstractRegistry(void)
Default constructor.
Definition: easylogging++.h:1325
static void setVModules(const char *modules)
Sets vmodules as specified (on the fly)
Definition: easylogging++.cc:2980
Information representing errors in application but application will keep running. ...
void setThreadName(const std::string &name)
Sets thread name for current thread. Requires std::thread.
Definition: easylogging++.h:2731
static Level convertFromString(const char *levelStr)
Converts from levelStr to Level.
Definition: easylogging++.cc:78
static void buildBaseFilename(const std::string &fullPath, char buff[], std::size_t limit=base::consts::kSourceFilenameMaxLength, const char *seperator=base::consts::kFilePathSeperator)
builds base filename and puts it in buff
Definition: easylogging++.cc:769
ConfigurationType configurationType(void) const
Gets configuration type of current configuration.
Definition: easylogging++.h:1754
virtual const Container & list(void) const ELPP_FINAL
Returns underlying container by constant reference.
Definition: easylogging++.h:1410
Registry(const Registry &sr)
Copy constructor that is useful for base classes. Try to avoid this constructor, use move constructor...
Definition: easylogging++.h:1442
static std::string getEnvironmentVariable(const char *variableName, const char *defaultVal, const char *alternativeBashCommand=nullptr)
Gets environment variable. This is cross-platform and CRT safe (for VC++)
Definition: easylogging++.cc:1018
static void reconfigureAllLoggers(const Configurations &configurations)
Reconfigures all the existing loggers with new configurations.
Definition: easylogging++.cc:2868
static const base::type::EnumType kMaxValid
Represents maximum valid configuration type. This is used internally and you should not need it...
Definition: easylogging++.h:659
static void setArgs(int argc, const char **argv)
Sets application arguments and figures out whats active for logging and whats not.
Definition: easylogging++.h:3711
Predicate(Level level, ConfigurationType configurationType)
Used to find configuration from configuration (pointers) repository. Avoid using it.
Definition: easylogging++.cc:181
void reconfigure(void)
Reconfigures logger using existing configurations.
Definition: easylogging++.cc:590
static ConfigurationType castFromInt(base::type::EnumType c)
Casts int(ushort) to configurationt type, useful for iterating through enum.
Definition: easylogging++.h:665
static ConfigurationType convertFromString(const char *configStr)
Converts from configStr to ConfigurationType.
Definition: easylogging++.cc:131
Mutex wrapper used when multi-threading is disabled.
Definition: easylogging++.h:1041
static bool startsWith(const std::string &str, const std::string &start)
Determines whether or not str starts with specified string.
Definition: easylogging++.cc:828
virtual void updateFormatSpec(void) ELPP_FINAL
Updates level from format. This is so that we dont have to do it at log-writing-time. It uses m_format and m_level.
Definition: easylogging++.cc:1489
virtual const_iterator cend(void) const ELPP_FINAL
Definition: easylogging++.h:1390
static bool wildCardMatch(const char *str, const char *pattern)
Matches wildcards, '*' and '?' only supported.
Definition: easylogging++.cc:786
static void reconfigureAllLoggers(ConfigurationType configurationType, const std::string &value)
Reconfigures single configuration for all the loggers.
Definition: easylogging++.h:3856
Informational events most useful for developers to debug application.
void resetLocation(const char *filename, base::type::LineNumber lineNumber)
Resets location of current hit counter.
Definition: easylogging++.h:2129
static bool endsWith(const std::string &str, const std::string &end)
Determines whether or not str ends with specified string.
Definition: easylogging++.cc:832
void setToDefault(void)
Sets configurations to "factory based" configurations.
Definition: easylogging++.cc:281
virtual iterator begin(void) ELPP_FINAL
Definition: easylogging++.h:1374
Severe error information that will presumably abort application.
bool empty(void) const
Returns true if no params available. This exclude argv[0].
Definition: easylogging++.cc:1287
static const Configurations * defaultConfigurations(void)
Returns current default.
Definition: easylogging++.cc:2892
static base::type::VerboseLevel verboseLevel(void)
Gets current verbose level.
Definition: easylogging++.cc:2976
static void gettimeofday(struct timeval *tv)
Cross platform gettimeofday for Windows and unix platform. This can be used to determine current micr...
Definition: easylogging++.cc:1077
LoggingFlag
Flags used while writing logs. This flags are set by user.
Definition: easylogging++.h:683
Operating System helper static class used internally. You should not use it.
Definition: easylogging++.h:1201
Makes sure we have new line for each container log entry.
SubsecondPrecision MillisecondsWidth
Type alias of SubsecondPrecision.
Definition: easylogging++.h:915
bool hasParamWithValue(const char *paramKey) const
Returns true if arguments contain paramKey with a value (seperated by '=')
Definition: easylogging++.cc:1274
Disables comparing performance tracker's checkpoints.
virtual void updateDateFormat(std::size_t index, base::type::string_t &currFormat) ELPP_FINAL
Updates date time format if available in currFormat.
Definition: easylogging++.cc:1462
static void configureFromGlobal(const char *globalConfigurationFilePath)
Sets configurations from global configuration file.
Definition: easylogging++.cc:2915
static bool configureFromArg(const char *argKey)
Configures loggers using command line arg. Ensure you have already set command line args...
Definition: easylogging++.cc:2956
void setFromBase(Configurations *base)
Sets configuration based-off an existing configurations.
Definition: easylogging++.cc:233
static const base::type::EnumType kMaxValid
Represents maximum valid level. This is used internally and you should not need it.
Definition: easylogging++.h:598
Represents unknown level.
static void addFlag(LoggingFlag flag)
Adds logging flag used internally.
Definition: easylogging++.h:3884
Level
Represents enumeration for severity level used to determine level of logging.
Definition: easylogging++.h:572
Thread-safe Configuration repository.
Definition: easylogging++.h:1793
Internal helper class that prevent copy constructor for class.
Definition: easylogging++.h:550
FormatFlags
Format flags used to determine specifiers that are active for performance improvements.
Definition: easylogging++.h:880
Definition: easylogging++.h:2816
void setRemainingToDefault(void)
Lets you set the remaining configurations to default.
Definition: easylogging++.cc:309
virtual std::size_t size(void) const ELPP_FINAL
Definition: easylogging++.h:1400
Static class that contains helper functions for el::Level.
Definition: easylogging++.h:593
Definition: easylogging++.h:2247
Adds flag and removes it when scope goes out.
Definition: easylogging++.h:3896
Determines log file (full path) to write logs to for correponding level and logger.
Dispatches log messages.
Definition: easylogging++.h:2821
Definition: easylogging++.h:2913
Registry & operator=(const Registry &sr)
Assignment operator that unregisters all the existing registeries and deeply copies each of repo elem...
Definition: easylogging++.h:1452
Contains utilities for cross-platform date/time. This class make use of el::base::utils::Str.
Definition: easylogging++.h:1243
static base::TypedConfigurations defaultTypedConfigurations(void)
Default typed configuration based on existing defaultConf.
Definition: easylogging++.cc:2900
static void clearVModules(void)
Clears vmodules.
Definition: easylogging++.cc:2986
Repository for hit counters used across the application.
Definition: easylogging++.h:2181
Adds spaces b/w logs that separated by left-shift operator.
void configure(const Configurations &configurations)
Configures the logger using specified configurations.
Definition: easylogging++.cc:570
static void installCustomFormatSpecifier(const CustomFormatSpecifier &customFormatSpecifier)
Installs user defined format specifier and handler.
Definition: easylogging++.h:3804
const char * getParamValue(const char *paramKey) const
Returns value of arguments.
Definition: easylogging++.cc:1278
Base of Easylogging++ friendly class.
Definition: easylogging++.h:1627
Makes sure if -vmodule is used and does not specifies a module, then verbose logging is allowed via t...
Information that can be highly useful and vary with verbose logging level.
Determines format of logging corresponding level and logger.
AbstractRegistry & operator=(AbstractRegistry &&sr)
Assignment move operator.
Definition: easylogging++.h:1361
Disable VModules extensions.
Configurations(void)
Default constructor with empty repository.
Definition: easylogging++.cc:192
static void setVerboseLevel(base::type::VerboseLevel level)
Sets verbose level on the fly.
Definition: easylogging++.cc:2972
void setGlobally(ConfigurationType configurationType, const std::string &value)
Sets configuration for all levels.
Definition: easylogging++.h:1871
static void installPreRollOutCallback(const PreRollOutCallback &callback)
Installs pre rollout callback, this callback is triggered when log file is about to be rolled out (ca...
Definition: easylogging++.h:3741
static const el::base::utils::CommandLineArgs * commandLineArgs(void)
Returns command line arguments (pointer) provided to easylogging++.
Definition: easylogging++.h:3800
static std::string currentHost(void)
Gets current host name or computer name.
Definition: easylogging++.cc:1055
static bool isDigit(char c)
Checks if character is digit. Dont use libc implementation of it to prevent locale issues...
Definition: easylogging++.h:1133
Main entry point of each logging.
Definition: easylogging++.h:3241
static bool createPath(const std::string &path)
Creates specified path on file system.
Definition: easylogging++.cc:706
Used to find configuration from configuration (pointers) repository. Avoid using it.
Definition: easylogging++.h:1773
static base::type::StoragePointer storage()
Definition: easylogging++.h:3703
static bool uninstallCustomFormatSpecifier(const char *formatSpecifier)
Uninstalls user defined format specifier and handler.
Definition: easylogging++.h:3808
Preserves time format and does not convert it to sec, hour etc (performance tracking only) ...
std::function< std::string(const LogMessage *)> FormatSpecifierValueResolver
Resolving function for format specifier.
Definition: easylogging++.h:1706
Command line arguments for application if specified using el::Helpers::setArgs(..) or START_EASYLOGGI...
Definition: easylogging++.h:1275
static bool termSupportsColor(void)
Whether or not terminal supports colors.
Definition: easylogging++.cc:1068
static bool unregisterLogger(const std::string &identity)
Unregisters logger - use it only when you know what you are doing, you may unregister loggers initial...
Definition: easylogging++.cc:2837
bool hasParam(const char *paramKey) const
Return true if arguments has a param (not having a value) i,e without '='.
Definition: easylogging++.cc:1283
Represents single configuration that has representing level, configuration type and a string based va...
Definition: easylogging++.h:1737
Lock guard wrapper used when multi-threading is disabled.
Definition: easylogging++.h:1052
const std::string & value(void) const
Gets string based configuration value.
Definition: easylogging++.h:1759
static const std::string releaseDate(void)
Release date of current version.
Definition: easylogging++.cc:2996
virtual void registerNew(const T_Key &uniqKey, T_Ptr *ptr) ELPP_FINAL
Registers new registry to repository.
Definition: easylogging++.h:1475
Definition: easylogging++.h:2243
static std::string convertTemplateToStdString(const T &templ)
Converts template to std::string - useful for loggable classes to log containers within log(std::ostr...
Definition: easylogging++.h:3780
bool vModulesEnabled(void)
Whether or not vModules enabled.
Definition: easylogging++.h:2502
static bool hasFlag(LoggingFlag flag)
Determines whether or not certain flag is active.
Definition: easylogging++.h:3892
Abstract registry (aka repository) that provides basic interface for pointer repository specified by ...
Definition: easylogging++.h:1319
static void setDefaultConfigurations(const Configurations &configurations, bool reconfigureExistingLoggers=false)
Sets default configurations. This configuration is used for future (and conditionally for existing) l...
Definition: easylogging++.cc:2885
virtual void unregisterAll(void)=0
Unregisters all the pointers from current repository.
Writes nothing - Used when certain log is disabled.
Definition: easylogging++.h:3222
Definition: easylogging++.h:2222
Alias of SubsecondPrecision (for backward compatibility)
Make terminal output colorful for supported terminals.
static bool hasLogger(const std::string &identity)
Whether or not logger with id is registered.
Definition: easylogging++.cc:2842
static void setDefaultLogBuilder(el::LogBuilderPtr &logBuilderPtr)
Changes default log builder for future loggers.
Definition: easylogging++.cc:2833
Represents log format containing flags and date format. This is used internally to start initial log...
Definition: easylogging++.h:1639
bool validateEveryN(const char *filename, base::type::LineNumber lineNumber, std::size_t n)
Validates counter for every N, i.e, registers new if does not exist otherwise updates original one...
Definition: easylogging++.cc:1768
static bool cStringEq(const char *s1, const char *s2)
Compares cstring equality - uses strcmp.
Definition: easylogging++.cc:880
static Level castFromInt(base::type::EnumType l)
Casts int(ushort) to level, useful for iterating through enum.
Definition: easylogging++.h:604
RegistryWithPred & operator=(const RegistryWithPred &sr)
Assignment operator that unregisters all the existing registeries and deeply copies each of repo elem...
Definition: easylogging++.h:1533
Useful when application has potentially harmful situtaions.
TypedConfigurations(Configurations *configurations, base::LogStreamsReferenceMap *logStreamsReference)
Constructor to initialize (construct) the object off el::Configurations.
Definition: easylogging++.cc:1540
Class that keeps record of current line hit for occasional logging.
Definition: easylogging++.h:2096
When handling crashes by default, detailed crash reason will be logged as well.
DispatchAction
Action to be taken for dispatching.
Definition: easylogging++.h:2202
Enables strict file rolling.
virtual bool empty(void) const ELPP_FINAL
Definition: easylogging++.h:1395
Removes flag and add it when scope goes out.
Definition: easylogging++.h:3908
void setArgs(int argc, const char **argv)
Sets arguments and parses them.
Definition: easylogging++.h:1288
static std::string & toUpper(std::string &str)
Converts string to uppercase.
Definition: easylogging++.cc:872
static const base::type::EnumType kMinValid
Represents minimum valid configuration type. Useful when iterating through enum.
Definition: easylogging++.h:657
static unsigned long long getTimeDifference(const struct timeval &endTime, const struct timeval &startTime, base::TimestampUnit timestampUnit)
Gets time difference in milli/micro second depending on timestampUnit.
Definition: easylogging++.cc:1139
static base::type::EnumType castToInt(ConfigurationType configurationType)
Casts configuration type to int, useful for iterating through enum.
Definition: easylogging++.h:661
static bool parseFromText(const std::string &configurationsString, Configurations *sender, Configurations *base=nullptr)
Parse configurations from configuration string.
Definition: easylogging++.cc:352
Flushes log with every log-entry (performance sensative) - Disabled by default.
static std::size_t getSizeOfFile(base::type::fstream_t *fs)
Gets size of file provided in stream.
Definition: easylogging++.cc:678
A pointer registry mechanism to manage memory and provide search functionalities. (non-predicate vers...
Definition: easylogging++.h:1434
static void forEachLevel(base::type::EnumType *startIndex, const std::function< bool(void)> &fn)
Applies specified function to each level starting from startIndex.
Definition: easylogging++.cc:87
Mainly useful to represent current progress of application.
Definition: easylogging++.h:3296
static base::type::fstream_t * newFileStream(const std::string &filename)
Creates new out file stream for specified filename.
Definition: easylogging++.cc:654
std::size_t size(void) const
Returns total number of arguments. This exclude argv[0].
Definition: easylogging++.cc:1291
static void forEachConfigType(base::type::EnumType *startIndex, const std::function< bool(void)> &fn)
Applies specified function to each configuration type starting from startIndex.
Definition: easylogging++.cc:140
Definition: easylogging++.h:1103
Configurations with data types.
Definition: easylogging++.h:1968
static base::type::string_t formatTime(unsigned long long time, base::TimestampUnit timestampUnit)
Formats time to get unit accordingly, units like second if > 1000 or minutes if > 60000 etc...
Definition: easylogging++.cc:1121
void parseFromFormat(const base::type::string_t &userFormat)
Updates format to be used while logging.
Definition: easylogging++.cc:1412
static const base::LogStreamsReferenceMap * logStreamsReference(void)
Returns log stream reference pointer if needed by user.
Definition: easylogging++.cc:2896
void set(Level level, ConfigurationType configurationType, const std::string &value)
Sets value of configuration for specified level.
Definition: easylogging++.cc:266
static bool hasCustomFormatSpecifier(const char *formatSpecifier)
Returns true if custom format specifier is installed.
Definition: easylogging++.h:3812
static bool installLogDispatchCallback(const std::string &id)
Installs post log dispatch callback, this callback is triggered when log is dispatched.
Definition: easylogging++.h:3750
TimestampUnit
Enum to represent timestamp unit.
Definition: easylogging++.h:876
Static helpers to deal with loggers and their configurations.
Definition: easylogging++.h:3821
Specifies number of log entries to hold until we flush pending log data.
static std::string currentUser(void)
Gets current username.
Definition: easylogging++.cc:1042
static Logger * getLogger(const std::string &identity, bool registerIfNotAvailable=true)
Gets existing or registers new logger.
Definition: easylogging++.cc:2828
void flush(void)
Flushes logger to sync all log files for all levels.
Definition: easylogging++.cc:604
static char * wcharPtrToCharPtr(const wchar_t *line)
Converst wchar* to char* NOTE: Need to free return value after use!
Definition: easylogging++.cc:942
static const char * convertToString(Level level)
Converts level to associated const char*.
Definition: easylogging++.cc:49
Base of thread safe class, this class is inheritable-only.
Definition: easylogging++.h:1066
const std::string & configurationFile(void) const
Gets configuration file used in parsing this configurations.
Definition: easylogging++.h:1884
Definition: easylogging++.h:3932
static bool cStringCaseEq(const char *s1, const char *s2)
Compares cstring equality (case-insensitive) - uses toupper(char) Dont use strcasecmp because of CRT ...
Definition: easylogging++.cc:886
Static class that contains helper functions for el::ConfigurationType.
Definition: easylogging++.h:654
static const base::type::EnumType kMinValid
Represents minimum valid level. Useful when iterating through enum.
Definition: easylogging++.h:596
static void uninstallPreRollOutCallback(void)
Uninstalls pre rollout callback.
Definition: easylogging++.h:3745
Represents a logger holding ID and configurations we need to write logs.
Definition: easylogging++.h:2271
Definition: easylogging++.h:2158
static void uninstallLogDispatchCallback(const std::string &id)
Uninstalls log dispatch callback.
Definition: easylogging++.h:3755
String utilities helper class used internally. You should not use it.
Definition: easylogging++.h:1130
Represents registries for verbose logging.
Definition: easylogging++.h:2475
Loggers repository.
Definition: easylogging++.h:2405
Generic level that represents all the levels. Useful when setting global configuration for all levels...
void setLevel(base::type::VerboseLevel level)
Sets verbose level. Accepted range is 0-9.
Definition: easylogging++.cc:1868
static bool pathExists(const char *path, bool considerFile=false)
Determines whether or not provided path exist in current file system.
Definition: easylogging++.cc:689
void setValue(const std::string &value)
Set string based configuration value.
Definition: easylogging++.h:1766
Whether or not to write corresponding log to log file.
static std::vector< std::string > * populateAllLoggerIds(std::vector< std::string > *targetList)
Populates all logger IDs in current repository.
Definition: easylogging++.cc:2906
static bool installLoggerRegistrationCallback(const std::string &id)
Installs logger registration callback, this callback is triggered when new logger is registered...
Definition: easylogging++.h:3829
const base::HitCounter * getCounter(const char *filename, base::type::LineNumber lineNumber)
Gets hit counter registered at specified position.
Definition: easylogging++.h:2196
static void setStorage(base::type::StoragePointer storage)
Shares logging repository (base::Storage)
Definition: easylogging++.h:3699
Definition: easylogging++.h:2512
static std::string & replaceAll(std::string &str, char replaceWhat, char replaceWith)
Replaces all instances of replaceWhat with 'replaceWith'. Original variable is changed for performanc...
Definition: easylogging++.cc:836
bool parseFromText(const std::string &configurationsString, Configurations *base=nullptr)
Parse configurations from configuration string.
Definition: easylogging++.cc:225
Whether or not to write corresponding level and logger log to standard output. By standard output mea...
static std::string timevalToString(struct timeval tval, const char *format, const el::base::SubsecondPrecision *ssPrec)
Converts timeval (struct from ctime) to string using specified format and subsecond precision...
Definition: easylogging++.cc:1110
ConfigurationType
Represents enumeration of ConfigurationType used to configure or access certain aspect of logging...
Definition: easylogging++.h:622
bool validateNTimes(const char *filename, base::type::LineNumber lineNumber, std::size_t n)
Validates counter for hits are <= n, i.e, registers new if does not exist otherwise updates original ...
Definition: easylogging++.cc:1798
static void uninstallLoggerRegistrationCallback(const std::string &id)
Uninstalls log dispatch callback.
Definition: easylogging++.h:3834
Parser used internally to parse configurations from file or text.
Definition: easylogging++.h:1904
bool hasConfiguration(ConfigurationType configurationType)
Determines whether or not specified configuration type exists in the repository.
Definition: easylogging++.cc:243
static const std::string getBashOutput(const char *command)
Runs command on terminal and returns the output.
Definition: easylogging++.cc:991
A pointer registry mechanism to manage memory and provide search functionalities. (predicate version)...
Definition: easylogging++.h:1510
static void flushAll(void)
Flushes all loggers for all levels - Be careful if you dont know how many loggers are registered...
Definition: easylogging++.cc:2968
static void setArgs(int argc, char **argv)
Sets application arguments and figures out whats active for logging and whats not.
Definition: easylogging++.h:3707
AbstractRegistry(AbstractRegistry &&sr)
Move constructor that is useful for base classes.
Definition: easylogging++.h:1328
static void setLoggingLevel(Level level)
Sets hierarchy for logging. Needs to enable logging flag (HierarchicalLogging)
Definition: easylogging++.h:3920
virtual void unregisterAll(void) ELPP_FINAL
Unregisters all the pointers from current repository.
Definition: easylogging++.h:1465
void validateHitCounts(std::size_t n)
Validates hit counts and resets it if necessary.
Definition: easylogging++.h:2135
static bool contains(const char *str, char c)
Returns true if c exist in str.
Definition: easylogging++.cc:905
Definition: easylogging++.h:2777
static Logger * reconfigureLogger(Logger *logger, const Configurations &configurations)
Reconfigures specified logger with new configurations.
Definition: easylogging++.cc:2847
bool validateAfterN(const char *filename, base::type::LineNumber lineNumber, std::size_t n)
Validates counter for hits >= N, i.e, registers new if does not exist otherwise updates original one...
Definition: easylogging++.cc:1781
User-provided custom format specifier.
Definition: easylogging++.h:1710
Initializes syslog with process ID, options and facility. calls closelog() on d'tor.
Definition: easylogging++.h:3677
Enables hierarchical logging.
static void buildStrippedFilename(const char *filename, char buff[], std::size_t limit=base::consts::kSourceFilenameMaxLength)
builds stripped filename and puts it in buff
Definition: easylogging++.cc:757
virtual void unregisterAll(void) ELPP_FINAL
Unregisters all the pointers from current repository.
Definition: easylogging++.h:1549
static base::type::EnumType castToInt(Level level)
Casts level to int, useful for iterating through enum.
Definition: easylogging++.h:600
Supports use of multiple logging in same macro, e.g, CLOG(INFO, "default", "network") ...
void unregister(const T_Key &uniqKey)
Unregisters single entry mapped to specified unique key.
Definition: easylogging++.h:1481
Definition: easylogging++.h:471
static std::string getDateTime(const char *format, const base::SubsecondPrecision *ssPrec)
Gets current date and time with a subsecond part.
Definition: easylogging++.cc:1104
void clear(void)
Clears repository so that all the configurations are unset.
Definition: easylogging++.h:1876
Definition: easylogging++.h:2251
Information that can be useful to back-trace certain events - mostly useful than debug logs...
Internal helper class that makes all default constructors private.
Definition: easylogging++.h:561
Definition: easylogging++.h:2255
Easylogging++ management storage.
Definition: easylogging++.h:2609
Specifies log file max size.
Configuration * get(const T &arg1, const T2 arg2)
Gets pointer from repository with speicifed arguments. Arguments are passed to predicate in order to ...
Definition: easylogging++.h:1580
Allows to disable application abortion when logged using FATAL level.