easylogging++.h
Go to the documentation of this file.
1 //
2 // Bismillah ar-Rahmaan ar-Raheem
3 //
4 // Easylogging++ v9.96.5
5 // Single-header only, cross-platform logging library for C++ applications
6 //
7 // Copyright (c) 2012-2018 Muflihun Labs
8 // Copyright (c) 2012-2018 @abumusamq
9 //
10 // This library is released under the MIT Licence.
11 // https://github.com/muflihun/easyloggingpp/blob/master/LICENSE
12 //
13 // https://github.com/muflihun/easyloggingpp
14 // https://muflihun.github.io/easyloggingpp
15 // http://muflihun.com
16 //
17 
18 #ifndef EASYLOGGINGPP_H
19 #define EASYLOGGINGPP_H
20 // Compilers and C++0x/C++11 Evaluation
21 #if __cplusplus >= 201103L
22 # define ELPP_CXX11 1
23 #endif // __cplusplus >= 201103L
24 #if (defined(__GNUC__))
25 # define ELPP_COMPILER_GCC 1
26 #else
27 # define ELPP_COMPILER_GCC 0
28 #endif
29 #if ELPP_COMPILER_GCC
30 # define ELPP_GCC_VERSION (__GNUC__ * 10000 \
31 + __GNUC_MINOR__ * 100 \
32 + __GNUC_PATCHLEVEL__)
33 # if defined(__GXX_EXPERIMENTAL_CXX0X__)
34 # define ELPP_CXX0X 1
35 # endif
36 #endif
37 // Visual C++
38 #if defined(_MSC_VER)
39 # define ELPP_COMPILER_MSVC 1
40 #else
41 # define ELPP_COMPILER_MSVC 0
42 #endif
43 #define ELPP_CRT_DBG_WARNINGS ELPP_COMPILER_MSVC
44 #if ELPP_COMPILER_MSVC
45 # if (_MSC_VER == 1600)
46 # define ELPP_CXX0X 1
47 # elif(_MSC_VER >= 1700)
48 # define ELPP_CXX11 1
49 # endif
50 #endif
51 // Clang++
52 #if (defined(__clang__) && (__clang__ == 1))
53 # define ELPP_COMPILER_CLANG 1
54 #else
55 # define ELPP_COMPILER_CLANG 0
56 #endif
57 #if ELPP_COMPILER_CLANG
58 # if __has_include(<thread>)
59 # include <cstddef> // Make __GLIBCXX__ defined when using libstdc++
60 # if !defined(__GLIBCXX__) || __GLIBCXX__ >= 20150426
61 # define ELPP_CLANG_SUPPORTS_THREAD
62 # endif // !defined(__GLIBCXX__) || __GLIBCXX__ >= 20150426
63 # endif // __has_include(<thread>)
64 #endif
65 #if (defined(__MINGW32__) || defined(__MINGW64__))
66 # define ELPP_MINGW 1
67 #else
68 # define ELPP_MINGW 0
69 #endif
70 #if (defined(__CYGWIN__) && (__CYGWIN__ == 1))
71 # define ELPP_CYGWIN 1
72 #else
73 # define ELPP_CYGWIN 0
74 #endif
75 #if (defined(__INTEL_COMPILER))
76 # define ELPP_COMPILER_INTEL 1
77 #else
78 # define ELPP_COMPILER_INTEL 0
79 #endif
80 // Operating System Evaluation
81 // Windows
82 #if (defined(_WIN32) || defined(_WIN64))
83 # define ELPP_OS_WINDOWS 1
84 #else
85 # define ELPP_OS_WINDOWS 0
86 #endif
87 // Linux
88 #if (defined(__linux) || defined(__linux__))
89 # define ELPP_OS_LINUX 1
90 #else
91 # define ELPP_OS_LINUX 0
92 #endif
93 #if (defined(__APPLE__))
94 # define ELPP_OS_MAC 1
95 #else
96 # define ELPP_OS_MAC 0
97 #endif
98 #if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
99 # define ELPP_OS_FREEBSD 1
100 #else
101 # define ELPP_OS_FREEBSD 0
102 #endif
103 #if (defined(__sun))
104 # define ELPP_OS_SOLARIS 1
105 #else
106 # define ELPP_OS_SOLARIS 0
107 #endif
108 #if (defined(_AIX))
109 # define ELPP_OS_AIX 1
110 #else
111 # define ELPP_OS_AIX 0
112 #endif
113 #if (defined(__NetBSD__))
114 # define ELPP_OS_NETBSD 1
115 #else
116 # define ELPP_OS_NETBSD 0
117 #endif
118 // Unix
119 #if ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_NETBSD || ELPP_OS_SOLARIS || ELPP_OS_AIX) && (!ELPP_OS_WINDOWS))
120 # define ELPP_OS_UNIX 1
121 #else
122 # define ELPP_OS_UNIX 0
123 #endif
124 #if (defined(__ANDROID__))
125 # define ELPP_OS_ANDROID 1
126 #else
127 # define ELPP_OS_ANDROID 0
128 #endif
129 // Evaluating Cygwin as *nix OS
130 #if !ELPP_OS_UNIX && !ELPP_OS_WINDOWS && ELPP_CYGWIN
131 # undef ELPP_OS_UNIX
132 # undef ELPP_OS_LINUX
133 # define ELPP_OS_UNIX 1
134 # define ELPP_OS_LINUX 1
135 #endif // !ELPP_OS_UNIX && !ELPP_OS_WINDOWS && ELPP_CYGWIN
136 #if !defined(ELPP_INTERNAL_DEBUGGING_OUT_INFO)
137 # define ELPP_INTERNAL_DEBUGGING_OUT_INFO std::cout
138 #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
139 #if !defined(ELPP_INTERNAL_DEBUGGING_OUT_ERROR)
140 # define ELPP_INTERNAL_DEBUGGING_OUT_ERROR std::cerr
141 #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
142 #if !defined(ELPP_INTERNAL_DEBUGGING_ENDL)
143 # define ELPP_INTERNAL_DEBUGGING_ENDL std::endl
144 #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
145 #if !defined(ELPP_INTERNAL_DEBUGGING_MSG)
146 # define ELPP_INTERNAL_DEBUGGING_MSG(msg) msg
147 #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
148 // Internal Assertions and errors
149 #if !defined(ELPP_DISABLE_ASSERT)
150 # if (defined(ELPP_DEBUG_ASSERT_FAILURE))
151 # define ELPP_ASSERT(expr, msg) if (!(expr)) { \
152 std::stringstream internalInfoStream; internalInfoStream << msg; \
153 ELPP_INTERNAL_DEBUGGING_OUT_ERROR \
154 << "EASYLOGGING++ ASSERTION FAILED (LINE: " << __LINE__ << ") [" #expr << "] WITH MESSAGE \"" \
155 << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << "\"" << ELPP_INTERNAL_DEBUGGING_ENDL; base::utils::abort(1, \
156 "ELPP Assertion failure, please define ELPP_DEBUG_ASSERT_FAILURE"); }
157 # else
158 # define ELPP_ASSERT(expr, msg) if (!(expr)) { \
159 std::stringstream internalInfoStream; internalInfoStream << msg; \
160 ELPP_INTERNAL_DEBUGGING_OUT_ERROR\
161 << "ASSERTION FAILURE FROM EASYLOGGING++ (LINE: " \
162 << __LINE__ << ") [" #expr << "] WITH MESSAGE \"" << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << "\"" \
163 << ELPP_INTERNAL_DEBUGGING_ENDL; }
164 # endif // (defined(ELPP_DEBUG_ASSERT_FAILURE))
165 #else
166 # define ELPP_ASSERT(x, y)
167 #endif //(!defined(ELPP_DISABLE_ASSERT)
168 #if ELPP_COMPILER_MSVC
169 # define ELPP_INTERNAL_DEBUGGING_WRITE_PERROR \
170 { char buff[256]; strerror_s(buff, 256, errno); \
171 ELPP_INTERNAL_DEBUGGING_OUT_ERROR << ": " << buff << " [" << errno << "]";} (void)0
172 #else
173 # define ELPP_INTERNAL_DEBUGGING_WRITE_PERROR \
174 ELPP_INTERNAL_DEBUGGING_OUT_ERROR << ": " << strerror(errno) << " [" << errno << "]"; (void)0
175 #endif // ELPP_COMPILER_MSVC
176 #if defined(ELPP_DEBUG_ERRORS)
177 # if !defined(ELPP_INTERNAL_ERROR)
178 # define ELPP_INTERNAL_ERROR(msg, pe) { \
179 std::stringstream internalInfoStream; internalInfoStream << "<ERROR> " << msg; \
180 ELPP_INTERNAL_DEBUGGING_OUT_ERROR \
181 << "ERROR FROM EASYLOGGING++ (LINE: " << __LINE__ << ") " \
182 << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << ELPP_INTERNAL_DEBUGGING_ENDL; \
183 if (pe) { ELPP_INTERNAL_DEBUGGING_OUT_ERROR << " "; ELPP_INTERNAL_DEBUGGING_WRITE_PERROR; }} (void)0
184 # endif
185 #else
186 # undef ELPP_INTERNAL_INFO
187 # define ELPP_INTERNAL_ERROR(msg, pe)
188 #endif // defined(ELPP_DEBUG_ERRORS)
189 #if (defined(ELPP_DEBUG_INFO))
190 # if !(defined(ELPP_INTERNAL_INFO_LEVEL))
191 # define ELPP_INTERNAL_INFO_LEVEL 9
192 # endif // !(defined(ELPP_INTERNAL_INFO_LEVEL))
193 # if !defined(ELPP_INTERNAL_INFO)
194 # define ELPP_INTERNAL_INFO(lvl, msg) { if (lvl <= ELPP_INTERNAL_INFO_LEVEL) { \
195 std::stringstream internalInfoStream; internalInfoStream << "<INFO> " << msg; \
196 ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) \
197 << ELPP_INTERNAL_DEBUGGING_ENDL; }}
198 # endif
199 #else
200 # undef ELPP_INTERNAL_INFO
201 # define ELPP_INTERNAL_INFO(lvl, msg)
202 #endif // (defined(ELPP_DEBUG_INFO))
203 #if (defined(ELPP_FEATURE_ALL)) || (defined(ELPP_FEATURE_CRASH_LOG))
204 # if (ELPP_COMPILER_GCC && !ELPP_MINGW && !ELPP_OS_ANDROID)
205 # define ELPP_STACKTRACE 1
206 # else
207 # if ELPP_COMPILER_MSVC
208 # pragma message("Stack trace not available for this compiler")
209 # else
210 # warning "Stack trace not available for this compiler";
211 # endif // ELPP_COMPILER_MSVC
212 # define ELPP_STACKTRACE 0
213 # endif // ELPP_COMPILER_GCC
214 #else
215 # define ELPP_STACKTRACE 0
216 #endif // (defined(ELPP_FEATURE_ALL)) || (defined(ELPP_FEATURE_CRASH_LOG))
217 // Miscellaneous macros
218 #define ELPP_UNUSED(x) (void)x
219 #if ELPP_OS_UNIX
220 // Log file permissions for unix-based systems
221 # define ELPP_LOG_PERMS S_IRUSR | S_IWUSR | S_IXUSR | S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IXOTH
222 #endif // ELPP_OS_UNIX
223 #if defined(ELPP_AS_DLL) && ELPP_COMPILER_MSVC
224 # if defined(ELPP_EXPORT_SYMBOLS)
225 # define ELPP_EXPORT __declspec(dllexport)
226 # else
227 # define ELPP_EXPORT __declspec(dllimport)
228 # endif // defined(ELPP_EXPORT_SYMBOLS)
229 #else
230 # define ELPP_EXPORT
231 #endif // defined(ELPP_AS_DLL) && ELPP_COMPILER_MSVC
232 // Some special functions that are VC++ specific
233 #undef STRTOK
234 #undef STRERROR
235 #undef STRCAT
236 #undef STRCPY
237 #if ELPP_CRT_DBG_WARNINGS
238 # define STRTOK(a, b, c) strtok_s(a, b, c)
239 # define STRERROR(a, b, c) strerror_s(a, b, c)
240 # define STRCAT(a, b, len) strcat_s(a, len, b)
241 # define STRCPY(a, b, len) strcpy_s(a, len, b)
242 #else
243 # define STRTOK(a, b, c) strtok(a, b)
244 # define STRERROR(a, b, c) strerror(c)
245 # define STRCAT(a, b, len) strcat(a, b)
246 # define STRCPY(a, b, len) strcpy(a, b)
247 #endif
248 // Compiler specific support evaluations
249 #if (ELPP_MINGW && !defined(ELPP_FORCE_USE_STD_THREAD))
250 # define ELPP_USE_STD_THREADING 0
251 #else
252 # if ((ELPP_COMPILER_CLANG && defined(ELPP_CLANG_SUPPORTS_THREAD)) || \
253  (!ELPP_COMPILER_CLANG && defined(ELPP_CXX11)) || \
254  defined(ELPP_FORCE_USE_STD_THREAD))
255 # define ELPP_USE_STD_THREADING 1
256 # else
257 # define ELPP_USE_STD_THREADING 0
258 # endif
259 #endif
260 #undef ELPP_FINAL
261 #if ELPP_COMPILER_INTEL || (ELPP_GCC_VERSION < 40702)
262 # define ELPP_FINAL
263 #else
264 # define ELPP_FINAL final
265 #endif // ELPP_COMPILER_INTEL || (ELPP_GCC_VERSION < 40702)
266 #if defined(EASYLOGGINGPP_ASYNC)
267 # define ELPP_ASYNC_LOGGING 1
268 #else
269 # define ELPP_ASYNC_LOGGING 0
270 #endif // defined(EASYLOGGINGPP_ASYNC)
271 #if defined(ELPP_THREAD_SAFE) || ELPP_ASYNC_LOGGING
272 # define ELPP_THREADING_ENABLED 1
273 #else
274 # define ELPP_THREADING_ENABLED 0
275 #endif // defined(ELPP_THREAD_SAFE) || ELPP_ASYNC_LOGGING
276 // Function macro ELPP_FUNC
277 #undef ELPP_FUNC
278 #if ELPP_COMPILER_MSVC // Visual C++
279 # define ELPP_FUNC __FUNCSIG__
280 #elif ELPP_COMPILER_GCC // GCC
281 # define ELPP_FUNC __PRETTY_FUNCTION__
282 #elif ELPP_COMPILER_INTEL // Intel C++
283 # define ELPP_FUNC __PRETTY_FUNCTION__
284 #elif ELPP_COMPILER_CLANG // Clang++
285 # define ELPP_FUNC __PRETTY_FUNCTION__
286 #else
287 # if defined(__func__)
288 # define ELPP_FUNC __func__
289 # else
290 # define ELPP_FUNC ""
291 # endif // defined(__func__)
292 #endif // defined(_MSC_VER)
293 #undef ELPP_VARIADIC_TEMPLATES_SUPPORTED
294 // Keep following line commented until features are fixed
295 #define ELPP_VARIADIC_TEMPLATES_SUPPORTED \
296 (ELPP_COMPILER_GCC || ELPP_COMPILER_CLANG || ELPP_COMPILER_INTEL || (ELPP_COMPILER_MSVC && _MSC_VER >= 1800))
297 // Logging Enable/Disable macros
298 #if defined(ELPP_DISABLE_LOGS)
299 #define ELPP_LOGGING_ENABLED 0
300 #else
301 #define ELPP_LOGGING_ENABLED 1
302 #endif
303 #if (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED))
304 # define ELPP_DEBUG_LOG 1
305 #else
306 # define ELPP_DEBUG_LOG 0
307 #endif // (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED))
308 #if (!defined(ELPP_DISABLE_INFO_LOGS) && (ELPP_LOGGING_ENABLED))
309 # define ELPP_INFO_LOG 1
310 #else
311 # define ELPP_INFO_LOG 0
312 #endif // (!defined(ELPP_DISABLE_INFO_LOGS) && (ELPP_LOGGING_ENABLED))
313 #if (!defined(ELPP_DISABLE_WARNING_LOGS) && (ELPP_LOGGING_ENABLED))
314 # define ELPP_WARNING_LOG 1
315 #else
316 # define ELPP_WARNING_LOG 0
317 #endif // (!defined(ELPP_DISABLE_WARNING_LOGS) && (ELPP_LOGGING_ENABLED))
318 #if (!defined(ELPP_DISABLE_ERROR_LOGS) && (ELPP_LOGGING_ENABLED))
319 # define ELPP_ERROR_LOG 1
320 #else
321 # define ELPP_ERROR_LOG 0
322 #endif // (!defined(ELPP_DISABLE_ERROR_LOGS) && (ELPP_LOGGING_ENABLED))
323 #if (!defined(ELPP_DISABLE_FATAL_LOGS) && (ELPP_LOGGING_ENABLED))
324 # define ELPP_FATAL_LOG 1
325 #else
326 # define ELPP_FATAL_LOG 0
327 #endif // (!defined(ELPP_DISABLE_FATAL_LOGS) && (ELPP_LOGGING_ENABLED))
328 #if (!defined(ELPP_DISABLE_TRACE_LOGS) && (ELPP_LOGGING_ENABLED))
329 # define ELPP_TRACE_LOG 1
330 #else
331 # define ELPP_TRACE_LOG 0
332 #endif // (!defined(ELPP_DISABLE_TRACE_LOGS) && (ELPP_LOGGING_ENABLED))
333 #if (!defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED))
334 # define ELPP_VERBOSE_LOG 1
335 #else
336 # define ELPP_VERBOSE_LOG 0
337 #endif // (!defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED))
338 #if (!(ELPP_CXX0X || ELPP_CXX11))
339 # error "C++0x (or higher) support not detected! (Is `-std=c++11' missing?)"
340 #endif // (!(ELPP_CXX0X || ELPP_CXX11))
341 // Headers
342 #if defined(ELPP_SYSLOG)
343 # include <syslog.h>
344 #endif // defined(ELPP_SYSLOG)
345 #include <ctime>
346 #include <cstring>
347 #include <cstdlib>
348 #include <cctype>
349 #include <cwchar>
350 #include <csignal>
351 #include <cerrno>
352 #include <cstdarg>
353 #if defined(ELPP_UNICODE)
354 # include <locale>
355 # if ELPP_OS_WINDOWS
356 # include <codecvt>
357 # endif // ELPP_OS_WINDOWS
358 #endif // defined(ELPP_UNICODE)
359 #if ELPP_STACKTRACE
360 # include <cxxabi.h>
361 # include <execinfo.h>
362 #endif // ELPP_STACKTRACE
363 #if ELPP_OS_ANDROID
364 # include <sys/system_properties.h>
365 #endif // ELPP_OS_ANDROID
366 #if ELPP_OS_UNIX
367 # include <sys/stat.h>
368 # include <sys/time.h>
369 #elif ELPP_OS_WINDOWS
370 # include <direct.h>
371 # include <windows.h>
372 # if defined(WIN32_LEAN_AND_MEAN)
373 # if defined(ELPP_WINSOCK2)
374 # include <winsock2.h>
375 # else
376 # include <winsock.h>
377 # endif // defined(ELPP_WINSOCK2)
378 # endif // defined(WIN32_LEAN_AND_MEAN)
379 #endif // ELPP_OS_UNIX
380 #include <string>
381 #include <vector>
382 #include <map>
383 #include <unordered_map>
384 #include <utility>
385 #include <functional>
386 #include <algorithm>
387 #include <fstream>
388 #include <iostream>
389 #include <sstream>
390 #include <memory>
391 #include <type_traits>
392 #if ELPP_THREADING_ENABLED
393 # if ELPP_USE_STD_THREADING
394 # include <mutex>
395 # include <thread>
396 # else
397 # if ELPP_OS_UNIX
398 # include <pthread.h>
399 # endif // ELPP_OS_UNIX
400 # endif // ELPP_USE_STD_THREADING
401 #endif // ELPP_THREADING_ENABLED
402 #if ELPP_ASYNC_LOGGING
403 # if defined(ELPP_NO_SLEEP_FOR)
404 # include <unistd.h>
405 # endif // defined(ELPP_NO_SLEEP_FOR)
406 # include <thread>
407 # include <queue>
408 # include <condition_variable>
409 #endif // ELPP_ASYNC_LOGGING
410 #if defined(ELPP_STL_LOGGING)
411 // For logging STL based templates
412 # include <list>
413 # include <queue>
414 # include <deque>
415 # include <set>
416 # include <bitset>
417 # include <stack>
418 # if defined(ELPP_LOG_STD_ARRAY)
419 # include <array>
420 # endif // defined(ELPP_LOG_STD_ARRAY)
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;
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 typedef unsigned int EnumType;
535 typedef unsigned short VerboseLevel;
536 typedef unsigned long int LineNumber;
537 typedef std::shared_ptr<base::Storage> StoragePointer;
538 typedef std::shared_ptr<LogDispatchCallback> LogDispatchCallbackPtr;
539 typedef std::shared_ptr<PerformanceTrackingCallback> PerformanceTrackingCallbackPtr;
540 typedef std::shared_ptr<LoggerRegistrationCallback> LoggerRegistrationCallbackPtr;
541 typedef std::unique_ptr<el::base::PerformanceTracker> PerformanceTrackerPtr;
542 } // namespace type
546 class NoCopy {
547  protected:
548  NoCopy(void) {}
549  private:
550  NoCopy(const NoCopy&);
551  NoCopy& operator=(const NoCopy&);
552 };
557 class StaticClass {
558  private:
559  StaticClass(void);
560  StaticClass(const StaticClass&);
561  StaticClass& operator=(const StaticClass&);
562 };
563 } // namespace base
570  Global = 1,
572  Trace = 2,
574  Debug = 4,
576  Fatal = 8,
578  Error = 16,
580  Warning = 32,
582  Verbose = 64,
584  Info = 128,
586  Unknown = 1010
587 };
588 } // namespace el
589 namespace std {
590 template<> struct hash<el::Level> {
591  public:
592  std::size_t operator()(const el::Level& l) const {
593  return hash<el::base::type::EnumType> {}(static_cast<el::base::type::EnumType>(l));
594  }
595 };
596 }
597 namespace el {
600  public:
602  static const base::type::EnumType kMinValid = static_cast<base::type::EnumType>(Level::Trace);
604  static const base::type::EnumType kMaxValid = static_cast<base::type::EnumType>(Level::Info);
607  return static_cast<base::type::EnumType>(level);
608  }
611  return static_cast<Level>(l);
612  }
615  static const char* convertToString(Level level);
619  static Level convertFromString(const char* levelStr);
624  static void forEachLevel(base::type::EnumType* startIndex, const std::function<bool(void)>& fn);
625 };
631  Enabled = 1,
633  ToFile = 2,
636  ToStandardOutput = 4,
638  Format = 8,
640  Filename = 16,
642  SubsecondPrecision = 32,
648  PerformanceTracking = 64,
653  MaxLogFileSize = 128,
655  LogFlushThreshold = 256,
657  Unknown = 1010
658 };
661  public:
668  return static_cast<base::type::EnumType>(configurationType);
669  }
672  return static_cast<ConfigurationType>(c);
673  }
676  static const char* convertToString(ConfigurationType configurationType);
680  static ConfigurationType convertFromString(const char* configStr);
686  static inline void forEachConfigType(base::type::EnumType* startIndex, const std::function<bool(void)>& fn);
687 };
700  ImmediateFlush = 16,
706  MultiLoggerSupport = 128,
710  DisableVModules = 512,
714  HierarchicalLogging = 2048,
718  AutoSpacing = 8192,
720  FixedTimeFormat = 16384,
721  // @brief Ignore SIGINT or crash
722  IgnoreSigInt = 32768,
723 };
724 namespace base {
726 namespace consts {
727 static const char kFormatSpecifierCharValue = 'v';
728 static const char kFormatSpecifierChar = '%';
729 static const unsigned int kMaxLogPerCounter = 100000;
730 static const unsigned int kMaxLogPerContainer = 100;
731 static const unsigned int kDefaultSubsecondPrecision = 3;
732 
733 #ifdef ELPP_DEFAULT_LOGGER
734 static const char* kDefaultLoggerId = ELPP_DEFAULT_LOGGER;
735 #else
736 static const char* kDefaultLoggerId = "default";
737 #endif
738 
739 #ifdef ELPP_DEFAULT_PERFORMANCE_LOGGER
740 static const char* kPerformanceLoggerId = ELPP_DEFAULT_PERFORMANCE_LOGGER;
741 #else
742 static const char* kPerformanceLoggerId = "performance";
743 #endif
744 
745 #if defined(ELPP_SYSLOG)
746 static const char* kSysLogLoggerId = "syslog";
747 #endif // defined(ELPP_SYSLOG)
748 
749 #if ELPP_OS_WINDOWS
750 static const char* kFilePathSeperator = "\\";
751 #else
752 static const char* kFilePathSeperator = "/";
753 #endif // ELPP_OS_WINDOWS
754 
755 static const std::size_t kSourceFilenameMaxLength = 100;
756 static const std::size_t kSourceLineMaxLength = 10;
758 const struct {
759  double value;
761 } kTimeFormats[] = {
762  { 1000.0f, ELPP_LITERAL("us") },
763  { 1000.0f, ELPP_LITERAL("ms") },
764  { 60.0f, ELPP_LITERAL("seconds") },
765  { 60.0f, ELPP_LITERAL("minutes") },
766  { 24.0f, ELPP_LITERAL("hours") },
767  { 7.0f, ELPP_LITERAL("days") }
768 };
769 static const int kTimeFormatsCount = sizeof(kTimeFormats) / sizeof(kTimeFormats[0]);
770 const struct {
771  int numb;
772  const char* name;
773  const char* brief;
774  const char* detail;
775 } kCrashSignals[] = {
776  // NOTE: Do not re-order, if you do please check CrashHandler(bool) constructor and CrashHandler::setHandler(..)
777  {
778  SIGABRT, "SIGABRT", "Abnormal termination",
779  "Program was abnormally terminated."
780  },
781  {
782  SIGFPE, "SIGFPE", "Erroneous arithmetic operation",
783  "Arithemetic operation issue such as division by zero or operation resulting in overflow."
784  },
785  {
786  SIGILL, "SIGILL", "Illegal instruction",
787  "Generally due to a corruption in the code or to an attempt to execute data."
788  },
789  {
790  SIGSEGV, "SIGSEGV", "Invalid access to memory",
791  "Program is trying to read an invalid (unallocated, deleted or corrupted) or inaccessible memory."
792  },
793  {
794  SIGINT, "SIGINT", "Interactive attention signal",
795  "Interruption generated (generally) by user or operating system."
796  },
797 };
798 static const int kCrashSignalsCount = sizeof(kCrashSignals) / sizeof(kCrashSignals[0]);
799 } // namespace consts
800 } // namespace base
801 typedef std::function<void(const char*, std::size_t)> PreRollOutCallback;
802 namespace base {
803 static inline void defaultPreRollOutCallback(const char*, std::size_t) {}
806  Microsecond = 0, Millisecond = 1, Second = 2, Minute = 3, Hour = 4, Day = 5
807 };
810  DateTime = 1 << 1,
811  LoggerId = 1 << 2,
812  File = 1 << 3,
813  Line = 1 << 4,
814  Location = 1 << 5,
815  Function = 1 << 6,
816  User = 1 << 7,
817  Host = 1 << 8,
818  LogMessage = 1 << 9,
819  VerboseLevel = 1 << 10,
820  AppName = 1 << 11,
821  ThreadId = 1 << 12,
822  Level = 1 << 13,
823  FileBase = 1 << 14,
824  LevelShort = 1 << 15
825 };
828  public:
831  }
832  explicit SubsecondPrecision(int width) {
833  init(width);
834  }
835  bool operator==(const SubsecondPrecision& ssPrec) {
836  return m_width == ssPrec.m_width && m_offset == ssPrec.m_offset;
837  }
838  int m_width;
839  unsigned int m_offset;
840  private:
841  void init(int width);
842 };
846 namespace utils {
848 template <typename T>
849 static
852  if (pointer == nullptr)
853  return;
854  delete pointer;
855  pointer = nullptr;
856 }
859 namespace bitwise {
860 template <typename Enum>
861 static inline base::type::EnumType And(Enum e, base::type::EnumType flag) {
862  return static_cast<base::type::EnumType>(flag) & static_cast<base::type::EnumType>(e);
863 }
864 template <typename Enum>
865 static inline base::type::EnumType Not(Enum e, base::type::EnumType flag) {
866  return static_cast<base::type::EnumType>(flag) & ~(static_cast<base::type::EnumType>(e));
867 }
868 template <typename Enum>
869 static inline base::type::EnumType Or(Enum e, base::type::EnumType flag) {
870  return static_cast<base::type::EnumType>(flag) | static_cast<base::type::EnumType>(e);
871 }
872 } // namespace bitwise
873 template <typename Enum>
874 static inline void addFlag(Enum e, base::type::EnumType* flag) {
875  *flag = base::utils::bitwise::Or<Enum>(e, *flag);
876 }
877 template <typename Enum>
878 static inline void removeFlag(Enum e, base::type::EnumType* flag) {
879  *flag = base::utils::bitwise::Not<Enum>(e, *flag);
880 }
881 template <typename Enum>
882 static inline bool hasFlag(Enum e, base::type::EnumType flag) {
883  return base::utils::bitwise::And<Enum>(e, flag) > 0x0;
884 }
885 } // namespace utils
886 namespace threading {
887 #if ELPP_THREADING_ENABLED
888 # if !ELPP_USE_STD_THREADING
889 namespace internal {
891 class Mutex : base::NoCopy {
892  public:
893  Mutex(void) {
894 # if ELPP_OS_UNIX
895  pthread_mutexattr_t attr;
896  pthread_mutexattr_init(&attr);
897  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
898  pthread_mutex_init(&m_underlyingMutex, &attr);
899  pthread_mutexattr_destroy(&attr);
900 # elif ELPP_OS_WINDOWS
901  InitializeCriticalSection(&m_underlyingMutex);
902 # endif // ELPP_OS_UNIX
903  }
904 
905  virtual ~Mutex(void) {
906 # if ELPP_OS_UNIX
907  pthread_mutex_destroy(&m_underlyingMutex);
908 # elif ELPP_OS_WINDOWS
909  DeleteCriticalSection(&m_underlyingMutex);
910 # endif // ELPP_OS_UNIX
911  }
912 
913  inline void lock(void) {
914 # if ELPP_OS_UNIX
915  pthread_mutex_lock(&m_underlyingMutex);
916 # elif ELPP_OS_WINDOWS
917  EnterCriticalSection(&m_underlyingMutex);
918 # endif // ELPP_OS_UNIX
919  }
920 
921  inline bool try_lock(void) {
922 # if ELPP_OS_UNIX
923  return (pthread_mutex_trylock(&m_underlyingMutex) == 0);
924 # elif ELPP_OS_WINDOWS
925  return TryEnterCriticalSection(&m_underlyingMutex);
926 # endif // ELPP_OS_UNIX
927  }
928 
929  inline void unlock(void) {
930 # if ELPP_OS_UNIX
931  pthread_mutex_unlock(&m_underlyingMutex);
932 # elif ELPP_OS_WINDOWS
933  LeaveCriticalSection(&m_underlyingMutex);
934 # endif // ELPP_OS_UNIX
935  }
936 
937  private:
938 # if ELPP_OS_UNIX
939  pthread_mutex_t m_underlyingMutex;
940 # elif ELPP_OS_WINDOWS
941  CRITICAL_SECTION m_underlyingMutex;
942 # endif // ELPP_OS_UNIX
943 };
945 template <typename M>
946 class ScopedLock : base::NoCopy {
947  public:
948  explicit ScopedLock(M& mutex) {
949  m_mutex = &mutex;
950  m_mutex->lock();
951  }
952 
953  virtual ~ScopedLock(void) {
954  m_mutex->unlock();
955  }
956  private:
957  M* m_mutex;
958  ScopedLock(void);
959 };
960 } // namespace internal
962 typedef base::threading::internal::ScopedLock<base::threading::Mutex> ScopedLock;
963 # else
964 typedef std::recursive_mutex Mutex;
965 typedef std::lock_guard<base::threading::Mutex> ScopedLock;
966 # endif // !ELPP_USE_STD_THREADING
967 #else
968 namespace internal {
971  public:
972  NoMutex(void) {}
973  inline void lock(void) {}
974  inline bool try_lock(void) {
975  return true;
976  }
977  inline void unlock(void) {}
978 };
980 template <typename Mutex>
982  public:
983  explicit NoScopedLock(Mutex&) {
984  }
985  virtual ~NoScopedLock(void) {
986  }
987  private:
988  NoScopedLock(void);
989 };
990 } // namespace internal
993 #endif // ELPP_THREADING_ENABLED
994 class ThreadSafe {
996  public:
997  virtual inline void acquireLock(void) ELPP_FINAL { m_mutex.lock(); }
998  virtual inline void releaseLock(void) ELPP_FINAL { m_mutex.unlock(); }
999  virtual inline base::threading::Mutex& lock(void) ELPP_FINAL { return m_mutex; }
1000  protected:
1001  ThreadSafe(void) {}
1002  virtual ~ThreadSafe(void) {}
1003  private:
1005 };
1006 
1007 #if ELPP_THREADING_ENABLED
1008 # if !ELPP_USE_STD_THREADING
1009 static std::string getCurrentThreadId(void) {
1011  std::stringstream ss;
1012 # if (ELPP_OS_WINDOWS)
1013  ss << GetCurrentThreadId();
1014 # endif // (ELPP_OS_WINDOWS)
1015  return ss.str();
1016 }
1017 # else
1018 static std::string getCurrentThreadId(void) {
1020  std::stringstream ss;
1021  ss << std::this_thread::get_id();
1022  return ss.str();
1023 }
1024 # endif // !ELPP_USE_STD_THREADING
1025 #else
1026 static inline std::string getCurrentThreadId(void) {
1027  return std::string();
1028 }
1029 #endif // ELPP_THREADING_ENABLED
1030 } // namespace threading
1031 namespace utils {
1033  public:
1036  static base::type::fstream_t* newFileStream(const std::string& filename);
1037 
1039  static std::size_t getSizeOfFile(base::type::fstream_t* fs);
1040 
1042  static bool pathExists(const char* path, bool considerFile = false);
1043 
1046  static bool createPath(const std::string& path);
1048  static std::string extractPathFromFilename(const std::string& fullPath,
1049  const char* seperator = base::consts::kFilePathSeperator);
1051  static void buildStrippedFilename(const char* filename, char buff[],
1054  static void buildBaseFilename(const std::string& fullPath, char buff[],
1056  const char* seperator = base::consts::kFilePathSeperator);
1057 };
1060  public:
1062  static inline bool isDigit(char c) {
1063  return c >= '0' && c <= '9';
1064  }
1065 
1067  static bool wildCardMatch(const char* str, const char* pattern);
1068 
1069  static std::string& ltrim(std::string& str);
1070  static std::string& rtrim(std::string& str);
1071  static std::string& trim(std::string& str);
1072 
1077  static bool startsWith(const std::string& str, const std::string& start);
1078 
1083  static bool endsWith(const std::string& str, const std::string& end);
1084 
1090  static std::string& replaceAll(std::string& str, char replaceWhat, char replaceWith);
1091 
1097  static std::string& replaceAll(std::string& str, const std::string& replaceWhat,
1098  const std::string& replaceWith);
1099 
1100  static void replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat,
1101  const base::type::string_t& replaceWith);
1102 #if defined(ELPP_UNICODE)
1103  static void replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat,
1104  const std::string& replaceWith);
1105 #endif // defined(ELPP_UNICODE)
1106  static std::string& toUpper(std::string& str);
1110 
1112  static bool cStringEq(const char* s1, const char* s2);
1113 
1116  static bool cStringCaseEq(const char* s1, const char* s2);
1117 
1119  static bool contains(const char* str, char c);
1120 
1121  static char* convertAndAddToBuff(std::size_t n, int len, char* buf, const char* bufLim, bool zeroPadded = true);
1122  static char* addToBuff(const char* str, char* buf, const char* bufLim);
1123  static char* clearBuff(char buff[], std::size_t lim);
1124 
1127  static char* wcharPtrToCharPtr(const wchar_t* line);
1128 };
1131  public:
1132 #if ELPP_OS_WINDOWS
1133  static const char* getWindowsEnvironmentVariable(const char* varname);
1138 #endif // ELPP_OS_WINDOWS
1139 #if ELPP_OS_ANDROID
1140  static std::string getProperty(const char* prop);
1142 
1144  static std::string getDeviceName(void);
1145 #endif // ELPP_OS_ANDROID
1146 
1152  static const std::string getBashOutput(const char* command);
1153 
1159  static std::string getEnvironmentVariable(const char* variableName, const char* defaultVal,
1160  const char* alternativeBashCommand = nullptr);
1162  static std::string currentUser(void);
1163 
1167  static std::string currentHost(void);
1169  static bool termSupportsColor(void);
1170 };
1173  public:
1178  static void gettimeofday(struct timeval* tv);
1179 
1184  static std::string getDateTime(const char* format, const base::SubsecondPrecision* ssPrec);
1185 
1187  static std::string timevalToString(struct timeval tval, const char* format,
1188  const el::base::SubsecondPrecision* ssPrec);
1189 
1191  static base::type::string_t formatTime(unsigned long long time, base::TimestampUnit timestampUnit);
1192 
1194  static unsigned long long getTimeDifference(const struct timeval& endTime, const struct timeval& startTime,
1195  base::TimestampUnit timestampUnit);
1196 
1197 
1198  static struct ::tm* buildTimeInfo(struct timeval* currTime, struct ::tm* timeInfo);
1199  private:
1200  static char* parseFormat(char* buf, std::size_t bufSz, const char* format, const struct tm* tInfo,
1201  std::size_t msec, const base::SubsecondPrecision* ssPrec);
1202 };
1205  public:
1207  setArgs(0, static_cast<char**>(nullptr));
1208  }
1209  CommandLineArgs(int argc, const char** argv) {
1210  setArgs(argc, argv);
1211  }
1212  CommandLineArgs(int argc, char** argv) {
1213  setArgs(argc, argv);
1214  }
1215  virtual ~CommandLineArgs(void) {}
1217  inline void setArgs(int argc, const char** argv) {
1218  setArgs(argc, const_cast<char**>(argv));
1219  }
1221  void setArgs(int argc, char** argv);
1223  bool hasParamWithValue(const char* paramKey) const;
1226  const char* getParamValue(const char* paramKey) const;
1228  bool hasParam(const char* paramKey) const;
1230  bool empty(void) const;
1232  std::size_t size(void) const;
1234 
1235  private:
1236  int m_argc;
1237  char** m_argv;
1238  std::unordered_map<std::string, std::string> m_paramsWithValue;
1239  std::vector<std::string> m_params;
1240 };
1247 template <typename T_Ptr, typename Container>
1249  public:
1250  typedef typename Container::iterator iterator;
1251  typedef typename Container::const_iterator const_iterator;
1252 
1255 
1258  if (this == &sr) {
1259  return;
1260  }
1261  unregisterAll();
1262  m_list = std::move(sr.m_list);
1263  }
1264 
1266  if (size() != other.size()) {
1267  return false;
1268  }
1269  for (std::size_t i = 0; i < m_list.size(); ++i) {
1270  if (m_list.at(i) != other.m_list.at(i)) {
1271  return false;
1272  }
1273  }
1274  return true;
1275  }
1276 
1278  if (size() != other.size()) {
1279  return true;
1280  }
1281  for (std::size_t i = 0; i < m_list.size(); ++i) {
1282  if (m_list.at(i) != other.m_list.at(i)) {
1283  return true;
1284  }
1285  }
1286  return false;
1287  }
1288 
1291  if (this == &sr) {
1292  return *this;
1293  }
1294  unregisterAll();
1295  m_list = std::move(sr.m_list);
1296  return *this;
1297  }
1298 
1299  virtual ~AbstractRegistry(void) {
1300  }
1301 
1303  virtual inline iterator begin(void) ELPP_FINAL {
1304  return m_list.begin();
1305  }
1306 
1308  virtual inline iterator end(void) ELPP_FINAL {
1309  return m_list.end();
1310  }
1311 
1312 
1314  virtual inline const_iterator cbegin(void) const ELPP_FINAL {
1315  return m_list.cbegin();
1316  }
1317 
1319  virtual inline const_iterator cend(void) const ELPP_FINAL {
1320  return m_list.cend();
1321  }
1322 
1324  virtual inline bool empty(void) const ELPP_FINAL {
1325  return m_list.empty();
1326  }
1327 
1329  virtual inline std::size_t size(void) const ELPP_FINAL {
1330  return m_list.size();
1331  }
1332 
1334  virtual inline Container& list(void) ELPP_FINAL {
1335  return m_list;
1336  }
1337 
1339  virtual inline const Container& list(void) const ELPP_FINAL {
1340  return m_list;
1341  }
1342 
1344  virtual void unregisterAll(void) = 0;
1345 
1346  protected:
1347  virtual void deepCopy(const AbstractRegistry<T_Ptr, Container>&) = 0;
1349  unregisterAll();
1350  deepCopy(sr);
1351  }
1352 
1353  private:
1354  Container m_list;
1355 };
1356 
1362 template <typename T_Ptr, typename T_Key = const char*>
1363 class Registry : public AbstractRegistry<T_Ptr, std::unordered_map<T_Key, T_Ptr*>> {
1364  public:
1367 
1368  Registry(void) {}
1369 
1371  Registry(const Registry& sr) : AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>() {
1372  if (this == &sr) {
1373  return;
1374  }
1375  this->reinitDeepCopy(sr);
1376  }
1377 
1382  if (this == &sr) {
1383  return *this;
1384  }
1385  this->reinitDeepCopy(sr);
1386  return *this;
1387  }
1388 
1389  virtual ~Registry(void) {
1390  unregisterAll();
1391  }
1392 
1393  protected:
1394  virtual void unregisterAll(void) ELPP_FINAL {
1395  if (!this->empty()) {
1396  for (auto&& curr : this->list()) {
1397  base::utils::safeDelete(curr.second);
1398  }
1399  this->list().clear();
1400  }
1401  }
1402 
1404  virtual void registerNew(const T_Key& uniqKey, T_Ptr* ptr) ELPP_FINAL {
1405  unregister(uniqKey);
1406  this->list().insert(std::make_pair(uniqKey, ptr));
1407  }
1408 
1410  void unregister(const T_Key& uniqKey) {
1411  T_Ptr* existing = get(uniqKey);
1412  if (existing != nullptr) {
1413  this->list().erase(uniqKey);
1414  base::utils::safeDelete(existing);
1415  }
1416  }
1417 
1419  T_Ptr* get(const T_Key& uniqKey) {
1420  iterator it = this->list().find(uniqKey);
1421  return it == this->list().end()
1422  ? nullptr
1423  : it->second;
1424  }
1425 
1426  private:
1427  virtual void deepCopy(const AbstractRegistry<T_Ptr, std::unordered_map<T_Key, T_Ptr*>>& sr) ELPP_FINAL {
1428  for (const_iterator it = sr.cbegin(); it != sr.cend(); ++it) {
1429  registerNew(it->first, new T_Ptr(*it->second));
1430  }
1431  }
1432 };
1433 
1438 template <typename T_Ptr, typename Pred>
1439 class RegistryWithPred : public AbstractRegistry<T_Ptr, std::vector<T_Ptr*>> {
1440  public:
1443 
1445  }
1446 
1447  virtual ~RegistryWithPred(void) {
1448  unregisterAll();
1449  }
1450 
1452  RegistryWithPred(const RegistryWithPred& sr) : AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>() {
1453  if (this == &sr) {
1454  return;
1455  }
1456  this->reinitDeepCopy(sr);
1457  }
1458 
1463  if (this == &sr) {
1464  return *this;
1465  }
1466  this->reinitDeepCopy(sr);
1467  return *this;
1468  }
1469 
1471  for (const_iterator it = sr.list().begin(); it != sr.list().end(); ++it) {
1472  os << ELPP_LITERAL(" ") << **it << ELPP_LITERAL("\n");
1473  }
1474  return os;
1475  }
1476 
1477  protected:
1478  virtual void unregisterAll(void) ELPP_FINAL {
1479  if (!this->empty()) {
1480  for (auto&& curr : this->list()) {
1482  }
1483  this->list().clear();
1484  }
1485  }
1486 
1487  virtual void unregister(T_Ptr*& ptr) ELPP_FINAL {
1488  if (ptr) {
1489  iterator iter = this->begin();
1490  for (; iter != this->end(); ++iter) {
1491  if (ptr == *iter) {
1492  break;
1493  }
1494  }
1495  if (iter != this->end() && *iter != nullptr) {
1496  this->list().erase(iter);
1497  base::utils::safeDelete(*iter);
1498  }
1499  }
1500  }
1501 
1502  virtual inline void registerNew(T_Ptr* ptr) ELPP_FINAL {
1503  this->list().push_back(ptr);
1504  }
1505 
1508  template <typename T, typename T2>
1509  T_Ptr* get(const T& arg1, const T2 arg2) {
1510  iterator iter = std::find_if(this->list().begin(), this->list().end(), Pred(arg1, arg2));
1511  if (iter != this->list().end() && *iter != nullptr) {
1512  return *iter;
1513  }
1514  return nullptr;
1515  }
1516 
1517  private:
1518  virtual void deepCopy(const AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>& sr) {
1519  for (const_iterator it = sr.list().begin(); it != sr.list().end(); ++it) {
1520  registerNew(new T_Ptr(**it));
1521  }
1522  }
1523 };
1524 class Utils {
1525  public:
1526  template <typename T, typename TPtr>
1527  static bool installCallback(const std::string& id, std::unordered_map<std::string, TPtr>* mapT) {
1528  if (mapT->find(id) == mapT->end()) {
1529  mapT->insert(std::make_pair(id, TPtr(new T())));
1530  return true;
1531  }
1532  return false;
1533  }
1534 
1535  template <typename T, typename TPtr>
1536  static void uninstallCallback(const std::string& id, std::unordered_map<std::string, TPtr>* mapT) {
1537  if (mapT->find(id) != mapT->end()) {
1538  mapT->erase(id);
1539  }
1540  }
1541 
1542  template <typename T, typename TPtr>
1543  static T* callback(const std::string& id, std::unordered_map<std::string, TPtr>* mapT) {
1544  typename std::unordered_map<std::string, TPtr>::iterator iter = mapT->find(id);
1545  if (iter != mapT->end()) {
1546  return static_cast<T*>(iter->second.get());
1547  }
1548  return nullptr;
1549  }
1550 };
1551 } // namespace utils
1552 } // namespace base
1556 class Loggable {
1557  public:
1558  virtual ~Loggable(void) {}
1559  virtual void log(el::base::type::ostream_t&) const = 0;
1560  private:
1562  loggable.log(os);
1563  return os;
1564  }
1565 };
1566 namespace base {
1568 class LogFormat : public Loggable {
1569  public:
1570  LogFormat(void);
1572  LogFormat(const LogFormat& logFormat);
1573  LogFormat(LogFormat&& logFormat);
1574  LogFormat& operator=(const LogFormat& logFormat);
1575  virtual ~LogFormat(void) {}
1576  bool operator==(const LogFormat& other);
1577 
1580  void parseFromFormat(const base::type::string_t& userFormat);
1581 
1582  inline Level level(void) const {
1583  return m_level;
1584  }
1585 
1586  inline const base::type::string_t& userFormat(void) const {
1587  return m_userFormat;
1588  }
1589 
1590  inline const base::type::string_t& format(void) const {
1591  return m_format;
1592  }
1593 
1594  inline const std::string& dateTimeFormat(void) const {
1595  return m_dateTimeFormat;
1596  }
1597 
1598  inline base::type::EnumType flags(void) const {
1599  return m_flags;
1600  }
1601 
1602  inline bool hasFlag(base::FormatFlags flag) const {
1603  return base::utils::hasFlag(flag, m_flags);
1604  }
1605 
1606  virtual void log(el::base::type::ostream_t& os) const {
1607  os << m_format;
1608  }
1609 
1610  protected:
1614  virtual void updateDateFormat(std::size_t index, base::type::string_t& currFormat) ELPP_FINAL;
1615 
1617  virtual void updateFormatSpec(void) ELPP_FINAL;
1618 
1619  inline void addFlag(base::FormatFlags flag) {
1620  base::utils::addFlag(flag, &m_flags);
1621  }
1622 
1623  private:
1631  friend class el::Logger; // To resolve loggerId format specifier easily
1632 };
1633 } // namespace base
1635 typedef std::function<std::string(const LogMessage*)> FormatSpecifierValueResolver;
1640  public:
1641  CustomFormatSpecifier(const char* formatSpecifier, const FormatSpecifierValueResolver& resolver) :
1642  m_formatSpecifier(formatSpecifier), m_resolver(resolver) {}
1643  inline const char* formatSpecifier(void) const {
1644  return m_formatSpecifier;
1645  }
1646  inline const FormatSpecifierValueResolver& resolver(void) const {
1647  return m_resolver;
1648  }
1649  inline bool operator==(const char* formatSpecifier) {
1650  return strcmp(m_formatSpecifier, formatSpecifier) == 0;
1651  }
1652 
1653  private:
1654  const char* m_formatSpecifier;
1655  FormatSpecifierValueResolver m_resolver;
1656 };
1666 class Configuration : public Loggable {
1667  public:
1668  Configuration(const Configuration& c);
1669  Configuration& operator=(const Configuration& c);
1670 
1671  virtual ~Configuration(void) {
1672  }
1673 
1675  Configuration(Level level, ConfigurationType configurationType, const std::string& value);
1676 
1678  inline Level level(void) const {
1679  return m_level;
1680  }
1681 
1684  return m_configurationType;
1685  }
1686 
1688  inline const std::string& value(void) const {
1689  return m_value;
1690  }
1691 
1695  inline void setValue(const std::string& value) {
1696  m_value = value;
1697  }
1698 
1699  virtual void log(el::base::type::ostream_t& os) const;
1700 
1702  class Predicate {
1703  public:
1704  Predicate(Level level, ConfigurationType configurationType);
1705 
1706  bool operator()(const Configuration* conf) const;
1707 
1708  private:
1711  };
1712 
1713  private:
1717 };
1718 
1722 class Configurations : public base::utils::RegistryWithPred<Configuration, Configuration::Predicate> {
1723  public:
1725  Configurations(void);
1726 
1733  Configurations(const std::string& configurationFile, bool useDefaultsForRemaining = true,
1734  Configurations* base = nullptr);
1735 
1736  virtual ~Configurations(void) {
1737  }
1738 
1745  bool parseFromFile(const std::string& configurationFile, Configurations* base = nullptr);
1746 
1755  bool parseFromText(const std::string& configurationsString, Configurations* base = nullptr);
1756 
1759  void setFromBase(Configurations* base);
1760 
1765  bool hasConfiguration(ConfigurationType configurationType);
1766 
1770  bool hasConfiguration(Level level, ConfigurationType configurationType);
1771 
1784  void set(Level level, ConfigurationType configurationType, const std::string& value);
1785 
1788  void set(Configuration* conf);
1789 
1790  inline Configuration* get(Level level, ConfigurationType configurationType) {
1791  base::threading::ScopedLock scopedLock(lock());
1792  return RegistryWithPred<Configuration, Configuration::Predicate>::get(level, configurationType);
1793  }
1794 
1799  inline void setGlobally(ConfigurationType configurationType, const std::string& value) {
1800  setGlobally(configurationType, value, false);
1801  }
1802 
1804  inline void clear(void) {
1805  base::threading::ScopedLock scopedLock(lock());
1806  unregisterAll();
1807  }
1808 
1812  inline const std::string& configurationFile(void) const {
1813  return m_configurationFile;
1814  }
1815 
1817  void setToDefault(void);
1818 
1826  void setRemainingToDefault(void);
1827 
1833  public:
1841  static bool parseFromFile(const std::string& configurationFile, Configurations* sender,
1842  Configurations* base = nullptr);
1843 
1854  static bool parseFromText(const std::string& configurationsString, Configurations* sender,
1855  Configurations* base = nullptr);
1856 
1857  private:
1858  friend class el::Loggers;
1859  static void ignoreComments(std::string* line);
1860  static bool isLevel(const std::string& line);
1861  static bool isComment(const std::string& line);
1862  static inline bool isConfig(const std::string& line);
1863  static bool parseLine(std::string* line, std::string* currConfigStr, std::string* currLevelStr, Level* currLevel,
1864  Configurations* conf);
1865  };
1866 
1867  private:
1870  friend class el::Loggers;
1871 
1873  void unsafeSetIfNotExist(Level level, ConfigurationType configurationType, const std::string& value);
1874 
1876  void unsafeSet(Level level, ConfigurationType configurationType, const std::string& value);
1877 
1880  void setGlobally(ConfigurationType configurationType, const std::string& value, bool includeGlobalLevel);
1881 
1884  void unsafeSetGlobally(ConfigurationType configurationType, const std::string& value, bool includeGlobalLevel);
1885 };
1886 
1887 namespace base {
1888 typedef std::shared_ptr<base::type::fstream_t> FileStreamPtr;
1889 typedef std::unordered_map<std::string, FileStreamPtr> LogStreamsReferenceMap;
1897  public:
1902 
1904 
1905  virtual ~TypedConfigurations(void) {
1906  }
1907 
1908  const Configurations* configurations(void) const {
1909  return m_configurations;
1910  }
1911 
1912  bool enabled(Level level);
1913  bool toFile(Level level);
1914  const std::string& filename(Level level);
1915  bool toStandardOutput(Level level);
1916  const base::LogFormat& logFormat(Level level);
1917  const base::SubsecondPrecision& subsecondPrecision(Level level = Level::Global);
1918  const base::MillisecondsWidth& millisecondsWidth(Level level = Level::Global);
1919  bool performanceTracking(Level level = Level::Global);
1920  base::type::fstream_t* fileStream(Level level);
1921  std::size_t maxLogFileSize(Level level);
1922  std::size_t logFlushThreshold(Level level);
1923 
1924  private:
1926  std::unordered_map<Level, bool> m_enabledMap;
1927  std::unordered_map<Level, bool> m_toFileMap;
1928  std::unordered_map<Level, std::string> m_filenameMap;
1929  std::unordered_map<Level, bool> m_toStandardOutputMap;
1930  std::unordered_map<Level, base::LogFormat> m_logFormatMap;
1931  std::unordered_map<Level, base::SubsecondPrecision> m_subsecondPrecisionMap;
1932  std::unordered_map<Level, bool> m_performanceTrackingMap;
1933  std::unordered_map<Level, base::FileStreamPtr> m_fileStreamMap;
1934  std::unordered_map<Level, std::size_t> m_maxLogFileSizeMap;
1935  std::unordered_map<Level, std::size_t> m_logFlushThresholdMap;
1937 
1938  friend class el::Helpers;
1940  friend class el::base::Writer;
1943 
1944  template <typename Conf_T>
1945  inline Conf_T getConfigByVal(Level level, const std::unordered_map<Level, Conf_T>* confMap, const char* confName) {
1946  base::threading::ScopedLock scopedLock(lock());
1947  return unsafeGetConfigByVal(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope
1948  }
1949 
1950  template <typename Conf_T>
1951  inline Conf_T& getConfigByRef(Level level, std::unordered_map<Level, Conf_T>* confMap, const char* confName) {
1952  base::threading::ScopedLock scopedLock(lock());
1953  return unsafeGetConfigByRef(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope
1954  }
1955 
1956  template <typename Conf_T>
1957  Conf_T unsafeGetConfigByVal(Level level, const std::unordered_map<Level, Conf_T>* confMap, const char* confName) {
1958  ELPP_UNUSED(confName);
1959  typename std::unordered_map<Level, Conf_T>::const_iterator it = confMap->find(level);
1960  if (it == confMap->end()) {
1961  try {
1962  return confMap->at(Level::Global);
1963  } catch (...) {
1964  ELPP_INTERNAL_ERROR("Unable to get configuration [" << confName << "] for level ["
1965  << LevelHelper::convertToString(level) << "]"
1966  << std::endl << "Please ensure you have properly configured logger.", false);
1967  return Conf_T();
1968  }
1969  }
1970  return it->second;
1971  }
1972 
1973  template <typename Conf_T>
1974  Conf_T& unsafeGetConfigByRef(Level level, std::unordered_map<Level, Conf_T>* confMap, const char* confName) {
1975  ELPP_UNUSED(confName);
1976  typename std::unordered_map<Level, Conf_T>::iterator it = confMap->find(level);
1977  if (it == confMap->end()) {
1978  try {
1979  return confMap->at(Level::Global);
1980  } catch (...) {
1981  ELPP_INTERNAL_ERROR("Unable to get configuration [" << confName << "] for level ["
1982  << LevelHelper::convertToString(level) << "]"
1983  << std::endl << "Please ensure you have properly configured logger.", false);
1984  }
1985  }
1986  return it->second;
1987  }
1988 
1989  template <typename Conf_T>
1990  void setValue(Level level, const Conf_T& value, std::unordered_map<Level, Conf_T>* confMap,
1991  bool includeGlobalLevel = true) {
1992  // If map is empty and we are allowed to add into generic level (Level::Global), do it!
1993  if (confMap->empty() && includeGlobalLevel) {
1994  confMap->insert(std::make_pair(Level::Global, value));
1995  return;
1996  }
1997  // If same value exist in generic level already, dont add it to explicit level
1998  typename std::unordered_map<Level, Conf_T>::iterator it = confMap->find(Level::Global);
1999  if (it != confMap->end() && it->second == value) {
2000  return;
2001  }
2002  // Now make sure we dont double up values if we really need to add it to explicit level
2003  it = confMap->find(level);
2004  if (it == confMap->end()) {
2005  // Value not found for level, add new
2006  confMap->insert(std::make_pair(level, value));
2007  } else {
2008  // Value found, just update value
2009  confMap->at(level) = value;
2010  }
2011  }
2012 
2013  void build(Configurations* configurations);
2014  unsigned long getULong(std::string confVal);
2015  std::string resolveFilename(const std::string& filename);
2016  void insertFile(Level level, const std::string& fullFilename);
2017  bool unsafeValidateFileRolling(Level level, const PreRollOutCallback& preRollOutCallback);
2018 
2019  inline bool validateFileRolling(Level level, const PreRollOutCallback& preRollOutCallback) {
2020  base::threading::ScopedLock scopedLock(lock());
2021  return unsafeValidateFileRolling(level, preRollOutCallback);
2022  }
2023 };
2025 class HitCounter {
2026  public:
2027  HitCounter(void) :
2028  m_filename(""),
2029  m_lineNumber(0),
2030  m_hitCounts(0) {
2031  }
2032 
2033  HitCounter(const char* filename, base::type::LineNumber lineNumber) :
2034  m_filename(filename),
2035  m_lineNumber(lineNumber),
2036  m_hitCounts(0) {
2037  }
2038 
2039  HitCounter(const HitCounter& hitCounter) :
2040  m_filename(hitCounter.m_filename),
2041  m_lineNumber(hitCounter.m_lineNumber),
2042  m_hitCounts(hitCounter.m_hitCounts) {
2043  }
2044 
2045  HitCounter& operator=(const HitCounter& hitCounter) {
2046  if (&hitCounter != this) {
2047  m_filename = hitCounter.m_filename;
2048  m_lineNumber = hitCounter.m_lineNumber;
2049  m_hitCounts = hitCounter.m_hitCounts;
2050  }
2051  return *this;
2052  }
2053 
2054  virtual ~HitCounter(void) {
2055  }
2056 
2058  inline void resetLocation(const char* filename, base::type::LineNumber lineNumber) {
2059  m_filename = filename;
2060  m_lineNumber = lineNumber;
2061  }
2062 
2064  inline void validateHitCounts(std::size_t n) {
2065  if (m_hitCounts >= base::consts::kMaxLogPerCounter) {
2066  m_hitCounts = (n >= 1 ? base::consts::kMaxLogPerCounter % n : 0);
2067  }
2068  ++m_hitCounts;
2069  }
2070 
2071  inline const char* filename(void) const {
2072  return m_filename;
2073  }
2074 
2075  inline base::type::LineNumber lineNumber(void) const {
2076  return m_lineNumber;
2077  }
2078 
2079  inline std::size_t hitCounts(void) const {
2080  return m_hitCounts;
2081  }
2082 
2083  inline void increment(void) {
2084  ++m_hitCounts;
2085  }
2086 
2087  class Predicate {
2088  public:
2089  Predicate(const char* filename, base::type::LineNumber lineNumber)
2090  : m_filename(filename),
2091  m_lineNumber(lineNumber) {
2092  }
2093  inline bool operator()(const HitCounter* counter) {
2094  return ((counter != nullptr) &&
2095  (strcmp(counter->m_filename, m_filename) == 0) &&
2096  (counter->m_lineNumber == m_lineNumber));
2097  }
2098 
2099  private:
2100  const char* m_filename;
2102  };
2103 
2104  private:
2105  const char* m_filename;
2107  std::size_t m_hitCounts;
2108 };
2110 class RegisteredHitCounters : public base::utils::RegistryWithPred<base::HitCounter, base::HitCounter::Predicate> {
2111  public:
2114  bool validateEveryN(const char* filename, base::type::LineNumber lineNumber, std::size_t n);
2115 
2118  bool validateAfterN(const char* filename, base::type::LineNumber lineNumber, std::size_t n);
2119 
2122  bool validateNTimes(const char* filename, base::type::LineNumber lineNumber, std::size_t n);
2123 
2125  inline const base::HitCounter* getCounter(const char* filename, base::type::LineNumber lineNumber) {
2126  base::threading::ScopedLock scopedLock(lock());
2127  return get(filename, lineNumber);
2128  }
2129 };
2132  None = 1, NormalLog = 2, SysLog = 4
2133 };
2134 } // namespace base
2135 template <typename T>
2136 class Callback : protected base::threading::ThreadSafe {
2137  public:
2138  Callback(void) : m_enabled(true) {}
2139  inline bool enabled(void) const {
2140  return m_enabled;
2141  }
2142  inline void setEnabled(bool enabled) {
2143  base::threading::ScopedLock scopedLock(lock());
2144  m_enabled = enabled;
2145  }
2146  protected:
2147  virtual void handle(const T* handlePtr) = 0;
2148  private:
2150 };
2152  public:
2153  LogDispatchData() : m_logMessage(nullptr), m_dispatchAction(base::DispatchAction::None) {}
2154  inline const LogMessage* logMessage(void) const {
2155  return m_logMessage;
2156  }
2158  return m_dispatchAction;
2159  }
2160  inline void setLogMessage(LogMessage* logMessage) {
2161  m_logMessage = logMessage;
2162  }
2163  inline void setDispatchAction(base::DispatchAction dispatchAction) {
2164  m_dispatchAction = dispatchAction;
2165  }
2166  private:
2169  friend class base::LogDispatcher;
2170 
2171 };
2172 class LogDispatchCallback : public Callback<LogDispatchData> {
2173  protected:
2174  virtual void handle(const LogDispatchData* data);
2175  base::threading::Mutex& fileHandle(const LogDispatchData* data);
2176  private:
2177  friend class base::LogDispatcher;
2178  std::unordered_map<std::string, std::unique_ptr<base::threading::Mutex>> m_fileLocks;
2180 };
2181 class PerformanceTrackingCallback : public Callback<PerformanceTrackingData> {
2182  private:
2183  friend class base::PerformanceTracker;
2184 };
2185 class LoggerRegistrationCallback : public Callback<Logger> {
2186  private:
2188 };
2190  public:
2191  LogBuilder() : m_termSupportsColor(base::utils::OS::termSupportsColor()) {}
2192  virtual ~LogBuilder(void) {
2193  ELPP_INTERNAL_INFO(3, "Destroying log builder...")
2194  }
2195  virtual base::type::string_t build(const LogMessage* logMessage, bool appendNewLine) const = 0;
2196  void convertToColoredOutput(base::type::string_t* logLine, Level level);
2197  private:
2200 };
2201 typedef std::shared_ptr<LogBuilder> LogBuilderPtr;
2206  public:
2207  Logger(const std::string& id, base::LogStreamsReferenceMap* logStreamsReference);
2208  Logger(const std::string& id, const Configurations& configurations, base::LogStreamsReferenceMap* logStreamsReference);
2209  Logger(const Logger& logger);
2210  Logger& operator=(const Logger& logger);
2211 
2212  virtual ~Logger(void) {
2213  base::utils::safeDelete(m_typedConfigurations);
2214  }
2215 
2216  virtual inline void log(el::base::type::ostream_t& os) const {
2217  os << m_id.c_str();
2218  }
2219 
2221  void configure(const Configurations& configurations);
2222 
2224  void reconfigure(void);
2225 
2226  inline const std::string& id(void) const {
2227  return m_id;
2228  }
2229 
2230  inline const std::string& parentApplicationName(void) const {
2231  return m_parentApplicationName;
2232  }
2233 
2234  inline void setParentApplicationName(const std::string& parentApplicationName) {
2235  m_parentApplicationName = parentApplicationName;
2236  }
2237 
2239  return &m_configurations;
2240  }
2241 
2243  return m_typedConfigurations;
2244  }
2245 
2246  static bool isValidId(const std::string& id);
2247 
2249  void flush(void);
2250 
2251  void flush(Level level, base::type::fstream_t* fs);
2252 
2253  inline bool isFlushNeeded(Level level) {
2254  return ++m_unflushedCount.find(level)->second >= m_typedConfigurations->logFlushThreshold(level);
2255  }
2256 
2257  inline LogBuilder* logBuilder(void) const {
2258  return m_logBuilder.get();
2259  }
2260 
2261  inline void setLogBuilder(const LogBuilderPtr& logBuilder) {
2262  m_logBuilder = logBuilder;
2263  }
2264 
2265  inline bool enabled(Level level) const {
2266  return m_typedConfigurations->enabled(level);
2267  }
2268 
2269 #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
2270 # define LOGGER_LEVEL_WRITERS_SIGNATURES(FUNCTION_NAME)\
2271 template <typename T, typename... Args>\
2272 inline void FUNCTION_NAME(const char*, const T&, const Args&...);\
2273 template <typename T>\
2274 inline void FUNCTION_NAME(const T&);
2275 
2276  template <typename T, typename... Args>
2277  inline void verbose(int, const char*, const T&, const Args&...);
2278 
2279  template <typename T>
2280  inline void verbose(int, const T&);
2281 
2282  LOGGER_LEVEL_WRITERS_SIGNATURES(info)
2283  LOGGER_LEVEL_WRITERS_SIGNATURES(debug)
2284  LOGGER_LEVEL_WRITERS_SIGNATURES(warn)
2285  LOGGER_LEVEL_WRITERS_SIGNATURES(error)
2286  LOGGER_LEVEL_WRITERS_SIGNATURES(fatal)
2287  LOGGER_LEVEL_WRITERS_SIGNATURES(trace)
2288 # undef LOGGER_LEVEL_WRITERS_SIGNATURES
2289 #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
2290  private:
2291  void performConfig(const Configurations& configurations);
2292 
2299  std::unordered_map<Level, unsigned int> m_unflushedCount;
2301  LogBuilderPtr m_logBuilder;
2302 
2303  friend class el::LogMessage;
2304  friend class el::Loggers;
2305  friend class el::Helpers;
2309  friend class el::base::Writer;
2311  friend class el::base::Storage;
2312  friend class el::base::PerformanceTracker;
2314 
2315  Logger(void);
2316 
2317 #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
2318  template <typename T, typename... Args>
2319  void log_(Level, int, const char*, const T&, const Args&...);
2320 
2321  template <typename T>
2322  inline void log_(Level, int, const T&);
2323 
2324  template <typename T, typename... Args>
2325  void log(Level, const char*, const T&, const Args&...);
2326 
2327  template <typename T>
2328  inline void log(Level, const T&);
2329 #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
2330 
2331  void initUnflushedCount(void);
2332 
2334  return m_stream;
2335  }
2336 
2337  void resolveLoggerFormatSpec(void) const;
2338 };
2339 namespace base {
2341 class RegisteredLoggers : public base::utils::Registry<Logger, std::string> {
2342  public:
2343  explicit RegisteredLoggers(const LogBuilderPtr& defaultLogBuilder);
2344 
2345  virtual ~RegisteredLoggers(void) {
2346  unsafeFlushAll();
2347  }
2348 
2350  base::threading::ScopedLock scopedLock(lock());
2351  m_defaultConfigurations.setFromBase(const_cast<Configurations*>(&configurations));
2352  }
2353 
2355  return &m_defaultConfigurations;
2356  }
2357 
2358  Logger* get(const std::string& id, bool forceCreation = true);
2359 
2360  template <typename T>
2362  return base::utils::Utils::installCallback<T, base::type::LoggerRegistrationCallbackPtr>(id,
2363  &m_loggerRegistrationCallbacks);
2364  }
2365 
2366  template <typename T>
2368  base::utils::Utils::uninstallCallback<T, base::type::LoggerRegistrationCallbackPtr>(id, &m_loggerRegistrationCallbacks);
2369  }
2370 
2371  template <typename T>
2373  return base::utils::Utils::callback<T, base::type::LoggerRegistrationCallbackPtr>(id, &m_loggerRegistrationCallbacks);
2374  }
2375 
2376  bool remove(const std::string& id);
2377 
2378  inline bool has(const std::string& id) {
2379  return get(id, false) != nullptr;
2380  }
2381 
2382  inline void unregister(Logger*& logger) {
2383  base::threading::ScopedLock scopedLock(lock());
2385  }
2386 
2388  return &m_logStreamsReference;
2389  }
2390 
2391  inline void flushAll(void) {
2392  base::threading::ScopedLock scopedLock(lock());
2393  unsafeFlushAll();
2394  }
2395 
2396  inline void setDefaultLogBuilder(LogBuilderPtr& logBuilderPtr) {
2397  base::threading::ScopedLock scopedLock(lock());
2398  m_defaultLogBuilder = logBuilderPtr;
2399  }
2400 
2401  private:
2402  LogBuilderPtr m_defaultLogBuilder;
2405  std::unordered_map<std::string, base::type::LoggerRegistrationCallbackPtr> m_loggerRegistrationCallbacks;
2406  friend class el::base::Storage;
2407 
2408  void unsafeFlushAll(void);
2409 };
2412  public:
2414 
2416  void setLevel(base::type::VerboseLevel level);
2417 
2418  inline base::type::VerboseLevel level(void) const {
2419  return m_level;
2420  }
2421 
2422  inline void clearModules(void) {
2423  base::threading::ScopedLock scopedLock(lock());
2424  m_modules.clear();
2425  }
2426 
2427  void setModules(const char* modules);
2428 
2429  bool allowed(base::type::VerboseLevel vlevel, const char* file);
2430 
2431  inline const std::unordered_map<std::string, base::type::VerboseLevel>& modules(void) const {
2432  return m_modules;
2433  }
2434 
2435  void setFromArgs(const base::utils::CommandLineArgs* commandLineArgs);
2436 
2438  inline bool vModulesEnabled(void) {
2440  }
2441 
2442  private:
2445  std::unordered_map<std::string, base::type::VerboseLevel> m_modules;
2446 };
2447 } // namespace base
2448 class LogMessage {
2449  public:
2451  base::type::VerboseLevel verboseLevel, Logger* logger) :
2452  m_level(level), m_file(file), m_line(line), m_func(func),
2453  m_verboseLevel(verboseLevel), m_logger(logger), m_message(logger->stream().str()) {
2454  }
2455  inline Level level(void) const {
2456  return m_level;
2457  }
2458  inline const std::string& file(void) const {
2459  return m_file;
2460  }
2461  inline base::type::LineNumber line(void) const {
2462  return m_line;
2463  }
2464  inline const std::string& func(void) const {
2465  return m_func;
2466  }
2468  return m_verboseLevel;
2469  }
2470  inline Logger* logger(void) const {
2471  return m_logger;
2472  }
2473  inline const base::type::string_t& message(void) const {
2474  return m_message;
2475  }
2476  private:
2484 };
2485 namespace base {
2486 #if ELPP_ASYNC_LOGGING
2487 class AsyncLogItem {
2488  public:
2489  explicit AsyncLogItem(const LogMessage& logMessage, const LogDispatchData& data, const base::type::string_t& logLine)
2490  : m_logMessage(logMessage), m_dispatchData(data), m_logLine(logLine) {}
2491  virtual ~AsyncLogItem() {}
2492  inline LogMessage* logMessage(void) {
2493  return &m_logMessage;
2494  }
2495  inline LogDispatchData* data(void) {
2496  return &m_dispatchData;
2497  }
2498  inline base::type::string_t logLine(void) {
2499  return m_logLine;
2500  }
2501  private:
2502  LogMessage m_logMessage;
2503  LogDispatchData m_dispatchData;
2504  base::type::string_t m_logLine;
2505 };
2506 class AsyncLogQueue : public base::threading::ThreadSafe {
2507  public:
2508  virtual ~AsyncLogQueue() {
2509  ELPP_INTERNAL_INFO(6, "~AsyncLogQueue");
2510  }
2511 
2512  inline AsyncLogItem next(void) {
2513  base::threading::ScopedLock scopedLock(lock());
2514  if (!m_queue.size())
2515  {
2516  throw ("Async Logger queue is empty!");
2517  }
2518  AsyncLogItem result = m_queue.back();
2519  m_queue.pop_back();
2520  return result;
2521  }
2522 
2523  inline void appendTo(AsyncLogQueue* otherQueue) {
2524  base::threading::ScopedLock scopedLock(lock());
2525  if (otherQueue) {
2526  base::threading::ScopedLock scopedLock(otherQueue->lock());
2527  otherQueue->m_queue.insert(otherQueue->m_queue.begin(), m_queue.begin(), m_queue.end());
2528  }
2529  }
2530 
2531  inline void push(const AsyncLogItem& item) {
2532  base::threading::ScopedLock scopedLock(lock());
2533  m_queue.push_front(item);
2534  }
2535  inline void pop(void) {
2536  base::threading::ScopedLock scopedLock(lock());
2537  m_queue.pop_back();
2538  }
2539  inline AsyncLogItem front(void) {
2540  base::threading::ScopedLock scopedLock(lock());
2541  return m_queue.front();
2542  }
2543  inline bool empty(void) {
2544  base::threading::ScopedLock scopedLock(lock());
2545  return m_queue.empty();
2546  }
2547  inline void clear(void) {
2548  base::threading::ScopedLock scopedLock(lock());
2549  m_queue.clear();
2550  }
2551  inline size_t size(void) {
2552  base::threading::ScopedLock scopedLock(lock());
2553  return m_queue.size();
2554  }
2555  private:
2556  std::deque<AsyncLogItem> m_queue;
2557 };
2558 class IWorker {
2559  public:
2560  virtual ~IWorker() {}
2561  virtual void start() = 0;
2562 };
2563 #endif // ELPP_ASYNC_LOGGING
2564 class Storage : base::NoCopy, public base::threading::ThreadSafe {
2566  public:
2567 #if ELPP_ASYNC_LOGGING
2568  Storage(const LogBuilderPtr& defaultLogBuilder, base::IWorker* asyncDispatchWorker);
2569 #else
2570  explicit Storage(const LogBuilderPtr& defaultLogBuilder);
2571 #endif // ELPP_ASYNC_LOGGING
2572 
2573  virtual ~Storage(void);
2574 
2575  inline bool validateEveryNCounter(const char* filename, base::type::LineNumber lineNumber, std::size_t occasion) {
2576  return hitCounters()->validateEveryN(filename, lineNumber, occasion);
2577  }
2578 
2579  inline bool validateAfterNCounter(const char* filename, base::type::LineNumber lineNumber, std::size_t n) {
2580  return hitCounters()->validateAfterN(filename, lineNumber, n);
2581  }
2582 
2583  inline bool validateNTimesCounter(const char* filename, base::type::LineNumber lineNumber, std::size_t n) {
2584  return hitCounters()->validateNTimes(filename, lineNumber, n);
2585  }
2586 
2588  return m_registeredHitCounters;
2589  }
2590 
2592  return m_registeredLoggers;
2593  }
2594 
2595  inline base::VRegistry* vRegistry(void) const {
2596  return m_vRegistry;
2597  }
2598 
2599 #if ELPP_ASYNC_LOGGING
2600  inline base::AsyncLogQueue* asyncLogWriteQueue(void) const {
2601  return m_asyncLogWriteQueue;
2602  }
2603 
2604  inline base::AsyncLogQueue* asyncLogReadQueue(void) const {
2605  return m_asyncLogReadQueue;
2606  }
2607 
2608  inline base::AsyncDispatchWorker* asyncDispatchWorker(void) const {
2609  return reinterpret_cast<el::base::AsyncDispatchWorker*>(m_asyncDispatchWorker);
2610  }
2611 #endif // ELPP_ASYNC_LOGGING
2612 
2613  inline const base::utils::CommandLineArgs* commandLineArgs(void) const {
2614  return &m_commandLineArgs;
2615  }
2616 
2617  inline void addFlag(LoggingFlag flag) {
2618  base::utils::addFlag(flag, &m_flags);
2619  }
2620 
2621  inline void removeFlag(LoggingFlag flag) {
2622  base::utils::removeFlag(flag, &m_flags);
2623  }
2624 
2625  inline bool hasFlag(LoggingFlag flag) const {
2626  return base::utils::hasFlag(flag, m_flags);
2627  }
2628 
2629  inline base::type::EnumType flags(void) const {
2630  return m_flags;
2631  }
2632 
2634  m_flags = flags;
2635  }
2636 
2637  inline void setPreRollOutCallback(const PreRollOutCallback& callback) {
2638  m_preRollOutCallback = callback;
2639  }
2640 
2641  inline void unsetPreRollOutCallback(void) {
2642  m_preRollOutCallback = base::defaultPreRollOutCallback;
2643  }
2644 
2645  inline PreRollOutCallback& preRollOutCallback(void) {
2646  return m_preRollOutCallback;
2647  }
2648 
2649  bool hasCustomFormatSpecifier(const char* formatSpecifier);
2650  void installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier);
2651  bool uninstallCustomFormatSpecifier(const char* formatSpecifier);
2652 
2653  const std::vector<CustomFormatSpecifier>* customFormatSpecifiers(void) const {
2654  return &m_customFormatSpecifiers;
2655  }
2656 
2658  return m_customFormatSpecifiersLock;
2659  }
2660 
2661  inline void setLoggingLevel(Level level) {
2662  m_loggingLevel = level;
2663  }
2664 
2665  template <typename T>
2666  inline bool installLogDispatchCallback(const std::string& id) {
2667  return base::utils::Utils::installCallback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks);
2668  }
2669 
2670  template <typename T>
2672  base::utils::Utils::uninstallCallback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks);
2673  }
2674  template <typename T>
2675  inline T* logDispatchCallback(const std::string& id) {
2676  return base::utils::Utils::callback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks);
2677  }
2678 
2679 #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
2680  template <typename T>
2681  inline bool installPerformanceTrackingCallback(const std::string& id) {
2682  return base::utils::Utils::installCallback<T, base::type::PerformanceTrackingCallbackPtr>(id,
2683  &m_performanceTrackingCallbacks);
2684  }
2685 
2686  template <typename T>
2687  inline void uninstallPerformanceTrackingCallback(const std::string& id) {
2688  base::utils::Utils::uninstallCallback<T, base::type::PerformanceTrackingCallbackPtr>(id,
2689  &m_performanceTrackingCallbacks);
2690  }
2691 
2692  template <typename T>
2693  inline T* performanceTrackingCallback(const std::string& id) {
2694  return base::utils::Utils::callback<T, base::type::PerformanceTrackingCallbackPtr>(id, &m_performanceTrackingCallbacks);
2695  }
2696 #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
2697 
2699  inline void setThreadName(const std::string& name) {
2700  if (name.empty()) return;
2701  base::threading::ScopedLock scopedLock(m_threadNamesLock);
2702  m_threadNames[base::threading::getCurrentThreadId()] = name;
2703  }
2704 
2705  inline std::string getThreadName(const std::string& threadId) {
2706  base::threading::ScopedLock scopedLock(m_threadNamesLock);
2707  std::unordered_map<std::string, std::string>::const_iterator it = m_threadNames.find(threadId);
2708  if (it == m_threadNames.end()) {
2709  return threadId;
2710  }
2711  return it->second;
2712  }
2713 #if ELPP_ASYNC_LOGGING
2714  inline base::threading::Mutex& configLock(void) { return m_configLock; }
2715 #endif // ELPP_ASYNC_LOGGING
2716 
2717  private:
2722 #if ELPP_ASYNC_LOGGING
2723  // logs are added to this queue by other threads
2724  base::AsyncLogQueue* m_asyncLogWriteQueue;
2725  // logs are read and dispatched from this queue, by the async logger's thread
2726  base::AsyncLogQueue* m_asyncLogReadQueue;
2727  // async logger worker - helds the async logger's thread
2728  base::IWorker* m_asyncDispatchWorker;
2729  // mutex used for configuration of the logger - so that no change will happen dwhile handling a log message
2730  base::threading::Mutex m_configLock;
2731 #endif // ELPP_ASYNC_LOGGING
2733  PreRollOutCallback m_preRollOutCallback;
2734  std::unordered_map<std::string, base::type::LogDispatchCallbackPtr> m_logDispatchCallbacks;
2735  std::unordered_map<std::string, base::type::PerformanceTrackingCallbackPtr> m_performanceTrackingCallbacks;
2736  std::unordered_map<std::string, std::string> m_threadNames;
2737  std::vector<CustomFormatSpecifier> m_customFormatSpecifiers;
2741 
2742  friend class el::Helpers;
2744  friend class el::LogBuilder;
2746  friend class el::base::Writer;
2747  friend class el::base::PerformanceTracker;
2749 
2750  void setApplicationArguments(int argc, char** argv);
2751 
2752  inline void setApplicationArguments(int argc, const char** argv) {
2753  setApplicationArguments(argc, const_cast<char**>(argv));
2754  }
2755 };
2757 #define ELPP el::base::elStorage
2759  protected:
2760  void handle(const LogDispatchData* data);
2761  private:
2763  void dispatch(base::type::string_t&& logLine);
2764 };
2765 #if ELPP_ASYNC_LOGGING
2766 class AsyncLogDispatchCallback : public LogDispatchCallback {
2767  protected:
2768  void handle(const LogDispatchData* data);
2769 };
2770 class AsyncDispatchWorker : public base::IWorker, public base::threading::ThreadSafe {
2771  public:
2772  AsyncDispatchWorker();
2773  virtual ~AsyncDispatchWorker();
2774 
2775  bool clean(void);
2776  void emptyQueue(void);
2777  virtual void start(void);
2778  void handle(AsyncLogItem* logItem);
2779  void run(void);
2780  void fetchLogQueue();
2781 
2782  void setContinueRunning(bool value) {
2783  base::threading::ScopedLock scopedLock(m_continueRunningLock);
2784  m_continueRunning = value;
2785  }
2786 
2787  bool continueRunning(void) const {
2788  return m_continueRunning;
2789  }
2790  private:
2791  std::condition_variable cv;
2792  bool m_continueRunning;
2793  base::threading::Mutex m_continueRunningLock;
2794  std::thread m_asyncWorkerThread;
2795  std::mutex _mtx;
2796 };
2797 #endif // ELPP_ASYNC_LOGGING
2798 } // namespace base
2799 namespace base {
2801  public:
2802  base::type::string_t build(const LogMessage* logMessage, bool appendNewLine) const;
2803 };
2806  public:
2807  LogDispatcher(bool proceed, LogMessage* logMessage, base::DispatchAction dispatchAction) :
2808  m_proceed(proceed),
2809  m_logMessage(logMessage),
2810  m_dispatchAction(std::move(dispatchAction)) {
2811  }
2812 
2813  void dispatch(void);
2814 
2815  private:
2819 };
2820 #if defined(ELPP_STL_LOGGING)
2821 namespace workarounds {
2829 template <typename T, typename Container>
2830 class IterableContainer {
2831  public:
2832  typedef typename Container::iterator iterator;
2833  typedef typename Container::const_iterator const_iterator;
2834  IterableContainer(void) {}
2835  virtual ~IterableContainer(void) {}
2836  iterator begin(void) {
2837  return getContainer().begin();
2838  }
2839  iterator end(void) {
2840  return getContainer().end();
2841  }
2842  private:
2843  virtual Container& getContainer(void) = 0;
2844 };
2846 template<typename T, typename Container = std::vector<T>, typename Comparator = std::less<typename Container::value_type>>
2847 class IterablePriorityQueue : public IterableContainer<T, Container>,
2848  public std::priority_queue<T, Container, Comparator> {
2849  public:
2850  IterablePriorityQueue(std::priority_queue<T, Container, Comparator> queue_) {
2851  std::size_t count_ = 0;
2852  while (++count_ < base::consts::kMaxLogPerContainer && !queue_.empty()) {
2853  this->push(queue_.top());
2854  queue_.pop();
2855  }
2856  }
2857  private:
2858  inline Container& getContainer(void) {
2859  return this->c;
2860  }
2861 };
2863 template<typename T, typename Container = std::deque<T>>
2864 class IterableQueue : public IterableContainer<T, Container>, public std::queue<T, Container> {
2865  public:
2866  IterableQueue(std::queue<T, Container> queue_) {
2867  std::size_t count_ = 0;
2868  while (++count_ < base::consts::kMaxLogPerContainer && !queue_.empty()) {
2869  this->push(queue_.front());
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 IterableStack : public IterableContainer<T, Container>, public std::stack<T, Container> {
2881  public:
2882  IterableStack(std::stack<T, Container> stack_) {
2883  std::size_t count_ = 0;
2884  while (++count_ < base::consts::kMaxLogPerContainer && !stack_.empty()) {
2885  this->push(stack_.top());
2886  stack_.pop();
2887  }
2888  }
2889  private:
2890  inline Container& getContainer(void) {
2891  return this->c;
2892  }
2893 };
2894 } // namespace workarounds
2895 #endif // defined(ELPP_STL_LOGGING)
2896 // Log message builder
2898  public:
2899  MessageBuilder(void) : m_logger(nullptr), m_containerLogSeperator(ELPP_LITERAL("")) {}
2900  void initialize(Logger* logger);
2901 
2902 # define ELPP_SIMPLE_LOG(LOG_TYPE)\
2903 MessageBuilder& operator<<(LOG_TYPE msg) {\
2904 m_logger->stream() << msg;\
2905 if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) {\
2906 m_logger->stream() << " ";\
2907 }\
2908 return *this;\
2909 }
2910 
2911  inline MessageBuilder& operator<<(const std::string& msg) {
2912  return operator<<(msg.c_str());
2913  }
2914  ELPP_SIMPLE_LOG(char)
2915  ELPP_SIMPLE_LOG(bool)
2916  ELPP_SIMPLE_LOG(signed short)
2917  ELPP_SIMPLE_LOG(unsigned short)
2918  ELPP_SIMPLE_LOG(signed int)
2919  ELPP_SIMPLE_LOG(unsigned int)
2920  ELPP_SIMPLE_LOG(signed long)
2921  ELPP_SIMPLE_LOG(unsigned long)
2922  ELPP_SIMPLE_LOG(float)
2923  ELPP_SIMPLE_LOG(double)
2924  ELPP_SIMPLE_LOG(char*)
2925  ELPP_SIMPLE_LOG(const char*)
2926  ELPP_SIMPLE_LOG(const void*)
2927  ELPP_SIMPLE_LOG(long double)
2928  inline MessageBuilder& operator<<(const std::wstring& msg) {
2929  return operator<<(msg.c_str());
2930  }
2931  MessageBuilder& operator<<(const wchar_t* msg);
2932  // ostream manipulators
2933  inline MessageBuilder& operator<<(std::ostream& (*OStreamMani)(std::ostream&)) {
2934  m_logger->stream() << OStreamMani;
2935  return *this;
2936  }
2937 #define ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(temp) \
2938 template <typename T> \
2939 inline MessageBuilder& operator<<(const temp<T>& template_inst) { \
2940 return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
2941 }
2942 #define ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(temp) \
2943 template <typename T1, typename T2> \
2944 inline MessageBuilder& operator<<(const temp<T1, T2>& template_inst) { \
2945 return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
2946 }
2947 #define ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(temp) \
2948 template <typename T1, typename T2, typename T3> \
2949 inline MessageBuilder& operator<<(const temp<T1, T2, T3>& template_inst) { \
2950 return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
2951 }
2952 #define ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(temp) \
2953 template <typename T1, typename T2, typename T3, typename T4> \
2954 inline MessageBuilder& operator<<(const temp<T1, T2, T3, T4>& template_inst) { \
2955 return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
2956 }
2957 #define ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(temp) \
2958 template <typename T1, typename T2, typename T3, typename T4, typename T5> \
2959 inline MessageBuilder& operator<<(const temp<T1, T2, T3, T4, T5>& template_inst) { \
2960 return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
2961 }
2962 
2963 #if defined(ELPP_STL_LOGGING)
2971  template <class T, class Container>
2972  inline MessageBuilder& operator<<(const std::queue<T, Container>& queue_) {
2973  base::workarounds::IterableQueue<T, Container> iterableQueue_ =
2974  static_cast<base::workarounds::IterableQueue<T, Container> >(queue_);
2975  return writeIterator(iterableQueue_.begin(), iterableQueue_.end(), iterableQueue_.size());
2976  }
2977  template <class T, class Container>
2978  inline MessageBuilder& operator<<(const std::stack<T, Container>& stack_) {
2979  base::workarounds::IterableStack<T, Container> iterableStack_ =
2980  static_cast<base::workarounds::IterableStack<T, Container> >(stack_);
2981  return writeIterator(iterableStack_.begin(), iterableStack_.end(), iterableStack_.size());
2982  }
2983  template <class T, class Container, class Comparator>
2984  inline MessageBuilder& operator<<(const std::priority_queue<T, Container, Comparator>& priorityQueue_) {
2985  base::workarounds::IterablePriorityQueue<T, Container, Comparator> iterablePriorityQueue_ =
2986  static_cast<base::workarounds::IterablePriorityQueue<T, Container, Comparator> >(priorityQueue_);
2987  return writeIterator(iterablePriorityQueue_.begin(), iterablePriorityQueue_.end(), iterablePriorityQueue_.size());
2988  }
2989  template <class First, class Second>
2990  MessageBuilder& operator<<(const std::pair<First, Second>& pair_) {
2991  m_logger->stream() << ELPP_LITERAL("(");
2992  operator << (static_cast<First>(pair_.first));
2993  m_logger->stream() << ELPP_LITERAL(", ");
2994  operator << (static_cast<Second>(pair_.second));
2995  m_logger->stream() << ELPP_LITERAL(")");
2996  return *this;
2997  }
2998  template <std::size_t Size>
2999  MessageBuilder& operator<<(const std::bitset<Size>& bitset_) {
3000  m_logger->stream() << ELPP_LITERAL("[");
3001  operator << (bitset_.to_string());
3002  m_logger->stream() << ELPP_LITERAL("]");
3003  return *this;
3004  }
3005 # if defined(ELPP_LOG_STD_ARRAY)
3006  template <class T, std::size_t Size>
3007  inline MessageBuilder& operator<<(const std::array<T, Size>& array) {
3008  return writeIterator(array.begin(), array.end(), array.size());
3009  }
3010 # endif // defined(ELPP_LOG_STD_ARRAY)
3011 # if defined(ELPP_LOG_UNORDERED_MAP)
3012  ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(std::unordered_map)
3013  ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(std::unordered_multimap)
3014 # endif // defined(ELPP_LOG_UNORDERED_MAP)
3015 # if defined(ELPP_LOG_UNORDERED_SET)
3016  ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::unordered_set)
3017  ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::unordered_multiset)
3018 # endif // defined(ELPP_LOG_UNORDERED_SET)
3019 #endif // defined(ELPP_STL_LOGGING)
3020 #if defined(ELPP_QT_LOGGING)
3021  inline MessageBuilder& operator<<(const QString& msg) {
3022 # if defined(ELPP_UNICODE)
3023  m_logger->stream() << msg.toStdWString();
3024 # else
3025  m_logger->stream() << msg.toStdString();
3026 # endif // defined(ELPP_UNICODE)
3027  return *this;
3028  }
3029  inline MessageBuilder& operator<<(const QByteArray& msg) {
3030  return operator << (QString(msg));
3031  }
3032  inline MessageBuilder& operator<<(const QStringRef& msg) {
3033  return operator<<(msg.toString());
3034  }
3035  inline MessageBuilder& operator<<(qint64 msg) {
3036 # if defined(ELPP_UNICODE)
3037  m_logger->stream() << QString::number(msg).toStdWString();
3038 # else
3039  m_logger->stream() << QString::number(msg).toStdString();
3040 # endif // defined(ELPP_UNICODE)
3041  return *this;
3042  }
3043  inline MessageBuilder& operator<<(quint64 msg) {
3044 # if defined(ELPP_UNICODE)
3045  m_logger->stream() << QString::number(msg).toStdWString();
3046 # else
3047  m_logger->stream() << QString::number(msg).toStdString();
3048 # endif // defined(ELPP_UNICODE)
3049  return *this;
3050  }
3051  inline MessageBuilder& operator<<(QChar msg) {
3052  m_logger->stream() << msg.toLatin1();
3053  return *this;
3054  }
3055  inline MessageBuilder& operator<<(const QLatin1String& msg) {
3056  m_logger->stream() << msg.latin1();
3057  return *this;
3058  }
3065  template <typename First, typename Second>
3066  MessageBuilder& operator<<(const QPair<First, Second>& pair_) {
3067  m_logger->stream() << ELPP_LITERAL("(");
3068  operator << (static_cast<First>(pair_.first));
3069  m_logger->stream() << ELPP_LITERAL(", ");
3070  operator << (static_cast<Second>(pair_.second));
3071  m_logger->stream() << ELPP_LITERAL(")");
3072  return *this;
3073  }
3074  template <typename K, typename V>
3075  MessageBuilder& operator<<(const QMap<K, V>& map_) {
3076  m_logger->stream() << ELPP_LITERAL("[");
3077  QList<K> keys = map_.keys();
3078  typename QList<K>::const_iterator begin = keys.begin();
3079  typename QList<K>::const_iterator end = keys.end();
3080  int max_ = static_cast<int>(base::consts::kMaxLogPerContainer); // to prevent warning
3081  for (int index_ = 0; begin != end && index_ < max_; ++index_, ++begin) {
3082  m_logger->stream() << ELPP_LITERAL("(");
3083  operator << (static_cast<K>(*begin));
3084  m_logger->stream() << ELPP_LITERAL(", ");
3085  operator << (static_cast<V>(map_.value(*begin)));
3086  m_logger->stream() << ELPP_LITERAL(")");
3087  m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL(""));
3088  }
3089  if (begin != end) {
3090  m_logger->stream() << ELPP_LITERAL("...");
3091  }
3092  m_logger->stream() << ELPP_LITERAL("]");
3093  return *this;
3094  }
3095  template <typename K, typename V>
3096  inline MessageBuilder& operator<<(const QMultiMap<K, V>& map_) {
3097  operator << (static_cast<QMap<K, V>>(map_));
3098  return *this;
3099  }
3100  template <typename K, typename V>
3101  MessageBuilder& operator<<(const QHash<K, V>& hash_) {
3102  m_logger->stream() << ELPP_LITERAL("[");
3103  QList<K> keys = hash_.keys();
3104  typename QList<K>::const_iterator begin = keys.begin();
3105  typename QList<K>::const_iterator end = keys.end();
3106  int max_ = static_cast<int>(base::consts::kMaxLogPerContainer); // prevent type warning
3107  for (int index_ = 0; begin != end && index_ < max_; ++index_, ++begin) {
3108  m_logger->stream() << ELPP_LITERAL("(");
3109  operator << (static_cast<K>(*begin));
3110  m_logger->stream() << ELPP_LITERAL(", ");
3111  operator << (static_cast<V>(hash_.value(*begin)));
3112  m_logger->stream() << ELPP_LITERAL(")");
3113  m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL(""));
3114  }
3115  if (begin != end) {
3116  m_logger->stream() << ELPP_LITERAL("...");
3117  }
3118  m_logger->stream() << ELPP_LITERAL("]");
3119  return *this;
3120  }
3121  template <typename K, typename V>
3122  inline MessageBuilder& operator<<(const QMultiHash<K, V>& multiHash_) {
3123  operator << (static_cast<QHash<K, V>>(multiHash_));
3124  return *this;
3125  }
3126 #endif // defined(ELPP_QT_LOGGING)
3127 #if defined(ELPP_BOOST_LOGGING)
3128  ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::vector)
3129  ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::stable_vector)
3130  ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::list)
3131  ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::deque)
3133  ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(boost::container::flat_map)
3134  ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(boost::container::set)
3135  ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(boost::container::flat_set)
3136 #endif // defined(ELPP_BOOST_LOGGING)
3137 
3146 #define MAKE_CONTAINERELPP_FRIENDLY(ContainerType, SizeMethod, ElementInstance) \
3147 el::base::type::ostream_t& operator<<(el::base::type::ostream_t& ss, const ContainerType& container) {\
3148 const el::base::type::char_t* sep = ELPP->hasFlag(el::LoggingFlag::NewLineForContainer) ? \
3149 ELPP_LITERAL("\n ") : ELPP_LITERAL(", ");\
3150 ContainerType::const_iterator elem = container.begin();\
3151 ContainerType::const_iterator endElem = container.end();\
3152 std::size_t size_ = container.SizeMethod; \
3153 ss << ELPP_LITERAL("[");\
3154 for (std::size_t i = 0; elem != endElem && i < el::base::consts::kMaxLogPerContainer; ++i, ++elem) { \
3155 ss << ElementInstance;\
3156 ss << ((i < size_ - 1) ? sep : ELPP_LITERAL(""));\
3157 }\
3158 if (elem != endElem) {\
3159 ss << ELPP_LITERAL("...");\
3160 }\
3161 ss << ELPP_LITERAL("]");\
3162 return ss;\
3163 }
3164 #if defined(ELPP_WXWIDGETS_LOGGING)
3166 # define ELPP_WX_PTR_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), *(*elem))
3167 # define ELPP_WX_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), (*elem))
3168 # define ELPP_WX_HASH_MAP_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), \
3169 ELPP_LITERAL("(") << elem->first << ELPP_LITERAL(", ") << elem->second << ELPP_LITERAL(")")
3170 #else
3171 # define ELPP_WX_PTR_ENABLED(ContainerType)
3172 # define ELPP_WX_ENABLED(ContainerType)
3173 # define ELPP_WX_HASH_MAP_ENABLED(ContainerType)
3174 #endif // defined(ELPP_WXWIDGETS_LOGGING)
3175  // Other classes
3176  template <class Class>
3177  ELPP_SIMPLE_LOG(const Class&)
3178 #undef ELPP_SIMPLE_LOG
3179 #undef ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG
3180 #undef ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG
3181 #undef ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG
3182 #undef ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG
3183 #undef ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG
3184  private:
3187 
3188  template<class Iterator>
3189  MessageBuilder& writeIterator(Iterator begin_, Iterator end_, std::size_t size_) {
3190  m_logger->stream() << ELPP_LITERAL("[");
3191  for (std::size_t i = 0; begin_ != end_ && i < base::consts::kMaxLogPerContainer; ++i, ++begin_) {
3192  operator << (*begin_);
3193  m_logger->stream() << ((i < size_ - 1) ? m_containerLogSeperator : ELPP_LITERAL(""));
3194  }
3195  if (begin_ != end_) {
3196  m_logger->stream() << ELPP_LITERAL("...");
3197  }
3198  m_logger->stream() << ELPP_LITERAL("]");
3199  if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) {
3200  m_logger->stream() << " ";
3201  }
3202  return *this;
3203  }
3204 };
3207  public:
3208  NullWriter(void) {}
3209 
3210  // Null manipulator
3211  inline NullWriter& operator<<(std::ostream& (*)(std::ostream&)) {
3212  return *this;
3213  }
3214 
3215  template <typename T>
3216  inline NullWriter& operator<<(const T&) {
3217  return *this;
3218  }
3219 
3220  inline operator bool() {
3221  return true;
3222  }
3223 };
3226  public:
3228  const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog,
3229  base::type::VerboseLevel verboseLevel = 0) :
3230  m_msg(nullptr), m_level(level), m_file(file), m_line(line), m_func(func), m_verboseLevel(verboseLevel),
3231  m_logger(nullptr), m_proceed(false), m_dispatchAction(dispatchAction) {
3232  }
3233 
3235  m_msg(msg), m_level(msg != nullptr ? msg->level() : Level::Unknown),
3236  m_line(0), m_logger(nullptr), m_proceed(false), m_dispatchAction(dispatchAction) {
3237  }
3238 
3239  virtual ~Writer(void) {
3240  processDispatch();
3241  }
3242 
3243  template <typename T>
3244  inline Writer& operator<<(const T& log) {
3245 #if ELPP_LOGGING_ENABLED
3246  if (m_proceed) {
3247  m_messageBuilder << log;
3248  }
3249 #endif // ELPP_LOGGING_ENABLED
3250  return *this;
3251  }
3252 
3253  inline Writer& operator<<(std::ostream& (*log)(std::ostream&)) {
3254 #if ELPP_LOGGING_ENABLED
3255  if (m_proceed) {
3256  m_messageBuilder << log;
3257  }
3258 #endif // ELPP_LOGGING_ENABLED
3259  return *this;
3260  }
3261 
3262  inline operator bool() {
3263  return true;
3264  }
3265 
3266  Writer& construct(Logger* logger, bool needLock = true);
3267  Writer& construct(int count, const char* loggerIds, ...);
3268  protected:
3271  const char* m_file;
3273  const char* m_func;
3279  std::vector<std::string> m_loggerIds;
3280  friend class el::Helpers;
3281 
3282  void initializeLogger(const std::string& loggerId, bool lookup = true, bool needLock = true);
3283  void processDispatch();
3284  void triggerDispatch(void);
3285 };
3286 class PErrorWriter : public base::Writer {
3287  public:
3289  const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog,
3290  base::type::VerboseLevel verboseLevel = 0) :
3291  base::Writer(level, file, line, func, dispatchAction, verboseLevel) {
3292  }
3293 
3294  virtual ~PErrorWriter(void);
3295 };
3296 } // namespace base
3297 // Logging from Logger class. Why this is here? Because we have Storage and Writer class available
3298 #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
3299 template <typename T, typename... Args>
3300 void Logger::log_(Level level, int vlevel, const char* s, const T& value, const Args&... args) {
3302  b.initialize(this);
3303  while (*s) {
3305  if (*(s + 1) == base::consts::kFormatSpecifierChar) {
3306  ++s;
3307  } else {
3308  if (*(s + 1) == base::consts::kFormatSpecifierCharValue) {
3309  ++s;
3310  b << value;
3311  log_(level, vlevel, ++s, args...);
3312  return;
3313  }
3314  }
3315  }
3316  b << *s++;
3317  }
3318  ELPP_INTERNAL_ERROR("Too many arguments provided. Unable to handle. Please provide more format specifiers", false);
3319 }
3320 template <typename T>
3321 void Logger::log_(Level level, int vlevel, const T& log) {
3322  if (level == Level::Verbose) {
3323  if (ELPP->vRegistry()->allowed(vlevel, __FILE__)) {
3324  base::Writer(Level::Verbose, "FILE", 0, "FUNCTION",
3325  base::DispatchAction::NormalLog, vlevel).construct(this, false) << log;
3326  } else {
3327  stream().str(ELPP_LITERAL(""));
3328  releaseLock();
3329  }
3330  } else {
3331  base::Writer(level, "FILE", 0, "FUNCTION").construct(this, false) << log;
3332  }
3333 }
3334 template <typename T, typename... Args>
3335 inline void Logger::log(Level level, const char* s, const T& value, const Args&... args) {
3336  acquireLock(); // released in Writer!
3337  log_(level, 0, s, value, args...);
3338 }
3339 template <typename T>
3340 inline void Logger::log(Level level, const T& log) {
3341  acquireLock(); // released in Writer!
3342  log_(level, 0, log);
3343 }
3344 # if ELPP_VERBOSE_LOG
3345 template <typename T, typename... Args>
3346 inline void Logger::verbose(int vlevel, const char* s, const T& value, const Args&... args) {
3347  acquireLock(); // released in Writer!
3348  log_(el::Level::Verbose, vlevel, s, value, args...);
3349 }
3350 template <typename T>
3351 inline void Logger::verbose(int vlevel, const T& log) {
3352  acquireLock(); // released in Writer!
3353  log_(el::Level::Verbose, vlevel, log);
3354 }
3355 # else
3356 template <typename T, typename... Args>
3357 inline void Logger::verbose(int, const char*, const T&, const Args&...) {
3358  return;
3359 }
3360 template <typename T>
3361 inline void Logger::verbose(int, const T&) {
3362  return;
3363 }
3364 # endif // ELPP_VERBOSE_LOG
3365 # define LOGGER_LEVEL_WRITERS(FUNCTION_NAME, LOG_LEVEL)\
3366 template <typename T, typename... Args>\
3367 inline void Logger::FUNCTION_NAME(const char* s, const T& value, const Args&... args) {\
3368 log(LOG_LEVEL, s, value, args...);\
3369 }\
3370 template <typename T>\
3371 inline void Logger::FUNCTION_NAME(const T& value) {\
3372 log(LOG_LEVEL, value);\
3373 }
3374 # define LOGGER_LEVEL_WRITERS_DISABLED(FUNCTION_NAME, LOG_LEVEL)\
3375 template <typename T, typename... Args>\
3376 inline void Logger::FUNCTION_NAME(const char*, const T&, const Args&...) {\
3377 return;\
3378 }\
3379 template <typename T>\
3380 inline void Logger::FUNCTION_NAME(const T&) {\
3381 return;\
3382 }
3383 
3384 # if ELPP_INFO_LOG
3385 LOGGER_LEVEL_WRITERS(info, Level::Info)
3386 # else
3387 LOGGER_LEVEL_WRITERS_DISABLED(info, Level::Info)
3388 # endif // ELPP_INFO_LOG
3389 # if ELPP_DEBUG_LOG
3390 LOGGER_LEVEL_WRITERS(debug, Level::Debug)
3391 # else
3392 LOGGER_LEVEL_WRITERS_DISABLED(debug, Level::Debug)
3393 # endif // ELPP_DEBUG_LOG
3394 # if ELPP_WARNING_LOG
3395 LOGGER_LEVEL_WRITERS(warn, Level::Warning)
3396 # else
3397 LOGGER_LEVEL_WRITERS_DISABLED(warn, Level::Warning)
3398 # endif // ELPP_WARNING_LOG
3399 # if ELPP_ERROR_LOG
3400 LOGGER_LEVEL_WRITERS(error, Level::Error)
3401 # else
3402 LOGGER_LEVEL_WRITERS_DISABLED(error, Level::Error)
3403 # endif // ELPP_ERROR_LOG
3404 # if ELPP_FATAL_LOG
3405 LOGGER_LEVEL_WRITERS(fatal, Level::Fatal)
3406 # else
3407 LOGGER_LEVEL_WRITERS_DISABLED(fatal, Level::Fatal)
3408 # endif // ELPP_FATAL_LOG
3409 # if ELPP_TRACE_LOG
3410 LOGGER_LEVEL_WRITERS(trace, Level::Trace)
3411 # else
3412 LOGGER_LEVEL_WRITERS_DISABLED(trace, Level::Trace)
3413 # endif // ELPP_TRACE_LOG
3414 # undef LOGGER_LEVEL_WRITERS
3415 # undef LOGGER_LEVEL_WRITERS_DISABLED
3416 #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
3417 #if ELPP_COMPILER_MSVC
3418 # define ELPP_VARIADIC_FUNC_MSVC(variadicFunction, variadicArgs) variadicFunction variadicArgs
3419 # define ELPP_VARIADIC_FUNC_MSVC_RUN(variadicFunction, ...) ELPP_VARIADIC_FUNC_MSVC(variadicFunction, (__VA_ARGS__))
3420 # define el_getVALength(...) ELPP_VARIADIC_FUNC_MSVC_RUN(el_resolveVALength, 0, ## __VA_ARGS__,\
3421 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
3422 #else
3423 # if ELPP_COMPILER_CLANG
3424 # define el_getVALength(...) el_resolveVALength(0, __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
3425 # else
3426 # define el_getVALength(...) el_resolveVALength(0, ## __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
3427 # endif // ELPP_COMPILER_CLANG
3428 #endif // ELPP_COMPILER_MSVC
3429 #define el_resolveVALength(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
3430 #define ELPP_WRITE_LOG(writer, level, dispatchAction, ...) \
3431 writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
3432 #define ELPP_WRITE_LOG_IF(writer, condition, level, dispatchAction, ...) if (condition) \
3433 writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
3434 #define ELPP_WRITE_LOG_EVERY_N(writer, occasion, level, dispatchAction, ...) \
3435 ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion) && \
3436 writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
3437 #define ELPP_WRITE_LOG_AFTER_N(writer, n, level, dispatchAction, ...) \
3438 ELPP->validateAfterNCounter(__FILE__, __LINE__, n) && \
3439 writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
3440 #define ELPP_WRITE_LOG_N_TIMES(writer, n, level, dispatchAction, ...) \
3441 ELPP->validateNTimesCounter(__FILE__, __LINE__, n) && \
3442 writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
3443 #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
3444 class PerformanceTrackingData {
3445  public:
3446  enum class DataType : base::type::EnumType {
3447  Checkpoint = 1, Complete = 2
3448  };
3449  // Do not use constructor, will run into multiple definition error, use init(PerformanceTracker*)
3450  explicit PerformanceTrackingData(DataType dataType) : m_performanceTracker(nullptr),
3451  m_dataType(dataType), m_firstCheckpoint(false), m_file(""), m_line(0), m_func("") {}
3452  inline const std::string* blockName(void) const;
3453  inline const struct timeval* startTime(void) const;
3454  inline const struct timeval* endTime(void) const;
3455  inline const struct timeval* lastCheckpointTime(void) const;
3456  inline const base::PerformanceTracker* performanceTracker(void) const {
3457  return m_performanceTracker;
3458  }
3459  inline PerformanceTrackingData::DataType dataType(void) const {
3460  return m_dataType;
3461  }
3462  inline bool firstCheckpoint(void) const {
3463  return m_firstCheckpoint;
3464  }
3465  inline std::string checkpointId(void) const {
3466  return m_checkpointId;
3467  }
3468  inline const char* file(void) const {
3469  return m_file;
3470  }
3471  inline base::type::LineNumber line(void) const {
3472  return m_line;
3473  }
3474  inline const char* func(void) const {
3475  return m_func;
3476  }
3477  inline const base::type::string_t* formattedTimeTaken() const {
3478  return &m_formattedTimeTaken;
3479  }
3480  inline const std::string& loggerId(void) const;
3481  private:
3482  base::PerformanceTracker* m_performanceTracker;
3483  base::type::string_t m_formattedTimeTaken;
3484  PerformanceTrackingData::DataType m_dataType;
3485  bool m_firstCheckpoint;
3486  std::string m_checkpointId;
3487  const char* m_file;
3488  base::type::LineNumber m_line;
3489  const char* m_func;
3490  inline void init(base::PerformanceTracker* performanceTracker, bool firstCheckpoint = false) {
3491  m_performanceTracker = performanceTracker;
3492  m_firstCheckpoint = firstCheckpoint;
3493  }
3494 
3495  friend class el::base::PerformanceTracker;
3496 };
3497 namespace base {
3500 class PerformanceTracker : public base::threading::ThreadSafe, public Loggable {
3501  public:
3502  PerformanceTracker(const std::string& blockName,
3505  bool scopedLog = true, Level level = base::consts::kPerformanceTrackerDefaultLevel);
3507  PerformanceTracker(const PerformanceTracker& t) :
3508  m_blockName(t.m_blockName), m_timestampUnit(t.m_timestampUnit), m_loggerId(t.m_loggerId), m_scopedLog(t.m_scopedLog),
3509  m_level(t.m_level), m_hasChecked(t.m_hasChecked), m_lastCheckpointId(t.m_lastCheckpointId), m_enabled(t.m_enabled),
3510  m_startTime(t.m_startTime), m_endTime(t.m_endTime), m_lastCheckpointTime(t.m_lastCheckpointTime) {
3511  }
3512  virtual ~PerformanceTracker(void);
3514  void checkpoint(const std::string& id = std::string(), const char* file = __FILE__,
3515  base::type::LineNumber line = __LINE__,
3516  const char* func = "");
3517  inline Level level(void) const {
3518  return m_level;
3519  }
3520  private:
3521  std::string m_blockName;
3522  base::TimestampUnit m_timestampUnit;
3523  std::string m_loggerId;
3524  bool m_scopedLog;
3525  Level m_level;
3526  bool m_hasChecked;
3527  std::string m_lastCheckpointId;
3528  bool m_enabled;
3529  struct timeval m_startTime, m_endTime, m_lastCheckpointTime;
3530 
3531  PerformanceTracker(void);
3532 
3533  friend class el::PerformanceTrackingData;
3534  friend class base::DefaultPerformanceTrackingCallback;
3535 
3536  const inline base::type::string_t getFormattedTimeTaken() const {
3537  return getFormattedTimeTaken(m_startTime);
3538  }
3539 
3540  const base::type::string_t getFormattedTimeTaken(struct timeval startTime) const;
3541 
3542  virtual inline void log(el::base::type::ostream_t& os) const {
3543  os << getFormattedTimeTaken();
3544  }
3545 };
3546 class DefaultPerformanceTrackingCallback : public PerformanceTrackingCallback {
3547  protected:
3548  void handle(const PerformanceTrackingData* data) {
3549  m_data = data;
3551  if (m_data->dataType() == PerformanceTrackingData::DataType::Complete) {
3552  ss << ELPP_LITERAL("Executed [") << m_data->blockName()->c_str() << ELPP_LITERAL("] in [") <<
3553  *m_data->formattedTimeTaken() << ELPP_LITERAL("]");
3554  } else {
3555  ss << ELPP_LITERAL("Performance checkpoint");
3556  if (!m_data->checkpointId().empty()) {
3557  ss << ELPP_LITERAL(" [") << m_data->checkpointId().c_str() << ELPP_LITERAL("]");
3558  }
3559  ss << ELPP_LITERAL(" for block [") << m_data->blockName()->c_str() << ELPP_LITERAL("] : [") <<
3560  *m_data->performanceTracker();
3562  && m_data->performanceTracker()->m_hasChecked) {
3563  ss << ELPP_LITERAL(" ([") << *m_data->formattedTimeTaken() << ELPP_LITERAL("] from ");
3564  if (m_data->performanceTracker()->m_lastCheckpointId.empty()) {
3565  ss << ELPP_LITERAL("last checkpoint");
3566  } else {
3567  ss << ELPP_LITERAL("checkpoint '") << m_data->performanceTracker()->m_lastCheckpointId.c_str() << ELPP_LITERAL("'");
3568  }
3569  ss << ELPP_LITERAL(")]");
3570  } else {
3571  ss << ELPP_LITERAL("]");
3572  }
3573  }
3574  el::base::Writer(m_data->performanceTracker()->level(), m_data->file(), m_data->line(), m_data->func()).construct(1,
3575  m_data->loggerId().c_str()) << ss.str();
3576  }
3577  private:
3578  const PerformanceTrackingData* m_data;
3579 };
3580 } // namespace base
3581 inline const std::string* PerformanceTrackingData::blockName() const {
3582  return const_cast<const std::string*>(&m_performanceTracker->m_blockName);
3583 }
3584 inline const struct timeval* PerformanceTrackingData::startTime() const {
3585  return const_cast<const struct timeval*>(&m_performanceTracker->m_startTime);
3586 }
3587 inline const struct timeval* PerformanceTrackingData::endTime() const {
3588  return const_cast<const struct timeval*>(&m_performanceTracker->m_endTime);
3589 }
3590 inline const struct timeval* PerformanceTrackingData::lastCheckpointTime() const {
3591  return const_cast<const struct timeval*>(&m_performanceTracker->m_lastCheckpointTime);
3592 }
3593 inline const std::string& PerformanceTrackingData::loggerId(void) const {
3594  return m_performanceTracker->m_loggerId;
3595 }
3596 #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
3597 namespace base {
3599 namespace debug {
3600 #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG)
3601 class StackTrace : base::NoCopy {
3602  public:
3603  static const unsigned int kMaxStack = 64;
3604  static const unsigned int kStackStart = 2; // We want to skip c'tor and StackTrace::generateNew()
3605  class StackTraceEntry {
3606  public:
3607  StackTraceEntry(std::size_t index, const std::string& loc, const std::string& demang, const std::string& hex,
3608  const std::string& addr);
3609  StackTraceEntry(std::size_t index, const std::string& loc) :
3610  m_index(index),
3611  m_location(loc) {
3612  }
3613  std::size_t m_index;
3614  std::string m_location;
3615  std::string m_demangled;
3616  std::string m_hex;
3617  std::string m_addr;
3618  friend std::ostream& operator<<(std::ostream& ss, const StackTraceEntry& si);
3619 
3620  private:
3621  StackTraceEntry(void);
3622  };
3623 
3624  StackTrace(void) {
3625  generateNew();
3626  }
3627 
3628  virtual ~StackTrace(void) {
3629  }
3630 
3631  inline std::vector<StackTraceEntry>& getLatestStack(void) {
3632  return m_stack;
3633  }
3634 
3635  friend std::ostream& operator<<(std::ostream& os, const StackTrace& st);
3636 
3637  private:
3638  std::vector<StackTraceEntry> m_stack;
3639 
3640  void generateNew(void);
3641 };
3643 class CrashHandler : base::NoCopy {
3644  public:
3645  typedef void (*Handler)(int);
3646 
3647  explicit CrashHandler(bool useDefault);
3648  explicit CrashHandler(const Handler& cHandler) {
3649  setHandler(cHandler);
3650  }
3651  void setHandler(const Handler& cHandler);
3652 
3653  private:
3654  Handler m_handler;
3655 };
3656 #else
3658  public:
3659  explicit CrashHandler(bool) {}
3660 };
3661 #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG)
3662 } // namespace debug
3663 } // namespace base
3665 #define MAKE_LOGGABLE(ClassType, ClassInstance, OutputStreamInstance) \
3666 el::base::type::ostream_t& operator<<(el::base::type::ostream_t& OutputStreamInstance, const ClassType& ClassInstance)
3667 class SysLogInitializer {
3669  public:
3670  SysLogInitializer(const char* processIdent, int options = 0, int facility = 0) {
3671 #if defined(ELPP_SYSLOG)
3672  openlog(processIdent, options, facility);
3673 #else
3674  ELPP_UNUSED(processIdent);
3675  ELPP_UNUSED(options);
3676  ELPP_UNUSED(facility);
3677 #endif // defined(ELPP_SYSLOG)
3678  }
3679  virtual ~SysLogInitializer(void) {
3680 #if defined(ELPP_SYSLOG)
3681  closelog();
3682 #endif // defined(ELPP_SYSLOG)
3683  }
3684 };
3685 #define ELPP_INITIALIZE_SYSLOG(id, opt, fac) el::SysLogInitializer elSyslogInit(id, opt, fac)
3686 class Helpers : base::StaticClass {
3688  public:
3690  static inline void setStorage(base::type::StoragePointer storage) {
3691  ELPP = storage;
3692  }
3695  return ELPP;
3696  }
3698  static inline void setArgs(int argc, char** argv) {
3699  ELPP->setApplicationArguments(argc, argv);
3700  }
3702  static inline void setArgs(int argc, const char** argv) {
3703  ELPP->setApplicationArguments(argc, const_cast<char**>(argv));
3704  }
3706  static inline void setThreadName(const std::string& name) {
3707  ELPP->setThreadName(name);
3708  }
3709  static inline std::string getThreadName() {
3710  return ELPP->getThreadName(base::threading::getCurrentThreadId());
3711  }
3712 #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG)
3713  static inline void setCrashHandler(const el::base::debug::CrashHandler::Handler& crashHandler) {
3717  el::elCrashHandler.setHandler(crashHandler);
3718  }
3721  static void crashAbort(int sig, const char* sourceFile = "", unsigned int long line = 0);
3727  static void logCrashReason(int sig, bool stackTraceIfAvailable = false,
3728  Level level = Level::Fatal, const char* logger = base::consts::kDefaultLoggerId);
3729 #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG)
3730  static inline void installPreRollOutCallback(const PreRollOutCallback& callback) {
3733  ELPP->setPreRollOutCallback(callback);
3734  }
3736  static inline void uninstallPreRollOutCallback(void) {
3737  ELPP->unsetPreRollOutCallback();
3738  }
3740  template <typename T>
3741  static inline bool installLogDispatchCallback(const std::string& id) {
3742  return ELPP->installLogDispatchCallback<T>(id);
3743  }
3745  template <typename T>
3746  static inline void uninstallLogDispatchCallback(const std::string& id) {
3747  ELPP->uninstallLogDispatchCallback<T>(id);
3748  }
3749  template <typename T>
3750  static inline T* logDispatchCallback(const std::string& id) {
3751  return ELPP->logDispatchCallback<T>(id);
3752  }
3753 #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
3754  template <typename T>
3756  static inline bool installPerformanceTrackingCallback(const std::string& id) {
3757  return ELPP->installPerformanceTrackingCallback<T>(id);
3758  }
3760  template <typename T>
3761  static inline void uninstallPerformanceTrackingCallback(const std::string& id) {
3762  ELPP->uninstallPerformanceTrackingCallback<T>(id);
3763  }
3764  template <typename T>
3765  static inline T* performanceTrackingCallback(const std::string& id) {
3766  return ELPP->performanceTrackingCallback<T>(id);
3767  }
3768 #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
3769  template <typename T>
3772  el::Logger* logger =
3773  ELPP->registeredLoggers()->get(el::base::consts::kDefaultLoggerId);
3774  if (logger == nullptr) {
3775  return std::string();
3776  }
3778  b.initialize(logger);
3779  logger->acquireLock();
3780  b << templ;
3781 #if defined(ELPP_UNICODE)
3782  std::string s = std::string(logger->stream().str().begin(), logger->stream().str().end());
3783 #else
3784  std::string s = logger->stream().str();
3785 #endif // defined(ELPP_UNICODE)
3786  logger->stream().str(ELPP_LITERAL(""));
3787  logger->releaseLock();
3788  return s;
3789  }
3792  return ELPP->commandLineArgs();
3793  }
3796  static inline void reserveCustomFormatSpecifiers(std::size_t size) {
3797  ELPP->m_customFormatSpecifiers.reserve(size);
3798  }
3800  static inline void installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier) {
3801  ELPP->installCustomFormatSpecifier(customFormatSpecifier);
3802  }
3804  static inline bool uninstallCustomFormatSpecifier(const char* formatSpecifier) {
3805  return ELPP->uninstallCustomFormatSpecifier(formatSpecifier);
3806  }
3808  static inline bool hasCustomFormatSpecifier(const char* formatSpecifier) {
3809  return ELPP->hasCustomFormatSpecifier(formatSpecifier);
3810  }
3811  static inline void validateFileRolling(Logger* logger, Level level) {
3812  if (logger == nullptr) return;
3813  logger->m_typedConfigurations->validateFileRolling(level, ELPP->preRollOutCallback());
3814  }
3815 };
3818  public:
3820  static Logger* getLogger(const std::string& identity, bool registerIfNotAvailable = true);
3822  static void setDefaultLogBuilder(el::LogBuilderPtr& logBuilderPtr);
3824  template <typename T>
3825  static inline bool installLoggerRegistrationCallback(const std::string& id) {
3826  return ELPP->registeredLoggers()->installLoggerRegistrationCallback<T>(id);
3827  }
3829  template <typename T>
3830  static inline void uninstallLoggerRegistrationCallback(const std::string& id) {
3831  ELPP->registeredLoggers()->uninstallLoggerRegistrationCallback<T>(id);
3832  }
3833  template <typename T>
3834  static inline T* loggerRegistrationCallback(const std::string& id) {
3835  return ELPP->registeredLoggers()->loggerRegistrationCallback<T>(id);
3836  }
3839  static bool unregisterLogger(const std::string& identity);
3841  static bool hasLogger(const std::string& identity);
3843  static Logger* reconfigureLogger(Logger* logger, const Configurations& configurations);
3845  static Logger* reconfigureLogger(const std::string& identity, const Configurations& configurations);
3847  static Logger* reconfigureLogger(const std::string& identity, ConfigurationType configurationType,
3848  const std::string& value);
3850  static void reconfigureAllLoggers(const Configurations& configurations);
3852  static inline void reconfigureAllLoggers(ConfigurationType configurationType, const std::string& value) {
3853  reconfigureAllLoggers(Level::Global, configurationType, value);
3854  }
3856  static void reconfigureAllLoggers(Level level, ConfigurationType configurationType,
3857  const std::string& value);
3859  static void setDefaultConfigurations(const Configurations& configurations,
3860  bool reconfigureExistingLoggers = false);
3862  static const Configurations* defaultConfigurations(void);
3864  static const base::LogStreamsReferenceMap* logStreamsReference(void);
3866  static base::TypedConfigurations defaultTypedConfigurations(void);
3869  static std::vector<std::string>* populateAllLoggerIds(std::vector<std::string>* targetList);
3871  static void configureFromGlobal(const char* globalConfigurationFilePath);
3876  static bool configureFromArg(const char* argKey);
3878  static void flushAll(void);
3880  static inline void addFlag(LoggingFlag flag) {
3881  ELPP->addFlag(flag);
3882  }
3884  static inline void removeFlag(LoggingFlag flag) {
3885  ELPP->removeFlag(flag);
3886  }
3888  static inline bool hasFlag(LoggingFlag flag) {
3889  return ELPP->hasFlag(flag);
3890  }
3893  public:
3894  ScopedAddFlag(LoggingFlag flag) : m_flag(flag) {
3895  Loggers::addFlag(m_flag);
3896  }
3898  Loggers::removeFlag(m_flag);
3899  }
3900  private:
3902  };
3905  public:
3906  ScopedRemoveFlag(LoggingFlag flag) : m_flag(flag) {
3907  Loggers::removeFlag(m_flag);
3908  }
3910  Loggers::addFlag(m_flag);
3911  }
3912  private:
3914  };
3916  static void setLoggingLevel(Level level) {
3917  ELPP->setLoggingLevel(level);
3918  }
3920  static void setVerboseLevel(base::type::VerboseLevel level);
3922  static base::type::VerboseLevel verboseLevel(void);
3924  static void setVModules(const char* modules);
3926  static void clearVModules(void);
3927 };
3929  public:
3931  static const std::string version(void);
3932 
3934  static const std::string releaseDate(void);
3935 };
3936 } // namespace el
3937 #undef VLOG_IS_ON
3938 #define VLOG_IS_ON(verboseLevel) (ELPP->vRegistry()->allowed(verboseLevel, __FILE__))
3940 #undef TIMED_BLOCK
3941 #undef TIMED_SCOPE
3942 #undef TIMED_SCOPE_IF
3943 #undef TIMED_FUNC
3944 #undef TIMED_FUNC_IF
3945 #undef ELPP_MIN_UNIT
3946 #if defined(ELPP_PERFORMANCE_MICROSECONDS)
3947 # define ELPP_MIN_UNIT el::base::TimestampUnit::Microsecond
3948 #else
3949 # define ELPP_MIN_UNIT el::base::TimestampUnit::Millisecond
3950 #endif // (defined(ELPP_PERFORMANCE_MICROSECONDS))
3951 // Note: Do not surround this definition with null macro because of obj instance
3958 #define TIMED_SCOPE_IF(obj, blockname, condition) el::base::type::PerformanceTrackerPtr obj( condition ? \
3959  new el::base::PerformanceTracker(blockname, ELPP_MIN_UNIT) : nullptr )
3960 #define TIMED_SCOPE(obj, blockname) TIMED_SCOPE_IF(obj, blockname, true)
3961 #define TIMED_BLOCK(obj, blockName) for (struct { int i; el::base::type::PerformanceTrackerPtr timer; } obj = { 0, \
3962  el::base::type::PerformanceTrackerPtr(new el::base::PerformanceTracker(blockName, ELPP_MIN_UNIT)) }; obj.i < 1; ++obj.i)
3963 #define TIMED_FUNC_IF(obj,condition) TIMED_SCOPE_IF(obj, ELPP_FUNC, condition)
3970 #define TIMED_FUNC(obj) TIMED_SCOPE(obj, ELPP_FUNC)
3971 #undef PERFORMANCE_CHECKPOINT
3972 #undef PERFORMANCE_CHECKPOINT_WITH_ID
3973 #define PERFORMANCE_CHECKPOINT(obj) obj->checkpoint(std::string(), __FILE__, __LINE__, ELPP_FUNC)
3974 #define PERFORMANCE_CHECKPOINT_WITH_ID(obj, id) obj->checkpoint(id, __FILE__, __LINE__, ELPP_FUNC)
3975 #undef ELPP_COUNTER
3976 #undef ELPP_COUNTER_POS
3977 #define ELPP_COUNTER (ELPP->hitCounters()->getCounter(__FILE__, __LINE__))
3979 #define ELPP_COUNTER_POS (ELPP_COUNTER == nullptr ? -1 : ELPP_COUNTER->hitCounts())
3981 // Undef levels to support LOG(LEVEL)
3982 #undef INFO
3983 #undef WARNING
3984 #undef DEBUG
3985 #undef ERROR
3986 #undef FATAL
3987 #undef TRACE
3988 #undef VERBOSE
3989 // Undef existing
3990 #undef CINFO
3991 #undef CWARNING
3992 #undef CDEBUG
3993 #undef CFATAL
3994 #undef CERROR
3995 #undef CTRACE
3996 #undef CVERBOSE
3997 #undef CINFO_IF
3998 #undef CWARNING_IF
3999 #undef CDEBUG_IF
4000 #undef CERROR_IF
4001 #undef CFATAL_IF
4002 #undef CTRACE_IF
4003 #undef CVERBOSE_IF
4004 #undef CINFO_EVERY_N
4005 #undef CWARNING_EVERY_N
4006 #undef CDEBUG_EVERY_N
4007 #undef CERROR_EVERY_N
4008 #undef CFATAL_EVERY_N
4009 #undef CTRACE_EVERY_N
4010 #undef CVERBOSE_EVERY_N
4011 #undef CINFO_AFTER_N
4012 #undef CWARNING_AFTER_N
4013 #undef CDEBUG_AFTER_N
4014 #undef CERROR_AFTER_N
4015 #undef CFATAL_AFTER_N
4016 #undef CTRACE_AFTER_N
4017 #undef CVERBOSE_AFTER_N
4018 #undef CINFO_N_TIMES
4019 #undef CWARNING_N_TIMES
4020 #undef CDEBUG_N_TIMES
4021 #undef CERROR_N_TIMES
4022 #undef CFATAL_N_TIMES
4023 #undef CTRACE_N_TIMES
4024 #undef CVERBOSE_N_TIMES
4025 // Normal logs
4026 #if ELPP_INFO_LOG
4027 # define CINFO(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Info, dispatchAction, __VA_ARGS__)
4028 #else
4029 # define CINFO(writer, dispatchAction, ...) el::base::NullWriter()
4030 #endif // ELPP_INFO_LOG
4031 #if ELPP_WARNING_LOG
4032 # define CWARNING(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Warning, dispatchAction, __VA_ARGS__)
4033 #else
4034 # define CWARNING(writer, dispatchAction, ...) el::base::NullWriter()
4035 #endif // ELPP_WARNING_LOG
4036 #if ELPP_DEBUG_LOG
4037 # define CDEBUG(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Debug, dispatchAction, __VA_ARGS__)
4038 #else
4039 # define CDEBUG(writer, dispatchAction, ...) el::base::NullWriter()
4040 #endif // ELPP_DEBUG_LOG
4041 #if ELPP_ERROR_LOG
4042 # define CERROR(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Error, dispatchAction, __VA_ARGS__)
4043 #else
4044 # define CERROR(writer, dispatchAction, ...) el::base::NullWriter()
4045 #endif // ELPP_ERROR_LOG
4046 #if ELPP_FATAL_LOG
4047 # define CFATAL(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Fatal, dispatchAction, __VA_ARGS__)
4048 #else
4049 # define CFATAL(writer, dispatchAction, ...) el::base::NullWriter()
4050 #endif // ELPP_FATAL_LOG
4051 #if ELPP_TRACE_LOG
4052 # define CTRACE(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Trace, dispatchAction, __VA_ARGS__)
4053 #else
4054 # define CTRACE(writer, dispatchAction, ...) el::base::NullWriter()
4055 #endif // ELPP_TRACE_LOG
4056 #if ELPP_VERBOSE_LOG
4057 # define CVERBOSE(writer, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel)) writer(\
4058 el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
4059 #else
4060 # define CVERBOSE(writer, vlevel, dispatchAction, ...) el::base::NullWriter()
4061 #endif // ELPP_VERBOSE_LOG
4062 // Conditional logs
4063 #if ELPP_INFO_LOG
4064 # define CINFO_IF(writer, condition_, dispatchAction, ...) \
4065 ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Info, dispatchAction, __VA_ARGS__)
4066 #else
4067 # define CINFO_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
4068 #endif // ELPP_INFO_LOG
4069 #if ELPP_WARNING_LOG
4070 # define CWARNING_IF(writer, condition_, dispatchAction, ...)\
4071 ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Warning, dispatchAction, __VA_ARGS__)
4072 #else
4073 # define CWARNING_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
4074 #endif // ELPP_WARNING_LOG
4075 #if ELPP_DEBUG_LOG
4076 # define CDEBUG_IF(writer, condition_, dispatchAction, ...)\
4077 ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Debug, dispatchAction, __VA_ARGS__)
4078 #else
4079 # define CDEBUG_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
4080 #endif // ELPP_DEBUG_LOG
4081 #if ELPP_ERROR_LOG
4082 # define CERROR_IF(writer, condition_, dispatchAction, ...)\
4083 ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Error, dispatchAction, __VA_ARGS__)
4084 #else
4085 # define CERROR_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
4086 #endif // ELPP_ERROR_LOG
4087 #if ELPP_FATAL_LOG
4088 # define CFATAL_IF(writer, condition_, dispatchAction, ...)\
4089 ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Fatal, dispatchAction, __VA_ARGS__)
4090 #else
4091 # define CFATAL_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
4092 #endif // ELPP_FATAL_LOG
4093 #if ELPP_TRACE_LOG
4094 # define CTRACE_IF(writer, condition_, dispatchAction, ...)\
4095 ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Trace, dispatchAction, __VA_ARGS__)
4096 #else
4097 # define CTRACE_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
4098 #endif // ELPP_TRACE_LOG
4099 #if ELPP_VERBOSE_LOG
4100 # define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel) && (condition_)) writer( \
4101 el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
4102 #else
4103 # define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) el::base::NullWriter()
4104 #endif // ELPP_VERBOSE_LOG
4105 // Occasional logs
4106 #if ELPP_INFO_LOG
4107 # define CINFO_EVERY_N(writer, occasion, dispatchAction, ...)\
4108 ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Info, dispatchAction, __VA_ARGS__)
4109 #else
4110 # define CINFO_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
4111 #endif // ELPP_INFO_LOG
4112 #if ELPP_WARNING_LOG
4113 # define CWARNING_EVERY_N(writer, occasion, dispatchAction, ...)\
4114 ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Warning, dispatchAction, __VA_ARGS__)
4115 #else
4116 # define CWARNING_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
4117 #endif // ELPP_WARNING_LOG
4118 #if ELPP_DEBUG_LOG
4119 # define CDEBUG_EVERY_N(writer, occasion, dispatchAction, ...)\
4120 ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Debug, dispatchAction, __VA_ARGS__)
4121 #else
4122 # define CDEBUG_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
4123 #endif // ELPP_DEBUG_LOG
4124 #if ELPP_ERROR_LOG
4125 # define CERROR_EVERY_N(writer, occasion, dispatchAction, ...)\
4126 ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Error, dispatchAction, __VA_ARGS__)
4127 #else
4128 # define CERROR_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
4129 #endif // ELPP_ERROR_LOG
4130 #if ELPP_FATAL_LOG
4131 # define CFATAL_EVERY_N(writer, occasion, dispatchAction, ...)\
4132 ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Fatal, dispatchAction, __VA_ARGS__)
4133 #else
4134 # define CFATAL_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
4135 #endif // ELPP_FATAL_LOG
4136 #if ELPP_TRACE_LOG
4137 # define CTRACE_EVERY_N(writer, occasion, dispatchAction, ...)\
4138 ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Trace, dispatchAction, __VA_ARGS__)
4139 #else
4140 # define CTRACE_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
4141 #endif // ELPP_TRACE_LOG
4142 #if ELPP_VERBOSE_LOG
4143 # define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...)\
4144 CVERBOSE_IF(writer, ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion), vlevel, dispatchAction, __VA_ARGS__)
4145 #else
4146 # define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...) el::base::NullWriter()
4147 #endif // ELPP_VERBOSE_LOG
4148 // After N logs
4149 #if ELPP_INFO_LOG
4150 # define CINFO_AFTER_N(writer, n, dispatchAction, ...)\
4151 ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Info, dispatchAction, __VA_ARGS__)
4152 #else
4153 # define CINFO_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
4154 #endif // ELPP_INFO_LOG
4155 #if ELPP_WARNING_LOG
4156 # define CWARNING_AFTER_N(writer, n, dispatchAction, ...)\
4157 ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Warning, dispatchAction, __VA_ARGS__)
4158 #else
4159 # define CWARNING_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
4160 #endif // ELPP_WARNING_LOG
4161 #if ELPP_DEBUG_LOG
4162 # define CDEBUG_AFTER_N(writer, n, dispatchAction, ...)\
4163 ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Debug, dispatchAction, __VA_ARGS__)
4164 #else
4165 # define CDEBUG_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
4166 #endif // ELPP_DEBUG_LOG
4167 #if ELPP_ERROR_LOG
4168 # define CERROR_AFTER_N(writer, n, dispatchAction, ...)\
4169 ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Error, dispatchAction, __VA_ARGS__)
4170 #else
4171 # define CERROR_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
4172 #endif // ELPP_ERROR_LOG
4173 #if ELPP_FATAL_LOG
4174 # define CFATAL_AFTER_N(writer, n, dispatchAction, ...)\
4175 ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Fatal, dispatchAction, __VA_ARGS__)
4176 #else
4177 # define CFATAL_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
4178 #endif // ELPP_FATAL_LOG
4179 #if ELPP_TRACE_LOG
4180 # define CTRACE_AFTER_N(writer, n, dispatchAction, ...)\
4181 ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Trace, dispatchAction, __VA_ARGS__)
4182 #else
4183 # define CTRACE_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
4184 #endif // ELPP_TRACE_LOG
4185 #if ELPP_VERBOSE_LOG
4186 # define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...)\
4187 CVERBOSE_IF(writer, ELPP->validateAfterNCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__)
4188 #else
4189 # define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter()
4190 #endif // ELPP_VERBOSE_LOG
4191 // N Times logs
4192 #if ELPP_INFO_LOG
4193 # define CINFO_N_TIMES(writer, n, dispatchAction, ...)\
4194 ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Info, dispatchAction, __VA_ARGS__)
4195 #else
4196 # define CINFO_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
4197 #endif // ELPP_INFO_LOG
4198 #if ELPP_WARNING_LOG
4199 # define CWARNING_N_TIMES(writer, n, dispatchAction, ...)\
4200 ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Warning, dispatchAction, __VA_ARGS__)
4201 #else
4202 # define CWARNING_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
4203 #endif // ELPP_WARNING_LOG
4204 #if ELPP_DEBUG_LOG
4205 # define CDEBUG_N_TIMES(writer, n, dispatchAction, ...)\
4206 ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Debug, dispatchAction, __VA_ARGS__)
4207 #else
4208 # define CDEBUG_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
4209 #endif // ELPP_DEBUG_LOG
4210 #if ELPP_ERROR_LOG
4211 # define CERROR_N_TIMES(writer, n, dispatchAction, ...)\
4212 ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Error, dispatchAction, __VA_ARGS__)
4213 #else
4214 # define CERROR_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
4215 #endif // ELPP_ERROR_LOG
4216 #if ELPP_FATAL_LOG
4217 # define CFATAL_N_TIMES(writer, n, dispatchAction, ...)\
4218 ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Fatal, dispatchAction, __VA_ARGS__)
4219 #else
4220 # define CFATAL_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
4221 #endif // ELPP_FATAL_LOG
4222 #if ELPP_TRACE_LOG
4223 # define CTRACE_N_TIMES(writer, n, dispatchAction, ...)\
4224 ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Trace, dispatchAction, __VA_ARGS__)
4225 #else
4226 # define CTRACE_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
4227 #endif // ELPP_TRACE_LOG
4228 #if ELPP_VERBOSE_LOG
4229 # define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...)\
4230 CVERBOSE_IF(writer, ELPP->validateNTimesCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__)
4231 #else
4232 # define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter()
4233 #endif // ELPP_VERBOSE_LOG
4234 //
4235 // Custom Loggers - Requires (level, dispatchAction, loggerId/s)
4236 //
4237 // undef existing
4238 #undef CLOG
4239 #undef CLOG_VERBOSE
4240 #undef CVLOG
4241 #undef CLOG_IF
4242 #undef CLOG_VERBOSE_IF
4243 #undef CVLOG_IF
4244 #undef CLOG_EVERY_N
4245 #undef CVLOG_EVERY_N
4246 #undef CLOG_AFTER_N
4247 #undef CVLOG_AFTER_N
4248 #undef CLOG_N_TIMES
4249 #undef CVLOG_N_TIMES
4250 // Normal logs
4251 #define CLOG(LEVEL, ...)\
4252 C##LEVEL(el::base::Writer, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4253 #define CVLOG(vlevel, ...) CVERBOSE(el::base::Writer, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4254 // Conditional logs
4255 #define CLOG_IF(condition, LEVEL, ...)\
4256 C##LEVEL##_IF(el::base::Writer, condition, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4257 #define CVLOG_IF(condition, vlevel, ...)\
4258 CVERBOSE_IF(el::base::Writer, condition, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4259 // Hit counts based logs
4260 #define CLOG_EVERY_N(n, LEVEL, ...)\
4261 C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4262 #define CVLOG_EVERY_N(n, vlevel, ...)\
4263 CVERBOSE_EVERY_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4264 #define CLOG_AFTER_N(n, LEVEL, ...)\
4265 C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4266 #define CVLOG_AFTER_N(n, vlevel, ...)\
4267 CVERBOSE_AFTER_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4268 #define CLOG_N_TIMES(n, LEVEL, ...)\
4269 C##LEVEL##_N_TIMES(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4270 #define CVLOG_N_TIMES(n, vlevel, ...)\
4271 CVERBOSE_N_TIMES(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4272 //
4273 // Default Loggers macro using CLOG(), CLOG_VERBOSE() and CVLOG() macros
4274 //
4275 // undef existing
4276 #undef LOG
4277 #undef VLOG
4278 #undef LOG_IF
4279 #undef VLOG_IF
4280 #undef LOG_EVERY_N
4281 #undef VLOG_EVERY_N
4282 #undef LOG_AFTER_N
4283 #undef VLOG_AFTER_N
4284 #undef LOG_N_TIMES
4285 #undef VLOG_N_TIMES
4286 #undef ELPP_CURR_FILE_LOGGER_ID
4287 #if defined(ELPP_DEFAULT_LOGGER)
4288 # define ELPP_CURR_FILE_LOGGER_ID ELPP_DEFAULT_LOGGER
4289 #else
4290 # define ELPP_CURR_FILE_LOGGER_ID el::base::consts::kDefaultLoggerId
4291 #endif
4292 #undef ELPP_TRACE
4293 #define ELPP_TRACE CLOG(TRACE, ELPP_CURR_FILE_LOGGER_ID)
4294 // Normal logs
4295 #define LOG(LEVEL) CLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4296 #define VLOG(vlevel) CVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID)
4297 // Conditional logs
4298 #define LOG_IF(condition, LEVEL) CLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4299 #define VLOG_IF(condition, vlevel) CVLOG_IF(condition, vlevel, ELPP_CURR_FILE_LOGGER_ID)
4300 // Hit counts based logs
4301 #define LOG_EVERY_N(n, LEVEL) CLOG_EVERY_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4302 #define VLOG_EVERY_N(n, vlevel) CVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
4303 #define LOG_AFTER_N(n, LEVEL) CLOG_AFTER_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4304 #define VLOG_AFTER_N(n, vlevel) CVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
4305 #define LOG_N_TIMES(n, LEVEL) CLOG_N_TIMES(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4306 #define VLOG_N_TIMES(n, vlevel) CVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
4307 // Generic PLOG()
4308 #undef CPLOG
4309 #undef CPLOG_IF
4310 #undef PLOG
4311 #undef PLOG_IF
4312 #undef DCPLOG
4313 #undef DCPLOG_IF
4314 #undef DPLOG
4315 #undef DPLOG_IF
4316 #define CPLOG(LEVEL, ...)\
4317 C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4318 #define CPLOG_IF(condition, LEVEL, ...)\
4319 C##LEVEL##_IF(el::base::PErrorWriter, condition, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4320 #define DCPLOG(LEVEL, ...)\
4321 if (ELPP_DEBUG_LOG) C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__)
4322 #define DCPLOG_IF(condition, LEVEL, ...)\
4323 C##LEVEL##_IF(el::base::PErrorWriter, (ELPP_DEBUG_LOG) && (condition), el::base::DispatchAction::NormalLog, __VA_ARGS__)
4324 #define PLOG(LEVEL) CPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4325 #define PLOG_IF(condition, LEVEL) CPLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4326 #define DPLOG(LEVEL) DCPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4327 #define DPLOG_IF(condition, LEVEL) DCPLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4328 // Generic SYSLOG()
4329 #undef CSYSLOG
4330 #undef CSYSLOG_IF
4331 #undef CSYSLOG_EVERY_N
4332 #undef CSYSLOG_AFTER_N
4333 #undef CSYSLOG_N_TIMES
4334 #undef SYSLOG
4335 #undef SYSLOG_IF
4336 #undef SYSLOG_EVERY_N
4337 #undef SYSLOG_AFTER_N
4338 #undef SYSLOG_N_TIMES
4339 #undef DCSYSLOG
4340 #undef DCSYSLOG_IF
4341 #undef DCSYSLOG_EVERY_N
4342 #undef DCSYSLOG_AFTER_N
4343 #undef DCSYSLOG_N_TIMES
4344 #undef DSYSLOG
4345 #undef DSYSLOG_IF
4346 #undef DSYSLOG_EVERY_N
4347 #undef DSYSLOG_AFTER_N
4348 #undef DSYSLOG_N_TIMES
4349 #if defined(ELPP_SYSLOG)
4350 # define CSYSLOG(LEVEL, ...)\
4351 C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__)
4352 # define CSYSLOG_IF(condition, LEVEL, ...)\
4353 C##LEVEL##_IF(el::base::Writer, condition, el::base::DispatchAction::SysLog, __VA_ARGS__)
4354 # define CSYSLOG_EVERY_N(n, LEVEL, ...) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
4355 # define CSYSLOG_AFTER_N(n, LEVEL, ...) C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
4356 # define CSYSLOG_N_TIMES(n, LEVEL, ...) C##LEVEL##_N_TIMES(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
4357 # define SYSLOG(LEVEL) CSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId)
4358 # define SYSLOG_IF(condition, LEVEL) CSYSLOG_IF(condition, LEVEL, el::base::consts::kSysLogLoggerId)
4359 # define SYSLOG_EVERY_N(n, LEVEL) CSYSLOG_EVERY_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
4360 # define SYSLOG_AFTER_N(n, LEVEL) CSYSLOG_AFTER_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
4361 # define SYSLOG_N_TIMES(n, LEVEL) CSYSLOG_N_TIMES(n, LEVEL, el::base::consts::kSysLogLoggerId)
4362 # define DCSYSLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__)
4363 # define DCSYSLOG_IF(condition, LEVEL, ...)\
4364 C##LEVEL##_IF(el::base::Writer, (ELPP_DEBUG_LOG) && (condition), el::base::DispatchAction::SysLog, __VA_ARGS__)
4365 # define DCSYSLOG_EVERY_N(n, LEVEL, ...)\
4366 if (ELPP_DEBUG_LOG) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
4367 # define DCSYSLOG_AFTER_N(n, LEVEL, ...)\
4368 if (ELPP_DEBUG_LOG) C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
4369 # define DCSYSLOG_N_TIMES(n, LEVEL, ...)\
4370 if (ELPP_DEBUG_LOG) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
4371 # define DSYSLOG(LEVEL) DCSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId)
4372 # define DSYSLOG_IF(condition, LEVEL) DCSYSLOG_IF(condition, LEVEL, el::base::consts::kSysLogLoggerId)
4373 # define DSYSLOG_EVERY_N(n, LEVEL) DCSYSLOG_EVERY_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
4374 # define DSYSLOG_AFTER_N(n, LEVEL) DCSYSLOG_AFTER_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
4375 # define DSYSLOG_N_TIMES(n, LEVEL) DCSYSLOG_N_TIMES(n, LEVEL, el::base::consts::kSysLogLoggerId)
4376 #else
4377 # define CSYSLOG(LEVEL, ...) el::base::NullWriter()
4378 # define CSYSLOG_IF(condition, LEVEL, ...) el::base::NullWriter()
4379 # define CSYSLOG_EVERY_N(n, LEVEL, ...) el::base::NullWriter()
4380 # define CSYSLOG_AFTER_N(n, LEVEL, ...) el::base::NullWriter()
4381 # define CSYSLOG_N_TIMES(n, LEVEL, ...) el::base::NullWriter()
4382 # define SYSLOG(LEVEL) el::base::NullWriter()
4383 # define SYSLOG_IF(condition, LEVEL) el::base::NullWriter()
4384 # define SYSLOG_EVERY_N(n, LEVEL) el::base::NullWriter()
4385 # define SYSLOG_AFTER_N(n, LEVEL) el::base::NullWriter()
4386 # define SYSLOG_N_TIMES(n, LEVEL) el::base::NullWriter()
4387 # define DCSYSLOG(LEVEL, ...) el::base::NullWriter()
4388 # define DCSYSLOG_IF(condition, LEVEL, ...) el::base::NullWriter()
4389 # define DCSYSLOG_EVERY_N(n, LEVEL, ...) el::base::NullWriter()
4390 # define DCSYSLOG_AFTER_N(n, LEVEL, ...) el::base::NullWriter()
4391 # define DCSYSLOG_N_TIMES(n, LEVEL, ...) el::base::NullWriter()
4392 # define DSYSLOG(LEVEL) el::base::NullWriter()
4393 # define DSYSLOG_IF(condition, LEVEL) el::base::NullWriter()
4394 # define DSYSLOG_EVERY_N(n, LEVEL) el::base::NullWriter()
4395 # define DSYSLOG_AFTER_N(n, LEVEL) el::base::NullWriter()
4396 # define DSYSLOG_N_TIMES(n, LEVEL) el::base::NullWriter()
4397 #endif // defined(ELPP_SYSLOG)
4398 //
4399 // Custom Debug Only Loggers - Requires (level, loggerId/s)
4400 //
4401 // undef existing
4402 #undef DCLOG
4403 #undef DCVLOG
4404 #undef DCLOG_IF
4405 #undef DCVLOG_IF
4406 #undef DCLOG_EVERY_N
4407 #undef DCVLOG_EVERY_N
4408 #undef DCLOG_AFTER_N
4409 #undef DCVLOG_AFTER_N
4410 #undef DCLOG_N_TIMES
4411 #undef DCVLOG_N_TIMES
4412 // Normal logs
4413 #define DCLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG(LEVEL, __VA_ARGS__)
4414 #define DCLOG_VERBOSE(vlevel, ...) if (ELPP_DEBUG_LOG) CLOG_VERBOSE(vlevel, __VA_ARGS__)
4415 #define DCVLOG(vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG(vlevel, __VA_ARGS__)
4416 // Conditional logs
4417 #define DCLOG_IF(condition, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_IF(condition, LEVEL, __VA_ARGS__)
4418 #define DCVLOG_IF(condition, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_IF(condition, vlevel, __VA_ARGS__)
4419 // Hit counts based logs
4420 #define DCLOG_EVERY_N(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_EVERY_N(n, LEVEL, __VA_ARGS__)
4421 #define DCVLOG_EVERY_N(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_EVERY_N(n, vlevel, __VA_ARGS__)
4422 #define DCLOG_AFTER_N(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_AFTER_N(n, LEVEL, __VA_ARGS__)
4423 #define DCVLOG_AFTER_N(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_AFTER_N(n, vlevel, __VA_ARGS__)
4424 #define DCLOG_N_TIMES(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_N_TIMES(n, LEVEL, __VA_ARGS__)
4425 #define DCVLOG_N_TIMES(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_N_TIMES(n, vlevel, __VA_ARGS__)
4426 //
4427 // Default Debug Only Loggers macro using CLOG(), CLOG_VERBOSE() and CVLOG() macros
4428 //
4429 #if !defined(ELPP_NO_DEBUG_MACROS)
4430 // undef existing
4431 #undef DLOG
4432 #undef DVLOG
4433 #undef DLOG_IF
4434 #undef DVLOG_IF
4435 #undef DLOG_EVERY_N
4436 #undef DVLOG_EVERY_N
4437 #undef DLOG_AFTER_N
4438 #undef DVLOG_AFTER_N
4439 #undef DLOG_N_TIMES
4440 #undef DVLOG_N_TIMES
4441 // Normal logs
4442 #define DLOG(LEVEL) DCLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4443 #define DVLOG(vlevel) DCVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID)
4444 // Conditional logs
4445 #define DLOG_IF(condition, LEVEL) DCLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4446 #define DVLOG_IF(condition, vlevel) DCVLOG_IF(condition, vlevel, ELPP_CURR_FILE_LOGGER_ID)
4447 // Hit counts based logs
4448 #define DLOG_EVERY_N(n, LEVEL) DCLOG_EVERY_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4449 #define DVLOG_EVERY_N(n, vlevel) DCVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
4450 #define DLOG_AFTER_N(n, LEVEL) DCLOG_AFTER_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4451 #define DVLOG_AFTER_N(n, vlevel) DCVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
4452 #define DLOG_N_TIMES(n, LEVEL) DCLOG_N_TIMES(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
4453 #define DVLOG_N_TIMES(n, vlevel) DCVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
4454 #endif // defined(ELPP_NO_DEBUG_MACROS)
4455 #if !defined(ELPP_NO_CHECK_MACROS)
4456 // Check macros
4457 #undef CCHECK
4458 #undef CPCHECK
4459 #undef CCHECK_EQ
4460 #undef CCHECK_NE
4461 #undef CCHECK_LT
4462 #undef CCHECK_GT
4463 #undef CCHECK_LE
4464 #undef CCHECK_GE
4465 #undef CCHECK_BOUNDS
4466 #undef CCHECK_NOTNULL
4467 #undef CCHECK_STRCASEEQ
4468 #undef CCHECK_STRCASENE
4469 #undef CHECK
4470 #undef PCHECK
4471 #undef CHECK_EQ
4472 #undef CHECK_NE
4473 #undef CHECK_LT
4474 #undef CHECK_GT
4475 #undef CHECK_LE
4476 #undef CHECK_GE
4477 #undef CHECK_BOUNDS
4478 #undef CHECK_NOTNULL
4479 #undef CHECK_STRCASEEQ
4480 #undef CHECK_STRCASENE
4481 #define CCHECK(condition, ...) CLOG_IF(!(condition), FATAL, __VA_ARGS__) << "Check failed: [" << #condition << "] "
4482 #define CPCHECK(condition, ...) CPLOG_IF(!(condition), FATAL, __VA_ARGS__) << "Check failed: [" << #condition << "] "
4483 #define CHECK(condition) CCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
4484 #define PCHECK(condition) CPCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
4485 #define CCHECK_EQ(a, b, ...) CCHECK(a == b, __VA_ARGS__)
4486 #define CCHECK_NE(a, b, ...) CCHECK(a != b, __VA_ARGS__)
4487 #define CCHECK_LT(a, b, ...) CCHECK(a < b, __VA_ARGS__)
4488 #define CCHECK_GT(a, b, ...) CCHECK(a > b, __VA_ARGS__)
4489 #define CCHECK_LE(a, b, ...) CCHECK(a <= b, __VA_ARGS__)
4490 #define CCHECK_GE(a, b, ...) CCHECK(a >= b, __VA_ARGS__)
4491 #define CCHECK_BOUNDS(val, min, max, ...) CCHECK(val >= min && val <= max, __VA_ARGS__)
4492 #define CHECK_EQ(a, b) CCHECK_EQ(a, b, ELPP_CURR_FILE_LOGGER_ID)
4493 #define CHECK_NE(a, b) CCHECK_NE(a, b, ELPP_CURR_FILE_LOGGER_ID)
4494 #define CHECK_LT(a, b) CCHECK_LT(a, b, ELPP_CURR_FILE_LOGGER_ID)
4495 #define CHECK_GT(a, b) CCHECK_GT(a, b, ELPP_CURR_FILE_LOGGER_ID)
4496 #define CHECK_LE(a, b) CCHECK_LE(a, b, ELPP_CURR_FILE_LOGGER_ID)
4497 #define CHECK_GE(a, b) CCHECK_GE(a, b, ELPP_CURR_FILE_LOGGER_ID)
4498 #define CHECK_BOUNDS(val, min, max) CCHECK_BOUNDS(val, min, max, ELPP_CURR_FILE_LOGGER_ID)
4499 #define CCHECK_NOTNULL(ptr, ...) CCHECK((ptr) != nullptr, __VA_ARGS__)
4500 #define CCHECK_STREQ(str1, str2, ...) CLOG_IF(!el::base::utils::Str::cStringEq(str1, str2), FATAL, __VA_ARGS__) \
4501 << "Check failed: [" << #str1 << " == " << #str2 << "] "
4502 #define CCHECK_STRNE(str1, str2, ...) CLOG_IF(el::base::utils::Str::cStringEq(str1, str2), FATAL, __VA_ARGS__) \
4503 << "Check failed: [" << #str1 << " != " << #str2 << "] "
4504 #define CCHECK_STRCASEEQ(str1, str2, ...) CLOG_IF(!el::base::utils::Str::cStringCaseEq(str1, str2), FATAL, __VA_ARGS__) \
4505 << "Check failed: [" << #str1 << " == " << #str2 << "] "
4506 #define CCHECK_STRCASENE(str1, str2, ...) CLOG_IF(el::base::utils::Str::cStringCaseEq(str1, str2), FATAL, __VA_ARGS__) \
4507 << "Check failed: [" << #str1 << " != " << #str2 << "] "
4508 #define CHECK_NOTNULL(ptr) CCHECK_NOTNULL((ptr), ELPP_CURR_FILE_LOGGER_ID)
4509 #define CHECK_STREQ(str1, str2) CCHECK_STREQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
4510 #define CHECK_STRNE(str1, str2) CCHECK_STRNE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
4511 #define CHECK_STRCASEEQ(str1, str2) CCHECK_STRCASEEQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
4512 #define CHECK_STRCASENE(str1, str2) CCHECK_STRCASENE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
4513 #undef DCCHECK
4514 #undef DCCHECK_EQ
4515 #undef DCCHECK_NE
4516 #undef DCCHECK_LT
4517 #undef DCCHECK_GT
4518 #undef DCCHECK_LE
4519 #undef DCCHECK_GE
4520 #undef DCCHECK_BOUNDS
4521 #undef DCCHECK_NOTNULL
4522 #undef DCCHECK_STRCASEEQ
4523 #undef DCCHECK_STRCASENE
4524 #undef DCPCHECK
4525 #undef DCHECK
4526 #undef DCHECK_EQ
4527 #undef DCHECK_NE
4528 #undef DCHECK_LT
4529 #undef DCHECK_GT
4530 #undef DCHECK_LE
4531 #undef DCHECK_GE
4532 #undef DCHECK_BOUNDS_
4533 #undef DCHECK_NOTNULL
4534 #undef DCHECK_STRCASEEQ
4535 #undef DCHECK_STRCASENE
4536 #undef DPCHECK
4537 #define DCCHECK(condition, ...) if (ELPP_DEBUG_LOG) CCHECK(condition, __VA_ARGS__)
4538 #define DCCHECK_EQ(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_EQ(a, b, __VA_ARGS__)
4539 #define DCCHECK_NE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_NE(a, b, __VA_ARGS__)
4540 #define DCCHECK_LT(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_LT(a, b, __VA_ARGS__)
4541 #define DCCHECK_GT(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_GT(a, b, __VA_ARGS__)
4542 #define DCCHECK_LE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_LE(a, b, __VA_ARGS__)
4543 #define DCCHECK_GE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_GE(a, b, __VA_ARGS__)
4544 #define DCCHECK_BOUNDS(val, min, max, ...) if (ELPP_DEBUG_LOG) CCHECK_BOUNDS(val, min, max, __VA_ARGS__)
4545 #define DCCHECK_NOTNULL(ptr, ...) if (ELPP_DEBUG_LOG) CCHECK_NOTNULL((ptr), __VA_ARGS__)
4546 #define DCCHECK_STREQ(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STREQ(str1, str2, __VA_ARGS__)
4547 #define DCCHECK_STRNE(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRNE(str1, str2, __VA_ARGS__)
4548 #define DCCHECK_STRCASEEQ(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRCASEEQ(str1, str2, __VA_ARGS__)
4549 #define DCCHECK_STRCASENE(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRCASENE(str1, str2, __VA_ARGS__)
4550 #define DCPCHECK(condition, ...) if (ELPP_DEBUG_LOG) CPCHECK(condition, __VA_ARGS__)
4551 #define DCHECK(condition) DCCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
4552 #define DCHECK_EQ(a, b) DCCHECK_EQ(a, b, ELPP_CURR_FILE_LOGGER_ID)
4553 #define DCHECK_NE(a, b) DCCHECK_NE(a, b, ELPP_CURR_FILE_LOGGER_ID)
4554 #define DCHECK_LT(a, b) DCCHECK_LT(a, b, ELPP_CURR_FILE_LOGGER_ID)
4555 #define DCHECK_GT(a, b) DCCHECK_GT(a, b, ELPP_CURR_FILE_LOGGER_ID)
4556 #define DCHECK_LE(a, b) DCCHECK_LE(a, b, ELPP_CURR_FILE_LOGGER_ID)
4557 #define DCHECK_GE(a, b) DCCHECK_GE(a, b, ELPP_CURR_FILE_LOGGER_ID)
4558 #define DCHECK_BOUNDS(val, min, max) DCCHECK_BOUNDS(val, min, max, ELPP_CURR_FILE_LOGGER_ID)
4559 #define DCHECK_NOTNULL(ptr) DCCHECK_NOTNULL((ptr), ELPP_CURR_FILE_LOGGER_ID)
4560 #define DCHECK_STREQ(str1, str2) DCCHECK_STREQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
4561 #define DCHECK_STRNE(str1, str2) DCCHECK_STRNE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
4562 #define DCHECK_STRCASEEQ(str1, str2) DCCHECK_STRCASEEQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
4563 #define DCHECK_STRCASENE(str1, str2) DCCHECK_STRCASENE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
4564 #define DPCHECK(condition) DCPCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
4565 #endif // defined(ELPP_NO_CHECK_MACROS)
4566 #if defined(ELPP_DISABLE_DEFAULT_CRASH_HANDLING)
4567 # define ELPP_USE_DEF_CRASH_HANDLER false
4568 #else
4569 # define ELPP_USE_DEF_CRASH_HANDLER true
4570 #endif // defined(ELPP_DISABLE_DEFAULT_CRASH_HANDLING)
4571 #define ELPP_CRASH_HANDLER_INIT
4572 #define ELPP_INIT_EASYLOGGINGPP(val) \
4573 namespace el { \
4574 namespace base { \
4575 el::base::type::StoragePointer elStorage(val); \
4576 } \
4577 el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER); \
4578 }
4579 
4580 #if ELPP_ASYNC_LOGGING
4581 # define INITIALIZE_EASYLOGGINGPP ELPP_INIT_EASYLOGGINGPP(new el::base::Storage(el::LogBuilderPtr(new el::base::DefaultLogBuilder()),\
4582 new el::base::AsyncDispatchWorker()))
4583 #else
4584 # define INITIALIZE_EASYLOGGINGPP ELPP_INIT_EASYLOGGINGPP(new el::base::Storage(el::LogBuilderPtr(new el::base::DefaultLogBuilder())))
4585 #endif // ELPP_ASYNC_LOGGING
4586 #define INITIALIZE_NULL_EASYLOGGINGPP \
4587 namespace el {\
4588 namespace base {\
4589 el::base::type::StoragePointer elStorage;\
4590 }\
4591 el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\
4592 }
4593 #define SHARE_EASYLOGGINGPP(initializedStorage)\
4594 namespace el {\
4595 namespace base {\
4596 el::base::type::StoragePointer elStorage(initializedStorage);\
4597 }\
4598 el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\
4599 }
4600 
4601 #if defined(ELPP_UNICODE)
4602 # define START_EASYLOGGINGPP(argc, argv) el::Helpers::setArgs(argc, argv); std::locale::global(std::locale(""))
4603 #else
4604 # define START_EASYLOGGINGPP(argc, argv) el::Helpers::setArgs(argc, argv)
4605 #endif // defined(ELPP_UNICODE)
4606 #endif // EASYLOGGINGPP_H
std::unordered_map< Level, std::size_t > m_logFlushThresholdMap
Conf_T & getConfigByRef(Level level, std::unordered_map< Level, Conf_T > *confMap, const char *confName)
static const textual_icon lock
Definition: model-views.h:218
const base::type::string_t & message(void) const
void setArgs(int argc, const char **argv)
Sets arguments and parses them.
std::shared_ptr< base::type::fstream_t > FileStreamPtr
Specifies precision of the subsecond part. It should be within range (1-6).
void setValue(Level level, const Conf_T &value, std::unordered_map< Level, Conf_T > *confMap, bool includeGlobalLevel=true)
void setLogBuilder(const LogBuilderPtr &logBuilder)
const std::string & configurationFile(void) const
Gets configuration file used in parsing this configurations.
Abstract registry (aka repository) that provides basic interface for pointer repository specified by ...
GLint level
std::unordered_map< Level, bool > m_enabledMap
const std::string & value(void) const
Gets string based configuration value.
virtual const_iterator cbegin(void) const ELPP_FINAL
FormatSpecifierValueResolver m_resolver
base::threading::Mutex m_mutex
Parser used internally to parse configurations from file or text.
void addFlag(base::FormatFlags flag)
void unregister(const T_Key &uniqKey)
Unregisters single entry mapped to specified unique key.
GLuint GLuint end
GLboolean GLboolean GLboolean b
static const unsigned int kMaxLogPerCounter
Determines whether or not corresponding level and logger of logging is enabled You may disable all lo...
Mutex wrapper used when multi-threading is disabled.
GLenum GLsizei const void * pointer
Operating System helper static class used internally. You should not use it.
base::type::EnumType flags(void) const
std::fstream fstream_t
static const textual_icon unlock
Definition: model-views.h:237
typedef void(APIENTRY *GLDEBUGPROC)(GLenum source
SysLogInitializer(const char *processIdent, int options=0, int facility=0)
Determines whether or not performance tracking is enabled.
GLuint const GLchar * name
virtual void releaseLock(void) ELPP_FINAL
static bool installLogDispatchCallback(const std::string &id)
Installs post log dispatch callback, this callback is triggered when log is dispatched.
static T * callback(const std::string &id, std::unordered_map< std::string, TPtr > *mapT)
void uninstallLoggerRegistrationCallback(const std::string &id)
Used to find configuration from configuration (pointers) repository. Avoid using it.
Creates logger automatically when not available.
static const char * kFilePathSeperator
static void removeFlag(LoggingFlag flag)
Removes logging flag used internally.
GLenum const void * addr
Definition: glext.h:8864
bool operator==(const plane &lhs, const plane &rhs)
Definition: rendering.h:134
Container::const_iterator const_iterator
static bool hasFlag(LoggingFlag flag)
Determines whether or not certain flag is active.
GLdouble s
void setLoggingLevel(Level level)
Information representing errors in application but application will keep running. ...
virtual ~Logger(void)
const base::type::LineNumber m_line
const std::unordered_map< std::string, base::type::VerboseLevel > & modules(void) const
ELPP_EXPORT base::type::StoragePointer elStorage
Represents log format containing flags and date format. This is used internally to start initial log...
void setDefaultLogBuilder(LogBuilderPtr &logBuilderPtr)
bool m_isConfigured
std::shared_ptr< base::Storage > StoragePointer
base::type::stringstream_t & stream(void)
static std::string getThreadName()
#define ELPP_EXPORT
static base::type::EnumType castToInt(Level level)
Casts level to int, useful for iterating through enum.
std::ostream ostream_t
static T * loggerRegistrationCallback(const std::string &id)
virtual void log(el::base::type::ostream_t &os) const
std::size_t hitCounts(void) const
virtual const_iterator cend(void) const ELPP_FINAL
MessageBuilder & operator<<(std::ostream &(*OStreamMani)(std::ostream &))
GLuint64 GLenum void * handle
Definition: glext.h:7785
virtual ~Configurations(void)
virtual ~LogFormat(void)
std::unordered_map< std::string, base::type::PerformanceTrackingCallbackPtr > m_performanceTrackingCallbacks
virtual void deepCopy(const AbstractRegistry< T_Ptr, std::vector< T_Ptr * >> &sr)
bool validateNTimesCounter(const char *filename, base::type::LineNumber lineNumber, std::size_t n)
GLsizei const GLchar *const * path
Definition: glext.h:4276
#define ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(temp)
GLfloat value
static void setThreadName(const std::string &name)
Sets thread name for current thread. Requires std::thread.
bool get_id(DEVINST devinst, std::string *p_out_str)
#define ELPP
bool enabled(Level level) const
friend base::type::ostream_t & operator<<(base::type::ostream_t &os, const RegistryWithPred &sr)
static bool uninstallCustomFormatSpecifier(const char *formatSpecifier)
Uninstalls user defined format specifier and handler.
std::shared_ptr< LogDispatchCallback > LogDispatchCallbackPtr
Informational events most useful for developers to debug application.
base::type::VerboseLevel m_level
base::RegisteredLoggers * registeredLoggers(void) const
Severe error information that will presumably abort application.
base::threading::Mutex m_threadNamesLock
Main entry point of each logging.
ConfigurationType m_configurationType
static Level castFromInt(base::type::EnumType l)
Casts int(ushort) to level, useful for iterating through enum.
Base of thread safe class, this class is inheritable-only.
ConfigurationType m_configurationType
void setGlobally(ConfigurationType configurationType, const std::string &value)
Sets configuration for all levels.
base::threading::internal::NoScopedLock< base::threading::Mutex > ScopedLock
Easylogging++ entry namespace.
Base of Easylogging++ friendly class.
LoggingFlag
Flags used while writing logs. This flags are set by user.
bool operator==(const char *formatSpecifier)
Makes sure we have new line for each container log entry.
SubsecondPrecision MillisecondsWidth
Type alias of SubsecondPrecision.
Disables comparing performance tracker&#39;s checkpoints.
Conf_T & unsafeGetConfigByRef(Level level, std::unordered_map< Level, Conf_T > *confMap, const char *confName)
void setFlags(base::type::EnumType flags)
static const unsigned int kMaxLogPerContainer
unsigned long int LineNumber
GLsizei const GLchar *const * string
static std::string getCurrentThreadId(void)
bool hasFlag(base::FormatFlags flag) const
base::DispatchAction dispatchAction(void) const
const char * formatSpecifier(void) const
bool hasFlag(LoggingFlag flag) const
const struct el::base::consts::@14 kCrashSignals[]
std::unordered_map< Level, bool > m_performanceTrackingMap
#define ELPP_INTERNAL_INFO(lvl, msg)
static const char * convertToString(Level level)
Converts level to associated const char*.
virtual void registerNew(T_Ptr *ptr) ELPP_FINAL
GLuint GLuint stream
Definition: glext.h:1790
virtual iterator end(void) ELPP_FINAL
RegistryWithPred(const RegistryWithPred &sr)
Copy constructor that is useful for base classes. Try to avoid this constructor, use move constructor...
base::VRegistry * m_vRegistry
std::unordered_map< Level, std::string > m_filenameMap
base::RegisteredLoggers * m_registeredLoggers
Represents unknown level.
base::type::string_t m_format
const base::type::string_t & format(void) const
GLdouble n
Definition: glext.h:1966
GLint limit
Definition: glext.h:9964
e
Definition: rmse.py:177
Writer & operator<<(const T &log)
virtual void unregisterAll(void) ELPP_FINAL
Unregisters all the pointers from current repository.
Level
Represents enumeration for severity level used to determine level of logging.
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:6216
AbstractRegistry(AbstractRegistry &&sr)
Move constructor that is useful for base classes.
RegistryWithPred< T_Ptr, Pred >::iterator iterator
base::DispatchAction m_dispatchAction
const char * name
const char * brief
static std::string convertTemplateToStdString(const T &templ)
Converts template to std::string - useful for loggable classes to log containers within log(std::ostr...
void setApplicationArguments(int argc, const char **argv)
T * logDispatchCallback(const std::string &id)
virtual void unregister(T_Ptr *&ptr) ELPP_FINAL
virtual ~Configuration(void)
const LogMessage * logMessage(void) const
FormatFlags
Format flags used to determine specifiers that are active for performance improvements.
GLenum GLuint id
std::ostream & operator<<(std::ostream &os, const textual_icon &i)
Definition: model-views.h:118
LogBuilderPtr m_logBuilder
virtual ~Writer(void)
std::unordered_map< Level, base::FileStreamPtr > m_fileStreamMap
GLuint index
Determines log file (full path) to write logs to for correponding level and logger.
base::RegisteredHitCounters * hitCounters(void) const
GLdouble t
base::type::LineNumber m_line
base::TypedConfigurations * m_typedConfigurations
Writes nothing - Used when certain log is disabled.
base::type::LineNumber m_lineNumber
Level level(void) const
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum GLsizei len
Definition: glext.h:3285
static const unsigned int kDefaultSubsecondPrecision
Loggers repository.
def info(name, value, persistent=False)
Definition: test.py:301
Conf_T getConfigByVal(Level level, const std::unordered_map< Level, Conf_T > *confMap, const char *confName)
virtual ~LogBuilder(void)
#define ELPP_INTERNAL_ERROR(msg, pe)
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:6215
std::size_t operator()(const el::Level &l) const
Adds spaces b/w logs that separated by left-shift operator.
std::unordered_map< std::string, std::string > m_paramsWithValue
Internal helper class that prevent copy constructor for class.
String utilities helper class used internally. You should not use it.
CommandLineArgs(int argc, const char **argv)
virtual ~Loggable(void)
not_this_one begin(...)
static void defaultPreRollOutCallback(const char *, std::size_t)
static const int kCrashSignalsCount
const struct el::base::consts::@13 kTimeFormats[]
Makes sure if -vmodule is used and does not specifies a module, then verbose logging is allowed via t...
void initialize(Logger *logger)
Information that can be highly useful and vary with verbose logging level.
void setDispatchAction(base::DispatchAction dispatchAction)
Determines format of logging corresponding level and logger.
static void removeFlag(Enum e, base::type::EnumType *flag)
static void setStorage(base::type::StoragePointer storage)
Shares logging repository (base::Storage)
CustomFormatSpecifier(const char *formatSpecifier, const FormatSpecifierValueResolver &resolver)
Disable VModules extensions.
#define ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(temp)
static void installCustomFormatSpecifier(const CustomFormatSpecifier &customFormatSpecifier)
Installs user defined format specifier and handler.
std::unique_ptr< el::base::PerformanceTracker > PerformanceTrackerPtr
bool contains(const std::shared_ptr< librealsense::device_info > &first, const std::shared_ptr< librealsense::device_info > &second)
Definition: context.cpp:49
friend el::base::type::ostream_t & operator<<(el::base::type::ostream_t &os, const Loggable &loggable)
GLsizeiptr size
base::type::EnumType m_flags
virtual std::size_t size(void) const ELPP_FINAL
base::TypedConfigurations * typedConfigurations(void)
void addFlag(LoggingFlag flag)
static std::enable_if< std::is_pointer< T * >::value, void >::type safeDelete(T *&pointer)
Deletes memory safely and points to null.
Writer & operator<<(std::ostream &(*log)(std::ostream &))
bool validateEveryNCounter(const char *filename, base::type::LineNumber lineNumber, std::size_t occasion)
std::unordered_map< Level, unsigned int > m_unflushedCount
A pointer registry mechanism to manage memory and provide search functionalities. (predicate version)...
const char * m_func
LogDispatcher(bool proceed, LogMessage *logMessage, base::DispatchAction dispatchAction)
bool operator==(const SubsecondPrecision &ssPrec)
const GLubyte * c
Definition: glext.h:12690
GLuint counter
Definition: glext.h:5684
base::type::EnumType flags(void) const
std::unordered_map< std::string, FileStreamPtr > LogStreamsReferenceMap
std::vector< std::string > m_params
std::shared_ptr< PerformanceTrackingCallback > PerformanceTrackingCallbackPtr
static base::type::EnumType And(Enum e, base::type::EnumType flag)
std::unordered_map< Level, bool > m_toStandardOutputMap
LogMessage * m_msg
virtual void log(el::base::type::ostream_t &os) const
static const Level kPerformanceTrackerDefaultLevel
base::LogStreamsReferenceMap m_logStreamsReference
static void uninstallLogDispatchCallback(const std::string &id)
Uninstalls log dispatch callback.
Registry & operator=(const Registry &sr)
Assignment operator that unregisters all the existing registeries and deeply copies each of repo elem...
const char * m_filename
LogMessage(Level level, const std::string &file, base::type::LineNumber line, const std::string &func, base::type::VerboseLevel verboseLevel, Logger *logger)
Preserves time format and does not convert it to sec, hour etc (performance tracking only) ...
#define ELPP_SIMPLE_LOG(LOG_TYPE)
void clear(void)
Clears repository so that all the configurations are unset.
unsigned int EnumType
std::function< std::string(const LogMessage *)> FormatSpecifierValueResolver
Resolving function for format specifier.
Registry< T_Ptr, T_Key >::const_iterator const_iterator
const base::utils::CommandLineArgs * commandLineArgs(void) const
static base::type::EnumType castToInt(ConfigurationType configurationType)
Casts configuration type to int, useful for iterating through enum.
base::LogStreamsReferenceMap * m_logStreamsReference
bool enabled(void) const
bool validateFileRolling(Level level, const PreRollOutCallback &preRollOutCallback)
static const char * kDefaultLoggerId
bool has(const std::string &id)
HitCounter(const HitCounter &hitCounter)
Static class that contains helper functions for el::ConfigurationType.
bool operator!=(const AbstractRegistry< T_Ptr, Container > &other)
const char * filename(void) const
bool isFlushNeeded(Level level)
virtual void log(el::base::type::ostream_t &) const =0
static std::condition_variable cv
std::string m_id
GLint GLint GLsizei GLint GLenum format
static void addFlag(Enum e, base::type::EnumType *flag)
void unsetPreRollOutCallback(void)
bool operator()(const HitCounter *counter)
def run(include_folder_path, addon_folder_path)
Definition: enums.py:46
std::string trim(std::string const &str)
Returns a new string without whitespace at the start/end.
static void setArgs(int argc, const char **argv)
Sets application arguments and figures out whats active for logging and whats not.
bool endsWith(std::string const &s, std::string const &suffix)
base::DispatchAction m_dispatchAction
static bool isDigit(char c)
Checks if character is digit. Dont use libc implementation of it to prevent locale issues...
static const char * kPerformanceLoggerId
Adds flag and removes it when scope goes out.
unsigned short VerboseLevel
void unregister(Logger *&logger)
#define ELPP_UNUSED(x)
void setEnabled(bool enabled)
GLbitfield flags
A pointer registry mechanism to manage memory and provide search functionalities. (non-predicate vers...
RegistryWithPred & operator=(const RegistryWithPred &sr)
Assignment operator that unregisters all the existing registeries and deeply copies each of repo elem...
static const std::size_t kSourceFilenameMaxLength
def callback(frame)
Definition: t265_stereo.py:91
Static helpers to deal with loggers and their configurations.
GLenum GLenum GLsizei const GLuint GLboolean enabled
base::VRegistry * vRegistry(void) const
std::string m_currentUser
base::threading::Mutex m_customFormatSpecifiersLock
bool installLogDispatchCallback(const std::string &id)
static bool hasFlag(Enum e, base::type::EnumType flag)
GLuint GLfloat x0
Definition: glext.h:9721
std::unordered_map< std::string, std::string > m_threadNames
Contains utilities for cross-platform date/time. This class make use of el::base::utils::Str.
void init(void)
Definition: boing.c:180
ScopedAddFlag(LoggingFlag flag)
GLuint start
base::threading::internal::NoMutex Mutex
static const char kFormatSpecifierCharValue
BOOST_DEDUCED_TYPENAME optional< T >::reference_const_type get(optional< T > const &opt)
const std::string & parentApplicationName(void) const
std::unordered_map< Level, base::LogFormat > m_logFormatMap
Configurations with data types.
base::type::VerboseLevel verboseLevel(void) const
MessageBuilder & writeIterator(Iterator begin_, Iterator end_, std::size_t size_)
static void setLoggingLevel(Level level)
Sets hierarchy for logging. Needs to enable logging flag (HierarchicalLogging)
virtual void unregisterAll(void) ELPP_FINAL
Unregisters all the pointers from current repository.
std::vector< std::string > m_loggerIds
Configurations * m_configurations
void setPreRollOutCallback(const PreRollOutCallback &callback)
base::utils::CommandLineArgs m_commandLineArgs
const base::type::char_t * unit
PreRollOutCallback m_preRollOutCallback
std::shared_ptr< LogBuilder > LogBuilderPtr
virtual void acquireLock(void) ELPP_FINAL
const base::HitCounter * getCounter(const char *filename, base::type::LineNumber lineNumber)
Gets hit counter registered at specified position.
Make terminal output colorful for supported terminals.
#define ELPP_LITERAL(txt)
HitCounter & operator=(const HitCounter &hitCounter)
Repository for hit counters used across the application.
void removeFlag(LoggingFlag flag)
Configurations m_defaultConfigurations
Writer(Level level, const char *file, base::type::LineNumber line, const char *func, base::DispatchAction dispatchAction=base::DispatchAction::NormalLog, base::type::VerboseLevel verboseLevel=0)
static const int kTimeFormatsCount
virtual ~SysLogInitializer(void)
ConfigurationType configurationType(void) const
Gets configuration type of current configuration.
bool installLoggerRegistrationCallback(const std::string &id)
std::vector< std::pair< stream_profile, frame_callback > > configurations
Definition: recorder.h:485
bool validateAfterNCounter(const char *filename, base::type::LineNumber lineNumber, std::size_t n)
User-provided custom format specifier.
void validateHitCounts(std::size_t n)
Validates hit counts and resets it if necessary.
Useful when application has potentially harmful situtaions.
PErrorWriter(Level level, const char *file, base::type::LineNumber line, const char *func, base::DispatchAction dispatchAction=base::DispatchAction::NormalLog, base::type::VerboseLevel verboseLevel=0)
GLenum func
std::string string_t
When handling crashes by default, detailed crash reason will be logged as well.
DispatchAction
Action to be taken for dispatching.
void setThreadName(const std::string &name)
Sets thread name for current thread. Requires std::thread.
Enables strict file rolling.
static base::type::StoragePointer storage()
Conf_T unsafeGetConfigByVal(Level level, const std::unordered_map< Level, Conf_T > *confMap, const char *confName)
std::unordered_map< std::string, std::unique_ptr< base::threading::Mutex > > m_fileLocks
static void uninstallPreRollOutCallback(void)
Uninstalls pre rollout callback.
const char * m_file
NullWriter & operator<<(const T &)
const char * detail
base::type::LineNumber lineNumber(void) const
std::string m_parentApplicationName
static void uninstallLoggerRegistrationCallback(const std::string &id)
Uninstalls log dispatch callback.
virtual Container & list(void) ELPP_FINAL
Returns underlying container by reference.
LONG WINAPI CrashHandler(EXCEPTION_POINTERS *ep)
Removes flag and add it when scope goes out.
static T * logDispatchCallback(const std::string &id)
Level level(void) const
Gets level of current configuration.
MessageBuilder & operator<<(const std::string &msg)
const std::string & dateTimeFormat(void) const
std::string m_func
Writer & construct(Logger *logger, bool needLock=true)
LogBuilder * logBuilder(void) const
Flushes log with every log-entry (performance sensative) - Disabled by default.
const Configurations * configurations(void) const
static void reserveCustomFormatSpecifiers(std::size_t size)
Reserve space for custom format specifiers for performance.
void next(auto_any_t cur, type2type< T, C > *)
Definition: foreach.hpp:757
Thread-safe Configuration repository.
CommandLineArgs(int argc, char **argv)
Writer(LogMessage *msg, base::DispatchAction dispatchAction=base::DispatchAction::NormalLog)
Mainly useful to represent current progress of application.
void setValue(const std::string &value)
Set string based configuration value.
GLenum array
Definition: glext.h:7022
base::threading::Mutex m_fileLocksMapLock
static bool installCallback(const std::string &id, std::unordered_map< std::string, TPtr > *mapT)
base::threading::Mutex & customFormatSpecifiersLock()
Dispatches log messages.
Predicate(const char *filename, base::type::LineNumber lineNumber)
virtual void deepCopy(const AbstractRegistry< T_Ptr, std::unordered_map< T_Key, T_Ptr * >> &sr) ELPP_FINAL
static void reconfigureAllLoggers(ConfigurationType configurationType, const std::string &value)
Reconfigures single configuration for all the loggers.
void construct(Factory const &factory, void *address)
std::function< void(const char *, std::size_t)> PreRollOutCallback
void resetLocation(const char *filename, base::type::LineNumber lineNumber)
Resets location of current hit counter.
Configurations * configurations(void)
bool operator==(const AbstractRegistry< T_Ptr, Container > &other)
TimestampUnit
Enum to represent timestamp unit.
Command line arguments for application if specified using el::Helpers::setArgs(..) or START_EASYLOGGI...
Configurations * defaultConfigurations(void)
PreRollOutCallback & preRollOutCallback(void)
static auto it
void setDefaultConfigurations(const Configurations &configurations)
base::RegisteredHitCounters * m_registeredHitCounters
base::DispatchAction m_dispatchAction
std::string getThreadName(const std::string &threadId)
static const char kFormatSpecifierChar
base::MessageBuilder m_messageBuilder
GLenum type
Specifies number of log entries to hold until we flush pending log data.