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