ifw  0.0.1-dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
easylogging++.h
Go to the documentation of this file.
1 //
2 // Easylogging++ v9.80
3 // Single-header only, cross-platform logging library for C++ applications
4 //
5 // Copyright (c) 2015 muflihun.com
6 //
7 // This library is released under the MIT Licence.
8 // http://easylogging.muflihun.com/licence.php
9 //
10 // easylogging@muflihun.com
11 //
12 // https://github.com/easylogging/easyloggingpp
13 // http://easylogging.muflihun.com
14 // http://muflihun.com
15 //
16 #ifndef EASYLOGGINGPP_H
17 #define EASYLOGGINGPP_H
18 // Compilers and C++0x/C++11 Evaluation
19 #if defined(__GNUC__)
20 # define ELPP_COMPILER_GCC 1
21 # define ELPP_GCC_VERSION (__GNUC__ * 10000 \
22  + __GNUC_MINOR__ * 100 \
23  + __GNUC_PATCHLEVEL__)
24 # if defined(__GXX_EXPERIMENTAL_CXX0X__)
25 # define ELPP_CXX0X 1
26 # elif(ELPP_GCC_VERSION >= 40801)
27 # define ELPP_CXX11 1
28 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
29 #endif // defined(__GNUC__)
30 // Visual C++
31 #if defined(_MSC_VER)
32 # define ELPP_COMPILER_MSVC 1
33 # define ELPP_CRT_DBG_WARNINGS 1
34 # if (_MSC_VER == 1600)
35 # define ELPP_CXX0X 1
36 # elif(_MSC_VER >= 1700)
37 # define ELPP_CXX11 1
38 # endif // (_MSC_VER == 1600)
39 #endif // defined(_MSC_VER)
40 // Clang++
41 #if defined(__clang__) && (__clang__ == 1)
42 # define ELPP_COMPILER_CLANG 1
43 # define ELPP_CLANG_VERSION (__clang_major__ * 10000 \
44  + __clang_minor__ * 100 \
45  + __clang_patchlevel__)
46 # if (ELPP_CLANG_VERSION >= 30300)
47 # define ELPP_CXX11 1
48 # endif // (ELPP_CLANG_VERSION >= 30300)
49 #endif // defined(__clang__) && (__clang__ == 1)
50 // MinGW
51 #if defined(__MINGW32__) || defined(__MINGW64__)
52 # define ELPP_MINGW 1
53 #endif // defined(__MINGW32__) || defined(__MINGW64__)
54 // Cygwin
55 #if defined(__CYGWIN__) && (__CYGWIN__ == 1)
56 # define ELPP_CYGWIN 1
57 #endif // defined(__CYGWIN__) && (__CYGWIN__ == 1)
58 // Intel C++
59 #if defined(__INTEL_COMPILER)
60 # define ELPP_COMPILER_INTEL 1
61 #endif
62 // Operating System Evaluation
63 // Windows
64 #if defined(_WIN32) || defined(_WIN64)
65 # define ELPP_OS_WINDOWS 1
66 #endif // defined(_WIN32) || defined(_WIN64)
67 // Linux
68 #if (defined(__linux) || defined(__linux__))
69 # define ELPP_OS_LINUX 1
70 #endif // (defined(__linux) || defined(__linux__))
71 // Mac
72 #if defined(__APPLE__)
73 # define ELPP_OS_MAC 1
74 #endif // defined(__APPLE__)
75 // FreeBSD
76 #if defined(__FreeBSD__)
77 # define ELPP_OS_FREEBSD 1
78 #endif
79 // Solaris
80 #if defined(__sun)
81 # define ELPP_OS_SOLARIS 1
82 #endif
83 // Unix
84 #if ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_SOLARIS) && (!ELPP_OS_WINDOWS))
85 # define ELPP_OS_UNIX 1
86 #endif // ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_SOLARIS) && (!ELPP_OS_WINDOWS))
87 // Android
88 #if defined(__ANDROID__)
89 # define ELPP_OS_ANDROID 1
90 #endif // defined(__ANDROID__)
91 // Evaluating Cygwin as *nix OS
92 #if !ELPP_OS_UNIX && !ELPP_OS_WINDOWS && ELPP_CYGWIN
93 # undef ELPP_OS_UNIX
94 # undef ELPP_OS_LINUX
95 # define ELPP_OS_UNIX 1
96 # define ELPP_OS_LINUX 1
97 #endif // !ELPP_OS_UNIX && !ELPP_OS_WINDOWS && ELPP_CYGWIN
98 #if !defined(ELPP_INTERNAL_DEBUGGING_OUT_INFO)
99 # define ELPP_INTERNAL_DEBUGGING_OUT_INFO std::cout
100 #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
101 #if !defined(ELPP_INTERNAL_DEBUGGING_OUT_ERROR)
102 # define ELPP_INTERNAL_DEBUGGING_OUT_ERROR std::cerr
103 #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
104 #if !defined(ELPP_INTERNAL_DEBUGGING_ENDL)
105 # define ELPP_INTERNAL_DEBUGGING_ENDL std::endl
106 #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
107 #if !defined(ELPP_INTERNAL_DEBUGGING_MSG)
108 # define ELPP_INTERNAL_DEBUGGING_MSG(msg) msg
109 #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
110 // Internal Assertions and errors
111 #if !defined(ELPP_DISABLE_ASSERT)
112 # if (defined(ELPP_DEBUG_ASSERT_FAILURE))
113 # define ELPP_ASSERT(expr, msg) if (!(expr)) { \
114  std::stringstream internalInfoStream; internalInfoStream << msg; \
115  ELPP_INTERNAL_DEBUGGING_OUT_ERROR \
116  << "EASYLOGGING++ ASSERTION FAILED (LINE: " << __LINE__ << ") [" #expr << "] WITH MESSAGE \"" \
117  << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << "\"" << ELPP_INTERNAL_DEBUGGING_ENDL; base::utils::abort(1, \
118  "ELPP Assertion failure, please define ELPP_DEBUG_ASSERT_FAILURE"); }
119 # else
120 # define ELPP_ASSERT(expr, msg) if (!(expr)) { \
121  std::stringstream internalInfoStream; internalInfoStream << msg; \
122  ELPP_INTERNAL_DEBUGGING_OUT_ERROR\
123  << "ASSERTION FAILURE FROM EASYLOGGING++ (LINE: " \
124  << __LINE__ << ") [" #expr << "] WITH MESSAGE \"" << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << "\"" \
125  << ELPP_INTERNAL_DEBUGGING_ENDL; }
126 # endif // (defined(ELPP_DEBUG_ASSERT_FAILURE))
127 #else
128 # define ELPP_ASSERT(x, y)
129 #endif //(!defined(ELPP_DISABLE_ASSERT)
130 #if ELPP_COMPILER_MSVC
131 # define ELPP_INTERNAL_DEBUGGING_WRITE_PERROR \
132  { char buff[256]; strerror_s(buff, 256, errno); \
133  ELPP_INTERNAL_DEBUGGING_OUT_ERROR << ": " << buff << " [" << errno << "]";} (void)0
134 #else
135 # define ELPP_INTERNAL_DEBUGGING_WRITE_PERROR \
136  ELPP_INTERNAL_DEBUGGING_OUT_ERROR << ": " << strerror(errno) << " [" << errno << "]"; (void)0
137 #endif // ELPP_COMPILER_MSVC
138 #if defined(ELPP_DEBUG_ERRORS)
139 # if !defined(ELPP_INTERNAL_ERROR)
140 # define ELPP_INTERNAL_ERROR(msg, pe) { \
141  std::stringstream internalInfoStream; internalInfoStream << "<ERROR> " << msg; \
142  ELPP_INTERNAL_DEBUGGING_OUT_ERROR \
143  << "ERROR FROM EASYLOGGING++ (LINE: " << __LINE__ << ") " \
144  << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << ELPP_INTERNAL_DEBUGGING_ENDL; \
145  if (pe) { ELPP_INTERNAL_DEBUGGING_OUT_ERROR << " "; ELPP_INTERNAL_DEBUGGING_WRITE_PERROR; }} (void)0
146 # endif
147 #else
148 # undef ELPP_INTERNAL_INFO
149 # define ELPP_INTERNAL_ERROR(msg, pe)
150 #endif // defined(ELPP_DEBUG_ERRORS)
151 #if (defined(ELPP_DEBUG_INFO))
152 # if !(defined(ELPP_INTERNAL_INFO_LEVEL))
153 # define ELPP_INTERNAL_INFO_LEVEL 9
154 # endif // !(defined(ELPP_INTERNAL_INFO_LEVEL))
155 # if !defined(ELPP_INTERNAL_INFO)
156 # define ELPP_INTERNAL_INFO(lvl, msg) { if (lvl <= ELPP_INTERNAL_INFO_LEVEL) { \
157  std::stringstream internalInfoStream; internalInfoStream << "<INFO> " << msg; \
158  ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) \
159  << ELPP_INTERNAL_DEBUGGING_ENDL; }}
160 # endif
161 #else
162 # undef ELPP_INTERNAL_INFO
163 # define ELPP_INTERNAL_INFO(lvl, msg)
164 #endif // (defined(ELPP_DEBUG_INFO))
165 #if defined(ELPP_STACKTRACE_ON_CRASH)
166 # if (ELPP_COMPILER_GCC && !ELPP_MINGW)
167 # define ELPP_STACKTRACE 1
168 # else
169 # if ELPP_COMPILER_MSVC
170 # pragma message("Stack trace not available for this compiler")
171 # else
172 # warning "Stack trace not available for this compiler";
173 # endif // ELPP_COMPILER_MSVC
174 # endif // ELPP_COMPILER_GCC
175 #endif // (defined(ELPP_STACKTRACE_ON_CRASH))
176 // Miscellaneous macros
177 #define ELPP_UNUSED(x) (void)x
178 #if ELPP_OS_UNIX
179 // Log file permissions for unix-based systems
180 # define ELPP_LOG_PERMS S_IRUSR | S_IWUSR | S_IXUSR | S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IXOTH
181 #endif // ELPP_OS_UNIX
182 #if defined(ELPP_AS_DLL) && ELPP_COMPILER_MSVC
183 # if defined(ELPP_EXPORT_SYMBOLS)
184 # define ELPP_EXPORT __declspec(dllexport)
185 # else
186 # define ELPP_EXPORT __declspec(dllimport)
187 # endif // defined(ELPP_EXPORT_SYMBOLS)
188 #else
189 # define ELPP_EXPORT
190 #endif // defined(ELPP_AS_DLL) && ELPP_COMPILER_MSVC
191 // Some special functions that are VC++ specific
192 #undef STRTOK
193 #undef STRERROR
194 #undef STRCAT
195 #undef STRCPY
196 #if ELPP_CRT_DBG_WARNINGS
197 # define STRTOK(a, b, c) strtok_s(a, b, c)
198 # define STRERROR(a, b, c) strerror_s(a, b, c)
199 # define STRCAT(a, b, len) strcat_s(a, len, b)
200 # define STRCPY(a, b, len) strcpy_s(a, len, b)
201 #else
202 # define STRTOK(a, b, c) strtok(a, b)
203 # define STRERROR(a, b, c) strerror(c)
204 # define STRCAT(a, b, len) strcat(a, b)
205 # define STRCPY(a, b, len) strcpy(a, b)
206 #endif
207 // Compiler specific support evaluations
208 #if (!ELPP_MINGW && !ELPP_COMPILER_CLANG) || defined(ELPP_FORCE_USE_STD_THREAD)
209 # define ELPP_USE_STD_THREADING 1
210 #endif // (!ELPP_MINGW && !ELPP_COMPILER_CLANG) || defined(ELPP_FORCE_USE_STD_THREAD)
211 #undef ELPP_FINAL
212 #if ELPP_COMPILER_INTEL || (ELPP_GCC_VERSION < 40702)
213 # define ELPP_FINAL
214 #else
215 # define ELPP_FINAL final
216 #endif // ELPP_COMPILER_INTEL || (ELPP_GCC_VERSION < 40702)
217 #if defined(ELPP_EXPERIMENTAL_ASYNC)
218 # define ELPP_ASYNC_LOGGING 1
219 #else
220 # define ELPP_ASYNC_LOGGING 0
221 #endif // defined(ELPP_EXPERIMENTAL_ASYNC)
222 #if defined(ELPP_THREAD_SAFE) || ELPP_ASYNC_LOGGING
223 # define ELPP_THREADING_ENABLED 1
224 #endif // defined(ELPP_THREAD_SAFE) || ELPP_ASYNC_LOGGING
225 // Function macro ELPP_FUNC
226 #undef ELPP_FUNC
227 #if ELPP_COMPILER_MSVC // Visual C++
228 # define ELPP_FUNC __FUNCSIG__
229 #elif ELPP_COMPILER_GCC // GCC
230 # define ELPP_FUNC __PRETTY_FUNCTION__
231 #elif ELPP_COMPILER_INTEL // Intel C++
232 # define ELPP_FUNC __PRETTY_FUNCTION__
233 #elif ELPP_COMPILER_CLANG // Clang++
234 # define ELPP_FUNC __PRETTY_FUNCTION__
235 #else
236 # if defined(__func__)
237 # define ELPP_FUNC __func__
238 # else
239 # define ELPP_FUNC ""
240 # endif // defined(__func__)
241 #endif // defined(_MSC_VER)
242 #undef ELPP_VARIADIC_TEMPLATES_SUPPORTED
243 // Keep following line commented until features are fixed
244 #if ELPP_COMPILER_GCC || ELPP_COMPILER_CLANG || ELPP_COMPILER_INTEL || (ELPP_COMPILER_MSVC && _MSC_VER >= 1800)
245 # define ELPP_VARIADIC_TEMPLATES_SUPPORTED 1
246 #endif // ELPP_COMPILER_GCC || ELPP_COMPILER_CLANG || ELPP_COMPILER_INTEL || (ELPP_COMPILER_MSVC && _MSC_VER >= 1800)
247 // Logging Enable/Disable macros
248 #if (!defined(ELPP_DISABLE_LOGS))
249 # define ELPP_LOGGING_ENABLED 1
250 #endif // (!defined(ELPP_DISABLE_LOGS))
251 #if (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED) && ((defined(_DEBUG)) || (!defined(NDEBUG))))
252 # define ELPP_DEBUG_LOG 1
253 #else
254 # define ELPP_DEBUG_LOG 0
255 #endif // (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED) && ((defined(_DEBUG)) || (!defined(NDEBUG))))
256 #if (!defined(ELPP_DISABLE_INFO_LOGS) && (ELPP_LOGGING_ENABLED))
257 # define ELPP_INFO_LOG 1
258 #else
259 # define ELPP_INFO_LOG 0
260 #endif // (!defined(ELPP_DISABLE_INFO_LOGS) && (ELPP_LOGGING_ENABLED))
261 #if (!defined(ELPP_DISABLE_WARNING_LOGS) && (ELPP_LOGGING_ENABLED))
262 # define ELPP_WARNING_LOG 1
263 #else
264 # define ELPP_WARNING_LOG 0
265 #endif // (!defined(ELPP_DISABLE_WARNING_LOGS) && (ELPP_LOGGING_ENABLED))
266 #if (!defined(ELPP_DISABLE_ERROR_LOGS) && (ELPP_LOGGING_ENABLED))
267 # define ELPP_ERROR_LOG 1
268 #else
269 # define ELPP_ERROR_LOG 0
270 #endif // (!defined(ELPP_DISABLE_ERROR_LOGS) && (ELPP_LOGGING_ENABLED))
271 #if (!defined(ELPP_DISABLE_FATAL_LOGS) && (ELPP_LOGGING_ENABLED))
272 # define ELPP_FATAL_LOG 1
273 #else
274 # define ELPP_FATAL_LOG 0
275 #endif // (!defined(ELPP_DISABLE_FATAL_LOGS) && (ELPP_LOGGING_ENABLED))
276 #if (!defined(ELPP_DISABLE_TRACE_LOGS) && (ELPP_LOGGING_ENABLED))
277 # define ELPP_TRACE_LOG 1
278 #else
279 # define ELPP_TRACE_LOG 0
280 #endif // (!defined(ELPP_DISABLE_TRACE_LOGS) && (ELPP_LOGGING_ENABLED))
281 #if (!defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED))
282 # define ELPP_VERBOSE_LOG 1
283 #else
284 # define ELPP_VERBOSE_LOG 0
285 #endif // (!defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED))
286 #if (!(ELPP_CXX0X || ELPP_CXX11))
287 # error "Easylogging++ 9.0+ is only compatible with C++0x (or higher) compliant compiler"
288 #endif // (!(ELPP_CXX0X || ELPP_CXX11))
289 // Headers
290 #if defined(ELPP_SYSLOG)
291 # include <syslog.h>
292 #endif // defined(ELPP_SYSLOG)
293 #include <ctime>
294 #include <cstring>
295 #include <cstdlib>
296 #include <cctype>
297 #include <cwchar>
298 #include <csignal>
299 #include <cerrno>
300 #include <cstdarg>
301 #if defined(ELPP_UNICODE)
302 # include <locale>
303 # if ELPP_OS_WINDOWS
304 # include <codecvt>
305 # endif // ELPP_OS_WINDOWS
306 #endif // defined(ELPP_UNICODE)
307 #if ELPP_STACKTRACE
308 # include <cxxabi.h>
309 # include <execinfo.h>
310 #endif // ELPP_STACKTRACE
311 #if ELPP_OS_ANDROID
312 # include <sys/system_properties.h>
313 #endif // ELPP_OS_ANDROID
314 #if ELPP_OS_UNIX
315 # include <sys/stat.h>
316 # include <sys/time.h>
317 #elif ELPP_OS_WINDOWS
318 # include <direct.h>
319 # include <windows.h>
320 # if defined(WIN32_LEAN_AND_MEAN)
321 # if defined(ELPP_WINSOCK2)
322 # include <winsock2.h>
323 # else
324 # include <winsock.h>
325 # endif // defined(ELPP_WINSOCK2)
326 # endif // defined(WIN32_LEAN_AND_MEAN)
327 #endif // ELPP_OS_UNIX
328 #include <string>
329 #include <vector>
330 #include <map>
331 #include <utility>
332 #include <functional>
333 #include <algorithm>
334 #include <fstream>
335 #include <iostream>
336 #include <sstream>
337 #include <memory>
338 #include <type_traits>
339 #if ELPP_THREADING_ENABLED
340 # if ELPP_USE_STD_THREADING
341 # include <mutex>
342 # include <thread>
343 # else
344 # if ELPP_OS_UNIX
345 # include <pthread.h>
346 # endif // ELPP_OS_UNIX
347 # endif // ELPP_USE_STD_THREADING
348 #endif // ELPP_THREADING_ENABLED
349 #if ELPP_ASYNC_LOGGING
350 # include <thread>
351 # include <queue>
352 # include <condition_variable>
353 #endif // ELPP_ASYNC_LOGGING
354 #if defined(ELPP_STL_LOGGING)
355 // For logging STL based templates
356 # include <list>
357 # include <queue>
358 # include <deque>
359 # include <set>
360 # include <bitset>
361 # include <stack>
362 # if defined(ELPP_LOG_STD_ARRAY)
363 # include <array>
364 # endif // defined(ELPP_LOG_STD_ARRAY)
365 # if defined(ELPP_LOG_UNORDERED_MAP)
366 # include <unordered_map>
367 # endif // defined(ELPP_LOG_UNORDERED_MAP)
368 # if defined(ELPP_LOG_UNORDERED_SET)
369 # include <unordered_set>
370 # endif // defined(ELPP_UNORDERED_SET)
371 #endif // defined(ELPP_STL_LOGGING)
372 #if defined(ELPP_QT_LOGGING)
373 // For logging Qt based classes & templates
374 # include <QString>
375 # include <QByteArray>
376 # include <QVector>
377 # include <QList>
378 # include <QPair>
379 # include <QMap>
380 # include <QQueue>
381 # include <QSet>
382 # include <QLinkedList>
383 # include <QHash>
384 # include <QMultiHash>
385 # include <QStack>
386 #endif // defined(ELPP_QT_LOGGING)
387 #if defined(ELPP_BOOST_LOGGING)
388 // For logging boost based classes & templates
389 # include <boost/container/vector.hpp>
390 # include <boost/container/stable_vector.hpp>
391 # include <boost/container/list.hpp>
392 # include <boost/container/deque.hpp>
393 # include <boost/container/map.hpp>
394 # include <boost/container/flat_map.hpp>
395 # include <boost/container/set.hpp>
396 # include <boost/container/flat_set.hpp>
397 #endif // defined(ELPP_BOOST_LOGGING)
398 #if defined(ELPP_WXWIDGETS_LOGGING)
399 // For logging wxWidgets based classes & templates
400 # include <wx/vector.h>
401 #endif // defined(ELPP_WXWIDGETS_LOGGING)
402 // Forward declarations
403 namespace el {
404 class Logger;
405 class LogMessage;
407 class Loggers;
408 class Helpers;
409 template <typename T> class Callback;
410 class LogDispatchCallback;
412 class LogDispatchData;
413 namespace base {
414 class Storage;
415 class RegisteredLoggers;
416 class PerformanceTracker;
417 class MessageBuilder;
418 class Writer;
419 class PErrorWriter;
420 class LogDispatcher;
421 class DefaultLogBuilder;
423 #if ELPP_ASYNC_LOGGING
424 class AsyncLogDispatchCallback;
425 class AsyncDispatchWorker;
426 #endif // ELPP_ASYNC_LOGGING
428 } // namespace base
429 } // namespace el
431 namespace el {
433 namespace base {
435 namespace type {
436 #undef ELPP_LITERAL
437 #undef ELPP_STRLEN
438 #undef ELPP_COUT
439 #if defined(ELPP_UNICODE)
440 # define ELPP_LITERAL(txt) L##txt
441 # define ELPP_STRLEN wcslen
442 # if defined ELPP_CUSTOM_COUT
443 # define ELPP_COUT ELPP_CUSTOM_COUT
444 # else
445 # define ELPP_COUT std::wcout
446 # endif // defined ELPP_CUSTOM_COUT
447 typedef wchar_t char_t;
448 typedef std::wstring string_t;
449 typedef std::wstringstream stringstream_t;
450 typedef std::wfstream fstream_t;
451 typedef std::wostream ostream_t;
452 #else
453 # define ELPP_LITERAL(txt) txt
454 # define ELPP_STRLEN strlen
455 # if defined ELPP_CUSTOM_COUT
456 # define ELPP_COUT ELPP_CUSTOM_COUT
457 # else
458 # define ELPP_COUT std::cout
459 # endif // defined ELPP_CUSTOM_COUT
460 typedef char char_t;
461 typedef std::string string_t;
462 typedef std::stringstream stringstream_t;
463 typedef std::fstream fstream_t;
464 typedef std::ostream ostream_t;
465 #endif // defined(ELPP_UNICODE)
466 #if defined(ELPP_CUSTOM_COUT_LINE)
467 # define ELPP_COUT_LINE(logLine) ELPP_CUSTOM_COUT_LINE(logLine)
468 #else
469 # define ELPP_COUT_LINE(logLine) logLine << std::flush
470 #endif // defined(ELPP_CUSTOM_COUT_LINE)
471 typedef unsigned short EnumType;
472 typedef std::shared_ptr<base::Storage> StoragePointer;
473 typedef int VerboseLevel;
474 typedef std::shared_ptr<LogDispatchCallback> LogDispatchCallbackPtr;
475 typedef std::shared_ptr<PerformanceTrackingCallback> PerformanceTrackingCallbackPtr;
476 } // namespace type
480 class NoCopy {
481 protected:
482  NoCopy(void) {}
483 private:
484  NoCopy(const NoCopy&);
485  NoCopy& operator=(const NoCopy&);
486 };
491 class StaticClass {
492 private:
493  StaticClass(void);
494  StaticClass(const StaticClass&);
495  StaticClass& operator=(const StaticClass&);
496 };
497 } // namespace base
504  Global = 1,
506  Trace = 2,
508  Debug = 4,
510  Fatal = 8,
512  Error = 16,
514  Warning = 32,
516  Verbose = 64,
518  Info = 128,
520  Unknown = 1010
521 };
524 public:
531  return static_cast<base::type::EnumType>(level);
532  }
535  return static_cast<Level>(l);
536  }
539  static const char* convertToString(Level level) {
540  // Do not use switch over strongly typed enums because Intel C++ compilers dont support them yet.
541  if (level == Level::Global) return "GLOBAL";
542  if (level == Level::Debug) return "DEBUG";
543  if (level == Level::Info) return "INFO";
544  if (level == Level::Warning) return "WARNING";
545  if (level == Level::Error) return "ERROR";
546  if (level == Level::Fatal) return "FATAL";
547  if (level == Level::Verbose) return "VERBOSE";
548  if (level == Level::Trace) return "TRACE";
549  return "UNKNOWN";
550  }
554  static Level convertFromString(const char* levelStr) {
555  if ((strcmp(levelStr, "GLOBAL") == 0) || (strcmp(levelStr, "global") == 0))
556  return Level::Global;
557  if ((strcmp(levelStr, "DEBUG") == 0) || (strcmp(levelStr, "debug") == 0))
558  return Level::Debug;
559  if ((strcmp(levelStr, "INFO") == 0) || (strcmp(levelStr, "info") == 0))
560  return Level::Info;
561  if ((strcmp(levelStr, "WARNING") == 0) || (strcmp(levelStr, "warning") == 0))
562  return Level::Warning;
563  if ((strcmp(levelStr, "ERROR") == 0) || (strcmp(levelStr, "error") == 0))
564  return Level::Error;
565  if ((strcmp(levelStr, "FATAL") == 0) || (strcmp(levelStr, "fatal") == 0))
566  return Level::Fatal;
567  if ((strcmp(levelStr, "VERBOSE") == 0) || (strcmp(levelStr, "verbose") == 0))
568  return Level::Verbose;
569  if ((strcmp(levelStr, "TRACE") == 0) || (strcmp(levelStr, "trace") == 0))
570  return Level::Trace;
571  return Level::Unknown;
572  }
577  static inline void forEachLevel(base::type::EnumType* startIndex, const std::function<bool(void)>& fn) {
579  do {
580  if (fn()) {
581  break;
582  }
583  *startIndex = static_cast<base::type::EnumType>(*startIndex << 1);
584  } while (*startIndex <= lIndexMax);
585  }
586 };
592  Enabled = 1,
594  ToFile = 2,
597  ToStandardOutput = 4,
599  Format = 8,
601  Filename = 16,
603  MillisecondsWidth = 32,
607  PerformanceTracking = 64,
612  MaxLogFileSize = 128,
614  LogFlushThreshold = 256,
616  Unknown = 1010
617 };
620 public:
627  return static_cast<base::type::EnumType>(configurationType);
628  }
631  return static_cast<ConfigurationType>(c);
632  }
635  static const char* convertToString(ConfigurationType configurationType) {
636  // Do not use switch over strongly typed enums because Intel C++ compilers dont support them yet.
637  if (configurationType == ConfigurationType::Enabled) return "ENABLED";
638  if (configurationType == ConfigurationType::Filename) return "FILENAME";
639  if (configurationType == ConfigurationType::Format) return "FORMAT";
640  if (configurationType == ConfigurationType::ToFile) return "TO_FILE";
641  if (configurationType == ConfigurationType::ToStandardOutput) return "TO_STANDARD_OUTPUT";
642  if (configurationType == ConfigurationType::MillisecondsWidth) return "MILLISECONDS_WIDTH";
643  if (configurationType == ConfigurationType::PerformanceTracking) return "PERFORMANCE_TRACKING";
644  if (configurationType == ConfigurationType::MaxLogFileSize) return "MAX_LOG_FILE_SIZE";
645  if (configurationType == ConfigurationType::LogFlushThreshold) return "LOG_FLUSH_THRESHOLD";
646  return "UNKNOWN";
647  }
651  static ConfigurationType convertFromString(const char* configStr) {
652  if ((strcmp(configStr, "ENABLED") == 0) || (strcmp(configStr, "enabled") == 0))
654  if ((strcmp(configStr, "TO_FILE") == 0) || (strcmp(configStr, "to_file") == 0))
656  if ((strcmp(configStr, "TO_STANDARD_OUTPUT") == 0) || (strcmp(configStr, "to_standard_output") == 0))
658  if ((strcmp(configStr, "FORMAT") == 0) || (strcmp(configStr, "format") == 0))
660  if ((strcmp(configStr, "FILENAME") == 0) || (strcmp(configStr, "filename") == 0))
662  if ((strcmp(configStr, "MILLISECONDS_WIDTH") == 0) || (strcmp(configStr, "milliseconds_width") == 0))
664  if ((strcmp(configStr, "PERFORMANCE_TRACKING") == 0) || (strcmp(configStr, "performance_tracking") == 0))
666  if ((strcmp(configStr, "MAX_LOG_FILE_SIZE") == 0) || (strcmp(configStr, "max_log_file_size") == 0))
668  if ((strcmp(configStr, "LOG_FLUSH_THRESHOLD") == 0) || (strcmp(configStr, "log_flush_threshold") == 0))
671  }
677  static inline void forEachConfigType(base::type::EnumType* startIndex, const std::function<bool(void)>& fn) {
679  do {
680  if (fn()) {
681  break;
682  }
683  *startIndex = static_cast<base::type::EnumType>(*startIndex << 1);
684  } while (*startIndex <= cIndexMax);
685  }
686 };
699  ImmediateFlush = 16,
705  MultiLoggerSupport = 128,
709  DisableVModules = 512,
713  HierarchicalLogging = 2048,
717  AutoSpacing = 8192,
719  FixedTimeFormat = 16384
720 };
721 namespace base {
723 namespace consts {
724  // Level log values - These are values that are replaced in place of %level format specifier
725  static const base::type::char_t* kInfoLevelLogValue = ELPP_LITERAL("INFO ");
726  static const base::type::char_t* kDebugLevelLogValue = ELPP_LITERAL("DEBUG");
727  static const base::type::char_t* kWarningLevelLogValue = ELPP_LITERAL("WARN ");
728  static const base::type::char_t* kErrorLevelLogValue = ELPP_LITERAL("ERROR");
729  static const base::type::char_t* kFatalLevelLogValue = ELPP_LITERAL("FATAL");
730  static const base::type::char_t* kVerboseLevelLogValue = ELPP_LITERAL("VER");
731  static const base::type::char_t* kTraceLevelLogValue = ELPP_LITERAL("TRACE");
732  static const base::type::char_t* kInfoLevelShortLogValue = ELPP_LITERAL("I");
733  static const base::type::char_t* kDebugLevelShortLogValue = ELPP_LITERAL("D");
734  static const base::type::char_t* kWarningLevelShortLogValue = ELPP_LITERAL("W");
735  static const base::type::char_t* kErrorLevelShortLogValue = ELPP_LITERAL("E");
736  static const base::type::char_t* kFatalLevelShortLogValue = ELPP_LITERAL("F");
737  static const base::type::char_t* kVerboseLevelShortLogValue = ELPP_LITERAL("V");
738  static const base::type::char_t* kTraceLevelShortLogValue = ELPP_LITERAL("T");
739  // Format specifiers - These are used to define log format
740  static const base::type::char_t* kAppNameFormatSpecifier = ELPP_LITERAL("%app");
741  static const base::type::char_t* kLoggerIdFormatSpecifier = ELPP_LITERAL("%logger");
742  static const base::type::char_t* kThreadIdFormatSpecifier = ELPP_LITERAL("%thread");
743  static const base::type::char_t* kSeverityLevelFormatSpecifier = ELPP_LITERAL("%level");
744  static const base::type::char_t* kSeverityLevelShortFormatSpecifier = ELPP_LITERAL("%levshort");
745  static const base::type::char_t* kDateTimeFormatSpecifier = ELPP_LITERAL("%datetime");
746  static const base::type::char_t* kLogFileFormatSpecifier = ELPP_LITERAL("%file");
747  static const base::type::char_t* kLogFileBaseFormatSpecifier = ELPP_LITERAL("%fbase");
748  static const base::type::char_t* kLogLineFormatSpecifier = ELPP_LITERAL("%line");
749  static const base::type::char_t* kLogLocationFormatSpecifier = ELPP_LITERAL("%loc");
750  static const base::type::char_t* kLogFunctionFormatSpecifier = ELPP_LITERAL("%func");
751  static const base::type::char_t* kCurrentUserFormatSpecifier = ELPP_LITERAL("%user");
752  static const base::type::char_t* kCurrentHostFormatSpecifier = ELPP_LITERAL("%host");
753  static const base::type::char_t* kMessageFormatSpecifier = ELPP_LITERAL("%msg");
754  static const base::type::char_t* kVerboseLevelFormatSpecifier = ELPP_LITERAL("%vlevel");
755  static const char* kDateTimeFormatSpecifierForFilename = "%datetime";
756  // Date/time
757  static const char* kDays[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
758  static const char* kDaysAbbrev[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
759  static const char* kMonths[12] = { "January", "February", "March", "Apri", "May", "June", "July", "August",
760  "September", "October", "November", "December" };
761  static const char* kMonthsAbbrev[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
762  static const char* kDefaultDateTimeFormat = "%Y-%M-%d %H:%m:%s,%g";
763  static const char* kDefaultDateTimeFormatInFilename = "%Y-%M-%d_%H-%m";
764  static const int kYearBase = 1900;
765  static const char* kAm = "AM";
766  static const char* kPm = "PM";
767  // Miscellaneous constants
768  static const char* kDefaultLoggerId = "default";
769  static const char* kPerformanceLoggerId = "performance";
770  static const char* kSysLogLoggerId = "syslog";
771  static const char* kNullPointer = "nullptr";
772  static const char kFormatSpecifierChar = '%';
773 #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
774  static const char kFormatSpecifierCharValue = 'v';
775 #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
776  static const unsigned int kMaxLogPerContainer = 100;
777  static const unsigned int kMaxLogPerCounter = 100000;
778  static const unsigned int kDefaultMillisecondsWidth = 3;
779  static const base::type::VerboseLevel kMaxVerboseLevel = 9;
780  static const char* kUnknownUser = "user";
781  static const char* kUnknownHost = "unknown-host";
782 #if defined(ELPP_DEFAULT_LOG_FILE)
783  static const char* kDefaultLogFile = ELPP_DEFAULT_LOG_FILE;
784 #else
785 # if ELPP_OS_UNIX
786 # if ELPP_OS_ANDROID
787  static const char* kDefaultLogFile = "logs/myeasylog.log";
788 # else
789  static const char* kDefaultLogFile = "logs/myeasylog.log";
790 # endif // ELPP_OS_ANDROID
791 # elif ELPP_OS_WINDOWS
792  static const char* kDefaultLogFile = "logs\\myeasylog.log";
793 # endif // ELPP_OS_UNIX
794 #endif // defined(ELPP_DEFAULT_LOG_FILE)
795 #if !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG)
796  static const char* kDefaultLogFileParam = "--default-log-file";
797 #endif // !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG)
798 #if defined(ELPP_LOGGING_FLAGS_FROM_ARG)
799  static const char* kLoggingFlagsParam = "--logging-flags";
800 #endif // defined(ELPP_LOGGING_FLAGS_FROM_ARG)
801 #if ELPP_OS_WINDOWS
802  static const char* kFilePathSeperator = "\\";
803 #else
804  static const char* kFilePathSeperator = "/";
805 #endif // ELPP_OS_WINDOWS
806  static const char* kValidLoggerIdSymbols = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._";
807  static const char* kConfigurationComment = "##";
808  static const char* kConfigurationLevel = "*";
809  static const char* kConfigurationLoggerId = "--";
810  static const std::size_t kSourceFilenameMaxLength = 100;
811  static const std::size_t kSourceLineMaxLength = 10;
812  static const Level kPerformanceTrackerDefaultLevel = Level::Info;
813  const struct {
814  double value;
816  } kTimeFormats[] = {
817  { 1000.0f, ELPP_LITERAL("mis") },
818  { 1000.0f, ELPP_LITERAL("ms") },
819  { 60.0f, ELPP_LITERAL("seconds") },
820  { 60.0f, ELPP_LITERAL("minutes") },
821  { 24.0f, ELPP_LITERAL("hours") },
822  { 7.0f, ELPP_LITERAL("days") }
823  };
824  static const int kTimeFormatsCount = sizeof(kTimeFormats) / sizeof(kTimeFormats[0]);
825  const struct {
826  int numb;
827  const char* name;
828  const char* brief;
829  const char* detail;
830  } kCrashSignals[] = {
831  // NOTE: Do not re-order, if you do please check CrashHandler(bool) constructor and CrashHandler::setHandler(..)
832  { SIGABRT, "SIGABRT", "Abnormal termination",
833  "Program was abnormally terminated." },
834  { SIGFPE, "SIGFPE", "Erroneous arithmetic operation",
835  "Arithemetic operation issue such as division by zero or operation resulting in overflow." },
836  { SIGILL, "SIGILL", "Illegal instruction",
837  "Generally due to a corruption in the code or to an attempt to execute data."},
838  { SIGSEGV, "SIGSEGV", "Invalid access to memory",
839  "Program is trying to read an invalid (unallocated, deleted or corrupted) or inaccessible memory." },
840  { SIGINT, "SIGINT", "Interactive attention signal",
841  "Interruption generated (generally) by user or operating system." },
842  };
843  static const int kCrashSignalsCount = sizeof(kCrashSignals) / sizeof(kCrashSignals[0]);
844 } // namespace consts
845 } // namespace base
846 typedef std::function<void(const char*, std::size_t)> PreRollOutCallback;
847 namespace base {
848 static inline void defaultPreRollOutCallback(const char*, std::size_t) {}
851  Microsecond = 0, Millisecond = 1, Second = 2, Minute = 3, Hour = 4, Day = 5
852 };
855  DateTime = 1<<1, LoggerId = 1<<2, File = 1<<3, Line = 1<<4, Location = 1<<5, Function = 1<<6,
856  User = 1<<7, Host = 1<<8, LogMessage = 1<<9, VerboseLevel = 1<<10, AppName = 1<<11, ThreadId = 1<<12,
857  Level = 1<<13, FileBase = 1<<14, LevelShort = 1<<15
858 };
861 public:
862  MillisecondsWidth(void) { init(base::consts::kDefaultMillisecondsWidth); }
863  explicit MillisecondsWidth(int width) { init(width); }
864  bool operator==(const MillisecondsWidth& msWidth) { return m_width == msWidth.m_width && m_offset == msWidth.m_offset; }
865  int m_width; unsigned int m_offset;
866 private:
867  void init(int width) {
868  if (width < 1 || width > 6) {
869  width = base::consts::kDefaultMillisecondsWidth;
870  }
871  m_width = width;
872  switch (m_width) {
873  case 3: m_offset = 1000; break;
874  case 4: m_offset = 100; break;
875  case 5: m_offset = 10; break;
876  case 6: m_offset = 1; break;
877  default: m_offset = 1000; break;
878  }
879  }
880 };
882 namespace utils {
884 template <typename T>
885 static inline
886 typename std::enable_if<std::is_pointer<T*>::value, void>::type
887 safeDelete(T*& pointer) {
888  if (pointer == nullptr)
889  return;
890  delete pointer;
891  pointer = nullptr;
892 }
894 static inline const char* charPtrVal(const char* pointer) {
895  return pointer == nullptr ? base::consts::kNullPointer : pointer;
896 }
898 static inline void abort(int status, const std::string& reason = std::string()) {
899  // Both status and reason params are there for debugging with tools like gdb etc
900  ELPP_UNUSED(status);
901  ELPP_UNUSED(reason);
902 #if defined(ELPP_COMPILER_MSVC) && defined(_M_IX86) && defined(_DEBUG)
903  // Ignore msvc critical error dialog - break instead (on debug mode)
904  _asm int 3
905 #else
906  ::abort();
907 #endif // defined(ELPP_COMPILER_MSVC) && defined(_M_IX86) && defined(_DEBUG)
908 }
911 namespace bitwise {
912 template <typename Enum>
913 static inline base::type::EnumType And(Enum e, base::type::EnumType flag) {
914  return static_cast<base::type::EnumType>(flag) & static_cast<base::type::EnumType>(e);
915 }
916 template <typename Enum>
917 static inline base::type::EnumType Not(Enum e, base::type::EnumType flag) {
918  return static_cast<base::type::EnumType>(flag) & ~(static_cast<base::type::EnumType>(e));
919 }
920 template <typename Enum>
921 static inline base::type::EnumType Or(Enum e, base::type::EnumType flag) {
922  return static_cast<base::type::EnumType>(flag) | static_cast<base::type::EnumType>(e);
923 }
924 } // namespace bitwise
925 template <typename Enum>
926 static inline void addFlag(Enum e, base::type::EnumType* flag) {
927  *flag = base::utils::bitwise::Or<Enum>(e, *flag);
928 }
929 template <typename Enum>
930 static inline void removeFlag(Enum e, base::type::EnumType* flag) {
931  *flag = base::utils::bitwise::Not<Enum>(e, *flag);
932 }
933 template <typename Enum>
934 static inline bool hasFlag(Enum e, base::type::EnumType flag) {
935  return base::utils::bitwise::And<Enum>(e, flag) > 0x0;
936 }
937 } // namespace utils
938 namespace threading {
939 #if ELPP_THREADING_ENABLED
940 # if !ELPP_USE_STD_THREADING
941 namespace internal {
943 class Mutex : base::NoCopy {
944 public:
945  Mutex(void) {
946 # if ELPP_OS_UNIX
947  pthread_mutex_init(&m_underlyingMutex, nullptr);
948 # elif ELPP_OS_WINDOWS
949  InitializeCriticalSection(&m_underlyingMutex);
950 # endif // ELPP_OS_UNIX
951  }
952 
953  virtual ~Mutex(void) {
954 # if ELPP_OS_UNIX
955  pthread_mutex_destroy(&m_underlyingMutex);
956 # elif ELPP_OS_WINDOWS
957  DeleteCriticalSection(&m_underlyingMutex);
958 # endif // ELPP_OS_UNIX
959  }
960 
961  inline void lock(void) {
962 # if ELPP_OS_UNIX
963  pthread_mutex_lock(&m_underlyingMutex);
964 # elif ELPP_OS_WINDOWS
965  EnterCriticalSection(&m_underlyingMutex);
966 # endif // ELPP_OS_UNIX
967  }
968 
969  inline bool try_lock(void) {
970 # if ELPP_OS_UNIX
971  return (pthread_mutex_trylock(&m_underlyingMutex) == 0);
972 # elif ELPP_OS_WINDOWS
973  return TryEnterCriticalSection(&m_underlyingMutex);
974 # endif // ELPP_OS_UNIX
975  }
976 
977  inline void unlock(void) {
978 # if ELPP_OS_UNIX
979  pthread_mutex_unlock(&m_underlyingMutex);
980 # elif ELPP_OS_WINDOWS
981  LeaveCriticalSection(&m_underlyingMutex);
982 # endif // ELPP_OS_UNIX
983  }
984 
985 private:
986 # if ELPP_OS_UNIX
987  pthread_mutex_t m_underlyingMutex;
988 # elif ELPP_OS_WINDOWS
989  CRITICAL_SECTION m_underlyingMutex;
990 # endif // ELPP_OS_UNIX
991 };
993 template <typename M>
994 class ScopedLock : base::NoCopy {
995 public:
996  explicit ScopedLock(M& mutex) {
997  m_mutex = &mutex;
998  m_mutex->lock();
999  }
1000 
1001  virtual ~ScopedLock(void) {
1002  m_mutex->unlock();
1003  }
1004 private:
1005  M* m_mutex;
1006  ScopedLock(void);
1007 };
1008 } // namespace internal
1010 static inline std::string getCurrentThreadId(void) {
1011  std::stringstream ss;
1012 # if (ELPP_OS_WINDOWS)
1013  ss << GetCurrentThreadId();
1014 # endif // (ELPP_OS_WINDOWS)
1015  return ss.str();
1016 }
1017 static inline void msleep(int) {
1018  // No implementation for non std::thread version
1019 }
1021 typedef base::threading::internal::ScopedLock<base::threading::Mutex> ScopedLock;
1022 # else
1023 static inline std::string getCurrentThreadId(void) {
1025  std::stringstream ss;
1026  ss << std::this_thread::get_id();
1027  return ss.str();
1028 }
1029 static inline void msleep(int ms) {
1030  // Only when async logging enabled - this is because async is strict on compiler
1031 #if ELPP_ASYNC_LOGGING
1032  std::this_thread::sleep_for(std::chrono::milliseconds(ms));
1033 #endif // ELPP_ASYNC_LOGGING
1034 }
1035 typedef std::mutex Mutex;
1036 typedef std::lock_guard<std::mutex> ScopedLock;
1037 # endif // !ELPP_USE_STD_THREADING
1038 #else
1039 namespace internal {
1042 public:
1043  NoMutex(void) {}
1044  inline void lock(void) {}
1045  inline bool try_lock(void) { return true; }
1046  inline void unlock(void) {}
1047 };
1049 template <typename Mutex>
1051 public:
1052  explicit NoScopedLock(Mutex&) {
1053  }
1054  virtual ~NoScopedLock(void) {
1055  }
1056 private:
1057  NoScopedLock(void);
1058 };
1059 } // namespace internal
1060 static inline std::string getCurrentThreadId(void) {
1061  return std::string();
1062 }
1063 static inline void msleep(int) {
1064  // No custom implementation
1065 }
1068 #endif // ELPP_THREADING_ENABLED
1069 class ThreadSafe {
1071 public:
1072  virtual inline void acquireLock(void) ELPP_FINAL { m_mutex.lock(); }
1073  virtual inline void releaseLock(void) ELPP_FINAL { m_mutex.unlock(); }
1074  virtual inline base::threading::Mutex& lock(void) ELPP_FINAL { return m_mutex; }
1075 protected:
1076  ThreadSafe(void) {}
1077  virtual ~ThreadSafe(void) {}
1078 private:
1079  base::threading::Mutex m_mutex;
1080 };
1081 } // namespace threading
1082 namespace utils {
1084 public:
1087  static base::type::fstream_t* newFileStream(const std::string& filename) {
1088  base::type::fstream_t *fs = new base::type::fstream_t(filename.c_str(),
1089  base::type::fstream_t::out | base::type::fstream_t::app);
1090 #if defined(ELPP_UNICODE)
1091  std::locale elppUnicodeLocale("");
1092 #if ELPP_OS_WINDOWS
1093  std::locale elppUnicodeLocaleWindows(elppUnicodeLocale, new std::codecvt_utf8_utf16<wchar_t>);
1094  elppUnicodeLocale = elppUnicodeLocaleWindows;
1095 #endif
1096  fs->imbue(elppUnicodeLocale);
1097 #endif // defined(ELPP_UNICODE)
1098  if (fs->is_open()) {
1099  fs->flush();
1100  } else {
1101  base::utils::safeDelete(fs);
1102  ELPP_INTERNAL_ERROR("Bad file [" << filename << "]", true);
1103  }
1104  return fs;
1105  }
1106 
1108  static std::size_t getSizeOfFile(base::type::fstream_t* fs) {
1109  if (fs == nullptr) {
1110  return 0;
1111  }
1112  std::streampos currPos = fs->tellg();
1113  fs->seekg(0, fs->end);
1114  std::size_t size = static_cast<std::size_t>(fs->tellg());
1115  fs->seekg(currPos);
1116  return size;
1117  }
1118 
1120  static inline bool pathExists(const char* path, bool considerFile = false) {
1121  if (path == nullptr) {
1122  return false;
1123  }
1124 #if ELPP_OS_UNIX
1125  ELPP_UNUSED(considerFile);
1126  struct stat st;
1127  return (stat(path, &st) == 0);
1128 #elif ELPP_OS_WINDOWS
1129  DWORD fileType = GetFileAttributesA(path);
1130  if (fileType == INVALID_FILE_ATTRIBUTES) {
1131  return false;
1132  }
1133  return considerFile ? true : ((fileType & FILE_ATTRIBUTE_DIRECTORY) == 0 ? false : true);
1134 #endif // ELPP_OS_UNIX
1135  }
1136 
1139  static bool createPath(const std::string& path) {
1140  if (path.empty()) {
1141  return false;
1142  }
1143  if (base::utils::File::pathExists(path.c_str())) {
1144  return true;
1145  }
1146  int status = -1;
1147 
1148  char* currPath = const_cast<char*>(path.c_str());
1149  std::string builtPath = std::string();
1150 #if ELPP_OS_UNIX
1151  if (path[0] == '/') {
1152  builtPath = "/";
1153  }
1154  currPath = STRTOK(currPath, base::consts::kFilePathSeperator, 0);
1155 #elif ELPP_OS_WINDOWS
1156  // Use secure functions API
1157  char* nextTok_ = nullptr;
1158  currPath = STRTOK(currPath, base::consts::kFilePathSeperator, &nextTok_);
1159  ELPP_UNUSED(nextTok_);
1160 #endif // ELPP_OS_UNIX
1161  while (currPath != nullptr) {
1162  builtPath.append(currPath);
1163  builtPath.append(base::consts::kFilePathSeperator);
1164 #if ELPP_OS_UNIX
1165  status = mkdir(builtPath.c_str(), ELPP_LOG_PERMS);
1166  currPath = STRTOK(nullptr, base::consts::kFilePathSeperator, 0);
1167 #elif ELPP_OS_WINDOWS
1168  status = _mkdir(builtPath.c_str());
1169  currPath = STRTOK(nullptr, base::consts::kFilePathSeperator, &nextTok_);
1170 #endif // ELPP_OS_UNIX
1171  }
1172  if (status == -1) {
1173  ELPP_INTERNAL_ERROR("Error while creating path [" << path << "]", true);
1174  return false;
1175  }
1176  return true;
1177  }
1179  static std::string extractPathFromFilename(const std::string& fullPath,
1180  const char* seperator = base::consts::kFilePathSeperator) {
1181  if ((fullPath == "") || (fullPath.find(seperator) == std::string::npos)) {
1182  return fullPath;
1183  }
1184  std::size_t lastSlashAt = fullPath.find_last_of(seperator);
1185  if (lastSlashAt == 0) {
1186  return std::string(seperator);
1187  }
1188  return fullPath.substr(0, lastSlashAt + 1);
1189  }
1191  static void buildStrippedFilename(const char* filename, char buff[],
1192  std::size_t limit = base::consts::kSourceFilenameMaxLength) {
1193  std::size_t sizeOfFilename = strlen(filename);
1194  if (sizeOfFilename >= limit) {
1195  filename += (sizeOfFilename - limit);
1196  if (filename[0] != '.' && filename[1] != '.') { // prepend if not already
1197  filename += 3; // 3 = '..'
1198  STRCAT(buff, "..", limit);
1199  }
1200  }
1201  STRCAT(buff, filename, limit);
1202  }
1204  static void buildBaseFilename(const std::string& fullPath, char buff[],
1205  std::size_t limit = base::consts::kSourceFilenameMaxLength,
1206  const char* seperator = base::consts::kFilePathSeperator) {
1207  const char *filename = fullPath.c_str();
1208  std::size_t lastSlashAt = fullPath.find_last_of(seperator);
1209  filename += lastSlashAt ? lastSlashAt+1 : 0;
1210  std::size_t sizeOfFilename = strlen(filename);
1211  if (sizeOfFilename >= limit) {
1212  filename += (sizeOfFilename - limit);
1213  if (filename[0] != '.' && filename[1] != '.') { // prepend if not already
1214  filename += 3; // 3 = '..'
1215  STRCAT(buff, "..", limit);
1216  }
1217  }
1218  STRCAT(buff, filename, limit);
1219  }
1220 };
1223 public:
1225  static inline bool isDigit(char c) {
1226  return c >= '0' && c <= '9';
1227  }
1228 
1230  static bool wildCardMatch(const char* str, const char* pattern) {
1231  while (*pattern) {
1232  switch (*pattern) {
1233  case '?':
1234  if (!*str)
1235  return false;
1236  ++str;
1237  ++pattern;
1238  break;
1239  case '*':
1240  if (wildCardMatch(str, pattern + 1))
1241  return true;
1242  if (*str && wildCardMatch(str + 1, pattern))
1243  return true;
1244  return false;
1245  break;
1246  default:
1247  if (*str++ != *pattern++)
1248  return false;
1249  break;
1250  }
1251  }
1252  return !*str && !*pattern;
1253  }
1254 
1257  static inline std::string& ltrim(std::string& str) {
1258  str.erase(str.begin(), std::find_if(str.begin(), str.end(), std::not1(std::ptr_fun<int, int>(&std::isspace))));
1259  return str;
1260  }
1261 
1264  static inline std::string& rtrim(std::string& str) {
1265  str.erase(std::find_if(str.rbegin(), str.rend(), std::not1(std::ptr_fun<int, int>(&std::isspace))).base(), str.end());
1266  return str;
1267  }
1268 
1271  static inline std::string& trim(std::string& str) {
1272  return ltrim(rtrim(str));
1273  }
1274 
1279  static inline bool startsWith(const std::string& str, const std::string& start) {
1280  return (str.length() >= start.length()) && (str.compare(0, start.length(), start) == 0);
1281  }
1282 
1287  static inline bool endsWith(const std::string& str, const std::string& end) {
1288  return (str.length() >= end.length()) && (str.compare(str.length() - end.length(), end.length(), end) == 0);
1289  }
1290 
1296  static inline std::string& replaceAll(std::string& str, char replaceWhat, char replaceWith) {
1297  std::replace(str.begin(), str.end(), replaceWhat, replaceWith);
1298  return str;
1299  }
1300 
1306  static inline std::string& replaceAll(std::string& str, const std::string& replaceWhat, // NOLINT
1307  const std::string& replaceWith) {
1308  if (replaceWhat == replaceWith)
1309  return str;
1310  std::size_t foundAt = std::string::npos;
1311  while ((foundAt = str.find(replaceWhat, foundAt + 1)) != std::string::npos) {
1312  str.replace(foundAt, replaceWhat.length(), replaceWith);
1313  }
1314  return str;
1315  }
1316 
1317  static void replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat, // NOLINT
1318  const base::type::string_t& replaceWith) {
1319  std::size_t foundAt = base::type::string_t::npos;
1320  while ((foundAt = str.find(replaceWhat, foundAt + 1)) != base::type::string_t::npos) {
1321  if (foundAt > 0 && str[foundAt - 1] == base::consts::kFormatSpecifierChar) {
1322  str.erase(foundAt > 0 ? foundAt - 1 : 0, 1);
1323  ++foundAt;
1324  } else {
1325  str.replace(foundAt, replaceWhat.length(), replaceWith);
1326  return;
1327  }
1328  }
1329  }
1330 #if defined(ELPP_UNICODE)
1331  static void replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat, // NOLINT
1332  const std::string& replaceWith) {
1333  replaceFirstWithEscape(str, replaceWhat, base::type::string_t(replaceWith.begin(), replaceWith.end()));
1334  }
1335 #endif // defined(ELPP_UNICODE)
1336  static inline std::string& toUpper(std::string& str) {
1340  std::transform(str.begin(), str.end(), str.begin(), ::toupper);
1341  return str;
1342  }
1343 
1345  static inline bool cStringEq(const char* s1, const char* s2) {
1346  if (s1 == nullptr && s2 == nullptr) return true;
1347  if (s1 == nullptr || s2 == nullptr) return false;
1348  return strcmp(s1, s2) == 0;
1349  }
1350 
1353  static bool cStringCaseEq(const char* s1, const char* s2) {
1354  if (s1 == nullptr && s2 == nullptr) return true;
1355  if (s1 == nullptr || s2 == nullptr) return false;
1356  if (strlen(s1) != strlen(s2)) return false;
1357  while (*s1 != '\0' && *s2 != '\0') {
1358  if (::toupper(*s1) != ::toupper(*s2)) return false;
1359  ++s1;
1360  ++s2;
1361  }
1362  return true;
1363  }
1364 
1366  static inline bool contains(const char* str, char c) {
1367  for (; *str; ++str) {
1368  if (*str == c)
1369  return true;
1370  }
1371  return false;
1372  }
1373 
1374  static inline char* convertAndAddToBuff(std::size_t n, int len, char* buf, const char* bufLim, bool zeroPadded = true) {
1375  char localBuff[10] = "";
1376  char* p = localBuff + sizeof(localBuff) - 2;
1377  if (n > 0) {
1378  for (; n > 0 && p > localBuff && len > 0; n /= 10, --len)
1379  *--p = static_cast<char>(n % 10 + '0');
1380  } else {
1381  *--p = '0';
1382  --len;
1383  }
1384  if (zeroPadded)
1385  while (p > localBuff && len-- > 0) *--p = static_cast<char>('0');
1386  return addToBuff(p, buf, bufLim);
1387  }
1388 
1389  static inline char* addToBuff(const char* str, char* buf, const char* bufLim) {
1390  while ((buf < bufLim) && ((*buf = *str++) != '\0'))
1391  ++buf;
1392  return buf;
1393  }
1394 
1395  static inline char* clearBuff(char buff[], std::size_t lim) {
1396  STRCPY(buff, "", lim);
1397  ELPP_UNUSED(lim); // For *nix we dont have anything using lim in above STRCPY macro
1398  return buff;
1399  }
1400 
1403  static char* wcharPtrToCharPtr(const wchar_t* line) {
1404  std::size_t len_ = wcslen(line) + 1;
1405  char* buff_ = static_cast<char*>(malloc(len_ + 1));
1406 # if ELPP_OS_UNIX || (ELPP_OS_WINDOWS && !ELPP_CRT_DBG_WARNINGS)
1407  std::wcstombs(buff_, line, len_);
1408 # elif ELPP_OS_WINDOWS
1409  std::size_t convCount_ = 0;
1410  mbstate_t mbState_;
1411  ::memset(static_cast<void*>(&mbState_), 0, sizeof(mbState_));
1412  wcsrtombs_s(&convCount_, buff_, len_, &line, len_, &mbState_);
1413 # endif // ELPP_OS_UNIX || (ELPP_OS_WINDOWS && !ELPP_CRT_DBG_WARNINGS)
1414  return buff_;
1415  }
1416 };
1419 public:
1420 #if ELPP_OS_WINDOWS
1421  static const char* getWindowsEnvironmentVariable(const char* varname) {
1426  const DWORD bufferLen = 50;
1427  static char buffer[bufferLen];
1428  if (GetEnvironmentVariableA(varname, buffer, bufferLen)) {
1429  return buffer;
1430  }
1431  return nullptr;
1432  }
1433 #endif // ELPP_OS_WINDOWS
1434 #if ELPP_OS_ANDROID
1435  static inline std::string getProperty(const char* prop) {
1437  char propVal[PROP_VALUE_MAX + 1];
1438  int ret = __system_property_get(prop, propVal);
1439  return ret == 0 ? std::string() : std::string(propVal);
1440  }
1441 
1443  static std::string getDeviceName(void) {
1444  std::stringstream ss;
1445  std::string manufacturer = getProperty("ro.product.manufacturer");
1446  std::string model = getProperty("ro.product.model");
1447  if (manufacturer.empty() || model.empty()) {
1448  return std::string();
1449  }
1450  ss << manufacturer << "-" << model;
1451  return ss.str();
1452  }
1453 #endif // ELPP_OS_ANDROID
1454 
1460  static const std::string getBashOutput(const char* command) {
1461 #if (ELPP_OS_UNIX && !ELPP_OS_ANDROID && !ELPP_CYGWIN)
1462  if (command == nullptr) {
1463  return std::string();
1464  }
1465  FILE* proc = nullptr;
1466  if ((proc = popen(command, "r")) == nullptr) {
1467  ELPP_INTERNAL_ERROR("\nUnable to run command [" << command << "]", true);
1468  return std::string();
1469  }
1470  char hBuff[4096];
1471  if (fgets(hBuff, sizeof(hBuff), proc) != nullptr) {
1472  pclose(proc);
1473  if (hBuff[strlen(hBuff) - 1] == '\n') {
1474  hBuff[strlen(hBuff) - 1] = '\0';
1475  }
1476  return std::string(hBuff);
1477  }
1478  return std::string();
1479 #else
1480  ELPP_UNUSED(command);
1481  return std::string();
1482 #endif // (ELPP_OS_UNIX && !ELPP_OS_ANDROID && !ELPP_CYGWIN)
1483  }
1484 
1490  static std::string getEnvironmentVariable(const char* variableName, const char* defaultVal, const char* alternativeBashCommand = nullptr) {
1491 #if ELPP_OS_UNIX
1492  const char* val = getenv(variableName);
1493 #elif ELPP_OS_WINDOWS
1494  const char* val = getWindowsEnvironmentVariable(variableName);
1495 #endif // ELPP_OS_UNIX
1496  if ((val == nullptr) || ((strcmp(val, "") == 0))) {
1497 #if ELPP_OS_UNIX && defined(ELPP_FORCE_ENV_VAR_FROM_BASH)
1498  // Try harder on unix-based systems
1499  std::string valBash = base::utils::OS::getBashOutput(alternativeBashCommand);
1500  if (valBash.empty()) {
1501  return std::string(defaultVal);
1502  } else {
1503  return valBash;
1504  }
1505 #elif ELPP_OS_WINDOWS || ELPP_OS_UNIX
1506  ELPP_UNUSED(alternativeBashCommand);
1507  return std::string(defaultVal);
1508 #endif // ELPP_OS_UNIX && defined(ELPP_FORCE_ENV_VAR_FROM_BASH)
1509  }
1510  return std::string(val);
1511  }
1513  static inline std::string currentUser(void) {
1514 #if ELPP_OS_UNIX && !ELPP_OS_ANDROID
1515  return getEnvironmentVariable("USER", base::consts::kUnknownUser, "whoami");
1516 #elif ELPP_OS_WINDOWS
1517  return getEnvironmentVariable("USERNAME", base::consts::kUnknownUser);
1518 #elif ELPP_OS_ANDROID
1519  ELPP_UNUSED(base::consts::kUnknownUser);
1520  return std::string("android");
1521 #else
1522  return std::string();
1523 #endif // ELPP_OS_UNIX && !ELPP_OS_ANDROID
1524  }
1525 
1529  static inline std::string currentHost(void) {
1530 #if ELPP_OS_UNIX && !ELPP_OS_ANDROID
1531  return getEnvironmentVariable("HOSTNAME", base::consts::kUnknownHost, "hostname");
1532 #elif ELPP_OS_WINDOWS
1533  return getEnvironmentVariable("COMPUTERNAME", base::consts::kUnknownHost);
1534 #elif ELPP_OS_ANDROID
1535  ELPP_UNUSED(base::consts::kUnknownHost);
1536  return getDeviceName();
1537 #else
1538  return std::string();
1539 #endif // ELPP_OS_UNIX && !ELPP_OS_ANDROID
1540  }
1542  static inline bool termSupportsColor(void) {
1543  std::string term = getEnvironmentVariable("TERM", "");
1544  return term == "xterm" || term == "xterm-color" || term == "xterm-256color" ||
1545  term == "screen" || term == "linux" || term == "cygwin";
1546  }
1547 };
1548 extern std::string s_currentUser;
1549 extern std::string s_currentHost;
1550 extern bool s_termSupportsColor;
1551 #define ELPP_INITI_BASIC_DECLR \
1552  namespace el {\
1553  namespace base {\
1554  namespace utils {\
1555  std::string s_currentUser = el::base::utils::OS::currentUser(); \
1556  std::string s_currentHost = el::base::utils::OS::currentHost(); \
1557  bool s_termSupportsColor = el::base::utils::OS::termSupportsColor(); \
1558  }\
1559  }\
1560  }
1561 class DateTime : base::StaticClass {
1563 public:
1568  static void gettimeofday(struct timeval* tv) {
1569 #if ELPP_OS_WINDOWS
1570  if (tv != nullptr) {
1571 # if ELPP_COMPILER_MSVC || defined(_MSC_EXTENSIONS)
1572  const unsigned __int64 delta_ = 11644473600000000Ui64;
1573 # else
1574  const unsigned __int64 delta_ = 11644473600000000ULL;
1575 # endif // ELPP_COMPILER_MSVC || defined(_MSC_EXTENSIONS)
1576  const double secOffSet = 0.000001;
1577  const unsigned long usecOffSet = 1000000;
1578  FILETIME fileTime;
1579  GetSystemTimeAsFileTime(&fileTime);
1580  unsigned __int64 present = 0;
1581  present |= fileTime.dwHighDateTime;
1582  present = present << 32;
1583  present |= fileTime.dwLowDateTime;
1584  present /= 10; // mic-sec
1585  // Subtract the difference
1586  present -= delta_;
1587  tv->tv_sec = static_cast<long>(present * secOffSet);
1588  tv->tv_usec = static_cast<long>(present % usecOffSet);
1589  }
1590 #else
1591  ::gettimeofday(tv, nullptr);
1592 #endif // ELPP_OS_WINDOWS
1593  }
1594 
1599  static inline std::string getDateTime(const char* format, const base::MillisecondsWidth* msWidth) {
1600  struct timeval currTime;
1601  gettimeofday(&currTime);
1602  struct ::tm timeInfo;
1603  buildTimeInfo(&currTime, &timeInfo);
1604  const int kBuffSize = 30;
1605  char buff_[kBuffSize] = "";
1606  parseFormat(buff_, kBuffSize, format, &timeInfo, static_cast<std::size_t>(currTime.tv_usec / msWidth->m_offset), msWidth);
1607  return std::string(buff_);
1608  }
1609 
1611  static base::type::string_t formatTime(unsigned long long time, base::TimestampUnit timestampUnit) {
1612  double result = static_cast<double>(time);
1613  base::type::EnumType start = static_cast<base::type::EnumType>(timestampUnit);
1614  const base::type::char_t* unit = base::consts::kTimeFormats[start].unit;
1615  for (base::type::EnumType i = start; i < base::consts::kTimeFormatsCount - 1; ++i) {
1616  if (result <= base::consts::kTimeFormats[i].value) {
1617  break;
1618  }
1619  result /= base::consts::kTimeFormats[i].value;
1620  unit = base::consts::kTimeFormats[i + 1].unit;
1621  }
1623  ss << result << " " << unit;
1624  return ss.str();
1625  }
1626 
1628  static inline unsigned long long getTimeDifference(const struct timeval& endTime, const struct timeval& startTime, base::TimestampUnit timestampUnit) {
1629  if (timestampUnit == base::TimestampUnit::Microsecond) {
1630  return static_cast<unsigned long long>(static_cast<unsigned long long>(1000000 * endTime.tv_sec + endTime.tv_usec) -
1631  static_cast<unsigned long long>(1000000 * startTime.tv_sec + startTime.tv_usec));
1632  } else {
1633  return static_cast<unsigned long long>((((endTime.tv_sec - startTime.tv_sec) * 1000000) + (endTime.tv_usec - startTime.tv_usec)) / 1000);
1634  }
1635  }
1636 
1637 private:
1638  static inline struct ::tm* buildTimeInfo(struct timeval* currTime, struct ::tm* timeInfo) {
1639 #if ELPP_OS_UNIX
1640  time_t rawTime = currTime->tv_sec;
1641  ::localtime_r(&rawTime, timeInfo);
1642  return timeInfo;
1643 #else
1644 # if ELPP_COMPILER_MSVC
1645  ELPP_UNUSED(currTime);
1646  time_t t;
1647  _time64(&t);
1648  localtime_s(timeInfo, &t);
1649  return timeInfo;
1650 # else
1651  // For any other compilers that don't have CRT warnings issue e.g, MinGW or TDM GCC- we use different method
1652  time_t rawTime = currTime->tv_sec;
1653  struct tm* tmInf = localtime(&rawTime);
1654  *timeInfo = *tmInf;
1655  return timeInfo;
1656 # endif // ELPP_COMPILER_MSVC
1657 #endif // ELPP_OS_UNIX
1658  }
1659  static char* parseFormat(char* buf, std::size_t bufSz, const char* format, const struct tm* tInfo,
1660  std::size_t msec, const base::MillisecondsWidth* msWidth) {
1661  const char* bufLim = buf + bufSz;
1662  for (; *format; ++format) {
1663  if (*format == base::consts::kFormatSpecifierChar) {
1664  switch (*++format) {
1665  case base::consts::kFormatSpecifierChar: // Escape
1666  break;
1667  case '\0': // End
1668  --format;
1669  break;
1670  case 'd': // Day
1671  buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_mday, 2, buf, bufLim);
1672  continue;
1673  case 'a': // Day of week (short)
1674  buf = base::utils::Str::addToBuff(base::consts::kDaysAbbrev[tInfo->tm_wday], buf, bufLim);
1675  continue;
1676  case 'A': // Day of week (long)
1677  buf = base::utils::Str::addToBuff(base::consts::kDays[tInfo->tm_wday], buf, bufLim);
1678  continue;
1679  case 'M': // month
1680  buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_mon + 1, 2, buf, bufLim);
1681  continue;
1682  case 'b': // month (short)
1683  buf = base::utils::Str::addToBuff(base::consts::kMonthsAbbrev[tInfo->tm_mon], buf, bufLim);
1684  continue;
1685  case 'B': // month (long)
1686  buf = base::utils::Str::addToBuff(base::consts::kMonths[tInfo->tm_mon], buf, bufLim);
1687  continue;
1688  case 'y': // year (two digits)
1689  buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_year + base::consts::kYearBase, 2, buf, bufLim);
1690  continue;
1691  case 'Y': // year (four digits)
1692  buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_year + base::consts::kYearBase, 4, buf, bufLim);
1693  continue;
1694  case 'h': // hour (12-hour)
1695  buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_hour % 12, 2, buf, bufLim);
1696  continue;
1697  case 'H': // hour (24-hour)
1698  buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_hour, 2, buf, bufLim);
1699  continue;
1700  case 'm': // minute
1701  buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_min, 2, buf, bufLim);
1702  continue;
1703  case 's': // second
1704  buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_sec, 2, buf, bufLim);
1705  continue;
1706  case 'z': // milliseconds
1707  case 'g':
1708  buf = base::utils::Str::convertAndAddToBuff(msec, msWidth->m_width, buf, bufLim);
1709  continue;
1710  case 'F': // AM/PM
1711  buf = base::utils::Str::addToBuff((tInfo->tm_hour >= 12) ? base::consts::kPm : base::consts::kAm, buf, bufLim);
1712  continue;
1713  default:
1714  continue;
1715  }
1716  }
1717  if (buf == bufLim) break;
1718  *buf++ = *format;
1719  }
1720  return buf;
1721  }
1722 };
1725 public:
1727  setArgs(0, static_cast<char**>(nullptr));
1728  }
1729  CommandLineArgs(int argc, const char** argv) {
1730  setArgs(argc, argv);
1731  }
1732  CommandLineArgs(int argc, char** argv) {
1733  setArgs(argc, argv);
1734  }
1735  virtual ~CommandLineArgs(void) {}
1737  inline void setArgs(int argc, const char** argv) {
1738  setArgs(argc, const_cast<char**>(argv));
1739  }
1741  inline void setArgs(int argc, char** argv) {
1742  m_params.clear();
1743  m_paramsWithValue.clear();
1744  if (argc == 0 || argv == nullptr) {
1745  return;
1746  }
1747  m_argc = argc;
1748  m_argv = argv;
1749  for (int i = 1; i < m_argc; ++i) {
1750  const char* v = (strstr(m_argv[i], "="));
1751  if (v != nullptr && strlen(v) > 0) {
1752  std::string key = std::string(m_argv[i]);
1753  key = key.substr(0, key.find_first_of('='));
1754  if (hasParamWithValue(key.c_str())) {
1755  ELPP_INTERNAL_INFO(1, "Skipping [" << key << "] arg since it already has value ["
1756  << getParamValue(key.c_str()) << "]");
1757  } else {
1758  m_paramsWithValue.insert(std::make_pair(key, std::string(v + 1)));
1759  }
1760  }
1761  if (v == nullptr) {
1762  if (hasParam(m_argv[i])) {
1763  ELPP_INTERNAL_INFO(1, "Skipping [" << m_argv[i] << "] arg since it already exists");
1764  } else {
1765  m_params.push_back(std::string(m_argv[i]));
1766  }
1767  }
1768  }
1769  }
1771  inline bool hasParamWithValue(const char* paramKey) const {
1772  return m_paramsWithValue.find(std::string(paramKey)) != m_paramsWithValue.end();
1773  }
1776  inline const char* getParamValue(const char* paramKey) const {
1777  return m_paramsWithValue.find(std::string(paramKey))->second.c_str();
1778  }
1780  inline bool hasParam(const char* paramKey) const {
1781  return std::find(m_params.begin(), m_params.end(), std::string(paramKey)) != m_params.end();
1782  }
1784  inline bool empty(void) const {
1785  return m_params.empty() && m_paramsWithValue.empty();
1786  }
1788  inline std::size_t size(void) const {
1789  return m_params.size() + m_paramsWithValue.size();
1790  }
1792  for (int i = 1; i < c.m_argc; ++i) {
1793  os << ELPP_LITERAL("[") << c.m_argv[i] << ELPP_LITERAL("]");
1794  if (i < c.m_argc - 1) {
1795  os << ELPP_LITERAL(" ");
1796  }
1797  }
1798  return os;
1799  }
1800 
1801 private:
1802  int m_argc;
1803  char** m_argv;
1804  std::map<std::string, std::string> m_paramsWithValue;
1805  std::vector<std::string> m_params;
1806 };
1813 template <typename T_Ptr, typename Container>
1815 public:
1816  typedef typename Container::iterator iterator;
1817  typedef typename Container::const_iterator const_iterator;
1818 
1821 
1824  if (this == &sr) {
1825  return;
1826  }
1827  unregisterAll();
1828  m_list = std::move(sr.m_list);
1829  }
1830 
1832  if (size() != other.size()) {
1833  return false;
1834  }
1835  for (std::size_t i = 0; i < m_list.size(); ++i) {
1836  if (m_list.at(i) != other.m_list.at(i)) {
1837  return false;
1838  }
1839  }
1840  return true;
1841  }
1842 
1844  if (size() != other.size()) {
1845  return true;
1846  }
1847  for (std::size_t i = 0; i < m_list.size(); ++i) {
1848  if (m_list.at(i) != other.m_list.at(i)) {
1849  return true;
1850  }
1851  }
1852  return false;
1853  }
1854 
1857  if (this == &sr) {
1858  return *this;
1859  }
1860  unregisterAll();
1861  m_list = std::move(sr.m_list);
1862  return *this;
1863  }
1864 
1865  virtual ~AbstractRegistry(void) {
1866  }
1867 
1869  virtual inline iterator begin(void) ELPP_FINAL {
1870  return m_list.begin();
1871  }
1872 
1874  virtual inline iterator end(void) ELPP_FINAL {
1875  return m_list.end();
1876  }
1877 
1878 
1880  virtual inline const_iterator cbegin(void) const ELPP_FINAL {
1881  return m_list.cbegin();
1882  }
1883 
1885  virtual inline const_iterator cend(void) const ELPP_FINAL {
1886  return m_list.cend();
1887  }
1888 
1890  virtual inline bool empty(void) const ELPP_FINAL {
1891  return m_list.empty();
1892  }
1893 
1895  virtual inline std::size_t size(void) const ELPP_FINAL {
1896  return m_list.size();
1897  }
1898 
1900  virtual inline Container& list(void) ELPP_FINAL {
1901  return m_list;
1902  }
1903 
1905  virtual inline const Container& list(void) const ELPP_FINAL {
1906  return m_list;
1907  }
1908 
1910  virtual void unregisterAll(void) = 0;
1911 
1912 protected:
1913  virtual void deepCopy(const AbstractRegistry<T_Ptr, Container>&) = 0;
1915  unregisterAll();
1916  deepCopy(sr);
1917  }
1918 
1919 private:
1920  Container m_list;
1921 };
1922 
1928 template <typename T_Ptr, typename T_Key = const char*>
1929 class Registry : public AbstractRegistry<T_Ptr, std::map<T_Key, T_Ptr*>> {
1930 public:
1933 
1934  Registry(void) {}
1935 
1937  Registry(const Registry& sr) : AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>() {
1938  if (this == &sr) {
1939  return;
1940  }
1941  this->reinitDeepCopy(sr);
1942  }
1943 
1948  if (this == &sr) {
1949  return *this;
1950  }
1951  this->reinitDeepCopy(sr);
1952  return *this;
1953  }
1954 
1955  virtual ~Registry(void) {
1956  unregisterAll();
1957  }
1958 
1959 protected:
1960  virtual inline void unregisterAll(void) ELPP_FINAL {
1961  if (!this->empty()) {
1962  for (auto&& curr : this->list()) {
1963  base::utils::safeDelete(curr.second);
1964  }
1965  this->list().clear();
1966  }
1967  }
1968 
1970  virtual inline void registerNew(const T_Key& uniqKey, T_Ptr* ptr) ELPP_FINAL {
1971  unregister(uniqKey);
1972  this->list().insert(std::make_pair(uniqKey, ptr));
1973  }
1974 
1976  inline void unregister(const T_Key& uniqKey) {
1977  T_Ptr* existing = get(uniqKey);
1978  if (existing != nullptr) {
1979  base::utils::safeDelete(existing);
1980  this->list().erase(uniqKey);
1981  }
1982  }
1983 
1985  inline T_Ptr* get(const T_Key& uniqKey) {
1986  iterator it = this->list().find(uniqKey);
1987  return it == this->list().end()
1988  ? nullptr
1989  : it->second;
1990  }
1991 
1992 private:
1993  virtual inline void deepCopy(const AbstractRegistry<T_Ptr, std::map<T_Key, T_Ptr*>>& sr) ELPP_FINAL {
1994  for (const_iterator it = sr.cbegin(); it != sr.cend(); ++it) {
1995  registerNew(it->first, new T_Ptr(*it->second));
1996  }
1997  }
1998 };
1999 
2004 template <typename T_Ptr, typename Pred>
2005 class RegistryWithPred : public AbstractRegistry<T_Ptr, std::vector<T_Ptr*>> {
2006 public:
2009 
2011  }
2012 
2013  virtual ~RegistryWithPred(void) {
2014  unregisterAll();
2015  }
2016 
2018  RegistryWithPred(const RegistryWithPred& sr) : AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>() {
2019  if (this == &sr) {
2020  return;
2021  }
2022  this->reinitDeepCopy(sr);
2023  }
2024 
2029  if (this == &sr) {
2030  return *this;
2031  }
2032  this->reinitDeepCopy(sr);
2033  return *this;
2034  }
2035 
2037  for (const_iterator it = sr.list().begin(); it != sr.list().end(); ++it) {
2038  os << ELPP_LITERAL(" ") << **it << ELPP_LITERAL("\n");
2039  }
2040  return os;
2041  }
2042 
2043 protected:
2044  virtual inline void unregisterAll(void) ELPP_FINAL {
2045  if (!this->empty()) {
2046  for (auto&& curr : this->list()) {
2047  base::utils::safeDelete(curr);
2048  }
2049  this->list().clear();
2050  }
2051  }
2052 
2053  virtual void unregister(T_Ptr*& ptr) ELPP_FINAL {
2054  if (ptr) {
2055  iterator iter = this->begin();
2056  for (; iter != this->end(); ++iter) {
2057  if (ptr == *iter) {
2058  break;
2059  }
2060  }
2061  if (iter != this->end() && *iter != nullptr) {
2062  this->list().erase(iter);
2063  base::utils::safeDelete(*iter);
2064  }
2065  }
2066  }
2067 
2068  virtual inline void registerNew(T_Ptr* ptr) ELPP_FINAL {
2069  this->list().push_back(ptr);
2070  }
2071 
2074  template <typename T, typename T2>
2075  inline T_Ptr* get(const T& arg1, const T2 arg2) {
2076  iterator iter = std::find_if(this->list().begin(), this->list().end(), Pred(arg1, arg2));
2077  if (iter != this->list().end() && *iter != nullptr) {
2078  return *iter;
2079  }
2080  return nullptr;
2081  }
2082 
2083 private:
2084  virtual inline void deepCopy(const AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>& sr) {
2085  for (const_iterator it = sr.list().begin(); it != sr.list().end(); ++it) {
2086  registerNew(new T_Ptr(**it));
2087  }
2088  }
2089 };
2090 
2091 } // namespace utils
2092 } // namespace base
2096 class Loggable {
2097 public:
2098  virtual ~Loggable(void) {}
2099  virtual void log(el::base::type::ostream_t&) const = 0;
2100 private:
2102  loggable.log(os);
2103  return os;
2104  }
2105 };
2106 namespace base {
2108 class LogFormat : public Loggable {
2109 public:
2110  LogFormat(void) :
2111  m_level(Level::Unknown),
2112  m_userFormat(base::type::string_t()),
2113  m_format(base::type::string_t()),
2114  m_dateTimeFormat(std::string()),
2115  m_flags(0x0) {
2116  }
2117 
2119  : m_level(level), m_userFormat(format) {
2120  parseFromFormat(m_userFormat);
2121  }
2122 
2123  LogFormat(const LogFormat& logFormat) {
2124  m_level = logFormat.m_level;
2125  m_userFormat = logFormat.m_userFormat;
2126  m_format = logFormat.m_format;
2127  m_dateTimeFormat = logFormat.m_dateTimeFormat;
2128  m_flags = logFormat.m_flags;
2129  }
2130 
2131  LogFormat(LogFormat&& logFormat) {
2132  m_level = std::move(logFormat.m_level);
2133  m_userFormat = std::move(logFormat.m_userFormat);
2134  m_format = std::move(logFormat.m_format);
2135  m_dateTimeFormat = std::move(logFormat.m_dateTimeFormat);
2136  m_flags = std::move(logFormat.m_flags);
2137  }
2138 
2139  LogFormat& operator=(const LogFormat& logFormat) {
2140  m_level = logFormat.m_level;
2141  m_userFormat = logFormat.m_userFormat;
2142  m_dateTimeFormat = logFormat.m_dateTimeFormat;
2143  m_flags = logFormat.m_flags;
2144  return *this;
2145  }
2146 
2147  virtual ~LogFormat(void) {
2148  }
2149 
2150  inline bool operator==(const LogFormat& other) {
2151  return m_level == other.m_level && m_userFormat == other.m_userFormat && m_format == other.m_format &&
2152  m_dateTimeFormat == other.m_dateTimeFormat && m_flags == other.m_flags;
2153  }
2154 
2158  // We make copy because we will be changing the format
2159  // i.e, removing user provided date format from original format
2160  // and then storing it.
2161  base::type::string_t formatCopy = userFormat;
2162  m_flags = 0x0;
2163  auto conditionalAddFlag = [&](const base::type::char_t* specifier, base::FormatFlags flag) {
2164  std::size_t foundAt = base::type::string_t::npos;
2165  while ((foundAt = formatCopy.find(specifier, foundAt + 1)) != base::type::string_t::npos){
2166  if (foundAt > 0 && formatCopy[foundAt - 1] == base::consts::kFormatSpecifierChar) {
2167  if (hasFlag(flag)) {
2168  // If we already have flag we remove the escape chars so that '%%' is turned to '%'
2169  // even after specifier resolution - this is because we only replaceFirst specifier
2170  formatCopy.erase(foundAt > 0 ? foundAt - 1 : 0, 1);
2171  ++foundAt;
2172  }
2173  } else {
2174  if (!hasFlag(flag)) addFlag(flag);
2175  }
2176  }
2177  };
2178  conditionalAddFlag(base::consts::kAppNameFormatSpecifier, base::FormatFlags::AppName);
2179  conditionalAddFlag(base::consts::kSeverityLevelFormatSpecifier, base::FormatFlags::Level);
2180  conditionalAddFlag(base::consts::kSeverityLevelShortFormatSpecifier, base::FormatFlags::LevelShort);
2181  conditionalAddFlag(base::consts::kLoggerIdFormatSpecifier, base::FormatFlags::LoggerId);
2182  conditionalAddFlag(base::consts::kThreadIdFormatSpecifier, base::FormatFlags::ThreadId);
2183  conditionalAddFlag(base::consts::kLogFileFormatSpecifier, base::FormatFlags::File);
2184  conditionalAddFlag(base::consts::kLogFileBaseFormatSpecifier, base::FormatFlags::FileBase);
2185  conditionalAddFlag(base::consts::kLogLineFormatSpecifier, base::FormatFlags::Line);
2186  conditionalAddFlag(base::consts::kLogLocationFormatSpecifier, base::FormatFlags::Location);
2187  conditionalAddFlag(base::consts::kLogFunctionFormatSpecifier, base::FormatFlags::Function);
2188  conditionalAddFlag(base::consts::kCurrentUserFormatSpecifier, base::FormatFlags::User);
2189  conditionalAddFlag(base::consts::kCurrentHostFormatSpecifier, base::FormatFlags::Host);
2190  conditionalAddFlag(base::consts::kMessageFormatSpecifier, base::FormatFlags::LogMessage);
2191  conditionalAddFlag(base::consts::kVerboseLevelFormatSpecifier, base::FormatFlags::VerboseLevel);
2192  // For date/time we need to extract user's date format first
2193  std::size_t dateIndex = std::string::npos;
2194  if ((dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier)) != std::string::npos) {
2195  while (dateIndex > 0 && formatCopy[dateIndex - 1] == base::consts::kFormatSpecifierChar) {
2196  dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier, dateIndex + 1);
2197  }
2198  if (dateIndex != std::string::npos) {
2200  updateDateFormat(dateIndex, formatCopy);
2201  }
2202  }
2203  m_format = formatCopy;
2204  updateFormatSpec();
2205  }
2206 
2207  inline Level level(void) const {
2208  return m_level;
2209  }
2210 
2211  inline const base::type::string_t& userFormat(void) const {
2212  return m_userFormat;
2213  }
2214 
2215  inline const base::type::string_t& format(void) const {
2216  return m_format;
2217  }
2218 
2219  inline const std::string& dateTimeFormat(void) const {
2220  return m_dateTimeFormat;
2221  }
2222 
2223  inline base::type::EnumType flags(void) const {
2224  return m_flags;
2225  }
2226 
2227  inline bool hasFlag(base::FormatFlags flag) const {
2228  return base::utils::hasFlag(flag, m_flags);
2229  }
2230 
2231  virtual void log(el::base::type::ostream_t& os) const {
2232  os << m_format;
2233  }
2234 
2235 protected:
2239  virtual void updateDateFormat(std::size_t index, base::type::string_t& currFormat) ELPP_FINAL {
2241  index += ELPP_STRLEN(base::consts::kDateTimeFormatSpecifier);
2242  }
2243  const base::type::char_t* ptr = currFormat.c_str() + index;
2244  if ((currFormat.size() > index) && (ptr[0] == '{')) {
2245  // User has provided format for date/time
2246  ++ptr;
2247  int count = 1; // Start by 1 in order to remove starting brace
2248  std::stringstream ss;
2249  for (; *ptr; ++ptr, ++count) {
2250  if (*ptr == '}') {
2251  ++count; // In order to remove ending brace
2252  break;
2253  }
2254  ss << *ptr;
2255  }
2256  currFormat.erase(index, count);
2257  m_dateTimeFormat = ss.str();
2258  } else {
2259  // No format provided, use default
2261  m_dateTimeFormat = std::string(base::consts::kDefaultDateTimeFormat);
2262  }
2263  }
2264  }
2265 
2267  virtual void updateFormatSpec(void) ELPP_FINAL {
2268  // Do not use switch over strongly typed enums because Intel C++ compilers dont support them yet.
2269  if (m_level == Level::Debug) {
2270  base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier,
2271  base::consts::kDebugLevelLogValue);
2272  base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier,
2273  base::consts::kDebugLevelShortLogValue);
2274  } else if (m_level == Level::Info) {
2275  base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier,
2276  base::consts::kInfoLevelLogValue);
2277  base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier,
2278  base::consts::kInfoLevelShortLogValue);
2279  } else if (m_level == Level::Warning) {
2280  base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier,
2281  base::consts::kWarningLevelLogValue);
2282  base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier,
2283  base::consts::kWarningLevelShortLogValue);
2284  } else if (m_level == Level::Error) {
2285  base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier,
2286  base::consts::kErrorLevelLogValue);
2287  base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier,
2288  base::consts::kErrorLevelShortLogValue);
2289  } else if (m_level == Level::Fatal) {
2290  base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier,
2291  base::consts::kFatalLevelLogValue);
2292  base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier,
2293  base::consts::kFatalLevelShortLogValue);
2294  } else if (m_level == Level::Verbose) {
2295  base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier,
2296  base::consts::kVerboseLevelLogValue);
2297  base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier,
2298  base::consts::kVerboseLevelShortLogValue);
2299  } else if (m_level == Level::Trace) {
2300  base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier,
2301  base::consts::kTraceLevelLogValue);
2302  base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier,
2303  base::consts::kTraceLevelShortLogValue);
2304  }
2306  std::string s = base::utils::s_currentUser;
2307  base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kCurrentUserFormatSpecifier,
2309  }
2311  base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kCurrentHostFormatSpecifier,
2313  }
2314  // Ignore Level::Global and Level::Unknown
2315  }
2316 
2317  inline void addFlag(base::FormatFlags flag) {
2318  base::utils::addFlag(flag, &m_flags);
2319  }
2320 
2321 private:
2322  Level m_level;
2323  base::type::string_t m_userFormat;
2324  base::type::string_t m_format;
2325  std::string m_dateTimeFormat;
2326  base::type::EnumType m_flags;
2327  friend class el::Logger; // To resolve loggerId format specifier easily
2328 };
2329 } // namespace base
2331 typedef std::function<const char*(void)> FormatSpecifierValueResolver;
2336 public:
2338  m_formatSpecifier(formatSpecifier), m_resolver(resolver) {}
2339  inline const char* formatSpecifier(void) const { return m_formatSpecifier; }
2340  inline const FormatSpecifierValueResolver& resolver(void) const { return m_resolver; }
2341  inline bool operator==(const char* formatSpecifier) {
2342  return strcmp(m_formatSpecifier, formatSpecifier) == 0;
2343  }
2344 
2345 private:
2346  const char* m_formatSpecifier;
2347  FormatSpecifierValueResolver m_resolver;
2348 };
2358 class Configuration : public Loggable {
2359 public:
2361  m_level(c.m_level),
2362  m_configurationType(c.m_configurationType),
2363  m_value(c.m_value) {
2364  }
2365 
2367  m_level = c.m_level;
2368  m_configurationType = c.m_configurationType;
2369  m_value = c.m_value;
2370  return *this;
2371  }
2372 
2373  virtual ~Configuration(void) {
2374  }
2375 
2378  m_level(level),
2379  m_configurationType(configurationType),
2380  m_value(value) {
2381  }
2382 
2384  inline Level level(void) const {
2385  return m_level;
2386  }
2387 
2390  return m_configurationType;
2391  }
2392 
2394  inline const std::string& value(void) const {
2395  return m_value;
2396  }
2397 
2401  inline void setValue(const std::string& value) {
2402  m_value = value;
2403  }
2404 
2405  virtual inline void log(el::base::type::ostream_t& os) const {
2406  os << LevelHelper::convertToString(m_level)
2407  << ELPP_LITERAL(" ") << ConfigurationTypeHelper::convertToString(m_configurationType)
2408  << ELPP_LITERAL(" = ") << m_value.c_str();
2409  }
2410 
2412  class Predicate {
2413  public:
2415  m_level(level),
2416  m_configurationType(configurationType) {
2417  }
2418 
2419  inline bool operator()(const Configuration* conf) const {
2420  return ((conf != nullptr) && (conf->level() == m_level) && (conf->configurationType() == m_configurationType));
2421  }
2422 
2423  private:
2424  Level m_level;
2425  ConfigurationType m_configurationType;
2426  };
2427 
2428 private:
2429  Level m_level;
2430  ConfigurationType m_configurationType;
2431  std::string m_value;
2432 };
2433 
2437 class Configurations : public base::utils::RegistryWithPred<Configuration, Configuration::Predicate> {
2438 public:
2441  m_configurationFile(std::string()),
2442  m_isFromFile(false) {
2443  }
2444 
2451  Configurations(const std::string& configurationFile, bool useDefaultsForRemaining = true, Configurations* base = nullptr) :
2452  m_configurationFile(configurationFile),
2453  m_isFromFile(false) {
2454  parseFromFile(configurationFile, base);
2455  if (useDefaultsForRemaining) {
2457  }
2458  }
2459 
2460  virtual ~Configurations(void) {
2461  }
2462 
2469  inline bool parseFromFile(const std::string& configurationFile, Configurations* base = nullptr) {
2470  // We initial assertion with true because if we have assertion diabled, we want to pass this
2471  // check and if assertion is enabled we will have values re-assigned any way.
2472  bool assertionPassed = true;
2473  ELPP_ASSERT((assertionPassed = base::utils::File::pathExists(configurationFile.c_str(), true)),
2474  "Configuration file [" << configurationFile << "] does not exist!");
2475  if (!assertionPassed) {
2476  return false;
2477  }
2478  bool success = Parser::parseFromFile(configurationFile, this, base);
2479  m_isFromFile = success;
2480  return success;
2481  }
2482 
2491  inline bool parseFromText(const std::string& configurationsString, Configurations* base = nullptr) {
2492  bool success = Parser::parseFromText(configurationsString, this, base);
2493  if (success) {
2494  m_isFromFile = false;
2495  }
2496  return success;
2497  }
2498 
2501  inline void setFromBase(Configurations* base) {
2502  if (base == nullptr || base == this) {
2503  return;
2504  }
2505  base::threading::ScopedLock scopedLock(base->lock());
2506  for (Configuration*& conf : base->list()) {
2507  set(conf);
2508  }
2509  }
2510 
2515  bool hasConfiguration(ConfigurationType configurationType) {
2517  bool result = false;
2518  LevelHelper::forEachLevel(&lIndex, [&](void) -> bool {
2519  if (hasConfiguration(LevelHelper::castFromInt(lIndex), configurationType)) {
2520  result = true;
2521  }
2522  return result;
2523  });
2524  return result;
2525  }
2526 
2530  inline bool hasConfiguration(Level level, ConfigurationType configurationType) {
2531  base::threading::ScopedLock scopedLock(lock());
2532 #if ELPP_COMPILER_INTEL
2533  // We cant specify template types here, Intel C++ throws compilation error
2534  // "error: type name is not allowed"
2535  return RegistryWithPred::get(level, configurationType) != nullptr;
2536 #else
2537  return RegistryWithPred<Configuration, Configuration::Predicate>::get(level, configurationType) != nullptr;
2538 #endif // ELPP_COMPILER_INTEL
2539  }
2540 
2553  inline void set(Level level, ConfigurationType configurationType, const std::string& value) {
2554  base::threading::ScopedLock scopedLock(lock());
2555  unsafeSet(level, configurationType, value); // This is not unsafe anymore as we have locked mutex
2556  if (level == Level::Global) {
2557  unsafeSetGlobally(configurationType, value, false); // Again this is not unsafe either
2558  }
2559  }
2560 
2563  inline void set(Configuration* conf) {
2564  if (conf == nullptr) {
2565  return;
2566  }
2567  set(conf->level(), conf->configurationType(), conf->value());
2568  }
2569 
2570  inline Configuration* get(Level level, ConfigurationType configurationType) {
2571  base::threading::ScopedLock scopedLock(lock());
2572  return RegistryWithPred<Configuration, Configuration::Predicate>::get(level, configurationType);
2573  }
2574 
2579  inline void setGlobally(ConfigurationType configurationType, const std::string& value) {
2580  setGlobally(configurationType, value, false);
2581  }
2582 
2584  inline void clear(void) {
2585  base::threading::ScopedLock scopedLock(lock());
2586  unregisterAll();
2587  }
2588 
2592  inline const std::string& configurationFile(void) const {
2593  return m_configurationFile;
2594  }
2595 
2597  void setToDefault(void) {
2598  setGlobally(ConfigurationType::Enabled, std::string("true"), true);
2599 #if !defined(ELPP_NO_DEFAULT_LOG_FILE)
2600  setGlobally(ConfigurationType::Filename, std::string(base::consts::kDefaultLogFile), true);
2601 #else
2602  ELPP_UNUSED(base::consts::kDefaultLogFile);
2603 #endif // !defined(ELPP_NO_DEFAULT_LOG_FILE)
2604  setGlobally(ConfigurationType::ToFile, std::string("true"), true);
2605  setGlobally(ConfigurationType::ToStandardOutput, std::string("true"), true);
2606  setGlobally(ConfigurationType::MillisecondsWidth, std::string("3"), true);
2607  setGlobally(ConfigurationType::PerformanceTracking, std::string("true"), true);
2608  setGlobally(ConfigurationType::MaxLogFileSize, std::string("0"), true);
2609  setGlobally(ConfigurationType::LogFlushThreshold, std::string("0"), true);
2610 
2611  setGlobally(ConfigurationType::Format, std::string("%datetime %level [%logger] %msg"), true);
2612  set(Level::Debug, ConfigurationType::Format, std::string("%datetime %level [%logger] [%user@%host] [%func] [%loc] %msg"));
2613  // INFO and WARNING are set to default by Level::Global
2614  set(Level::Error, ConfigurationType::Format, std::string("%datetime %level [%logger] %msg"));
2615  set(Level::Fatal, ConfigurationType::Format, std::string("%datetime %level [%logger] %msg"));
2616  set(Level::Verbose, ConfigurationType::Format, std::string("%datetime %level-%vlevel [%logger] %msg"));
2617  set(Level::Trace, ConfigurationType::Format, std::string("%datetime %level [%logger] [%func] [%loc] %msg"));
2618  }
2619 
2628  base::threading::ScopedLock scopedLock(lock());
2629  unsafeSetIfNotExist(Level::Global, ConfigurationType::Enabled, std::string("true"));
2630 #if !defined(ELPP_NO_DEFAULT_LOG_FILE)
2631  unsafeSetIfNotExist(Level::Global, ConfigurationType::Filename, std::string(base::consts::kDefaultLogFile));
2632 #endif // !defined(ELPP_NO_DEFAULT_LOG_FILE)
2633  unsafeSetIfNotExist(Level::Global, ConfigurationType::ToFile, std::string("true"));
2634  unsafeSetIfNotExist(Level::Global, ConfigurationType::ToStandardOutput, std::string("true"));
2635  unsafeSetIfNotExist(Level::Global, ConfigurationType::MillisecondsWidth, std::string("3"));
2636  unsafeSetIfNotExist(Level::Global, ConfigurationType::PerformanceTracking, std::string("true"));
2637  unsafeSetIfNotExist(Level::Global, ConfigurationType::MaxLogFileSize, std::string("0"));
2638  unsafeSetIfNotExist(Level::Global, ConfigurationType::Format, std::string("%datetime %level [%logger] %msg"));
2639  unsafeSetIfNotExist(Level::Debug, ConfigurationType::Format,
2640  std::string("%datetime %level [%logger] [%user@%host] [%func] [%loc] %msg"));
2641  // INFO and WARNING are set to default by Level::Global
2642  unsafeSetIfNotExist(Level::Error, ConfigurationType::Format, std::string("%datetime %level [%logger] %msg"));
2643  unsafeSetIfNotExist(Level::Fatal, ConfigurationType::Format, std::string("%datetime %level [%logger] %msg"));
2644  unsafeSetIfNotExist(Level::Verbose, ConfigurationType::Format, std::string("%datetime %level-%vlevel [%logger] %msg"));
2645  unsafeSetIfNotExist(Level::Trace, ConfigurationType::Format, std::string("%datetime %level [%logger] [%func] [%loc] %msg"));
2646  }
2647 
2653  public:
2661  static bool parseFromFile(const std::string& configurationFile, Configurations* sender, Configurations* base = nullptr) {
2662  sender->setFromBase(base);
2663  std::ifstream fileStream_(configurationFile.c_str(), std::ifstream::in);
2664  ELPP_ASSERT(fileStream_.is_open(), "Unable to open configuration file [" << configurationFile << "] for parsing.");
2665  bool parsedSuccessfully = false;
2666  std::string line = std::string();
2667  Level currLevel = Level::Unknown;
2668  std::string currConfigStr = std::string();
2669  std::string currLevelStr = std::string();
2670  while (fileStream_.good()) {
2671  std::getline(fileStream_, line);
2672  parsedSuccessfully = parseLine(&line, &currConfigStr, &currLevelStr, &currLevel, sender);
2673  ELPP_ASSERT(parsedSuccessfully, "Unable to parse configuration line: " << line);
2674  }
2675  return parsedSuccessfully;
2676  }
2677 
2688  static bool parseFromText(const std::string& configurationsString, Configurations* sender, Configurations* base = nullptr) {
2689  sender->setFromBase(base);
2690  bool parsedSuccessfully = false;
2691  std::stringstream ss(configurationsString);
2692  std::string line = std::string();
2693  Level currLevel = Level::Unknown;
2694  std::string currConfigStr = std::string();
2695  std::string currLevelStr = std::string();
2696  while (std::getline(ss, line)) {
2697  parsedSuccessfully = parseLine(&line, &currConfigStr, &currLevelStr, &currLevel, sender);
2698  ELPP_ASSERT(parsedSuccessfully, "Unable to parse configuration line: " << line);
2699  }
2700  return parsedSuccessfully;
2701  }
2702 
2703  private:
2704  friend class el::Loggers;
2705  static void ignoreComments(std::string* line) {
2706  std::size_t foundAt = 0;
2707  std::size_t quotesStart = line->find("\"");
2708  std::size_t quotesEnd = std::string::npos;
2709  if (quotesStart != std::string::npos) {
2710  quotesEnd = line->find("\"", quotesStart + 1);
2711  while (quotesEnd != std::string::npos && line->at(quotesEnd - 1) == '\\') {
2712  // Do not erase slash yet - we will erase it in parseLine(..) while loop
2713  quotesEnd = line->find("\"", quotesEnd + 2);
2714  }
2715  }
2716  if ((foundAt = line->find(base::consts::kConfigurationComment)) != std::string::npos) {
2717  if (foundAt < quotesEnd) {
2718  foundAt = line->find(base::consts::kConfigurationComment, quotesEnd + 1);
2719  }
2720  *line = line->substr(0, foundAt);
2721  }
2722  }
2723  static inline bool isLevel(const std::string& line) {
2724  return base::utils::Str::startsWith(line, std::string(base::consts::kConfigurationLevel));
2725  }
2726 
2727  static inline bool isComment(const std::string& line) {
2728  return base::utils::Str::startsWith(line, std::string(base::consts::kConfigurationComment));
2729  }
2730 
2731  static inline bool isConfig(const std::string& line) {
2732  std::size_t assignment = line.find('=');
2733  return line != "" &&
2734  (line[0] >= 65 || line[0] <= 90 || line[0] >= 97 || line[0] <= 122) &&
2735  (assignment != std::string::npos) &&
2736  (line.size() > assignment);
2737  }
2738 
2739  static bool parseLine(std::string* line, std::string* currConfigStr, std::string* currLevelStr, Level* currLevel, Configurations* conf) {
2741  std::string currValue = std::string();
2742  *line = base::utils::Str::trim(*line);
2743  if (isComment(*line)) return true;
2744  ignoreComments(line);
2745  *line = base::utils::Str::trim(*line);
2746  if (line->empty()) {
2747  // Comment ignored
2748  return true;
2749  }
2750  if (isLevel(*line)) {
2751  if (line->size() <= 2) {
2752  return true;
2753  }
2754  *currLevelStr = line->substr(1, line->size() - 2);
2755  *currLevelStr = base::utils::Str::toUpper(*currLevelStr);
2756  *currLevelStr = base::utils::Str::trim(*currLevelStr);
2757  *currLevel = LevelHelper::convertFromString(currLevelStr->c_str());
2758  return true;
2759  }
2760  if (isConfig(*line)) {
2761  std::size_t assignment = line->find('=');
2762  *currConfigStr = line->substr(0, assignment);
2763  *currConfigStr = base::utils::Str::toUpper(*currConfigStr);
2764  *currConfigStr = base::utils::Str::trim(*currConfigStr);
2765  currConfig = ConfigurationTypeHelper::convertFromString(currConfigStr->c_str());
2766  currValue = line->substr(assignment + 1);
2767  currValue = base::utils::Str::trim(currValue);
2768  std::size_t quotesStart = currValue.find("\"", 0);
2769  std::size_t quotesEnd = std::string::npos;
2770  if (quotesStart != std::string::npos) {
2771  quotesEnd = currValue.find("\"", quotesStart + 1);
2772  while (quotesEnd != std::string::npos && currValue.at(quotesEnd - 1) == '\\') {
2773  currValue = currValue.erase(quotesEnd - 1, 1);
2774  quotesEnd = currValue.find("\"", quotesEnd + 2);
2775  }
2776  }
2777  if (quotesStart != std::string::npos && quotesEnd != std::string::npos) {
2778  // Quote provided - check and strip if valid
2779  ELPP_ASSERT((quotesStart < quotesEnd), "Configuration error - No ending quote found in ["
2780  << currConfigStr << "]");
2781  ELPP_ASSERT((quotesStart + 1 != quotesEnd), "Empty configuration value for [" << currConfigStr << "]");
2782  if ((quotesStart != quotesEnd) && (quotesStart + 1 != quotesEnd)) {
2783  // Explicit check in case if assertion is disabled
2784  currValue = currValue.substr(quotesStart + 1, quotesEnd - 1);
2785  }
2786  }
2787  }
2788  ELPP_ASSERT(*currLevel != Level::Unknown, "Unrecognized severity level [" << *currLevelStr << "]");
2789  ELPP_ASSERT(currConfig != ConfigurationType::Unknown, "Unrecognized configuration [" << *currConfigStr << "]");
2790  if (*currLevel == Level::Unknown || currConfig == ConfigurationType::Unknown) {
2791  return false; // unrecognizable level or config
2792  }
2793  conf->set(*currLevel, currConfig, currValue);
2794  return true;
2795  }
2796  };
2797 
2798 private:
2799  std::string m_configurationFile;
2800  bool m_isFromFile;
2801  friend class el::Loggers;
2802 
2804  void unsafeSetIfNotExist(Level level, ConfigurationType configurationType, const std::string& value) {
2806  if (conf == nullptr) {
2807  unsafeSet(level, configurationType, value);
2808  }
2809  }
2810 
2812  void unsafeSet(Level level, ConfigurationType configurationType, const std::string& value) {
2813  Configuration* conf = RegistryWithPred<Configuration, Configuration::Predicate>::get(level, configurationType);
2814  if (conf == nullptr) {
2815  registerNew(new Configuration(level, configurationType, value));
2816  } else {
2817  conf->setValue(value);
2818  }
2819  if (level == Level::Global) {
2820  unsafeSetGlobally(configurationType, value, false);
2821  }
2822  }
2823 
2826  void setGlobally(ConfigurationType configurationType, const std::string& value, bool includeGlobalLevel) {
2827  if (includeGlobalLevel) {
2828  set(Level::Global, configurationType, value);
2829  }
2831  LevelHelper::forEachLevel(&lIndex, [&](void) -> bool {
2832  set(LevelHelper::castFromInt(lIndex), configurationType, value);
2833  return false; // Do not break lambda function yet as we need to set all levels regardless
2834  });
2835  }
2836 
2839  void unsafeSetGlobally(ConfigurationType configurationType, const std::string& value, bool includeGlobalLevel) {
2840  if (includeGlobalLevel) {
2841  unsafeSet(Level::Global, configurationType, value);
2842  }
2844  LevelHelper::forEachLevel(&lIndex, [&](void) -> bool {
2845  unsafeSet(LevelHelper::castFromInt(lIndex), configurationType, value);
2846  return false; // Do not break lambda function yet as we need to set all levels regardless
2847  });
2848  }
2849 };
2850 
2851 namespace base {
2852 typedef std::shared_ptr<base::type::fstream_t> FileStreamPtr;
2853 typedef std::map<std::string, FileStreamPtr> LogStreamsReferenceMap;
2861 public:
2866  m_configurations = configurations;
2867  m_logStreamsReference = logStreamsReference;
2868  build(m_configurations);
2869  }
2870 
2872  this->m_configurations = other.m_configurations;
2873  this->m_logStreamsReference = other.m_logStreamsReference;
2874  build(m_configurations);
2875  }
2876 
2877  virtual ~TypedConfigurations(void) {
2878  }
2879 
2880  const Configurations* configurations(void) const {
2881  return m_configurations;
2882  }
2883 
2884  inline bool enabled(Level level) {
2885  return getConfigByVal<bool>(level, &m_enabledMap, "enabled");
2886  }
2887 
2888  inline bool toFile(Level level) {
2889  return getConfigByVal<bool>(level, &m_toFileMap, "toFile");
2890  }
2891 
2892  inline const std::string& filename(Level level) {
2893  return getConfigByRef<std::string>(level, &m_filenameMap, "filename");
2894  }
2895 
2896  inline bool toStandardOutput(Level level) {
2897  return getConfigByVal<bool>(level, &m_toStandardOutputMap, "toStandardOutput");
2898  }
2899 
2900  inline const base::LogFormat& logFormat(Level level) {
2901  return getConfigByRef<base::LogFormat>(level, &m_logFormatMap, "logFormat");
2902  }
2903 
2905  return getConfigByRef<base::MillisecondsWidth>(level, &m_millisecondsWidthMap, "millisecondsWidth");
2906  }
2907 
2908  inline bool performanceTracking(Level level = Level::Global) {
2909  return getConfigByVal<bool>(level, &m_performanceTrackingMap, "performanceTracking");
2910  }
2911 
2913  return getConfigByRef<base::FileStreamPtr>(level, &m_fileStreamMap, "fileStream").get();
2914  }
2915 
2916  inline std::size_t maxLogFileSize(Level level) {
2917  return getConfigByVal<std::size_t>(level, &m_maxLogFileSizeMap, "maxLogFileSize");
2918  }
2919 
2920  inline std::size_t logFlushThreshold(Level level) {
2921  return getConfigByVal<std::size_t>(level, &m_logFlushThresholdMap, "logFlushThreshold");
2922  }
2923 
2924 private:
2925  Configurations* m_configurations;
2926  std::map<Level, bool> m_enabledMap;
2927  std::map<Level, bool> m_toFileMap;
2928  std::map<Level, std::string> m_filenameMap;
2929  std::map<Level, bool> m_toStandardOutputMap;
2930  std::map<Level, base::LogFormat> m_logFormatMap;
2931  std::map<Level, base::MillisecondsWidth> m_millisecondsWidthMap;
2932  std::map<Level, bool> m_performanceTrackingMap;
2933  std::map<Level, base::FileStreamPtr> m_fileStreamMap;
2934  std::map<Level, std::size_t> m_maxLogFileSizeMap;
2935  std::map<Level, std::size_t> m_logFlushThresholdMap;
2936  base::LogStreamsReferenceMap* m_logStreamsReference;
2937 
2938  friend class el::Helpers;
2940  friend class el::base::Writer;
2943 
2944  template <typename Conf_T>
2945  inline Conf_T getConfigByVal(Level level, const std::map<Level, Conf_T>* confMap, const char* confName) {
2946  base::threading::ScopedLock scopedLock(lock());
2947  return unsafeGetConfigByVal(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope
2948  }
2949 
2950  template <typename Conf_T>
2951  inline Conf_T& getConfigByRef(Level level, std::map<Level, Conf_T>* confMap, const char* confName) {
2952  base::threading::ScopedLock scopedLock(lock());
2953  return unsafeGetConfigByRef(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope
2954  }
2955 
2956  template <typename Conf_T>
2957  inline Conf_T unsafeGetConfigByVal(Level level, const std::map<Level, Conf_T>* confMap, const char* confName) {
2958  ELPP_UNUSED(confName);
2959  typename std::map<Level, Conf_T>::const_iterator it = confMap->find(level);
2960  if (it == confMap->end()) {
2961  try {
2962  return confMap->at(Level::Global);
2963  } catch (...) {
2964  ELPP_INTERNAL_ERROR("Unable to get configuration [" << confName << "] for level ["
2965  << LevelHelper::convertToString(level) << "]"
2966  << std::endl << "Please ensure you have properly configured logger.", false);
2967  return Conf_T();
2968  }
2969  }
2970  return it->second;
2971  }
2972 
2973  template <typename Conf_T>
2974  inline Conf_T& unsafeGetConfigByRef(Level level, std::map<Level, Conf_T>* confMap, const char* confName) {
2975  ELPP_UNUSED(confName);
2976  typename std::map<Level, Conf_T>::iterator it = confMap->find(level);
2977  if (it == confMap->end()) {
2978  try {
2979  return confMap->at(Level::Global);
2980  } catch (...) {
2981  ELPP_INTERNAL_ERROR("Unable to get configuration [" << confName << "] for level ["
2982  << LevelHelper::convertToString(level) << "]"
2983  << std::endl << "Please ensure you have properly configured logger.", false);
2984  }
2985  }
2986  return it->second;
2987  }
2988 
2989  template <typename Conf_T>
2990  void setValue(Level level, const Conf_T& value, std::map<Level, Conf_T>* confMap, bool includeGlobalLevel = true) {
2991  // If map is empty and we are allowed to add into generic level (Level::Global), do it!
2992  if (confMap->empty() && includeGlobalLevel) {
2993  confMap->insert(std::make_pair(Level::Global, value));
2994  return;
2995  }
2996  // If same value exist in generic level already, dont add it to explicit level
2997  typename std::map<Level, Conf_T>::iterator it = confMap->find(Level::Global);
2998  if (it != confMap->end() && it->second == value) {
2999  return;
3000  }
3001  // Now make sure we dont double up values if we really need to add it to explicit level
3002  it = confMap->find(level);
3003  if (it == confMap->end()) {
3004  // Value not found for level, add new
3005  confMap->insert(std::make_pair(level, value));
3006  } else {
3007  // Value found, just update value
3008  confMap->at(level) = value;
3009  }
3010  }
3011 
3012  void build(Configurations* configurations) {
3013  base::threading::ScopedLock scopedLock(lock());
3014  auto getBool = [] (std::string boolStr) -> bool { // Pass by value for trimming
3015  base::utils::Str::trim(boolStr);
3016  return (boolStr == "TRUE" || boolStr == "true" || boolStr == "1");
3017  };
3018  std::vector<Configuration*> withFileSizeLimit;
3019  for (Configurations::const_iterator it = configurations->begin(); it != configurations->end(); ++it) {
3020  Configuration* conf = *it;
3021  // We cannot use switch on strong enums because Intel C++ dont support them yet
3022  if (conf->configurationType() == ConfigurationType::Enabled) {
3023  setValue(conf->level(), getBool(conf->value()), &m_enabledMap);
3024  } else if (conf->configurationType() == ConfigurationType::ToFile) {
3025  setValue(conf->level(), getBool(conf->value()), &m_toFileMap);
3026  } else if (conf->configurationType() == ConfigurationType::ToStandardOutput) {
3027  setValue(conf->level(), getBool(conf->value()), &m_toStandardOutputMap);
3028  } else if (conf->configurationType() == ConfigurationType::Filename) {
3029  // We do not yet configure filename but we will configure in another
3030  // loop. This is because if file cannot be created, we will force ToFile
3031  // to be false. Because configuring logger is not necessarily performance
3032  // sensative operation, we can live with another loop; (by the way this loop
3033  // is not very heavy either)
3034  } else if (conf->configurationType() == ConfigurationType::Format) {
3035  setValue(conf->level(), base::LogFormat(conf->level(),
3036  base::type::string_t(conf->value().begin(), conf->value().end())), &m_logFormatMap);
3037  } else if (conf->configurationType() == ConfigurationType::MillisecondsWidth) {
3038  setValue(Level::Global,
3039  base::MillisecondsWidth(static_cast<int>(getULong(conf->value()))), &m_millisecondsWidthMap);
3040  } else if (conf->configurationType() == ConfigurationType::PerformanceTracking) {
3041  setValue(Level::Global, getBool(conf->value()), &m_performanceTrackingMap);
3042  } else if (conf->configurationType() == ConfigurationType::MaxLogFileSize) {
3043  setValue(conf->level(), static_cast<std::size_t>(getULong(conf->value())), &m_maxLogFileSizeMap);
3044 #if !defined(ELPP_NO_DEFAULT_LOG_FILE)
3045  withFileSizeLimit.push_back(conf);
3046 #endif // !defined(ELPP_NO_DEFAULT_LOG_FILE)
3047  } else if (conf->configurationType() == ConfigurationType::LogFlushThreshold) {
3048  setValue(conf->level(), static_cast<std::size_t>(getULong(conf->value())), &m_logFlushThresholdMap);
3049  }
3050  }
3051  // As mentioned early, we will now set filename configuration in separate loop to deal with non-existent files
3052  for (Configurations::const_iterator it = configurations->begin(); it != configurations->end(); ++it) {
3053  Configuration* conf = *it;
3054  if (conf->configurationType() == ConfigurationType::Filename) {
3055  insertFile(conf->level(), conf->value());
3056  }
3057  }
3058  for (std::vector<Configuration*>::iterator conf = withFileSizeLimit.begin();
3059  conf != withFileSizeLimit.end(); ++conf) {
3060  // This is not unsafe as mutex is locked in currect scope
3061  unsafeValidateFileRolling((*conf)->level(), base::defaultPreRollOutCallback);
3062  }
3063  }
3064 
3065  unsigned long getULong(std::string confVal) {
3066  bool valid = true;
3067  base::utils::Str::trim(confVal);
3068  valid = !confVal.empty() && std::find_if(confVal.begin(), confVal.end(),
3069  [](char c) { return !base::utils::Str::isDigit(c); }) == confVal.end();
3070  if (!valid) {
3071  valid = false;
3072  ELPP_ASSERT(valid, "Configuration value not a valid integer [" << confVal << "]");
3073  return 0;
3074  }
3075  return atol(confVal.c_str());
3076  }
3077 
3078  std::string resolveFilename(const std::string& filename) {
3079  std::string resultingFilename = filename;
3080  std::size_t dateIndex = std::string::npos;
3081  std::string dateTimeFormatSpecifierStr = std::string(base::consts::kDateTimeFormatSpecifierForFilename);
3082  if ((dateIndex = resultingFilename.find(dateTimeFormatSpecifierStr.c_str())) != std::string::npos) {
3083  while (dateIndex > 0 && resultingFilename[dateIndex - 1] == base::consts::kFormatSpecifierChar) {
3084  dateIndex = resultingFilename.find(dateTimeFormatSpecifierStr.c_str(), dateIndex + 1);
3085  }
3086  if (dateIndex != std::string::npos) {
3087  const char* ptr = resultingFilename.c_str() + dateIndex;
3088  // Goto end of specifier
3089  ptr += dateTimeFormatSpecifierStr.size();
3090  std::string fmt;
3091  if ((resultingFilename.size() > dateIndex) && (ptr[0] == '{')) {
3092  // User has provided format for date/time
3093  ++ptr;
3094  int count = 1; // Start by 1 in order to remove starting brace
3095  std::stringstream ss;
3096  for (; *ptr; ++ptr, ++count) {
3097  if (*ptr == '}') {
3098  ++count; // In order to remove ending brace
3099  break;
3100  }
3101  ss << *ptr;
3102  }
3103  resultingFilename.erase(dateIndex + dateTimeFormatSpecifierStr.size(), count);
3104  fmt = ss.str();
3105  } else {
3106  fmt = std::string(base::consts::kDefaultDateTimeFormatInFilename);
3107  }
3108  base::MillisecondsWidth msWidth(3);
3109  std::string now = base::utils::DateTime::getDateTime(fmt.c_str(), &msWidth);
3110  base::utils::Str::replaceAll(now, '/', '-'); // Replace path element since we are dealing with filename
3111  base::utils::Str::replaceAll(resultingFilename, dateTimeFormatSpecifierStr, now);
3112  }
3113  }
3114  return resultingFilename;
3115  }
3116 
3117  void insertFile(Level level, const std::string& fullFilename) {
3118  std::string resolvedFilename = resolveFilename(fullFilename);
3119  if (resolvedFilename.empty()) {
3120  std::cerr << "Could not load empty file for logging, please re-check your configurations for level ["
3121  << LevelHelper::convertToString(level) << "]";
3122  }
3123  std::string filePath = base::utils::File::extractPathFromFilename(resolvedFilename, base::consts::kFilePathSeperator);
3124  if (filePath.size() < resolvedFilename.size()) {
3126  }
3127  auto create = [&](Level level) {
3128  base::LogStreamsReferenceMap::iterator filestreamIter = m_logStreamsReference->find(resolvedFilename);
3129  base::type::fstream_t* fs = nullptr;
3130  if (filestreamIter == m_logStreamsReference->end()) {
3131  // We need a completely new stream, nothing to share with
3132  fs = base::utils::File::newFileStream(resolvedFilename);
3133  m_filenameMap.insert(std::make_pair(level, resolvedFilename));
3134  m_fileStreamMap.insert(std::make_pair(level, base::FileStreamPtr(fs)));
3135  m_logStreamsReference->insert(std::make_pair(resolvedFilename, base::FileStreamPtr(m_fileStreamMap.at(level))));
3136  } else {
3137  // Woops! we have an existing one, share it!
3138  m_filenameMap.insert(std::make_pair(level, filestreamIter->first));
3139  m_fileStreamMap.insert(std::make_pair(level, base::FileStreamPtr(filestreamIter->second)));
3140  fs = filestreamIter->second.get();
3141  }
3142  if (fs == nullptr) {
3143  // We display bad file error from newFileStream()
3144  ELPP_INTERNAL_ERROR("Setting [TO_FILE] of ["
3145  << LevelHelper::convertToString(level) << "] to FALSE", false);
3146  setValue(level, false, &m_toFileMap);
3147  }
3148  };
3149  // If we dont have file conf for any level, create it for Level::Global first
3150  // otherwise create for specified level
3151  create(m_filenameMap.empty() && m_fileStreamMap.empty() ? Level::Global : level);
3152  }
3153 
3154  bool unsafeValidateFileRolling(Level level, const PreRollOutCallback& PreRollOutCallback) {
3155  base::type::fstream_t* fs = unsafeGetConfigByRef(level, &m_fileStreamMap, "fileStream").get();
3156  if (fs == nullptr) {
3157  return true;
3158  }
3159  std::size_t maxLogFileSize = unsafeGetConfigByVal(level, &m_maxLogFileSizeMap, "maxLogFileSize");
3160  std::size_t currFileSize = base::utils::File::getSizeOfFile(fs);
3161  if (maxLogFileSize != 0 && currFileSize >= maxLogFileSize) {
3162  std::string fname = unsafeGetConfigByRef(level, &m_filenameMap, "filename");
3163  ELPP_INTERNAL_INFO(1, "Truncating log file [" << fname << "] as a result of configurations for level ["
3164  << LevelHelper::convertToString(level) << "]");
3165  fs->close();
3166  PreRollOutCallback(fname.c_str(), currFileSize);
3167  fs->open(fname, std::fstream::out | std::fstream::trunc);
3168  return true;
3169  }
3170  return false;
3171  }
3172 
3173  bool validateFileRolling(Level level, const PreRollOutCallback& PreRollOutCallback) {
3174  base::threading::ScopedLock scopedLock(lock());
3175  return unsafeValidateFileRolling(level, PreRollOutCallback);
3176  }
3177 };
3179 class HitCounter {
3180 public:
3181  HitCounter(void) :
3182  m_filename(""),
3183  m_lineNumber(0),
3184  m_hitCounts(0) {
3185  }
3186 
3187  HitCounter(const char* filename, unsigned long int lineNumber) :
3188  m_filename(filename),
3189  m_lineNumber(lineNumber),
3190  m_hitCounts(0) {
3191  }
3192 
3193  HitCounter(const HitCounter& hitCounter) :
3194  m_filename(hitCounter.m_filename),
3195  m_lineNumber(hitCounter.m_lineNumber),
3196  m_hitCounts(hitCounter.m_hitCounts) {
3197  }
3198 
3199  HitCounter& operator=(const HitCounter& hitCounter) {
3200  m_filename = hitCounter.m_filename;
3201  m_lineNumber = hitCounter.m_lineNumber;
3202  m_hitCounts = hitCounter.m_hitCounts;
3203  return *this;
3204  }
3205 
3206  virtual ~HitCounter(void) {
3207  }
3208 
3210  inline void resetLocation(const char* filename, unsigned long int lineNumber) {
3211  m_filename = filename;
3212  m_lineNumber = lineNumber;
3213  }
3214 
3216  inline void validateHitCounts(std::size_t n) {
3217  if (m_hitCounts >= base::consts::kMaxLogPerCounter) {
3218  m_hitCounts = (n >= 1 ? base::consts::kMaxLogPerCounter % n : 0);
3219  }
3220  ++m_hitCounts;
3221  }
3222 
3223  inline const char* filename(void) const {
3224  return m_filename;
3225  }
3226 
3227  inline unsigned long int lineNumber(void) const {
3228  return m_lineNumber;
3229  }
3230 
3231  inline std::size_t hitCounts(void) const {
3232  return m_hitCounts;
3233  }
3234 
3235  inline void increment(void) {
3236  ++m_hitCounts;
3237  }
3238 
3239  class Predicate {
3240  public:
3241  Predicate(const char* filename, unsigned long int lineNumber)
3242  : m_filename(filename),
3243  m_lineNumber(lineNumber) {
3244  }
3245  inline bool operator()(const HitCounter* counter) {
3246  return ((counter != nullptr) &&
3247  (strcmp(counter->m_filename, m_filename) == 0) &&
3248  (counter->m_lineNumber == m_lineNumber));
3249  }
3250 
3251  private:
3252  const char* m_filename;
3253  unsigned long int m_lineNumber;
3254  };
3255 
3256 private:
3257  const char* m_filename;
3258  unsigned long int m_lineNumber;
3259  std::size_t m_hitCounts;
3260 };
3262 class RegisteredHitCounters : public base::utils::RegistryWithPred<base::HitCounter, base::HitCounter::Predicate> {
3263 public:
3266  bool validateEveryN(const char* filename, unsigned long int lineNumber, std::size_t n) {
3267  base::threading::ScopedLock scopedLock(lock());
3268  base::HitCounter* counter = get(filename, lineNumber);
3269  if (counter == nullptr) {
3270  registerNew(counter = new base::HitCounter(filename, lineNumber));
3271  }
3272  counter->validateHitCounts(n);
3273  bool result = (n >= 1 && counter->hitCounts() != 0 && counter->hitCounts() % n == 0);
3274  return result;
3275  }
3276 
3279  bool validateAfterN(const char* filename, unsigned long int lineNumber, std::size_t n) {
3280  base::threading::ScopedLock scopedLock(lock());
3281  base::HitCounter* counter = get(filename, lineNumber);
3282  if (counter == nullptr) {
3283  registerNew(counter = new base::HitCounter(filename, lineNumber));
3284  }
3285  // Do not use validateHitCounts here since we do not want to reset counter here
3286  // Note the >= instead of > because we are incrementing
3287  // after this check
3288  if (counter->hitCounts() >= n)
3289  return true;
3290  counter->increment();
3291  return false;
3292  }
3293 
3296  bool validateNTimes(const char* filename, unsigned long int lineNumber, std::size_t n) {
3297  base::threading::ScopedLock scopedLock(lock());
3298  base::HitCounter* counter = get(filename, lineNumber);
3299  if (counter == nullptr) {
3300  registerNew(counter = new base::HitCounter(filename, lineNumber));
3301  }
3302  counter->increment();
3303  // Do not use validateHitCounts here since we do not want to reset counter here
3304  if (counter->hitCounts() <= n)
3305  return true;
3306  return false;
3307  }
3308 
3310  inline const base::HitCounter* getCounter(const char* filename, unsigned long int lineNumber) {
3311  base::threading::ScopedLock scopedLock(lock());
3312  return get(filename, lineNumber);
3313  }
3314 };
3317  None = 1, NormalLog = 2, SysLog = 4
3318 };
3319 } // namespace base
3320 template <typename T>
3321 class Callback : protected base::threading::ThreadSafe {
3322 public:
3323  Callback(void) : m_enabled(true) {}
3324  inline bool enabled(void) const { return m_enabled; }
3325  inline void setEnabled(bool enabled) {
3326  base::threading::ScopedLock scopedLock(lock());
3327  m_enabled = enabled;
3328  }
3329 protected:
3330  virtual void handle(const T* handlePtr) = 0;
3331 private:
3332  bool m_enabled;
3333 };
3335 public:
3336  LogDispatchData() : m_logMessage(nullptr), m_dispatchAction(base::DispatchAction::None) {}
3337  inline const LogMessage* logMessage(void) const { return m_logMessage; }
3338  inline base::DispatchAction dispatchAction(void) const { return m_dispatchAction; }
3339 private:
3340  LogMessage* m_logMessage;
3341  base::DispatchAction m_dispatchAction;
3342  friend class base::LogDispatcher;
3343 
3344  inline void setLogMessage(LogMessage* logMessage) { m_logMessage = logMessage; }
3345  inline void setDispatchAction(base::DispatchAction dispatchAction) { m_dispatchAction = dispatchAction; }
3346 };
3347 class LogDispatchCallback : public Callback<LogDispatchData> {
3348 private:
3349  friend class base::LogDispatcher;
3350 };
3351 class PerformanceTrackingCallback : public Callback<PerformanceTrackingData> {
3352 private:
3354 };
3356 public:
3357  virtual ~LogBuilder(void) { ELPP_INTERNAL_INFO(3, "Destroying log builder...")}
3358  virtual base::type::string_t build(const LogMessage* logMessage, bool appendNewLine) const = 0;
3360  if (!base::utils::s_termSupportsColor) return;
3361  const base::type::char_t* resetColor = ELPP_LITERAL("\x1b[0m");
3362  if (level == Level::Error || level == Level::Fatal)
3363  *logLine = ELPP_LITERAL("\x1b[31m") + *logLine + resetColor;
3364  else if (level == Level::Warning)
3365  *logLine = ELPP_LITERAL("\x1b[33m") + *logLine + resetColor;
3366  }
3367 private:
3369 };
3370 typedef std::shared_ptr<LogBuilder> LogBuilderPtr;
3375 public:
3376  Logger(const std::string& id, base::LogStreamsReferenceMap* logStreamsReference) :
3377  m_id(id),
3378  m_typedConfigurations(nullptr),
3379  m_parentApplicationName(std::string()),
3380  m_isConfigured(false),
3381  m_logStreamsReference(logStreamsReference) {
3382  initUnflushedCount();
3383  }
3384 
3385  Logger(const std::string& id, const Configurations& configurations, base::LogStreamsReferenceMap* logStreamsReference) :
3386  m_id(id),
3387  m_typedConfigurations(nullptr),
3388  m_parentApplicationName(std::string()),
3389  m_isConfigured(false),
3390  m_logStreamsReference(logStreamsReference) {
3391  initUnflushedCount();
3392  configure(configurations);
3393  }
3394 
3396  base::utils::safeDelete(m_typedConfigurations);
3397  m_id = logger.m_id;
3398  m_typedConfigurations = logger.m_typedConfigurations;
3399  m_parentApplicationName = logger.m_parentApplicationName;
3400  m_isConfigured = logger.m_isConfigured;
3401  m_configurations = logger.m_configurations;
3402  m_unflushedCount = logger.m_unflushedCount;
3403  m_logStreamsReference = logger.m_logStreamsReference;
3404  }
3405 
3407  base::utils::safeDelete(m_typedConfigurations);
3408  m_id = logger.m_id;
3409  m_typedConfigurations = logger.m_typedConfigurations;
3410  m_parentApplicationName = logger.m_parentApplicationName;
3411  m_isConfigured = logger.m_isConfigured;
3412  m_configurations = logger.m_configurations;
3413  m_unflushedCount = logger.m_unflushedCount;
3414  m_logStreamsReference = logger.m_logStreamsReference;
3415  return *this;
3416  }
3417 
3418  virtual ~Logger(void) {
3419  base::utils::safeDelete(m_typedConfigurations);
3420  }
3421 
3422  virtual inline void log(el::base::type::ostream_t& os) const {
3423  os << m_id.c_str();
3424  }
3425 
3427  void configure(const Configurations& configurations) {
3428  m_isConfigured = false; // we set it to false in case if we fail
3429  initUnflushedCount();
3430  if (m_typedConfigurations != nullptr) {
3431  Configurations* c = const_cast<Configurations*>(m_typedConfigurations->configurations());
3433  // This check is definitely needed for cases like ELPP_NO_DEFAULT_LOG_FILE
3434  flush();
3435  }
3436  }
3437  base::threading::ScopedLock scopedLock(lock());
3438  if (m_configurations != configurations) {
3439  m_configurations.setFromBase(const_cast<Configurations*>(&configurations));
3440  }
3441  base::utils::safeDelete(m_typedConfigurations);
3442  m_typedConfigurations = new base::TypedConfigurations(&m_configurations, m_logStreamsReference);
3443  resolveLoggerFormatSpec();
3444  m_isConfigured = true;
3445  }
3446 
3448  inline void reconfigure(void) {
3449  ELPP_INTERNAL_INFO(1, "Reconfiguring logger [" << m_id << "]");
3450  configure(m_configurations);
3451  }
3452 
3453  inline const std::string& id(void) const {
3454  return m_id;
3455  }
3456 
3457  inline const std::string& parentApplicationName(void) const {
3458  return m_parentApplicationName;
3459  }
3460 
3461  inline void setParentApplicationName(const std::string& parentApplicationName) {
3462  m_parentApplicationName = parentApplicationName;
3463  }
3464 
3466  return &m_configurations;
3467  }
3468 
3470  return m_typedConfigurations;
3471  }
3472 
3473  static inline bool isValidId(const std::string& id) {
3474  for (std::string::const_iterator it = id.begin(); it != id.end(); ++it) {
3475  if (!base::utils::Str::contains(base::consts::kValidLoggerIdSymbols, *it)) {
3476  return false;
3477  }
3478  }
3479  return true;
3480  }
3482  inline void flush(void) {
3483  ELPP_INTERNAL_INFO(3, "Flushing logger [" << m_id << "] all levels");
3484  base::threading::ScopedLock scopedLock(lock());
3486  LevelHelper::forEachLevel(&lIndex, [&](void) -> bool {
3487  flush(LevelHelper::castFromInt(lIndex), nullptr);
3488  return false;
3489  });
3490  }
3491 
3492  inline void flush(Level level, base::type::fstream_t* fs) {
3493  if (fs == nullptr && m_typedConfigurations->toFile(level)) {
3494  fs = m_typedConfigurations->fileStream(level);
3495  }
3496  if (fs != nullptr) {
3497  fs->flush();
3498  m_unflushedCount.find(level)->second = 0;
3499  }
3500  }
3501 
3502  inline bool isFlushNeeded(Level level) {
3503  return ++m_unflushedCount.find(level)->second >= m_typedConfigurations->logFlushThreshold(level);
3504  }
3505 
3506  inline LogBuilder* logBuilder(void) const {
3507  return m_logBuilder.get();
3508  }
3509 
3511  m_logBuilder = logBuilder;
3512  }
3513 
3514  inline bool enabled(Level level) const {
3515  return m_typedConfigurations->enabled(level);
3516  }
3517 
3518 #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
3519 # define LOGGER_LEVEL_WRITERS_SIGNATURES(FUNCTION_NAME)\
3520  template <typename T, typename... Args>\
3521  inline void FUNCTION_NAME(const char*, const T&, const Args&...);\
3522  template <typename T>\
3523  inline void FUNCTION_NAME(const T&);
3524 
3525  template <typename T, typename... Args>
3526  inline void verbose(int, const char*, const T&, const Args&...);
3527 
3528  template <typename T>
3529  inline void verbose(int, const T&);
3530 
3531  LOGGER_LEVEL_WRITERS_SIGNATURES(info)
3532  LOGGER_LEVEL_WRITERS_SIGNATURES(debug)
3533  LOGGER_LEVEL_WRITERS_SIGNATURES(warn)
3534  LOGGER_LEVEL_WRITERS_SIGNATURES(error)
3535  LOGGER_LEVEL_WRITERS_SIGNATURES(fatal)
3536  LOGGER_LEVEL_WRITERS_SIGNATURES(trace)
3537 # undef LOGGER_LEVEL_WRITERS_SIGNATURES
3538 #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
3539 private:
3540  std::string m_id;
3541  base::TypedConfigurations* m_typedConfigurations;
3542  base::type::stringstream_t m_stream;
3543  std::string m_parentApplicationName;
3544  bool m_isConfigured;
3545  Configurations m_configurations;
3546  std::map<Level, unsigned int> m_unflushedCount;
3547  base::LogStreamsReferenceMap* m_logStreamsReference;
3548  LogBuilderPtr m_logBuilder;
3549 
3550  friend class el::LogMessage;
3551  friend class el::Loggers;
3552  friend class el::Helpers;
3556  friend class el::base::Writer;
3558  friend class el::base::Storage;
3561 
3562  Logger(void);
3563 
3564 #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
3565  template <typename T, typename... Args>
3566  void log_(Level, int, const char*, const T&, const Args&...);
3567 
3568  template <typename T>
3569  inline void log_(Level, int, const T&);
3570 
3571  template <typename T, typename... Args>
3572  void log(Level, const char*, const T&, const Args&...);
3573 
3574  template <typename T>
3575  inline void log(Level, const T&);
3576 #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
3577 
3578  void initUnflushedCount(void) {
3579  m_unflushedCount.clear();
3581  LevelHelper::forEachLevel(&lIndex, [&](void) -> bool {
3582  m_unflushedCount.insert(std::make_pair(LevelHelper::castFromInt(lIndex), 0));
3583  return false;
3584  });
3585  }
3586 
3587  inline base::type::stringstream_t& stream(void) {
3588  return m_stream;
3589  }
3590 
3591  void resolveLoggerFormatSpec(void) const {
3593  LevelHelper::forEachLevel(&lIndex, [&](void) -> bool {
3594  base::LogFormat* logFormat =
3595  const_cast<base::LogFormat*>(&m_typedConfigurations->logFormat(LevelHelper::castFromInt(lIndex)));
3596  base::utils::Str::replaceFirstWithEscape(logFormat->m_format, base::consts::kLoggerIdFormatSpecifier, m_id);
3597  return false;
3598  });
3599  }
3600 };
3601 namespace base {
3603 class RegisteredLoggers : public base::utils::Registry<Logger, std::string> {
3604 public:
3605  explicit RegisteredLoggers(const LogBuilderPtr& defaultLogBuilder) :
3606  m_defaultLogBuilder(defaultLogBuilder) {
3607  m_defaultConfigurations.setToDefault();
3608  }
3609 
3610  virtual ~RegisteredLoggers(void) {
3611  flushAll();
3612  }
3613 
3614  inline void setDefaultConfigurations(const Configurations& configurations) {
3615  base::threading::ScopedLock scopedLock(lock());
3616  m_defaultConfigurations.setFromBase(const_cast<Configurations*>(&configurations));
3617  }
3618 
3620  return &m_defaultConfigurations;
3621  }
3622 
3623  Logger* get(const std::string& id, bool forceCreation = true) {
3624  base::threading::ScopedLock scopedLock(lock());
3626  if (logger_ == nullptr && forceCreation) {
3627  bool validId = Logger::isValidId(id);
3628  if (!validId) {
3629  ELPP_ASSERT(validId, "Invalid logger ID [" << id << "]. Not registering this logger.");
3630  return nullptr;
3631  }
3632  logger_ = new Logger(id, m_defaultConfigurations, &m_logStreamsReference);
3633  logger_->m_logBuilder = m_defaultLogBuilder;
3634  registerNew(id, logger_);
3635  }
3636  return logger_;
3637  }
3638 
3639  bool remove(const std::string& id) {
3640  if (id == "default") {
3641  return false;
3642  }
3644  if (logger != nullptr) {
3645  unregister(logger);
3646  }
3647  return true;
3648  }
3649 
3650  inline bool has(const std::string& id) {
3651  return get(id, false) != nullptr;
3652  }
3653 
3654  inline void unregister(Logger*& logger) {
3655  base::threading::ScopedLock scopedLock(lock());
3657  }
3658 
3660  return &m_logStreamsReference;
3661  }
3662 
3663  inline void flushAll(void) {
3664  ELPP_INTERNAL_INFO(1, "Flushing all log files");
3665  base::threading::ScopedLock scopedLock(lock());
3666  for (base::LogStreamsReferenceMap::iterator it = m_logStreamsReference.begin();
3667  it != m_logStreamsReference.end(); ++it) {
3668  if (it->second.get() == nullptr) continue;
3669  it->second->flush();
3670  }
3671  }
3672 
3673 private:
3674  LogBuilderPtr m_defaultLogBuilder;
3675  Configurations m_defaultConfigurations;
3676  base::LogStreamsReferenceMap m_logStreamsReference;
3677  friend class el::base::Storage;
3678 };
3681 public:
3682  explicit VRegistry(base::type::VerboseLevel level, base::type::EnumType* pFlags) : m_level(level), m_pFlags(pFlags) {
3683  }
3684 
3686  inline void setLevel(base::type::VerboseLevel level) {
3687  base::threading::ScopedLock scopedLock(lock());
3688  if (level < 0)
3689  m_level = 0;
3690  else if (level > 9)
3691  m_level = base::consts::kMaxVerboseLevel;
3692  else
3693  m_level = level;
3694  }
3695 
3696  inline base::type::VerboseLevel level(void) const {
3697  return m_level;
3698  }
3699 
3700  inline void clearModules(void) {
3701  base::threading::ScopedLock scopedLock(lock());
3702  m_modules.clear();
3703  }
3704 
3705  void setModules(const char* modules) {
3706  base::threading::ScopedLock scopedLock(lock());
3707  auto addSuffix = [](std::stringstream& ss, const char* sfx, const char* prev) {
3708  if (prev != nullptr && base::utils::Str::endsWith(ss.str(), std::string(prev))) {
3709  std::string chr(ss.str().substr(0, ss.str().size() - strlen(prev)));
3710  ss.str(std::string(""));
3711  ss << chr;
3712  }
3713  if (base::utils::Str::endsWith(ss.str(), std::string(sfx))) {
3714  std::string chr(ss.str().substr(0, ss.str().size() - strlen(sfx)));
3715  ss.str(std::string(""));
3716  ss << chr;
3717  }
3718  ss << sfx;
3719  };
3720  auto insert = [&](std::stringstream& ss, base::type::VerboseLevel level) {
3721  if (!base::utils::hasFlag(LoggingFlag::DisableVModulesExtensions, *m_pFlags)) {
3722  addSuffix(ss, ".h", nullptr);
3723  m_modules.insert(std::make_pair(ss.str(), level));
3724  addSuffix(ss, ".c", ".h");
3725  m_modules.insert(std::make_pair(ss.str(), level));
3726  addSuffix(ss, ".cpp", ".c");
3727  m_modules.insert(std::make_pair(ss.str(), level));
3728  addSuffix(ss, ".cc", ".cpp");
3729  m_modules.insert(std::make_pair(ss.str(), level));
3730  addSuffix(ss, ".cxx", ".cc");
3731  m_modules.insert(std::make_pair(ss.str(), level));
3732  addSuffix(ss, ".-inl.h", ".cxx");
3733  m_modules.insert(std::make_pair(ss.str(), level));
3734  addSuffix(ss, ".hxx", ".-inl.h");
3735  m_modules.insert(std::make_pair(ss.str(), level));
3736  addSuffix(ss, ".hpp", ".hxx");
3737  m_modules.insert(std::make_pair(ss.str(), level));
3738  addSuffix(ss, ".hh", ".hpp");
3739  }
3740  m_modules.insert(std::make_pair(ss.str(), level));
3741  };
3742  bool isMod = true;
3743  bool isLevel = false;
3744  std::stringstream ss;
3745  int level = -1;
3746  for (; *modules; ++modules) {
3747  switch (*modules) {
3748  case '=':
3749  isLevel = true;
3750  isMod = false;
3751  break;
3752  case ',':
3753  isLevel = false;
3754  isMod = true;
3755  if (!ss.str().empty() && level != -1) {
3756  insert(ss, level);
3757  ss.str(std::string(""));
3758  level = -1;
3759  }
3760  break;
3761  default:
3762  if (isMod) {
3763  ss << *modules;
3764  } else if (isLevel) {
3765  if (isdigit(*modules)) {
3766  level = static_cast<base::type::VerboseLevel>(*modules) - 48;
3767  }
3768  }
3769  break;
3770  }
3771  }
3772  if (!ss.str().empty() && level != -1) {
3773  insert(ss, level);
3774  }
3775  }
3776 
3777  bool allowed(base::type::VerboseLevel vlevel, const char* file) {
3778  base::threading::ScopedLock scopedLock(lock());
3779  if (m_modules.empty() || file == nullptr) {
3780  return vlevel <= m_level;
3781  } else {
3782  std::map<std::string, base::type::VerboseLevel>::iterator it = m_modules.begin();
3783  for (; it != m_modules.end(); ++it) {
3784  if (base::utils::Str::wildCardMatch(file, it->first.c_str())) {
3785  return vlevel <= it->second;
3786  }
3787  }
3788  if (base::utils::hasFlag(LoggingFlag::AllowVerboseIfModuleNotSpecified, *m_pFlags)) {
3789  return true;
3790  }
3791  return false;
3792  }
3793  }
3794 
3795  inline const std::map<std::string, base::type::VerboseLevel>& modules(void) const {
3796  return m_modules;
3797  }
3798 
3799  void setFromArgs(const base::utils::CommandLineArgs* commandLineArgs) {
3800  if (commandLineArgs->hasParam("-v") || commandLineArgs->hasParam("--verbose") ||
3801  commandLineArgs->hasParam("-V") || commandLineArgs->hasParam("--VERBOSE")) {
3802  setLevel(base::consts::kMaxVerboseLevel);
3803  } else if (commandLineArgs->hasParamWithValue("--v")) {
3804  setLevel(atoi(commandLineArgs->getParamValue("--v")));
3805  } else if (commandLineArgs->hasParamWithValue("--V")) {
3806  setLevel(atoi(commandLineArgs->getParamValue("--V")));
3807  } else if ((commandLineArgs->hasParamWithValue("-vmodule")) && vModulesEnabled()) {
3808  setModules(commandLineArgs->getParamValue("-vmodule"));
3809  } else if (commandLineArgs->hasParamWithValue("-VMODULE") && vModulesEnabled()) {
3810  setModules(commandLineArgs->getParamValue("-VMODULE"));
3811  }
3812  }
3813 
3815  inline bool vModulesEnabled(void) {
3816  return !base::utils::hasFlag(LoggingFlag::DisableVModules, *m_pFlags);
3817  }
3818 
3819 private:
3820  base::type::VerboseLevel m_level;
3821  base::type::EnumType* m_pFlags;
3822  std::map<std::string, base::type::VerboseLevel> m_modules;
3823 };
3824 } // namespace base
3825 class LogMessage {
3826 public:
3827  LogMessage(Level level, const std::string& file, unsigned long int line, const std::string& func,
3829  m_level(level), m_file(file), m_line(line), m_func(func),
3830  m_verboseLevel(verboseLevel), m_logger(logger), m_message(std::move(logger->stream().str())) {
3831  }
3832  inline Level level(void) const { return m_level; }
3833  inline const std::string& file(void) const { return m_file; }
3834  inline unsigned long int line(void) const { return m_line; } // NOLINT
3835  inline const std::string& func(void) const { return m_func; }
3836  inline base::type::VerboseLevel verboseLevel(void) const { return m_verboseLevel; }
3837  inline Logger* logger(void) const { return m_logger; }
3838  inline const base::type::string_t& message(void) const { return m_message; }
3839 private:
3840  Level m_level;
3841  std::string m_file;
3842  unsigned long int m_line;
3843  std::string m_func;
3844  base::type::VerboseLevel m_verboseLevel;
3845  Logger* m_logger;
3846  base::type::string_t m_message;
3847 };
3848 namespace base {
3849 #if ELPP_ASYNC_LOGGING
3850 class AsyncLogItem {
3851 public:
3852  explicit AsyncLogItem(const LogMessage& logMessage, const LogDispatchData& data, const base::type::string_t& logLine)
3853  : m_logMessage(logMessage), m_dispatchData(data), m_logLine(logLine) {}
3854  virtual ~AsyncLogItem() {}
3855  inline LogMessage* logMessage(void) { return &m_logMessage; }
3856  inline LogDispatchData* data(void) { return &m_dispatchData; }
3857  inline base::type::string_t logLine(void) { return m_logLine; }
3858 private:
3859  LogMessage m_logMessage;
3860  LogDispatchData m_dispatchData;
3861  base::type::string_t m_logLine;
3862 };
3863 class AsyncLogQueue : public base::threading::ThreadSafe {
3864 public:
3865  virtual ~AsyncLogQueue() {
3866  ELPP_INTERNAL_INFO(6, "~AsyncLogQueue");
3867  }
3868 
3869  inline AsyncLogItem next(void) {
3870  base::threading::ScopedLock scopedLock(lock());
3871  AsyncLogItem result = m_queue.front();
3872  m_queue.pop();
3873  return result;
3874  }
3875 
3876  inline void push(const AsyncLogItem& item) {
3877  base::threading::ScopedLock scopedLock(lock());
3878  m_queue.push(item);
3879  }
3880  inline void pop(void) {
3881  base::threading::ScopedLock scopedLock(lock());
3882  m_queue.pop();
3883  }
3884  inline AsyncLogItem front(void) {
3885  base::threading::ScopedLock scopedLock(lock());
3886  return m_queue.front();
3887  }
3888  inline bool empty(void) {
3889  base::threading::ScopedLock scopedLock(lock());
3890  return m_queue.empty();
3891  }
3892 private:
3893  std::queue<AsyncLogItem> m_queue;
3894 };
3895 class IWorker {
3896 public:
3897  virtual ~IWorker() {}
3898  virtual void start() = 0;
3899 };
3900 #endif // ELPP_ASYNC_LOGGING
3901 class Storage : base::NoCopy, public base::threading::ThreadSafe {
3903 public:
3904 #if ELPP_ASYNC_LOGGING
3905  Storage(const LogBuilderPtr& defaultLogBuilder, base::IWorker* asyncDispatchWorker) :
3906 #else
3907  explicit Storage(const LogBuilderPtr& defaultLogBuilder) :
3908 #endif // ELPP_ASYNC_LOGGING
3909  m_registeredHitCounters(new base::RegisteredHitCounters()),
3910  m_registeredLoggers(new base::RegisteredLoggers(defaultLogBuilder)),
3911  m_flags(0x0),
3912  m_vRegistry(new base::VRegistry(0, &m_flags)),
3914  m_asyncLogQueue(new base::AsyncLogQueue()),
3915  m_asyncDispatchWorker(asyncDispatchWorker),
3916 #endif // ELPP_ASYNC_LOGGING
3917  m_preRollOutCallback(base::defaultPreRollOutCallback) {
3918  // Register default logger
3919  m_registeredLoggers->get(std::string(base::consts::kDefaultLoggerId));
3920  // Register performance logger and reconfigure format
3921  Logger* performanceLogger = m_registeredLoggers->get(std::string(base::consts::kPerformanceLoggerId));
3922  performanceLogger->configurations()->setGlobally(ConfigurationType::Format, std::string("%datetime %level %msg"));
3923  performanceLogger->reconfigure();
3924 #if defined(ELPP_SYSLOG)
3925  // Register syslog logger and reconfigure format
3926  Logger* sysLogLogger = m_registeredLoggers->get(std::string(base::consts::kSysLogLoggerId));
3927  sysLogLogger->configurations()->setGlobally(ConfigurationType::Format, std::string("%level: %msg"));
3928  sysLogLogger->reconfigure();
3929 #else
3930  ELPP_UNUSED(base::consts::kSysLogLoggerId);
3931 #endif // defined(ELPP_SYSLOG)
3933 #if ELPP_ASYNC_LOGGING
3934  installLogDispatchCallback<base::AsyncLogDispatchCallback>(std::string("AsyncLogDispatchCallback"));
3935 #else
3936  installLogDispatchCallback<base::DefaultLogDispatchCallback>(std::string("DefaultLogDispatchCallback"));
3937 #endif // ELPP_ASYNC_LOGGING
3938  installPerformanceTrackingCallback<base::DefaultPerformanceTrackingCallback>(std::string("DefaultPerformanceTrackingCallback"));
3939  ELPP_INTERNAL_INFO(1, "Easylogging++ has been initialized");
3940 #if ELPP_ASYNC_LOGGING
3941  m_asyncDispatchWorker->start();
3942 #endif // ELPP_ASYNC_LOGGING
3943  }
3944 
3945  virtual ~Storage(void) {
3946  ELPP_INTERNAL_INFO(4, "Destroying storage");
3947 #if ELPP_ASYNC_LOGGING
3948  ELPP_INTERNAL_INFO(5, "Replacing log dispatch callback to synchronous");
3949  uninstallLogDispatchCallback<base::AsyncLogDispatchCallback>(std::string("AsyncLogDispatchCallback"));
3950  installLogDispatchCallback<base::DefaultLogDispatchCallback>(std::string("DefaultLogDispatchCallback"));
3951  ELPP_INTERNAL_INFO(5, "Destroying asyncDispatchWorker");
3952  base::utils::safeDelete(m_asyncDispatchWorker);
3953  ELPP_INTERNAL_INFO(5, "Destroying asyncLogQueue");
3954  base::utils::safeDelete(m_asyncLogQueue);
3955 #endif // ELPP_ASYNC_LOGGING
3956  ELPP_INTERNAL_INFO(5, "Destroying registeredHitCounters");
3957  base::utils::safeDelete(m_registeredHitCounters);
3958  ELPP_INTERNAL_INFO(5, "Destroying registeredLoggers");
3959  base::utils::safeDelete(m_registeredLoggers);
3960  ELPP_INTERNAL_INFO(5, "Destroying vRegistry");
3961  base::utils::safeDelete(m_vRegistry);
3962  }
3963 
3964  inline bool validateEveryNCounter(const char* filename, unsigned long int lineNumber, std::size_t occasion) {
3965  return hitCounters()->validateEveryN(filename, lineNumber, occasion);
3966  }
3967 
3968  inline bool validateAfterNCounter(const char* filename, unsigned long int lineNumber, std::size_t n) { // NOLINT
3969  return hitCounters()->validateAfterN(filename, lineNumber, n);
3970  }
3971 
3972  inline bool validateNTimesCounter(const char* filename, unsigned long int lineNumber, std::size_t n) { // NOLINT
3973  return hitCounters()->validateNTimes(filename, lineNumber, n);
3974  }
3975 
3977  return m_registeredHitCounters;
3978  }
3979 
3981  return m_registeredLoggers;
3982  }
3983 
3984  inline base::VRegistry* vRegistry(void) const {
3985  return m_vRegistry;
3986  }
3987 
3988 #if ELPP_ASYNC_LOGGING
3989  inline base::AsyncLogQueue* asyncLogQueue(void) const {
3990  return m_asyncLogQueue;
3991  }
3992 #endif // ELPP_ASYNC_LOGGING
3993 
3994  inline const base::utils::CommandLineArgs* commandLineArgs(void) const {
3995  return &m_commandLineArgs;
3996  }
3997 
3998  inline void addFlag(LoggingFlag flag) {
3999  base::utils::addFlag(flag, &m_flags);
4000  }
4001 
4002  inline void removeFlag(LoggingFlag flag) {
4003  base::utils::removeFlag(flag, &m_flags);
4004  }
4005 
4006  inline bool hasFlag(LoggingFlag flag) const {
4007  return base::utils::hasFlag(flag, m_flags);
4008  }
4009 
4010  inline base::type::EnumType flags(void) const {
4011  return m_flags;
4012  }
4013 
4015  m_flags = flags;
4016  }
4017 
4018  inline void setPreRollOutCallback(const PreRollOutCallback& callback) {
4019  m_preRollOutCallback = callback;
4020  }
4021 
4022  inline void unsetPreRollOutCallback(void) {
4023  m_preRollOutCallback = base::defaultPreRollOutCallback;
4024  }
4025 
4026  inline PreRollOutCallback& preRollOutCallback(void) {
4027  return m_preRollOutCallback;
4028  }
4029 
4030  inline bool hasCustomFormatSpecifier(const char* formatSpecifier) {
4031  base::threading::ScopedLock scopedLock(lock());
4032  return std::find(m_customFormatSpecifiers.begin(), m_customFormatSpecifiers.end(),
4033  formatSpecifier) != m_customFormatSpecifiers.end();
4034  }
4035 
4036  inline void installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier) {
4037  if (hasCustomFormatSpecifier(customFormatSpecifier.formatSpecifier())) {
4038  return;
4039  }
4040  base::threading::ScopedLock scopedLock(lock());
4041  m_customFormatSpecifiers.push_back(customFormatSpecifier);
4042  }
4043 
4044  inline bool uninstallCustomFormatSpecifier(const char* formatSpecifier) {
4045  base::threading::ScopedLock scopedLock(lock());
4046  std::vector<CustomFormatSpecifier>::iterator it = std::find(m_customFormatSpecifiers.begin(),
4047  m_customFormatSpecifiers.end(), formatSpecifier);
4048  if (it != m_customFormatSpecifiers.end() && strcmp(formatSpecifier, it->formatSpecifier()) == 0) {
4049  m_customFormatSpecifiers.erase(it);
4050  return true;
4051  }
4052  return false;
4053  }
4054 
4055  const std::vector<CustomFormatSpecifier>* customFormatSpecifiers(void) const {
4056  return &m_customFormatSpecifiers;
4057  }
4058 
4059  inline void setLoggingLevel(Level level) {
4060  m_loggingLevel = level;
4061  }
4062 
4063  template <typename T>
4064  inline bool installLogDispatchCallback(const std::string& id) {
4065  return installCallback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks);
4066  }
4067 
4068  template <typename T>
4069  inline void uninstallLogDispatchCallback(const std::string& id) {
4070  uninstallCallback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks);
4071  }
4072  template <typename T>
4073  inline T* logDispatchCallback(const std::string& id) {
4074  return callback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks);
4075  }
4076 
4077  template <typename T>
4078  inline bool installPerformanceTrackingCallback(const std::string& id) {
4079  return installCallback<T, base::type::PerformanceTrackingCallbackPtr>(id, &m_performanceTrackingCallbacks);
4080  }
4081 
4082  template <typename T>
4083  inline void uninstallPerformanceTrackingCallback(const std::string& id) {
4084  uninstallCallback<T, base::type::PerformanceTrackingCallbackPtr>(id, &m_performanceTrackingCallbacks);
4085  }
4086 
4087  template <typename T>
4088  inline T* performanceTrackingCallback(const std::string& id) {
4089  return callback<T, base::type::PerformanceTrackingCallbackPtr>(id, &m_performanceTrackingCallbacks);
4090  }
4091 private:
4092  base::RegisteredHitCounters* m_registeredHitCounters;
4093  base::RegisteredLoggers* m_registeredLoggers;
4094  base::type::EnumType m_flags;
4095  base::VRegistry* m_vRegistry;
4096 #if ELPP_ASYNC_LOGGING
4097  base::AsyncLogQueue* m_asyncLogQueue;
4098  base::IWorker* m_asyncDispatchWorker;
4099 #endif // ELPP_ASYNC_LOGGING
4100  base::utils::CommandLineArgs m_commandLineArgs;
4101  PreRollOutCallback m_preRollOutCallback;
4102  std::map<std::string, base::type::LogDispatchCallbackPtr> m_logDispatchCallbacks;
4103  std::map<std::string, base::type::PerformanceTrackingCallbackPtr> m_performanceTrackingCallbacks;
4104  std::vector<CustomFormatSpecifier> m_customFormatSpecifiers;
4105  Level m_loggingLevel;
4106 
4107  friend class el::Helpers;
4109  friend class el::LogBuilder;
4111  friend class el::base::Writer;
4114 
4115  void setApplicationArguments(int argc, char** argv) {
4116  m_commandLineArgs.setArgs(argc, argv);
4117  m_vRegistry->setFromArgs(commandLineArgs());
4118  // default log file
4119 #if !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG)
4120  if (m_commandLineArgs.hasParamWithValue(base::consts::kDefaultLogFileParam)) {
4121  Configurations c;
4122  c.setGlobally(ConfigurationType::Filename, std::string(m_commandLineArgs.getParamValue(base::consts::kDefaultLogFileParam)));
4125  it != registeredLoggers()->end(); ++it) {
4126  it->second->configure(c);
4127  }
4128  }
4129 #endif // !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG)
4130 #if defined(ELPP_LOGGING_FLAGS_FROM_ARG)
4131  if (m_commandLineArgs.hasParamWithValue(base::consts::kLoggingFlagsParam)) {
4132  m_flags = atoi(m_commandLineArgs.getParamValue(base::consts::kLoggingFlagsParam));
4133  }
4134 #endif // defined(ELPP_LOGGING_FLAGS_FROM_ARG)
4135  }
4136 
4137  inline void setApplicationArguments(int argc, const char** argv) {
4138  setApplicationArguments(argc, const_cast<char**>(argv));
4139  }
4140 
4141  template <typename T, typename TPtr>
4142  inline bool installCallback(const std::string& id, std::map<std::string, TPtr>* mapT) {
4143  if (mapT->find(id) == mapT->end()) {
4144  mapT->insert(std::make_pair(id, TPtr(new T())));
4145  return true;
4146  }
4147  return false;
4148  }
4149 
4150  template <typename T, typename TPtr>
4151  inline void uninstallCallback(const std::string& id, std::map<std::string, TPtr>* mapT) {
4152  if (mapT->find(id) != mapT->end()) {
4153  mapT->erase(id);
4154  }
4155  }
4156 
4157  template <typename T, typename TPtr>
4158  inline T* callback(const std::string& id, std::map<std::string, TPtr>* mapT) {
4159  typename std::map<std::string, TPtr>::iterator iter = mapT->find(id);
4160  if (iter != mapT->end()) {
4161  return static_cast<T*>(iter->second.get());
4162  }
4163  return nullptr;
4164  }
4165 };
4167 #define ELPP el::base::elStorage
4169 protected:
4170  void handle(const LogDispatchData* data) {
4171  m_data = data;
4172  dispatch(std::move(m_data->logMessage()->logger()->logBuilder()->build(m_data->logMessage(),
4174  }
4175 private:
4176  const LogDispatchData* m_data;
4177  void dispatch(base::type::string_t&& logLine) {
4179  if (m_data->logMessage()->logger()->m_typedConfigurations->toFile(m_data->logMessage()->level())) {
4180  base::type::fstream_t* fs = m_data->logMessage()->logger()->m_typedConfigurations->fileStream(m_data->logMessage()->level());
4181  if (fs != nullptr) {
4182  fs->write(logLine.c_str(), logLine.size());
4183  if (fs->fail()) {
4184  ELPP_INTERNAL_ERROR("Unable to write log to file ["
4185  << m_data->logMessage()->logger()->m_typedConfigurations->filename(m_data->logMessage()->level()) << "].\n"
4186  << "Few possible reasons (could be something else):\n" << " * Permission denied\n"
4187  << " * Disk full\n" << " * Disk is not writable", true);
4188  } else {
4189  if (ELPP->hasFlag(LoggingFlag::ImmediateFlush) || (m_data->logMessage()->logger()->isFlushNeeded(m_data->logMessage()->level()))) {
4190  m_data->logMessage()->logger()->flush(m_data->logMessage()->level(), fs);
4191  }
4192  }
4193  } else {
4194  ELPP_INTERNAL_ERROR("Log file for [" << LevelHelper::convertToString(m_data->logMessage()->level()) << "] "
4195  << "has not been configured but [TO_FILE] is configured to TRUE. [Logger ID: "
4196  << m_data->logMessage()->logger()->id() << "]", false);
4197  }
4198  }
4199  if (m_data->logMessage()->logger()->m_typedConfigurations->toStandardOutput(m_data->logMessage()->level())) {
4201  m_data->logMessage()->logger()->logBuilder()->convertToColoredOutput(&logLine, m_data->logMessage()->level());
4202  ELPP_COUT << ELPP_COUT_LINE(logLine);
4203  }
4204  }
4205 #if defined(ELPP_SYSLOG)
4206  else if (m_data->dispatchAction() == base::DispatchAction::SysLog) {
4207  // Determine syslog priority
4208  int sysLogPriority = 0;
4209  if (m_data->logMessage()->level() == Level::Fatal)
4210  sysLogPriority = LOG_EMERG;
4211  else if (m_data->logMessage()->level() == Level::Error)
4212  sysLogPriority = LOG_ERR;
4213  else if (m_data->logMessage()->level() == Level::Warning)
4214  sysLogPriority = LOG_WARNING;
4215  else if (m_data->logMessage()->level() == Level::Info)
4216  sysLogPriority = LOG_INFO;
4217  else if (m_data->logMessage()->level() == Level::Debug)
4218  sysLogPriority = LOG_DEBUG;
4219  else
4220  sysLogPriority = LOG_NOTICE;
4221 # if defined(ELPP_UNICODE)
4222  char* line = base::utils::Str::wcharPtrToCharPtr(logLine.c_str());
4223  syslog(sysLogPriority, "%s", line);
4224  free(line);
4225 # else
4226  syslog(sysLogPriority, "%s", logLine.c_str());
4227 # endif
4228  }
4229 #endif // defined(ELPP_SYSLOG)
4230  }
4231 };
4232 #if ELPP_ASYNC_LOGGING
4233 class AsyncLogDispatchCallback : public LogDispatchCallback {
4234 protected:
4235  void handle(const LogDispatchData* data) {
4236  base::type::string_t logLine = data->logMessage()->logger()->logBuilder()->build(data->logMessage(), data->dispatchAction() == base::DispatchAction::NormalLog);
4237  if (data->dispatchAction() == base::DispatchAction::NormalLog && data->logMessage()->logger()->typedConfigurations()->toStandardOutput(data->logMessage()->level())) {
4239  data->logMessage()->logger()->logBuilder()->convertToColoredOutput(&logLine, data->logMessage()->level());
4240  ELPP_COUT << ELPP_COUT_LINE(logLine);
4241  }
4242  // Save resources and only queue if we want to write to file otherwise just ignore handler
4243  if (data->logMessage()->logger()->typedConfigurations()->toFile(data->logMessage()->level())) {
4244  ELPP->asyncLogQueue()->push(AsyncLogItem(*(data->logMessage()), *data, logLine));
4245  }
4246  }
4247 };
4248 class AsyncDispatchWorker : public base::IWorker, public base::threading::ThreadSafe {
4249 public:
4250  AsyncDispatchWorker() {
4251  setContinueRunning(false);
4252  }
4253 
4254  virtual ~AsyncDispatchWorker() {
4255  setContinueRunning(false);
4256  ELPP_INTERNAL_INFO(6, "Stopping dispatch worker - Cleaning log queue");
4257  clean();
4258  ELPP_INTERNAL_INFO(6, "Log queue cleaned");
4259  }
4260 
4261  inline bool clean() {
4262  std::mutex m;
4263  std::unique_lock<std::mutex> lk(m);
4264  cv.wait(lk, []{ return !ELPP->asyncLogQueue()->empty(); });
4265  emptyQueue();
4266  lk.unlock();
4267  cv.notify_one();
4268  return ELPP->asyncLogQueue()->empty();
4269  }
4270 
4271  inline void emptyQueue() {
4272  while (!ELPP->asyncLogQueue()->empty()) {
4273  AsyncLogItem data = ELPP->asyncLogQueue()->next();
4274  handle(&data);
4275  base::threading::msleep(100);
4276  }
4277  }
4278 
4279  virtual inline void start() {
4280  base::threading::msleep(5000); // Wait extra few seconds
4281  setContinueRunning(true);
4282  std::thread t1(&AsyncDispatchWorker::runner, this);
4283  t1.join();
4284  }
4285 
4286  void handle(AsyncLogItem* logItem) {
4287  LogDispatchData* data = logItem->data();
4288  LogMessage* logMessage = logItem->logMessage();
4289  Logger* logger = logMessage->logger();
4290  base::TypedConfigurations* conf = logger->typedConfigurations();
4291  base::type::string_t logLine = logItem->logLine();
4292  if (data->dispatchAction() == base::DispatchAction::NormalLog) {
4293  if (conf->toFile(logMessage->level())) {
4294  base::type::fstream_t* fs = conf->fileStream(logMessage->level());
4295  if (fs != nullptr) {
4296  fs->write(logLine.c_str(), logLine.size());
4297  if (fs->fail()) {
4298  ELPP_INTERNAL_ERROR("Unable to write log to file ["
4299  << conf->filename(logMessage->level()) << "].\n"
4300  << "Few possible reasons (could be something else):\n" << " * Permission denied\n"
4301  << " * Disk full\n" << " * Disk is not writable", true);
4302  } else {
4303  if (ELPP->hasFlag(LoggingFlag::ImmediateFlush) || (logger->isFlushNeeded(logMessage->level()))) {
4304  logger->flush(logMessage->level(), fs);
4305  }
4306  }
4307  } else {
4308  ELPP_INTERNAL_ERROR("Log file for [" << LevelHelper::convertToString(logMessage->level()) << "] "
4309  << "has not been configured but [TO_FILE] is configured to TRUE. [Logger ID: " << logger->id() << "]", false);
4310  }
4311  }
4312  }
4313 # if defined(ELPP_SYSLOG)
4314  else if (data->dispatchAction() == base::DispatchAction::SysLog) {
4315  // Determine syslog priority
4316  int sysLogPriority = 0;
4317  if (logMessage->level() == Level::Fatal)
4318  sysLogPriority = LOG_EMERG;
4319  else if (logMessage->level() == Level::Error)
4320  sysLogPriority = LOG_ERR;
4321  else if (logMessage->level() == Level::Warning)
4322  sysLogPriority = LOG_WARNING;
4323  else if (logMessage->level() == Level::Info)
4324  sysLogPriority = LOG_INFO;
4325  else if (logMessage->level() == Level::Debug)
4326  sysLogPriority = LOG_DEBUG;
4327  else
4328  sysLogPriority = LOG_NOTICE;
4329 # if defined(ELPP_UNICODE)
4330  char* line = base::utils::Str::wcharPtrToCharPtr(logLine.c_str());
4331  syslog(sysLogPriority, "%s", line);
4332  free(line);
4333 # else
4334  syslog(sysLogPriority, "%s", logLine.c_str());
4335 # endif
4336  }
4337 # endif // defined(ELPP_SYSLOG)
4338  }
4339 
4340  void run() {
4341  while (continueRunning()) {
4342  emptyQueue();
4343  base::threading::msleep(10); // 10ms
4344  }
4345  }
4346 
4347  static void* runner(void *context) {
4348  static_cast<AsyncDispatchWorker*>(context)->run();
4349  return NULL;
4350  }
4351 
4352  void setContinueRunning(bool value) {
4353  base::threading::ScopedLock scopedLock(m_continueRunningMutex);
4354  m_continueRunning = value;
4355  }
4356  bool continueRunning(void) {
4357  return m_continueRunning;
4358  }
4359 private:
4360  std::condition_variable cv;
4361  bool m_continueRunning;
4362  base::threading::Mutex m_continueRunningMutex;
4363 };
4364 #endif // ELPP_ASYNC_LOGGING
4365 } // namespace base
4366 namespace base {
4368 public:
4369  base::type::string_t build(const LogMessage* logMessage, bool appendNewLine) const {
4370  base::TypedConfigurations* tc = logMessage->logger()->typedConfigurations();
4371  const base::LogFormat* logFormat = &tc->logFormat(logMessage->level());
4372  base::type::string_t logLine = logFormat->format();
4373  char buff[base::consts::kSourceFilenameMaxLength + base::consts::kSourceLineMaxLength] = "";
4374  const char* bufLim = buff + sizeof(buff);
4375  if (logFormat->hasFlag(base::FormatFlags::AppName)) {
4376  // App name
4377  base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kAppNameFormatSpecifier,
4378  logMessage->logger()->parentApplicationName());
4379  }
4380  if (logFormat->hasFlag(base::FormatFlags::ThreadId)) {
4381  // Thread ID
4382  base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kThreadIdFormatSpecifier,
4383  base::threading::getCurrentThreadId());
4384  }
4385  if (logFormat->hasFlag(base::FormatFlags::DateTime)) {
4386  // DateTime
4387  base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kDateTimeFormatSpecifier,
4388  base::utils::DateTime::getDateTime(logFormat->dateTimeFormat().c_str(),
4389  &tc->millisecondsWidth(logMessage->level())));
4390  }
4391  if (logFormat->hasFlag(base::FormatFlags::Function)) {
4392  // Function
4393  base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogFunctionFormatSpecifier, logMessage->func());
4394  }
4395  if (logFormat->hasFlag(base::FormatFlags::File)) {
4396  // File
4397  char* buf = base::utils::Str::clearBuff(buff, base::consts::kSourceFilenameMaxLength);
4398  base::utils::File::buildStrippedFilename(logMessage->file().c_str(), buff);
4399  buf = base::utils::Str::addToBuff(buff, buf, bufLim);
4400  base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogFileFormatSpecifier, std::string(buff));
4401  }
4402  if (logFormat->hasFlag(base::FormatFlags::FileBase)) {
4403  // FileBase
4404  char* buf = base::utils::Str::clearBuff(buff, base::consts::kSourceFilenameMaxLength);
4405  base::utils::File::buildBaseFilename(logMessage->file(), buff);
4406  buf = base::utils::Str::addToBuff(buff, buf, bufLim);
4407  base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogFileBaseFormatSpecifier, std::string(buff));
4408  }
4409  if (logFormat->hasFlag(base::FormatFlags::Line)) {
4410  // Line
4411  char* buf = base::utils::Str::clearBuff(buff, base::consts::kSourceLineMaxLength);
4412  buf = base::utils::Str::convertAndAddToBuff(logMessage->line(),
4413  base::consts::kSourceLineMaxLength, buf, bufLim, false);
4414  base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogLineFormatSpecifier, std::string(buff));
4415  }
4416  if (logFormat->hasFlag(base::FormatFlags::Location)) {
4417  // Location
4418  char* buf = base::utils::Str::clearBuff(buff,
4419  base::consts::kSourceFilenameMaxLength + base::consts::kSourceLineMaxLength);
4420  base::utils::File::buildStrippedFilename(logMessage->file().c_str(), buff);
4421  buf = base::utils::Str::addToBuff(buff, buf, bufLim);
4422  buf = base::utils::Str::addToBuff(":", buf, bufLim);
4423  buf = base::utils::Str::convertAndAddToBuff(logMessage->line(),
4424  base::consts::kSourceLineMaxLength, buf, bufLim, false);
4425  base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogLocationFormatSpecifier, std::string(buff));
4426  }
4427  if (logMessage->level() == Level::Verbose && logFormat->hasFlag(base::FormatFlags::VerboseLevel)) {
4428  // Verbose level
4429  char* buf = base::utils::Str::clearBuff(buff, 1);
4430  buf = base::utils::Str::convertAndAddToBuff(logMessage->verboseLevel(), 1, buf, bufLim, false);
4431  base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kVerboseLevelFormatSpecifier, std::string(buff));
4432  }
4433  if (logFormat->hasFlag(base::FormatFlags::LogMessage)) {
4434  // Log message
4435  base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kMessageFormatSpecifier, logMessage->message());
4436  }
4437 #if !defined(ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS)
4438  for (std::vector<CustomFormatSpecifier>::const_iterator it = ELPP->customFormatSpecifiers()->begin();
4439  it != ELPP->customFormatSpecifiers()->end(); ++it) {
4440  std::string fs(it->formatSpecifier());
4441  base::type::string_t wcsFormatSpecifier(fs.begin(), fs.end());
4442  base::utils::Str::replaceFirstWithEscape(logLine, wcsFormatSpecifier, std::string(it->resolver()()));
4443  }
4444 #endif // !defined(ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS)
4445  if (appendNewLine) logLine += ELPP_LITERAL("\n");
4446  return logLine;
4447  }
4448 };
4451 public:
4452  LogDispatcher(bool proceed, LogMessage&& logMessage, base::DispatchAction dispatchAction) :
4453  m_proceed(proceed),
4454  m_logMessage(std::move(logMessage)),
4455  m_dispatchAction(std::move(dispatchAction)) {
4456  }
4457 
4458  void dispatch(void) {
4459  if (m_proceed && m_dispatchAction == base::DispatchAction::None) {
4460  m_proceed = false;
4461  }
4462  if (!m_proceed) {
4463  return;
4464  }
4465  // We minimize the time of ELPP's lock - this lock is released after log is written
4466  base::threading::ScopedLock scopedLock(ELPP->lock());
4467  base::TypedConfigurations* tc = m_logMessage.logger()->m_typedConfigurations;
4468  if (ELPP->hasFlag(LoggingFlag::StrictLogFileSizeCheck)) {
4469  tc->validateFileRolling(m_logMessage.level(), ELPP->preRollOutCallback());
4470  }
4471  LogDispatchCallback* callback = nullptr;
4472  LogDispatchData data;
4473  for (const std::pair<std::string, base::type::LogDispatchCallbackPtr>& h
4474  : ELPP->m_logDispatchCallbacks) {
4475  callback = h.second.get();
4476  if (callback != nullptr && callback->enabled()) {
4477  data.setLogMessage(&m_logMessage);
4478  data.setDispatchAction(m_dispatchAction);
4479  callback->acquireLock();
4480  callback->handle(&data);
4481  callback->releaseLock();
4482  }
4483  }
4484  }
4485 
4486 private:
4487  bool m_proceed;
4488  LogMessage m_logMessage;
4489  base::DispatchAction m_dispatchAction;
4490 };
4491 #if defined(ELPP_STL_LOGGING)
4492 namespace workarounds {
4500 template <typename T, typename Container>
4501 class IterableContainer {
4502 public:
4503  typedef typename Container::iterator iterator;
4504  typedef typename Container::const_iterator const_iterator;
4505  IterableContainer(void) {}
4506  virtual ~IterableContainer(void) {}
4507  iterator begin(void) { return getContainer().begin(); }
4508  iterator end(void) { return getContainer().end(); }
4509 private:
4510  virtual Container& getContainer(void) = 0;
4511 };
4513 template<typename T, typename Container = std::vector<T>, typename Comparator = std::less<typename Container::value_type>>
4514 class IterablePriorityQueue : public IterableContainer<T, Container>, public std::priority_queue<T, Container, Comparator> {
4515 public:
4516  IterablePriorityQueue(std::priority_queue<T, Container, Comparator> queue_) {
4517  std::size_t count_ = 0;
4518  while (++count_ < base::consts::kMaxLogPerContainer && !queue_.empty()) {
4519  this->push(queue_.top());
4520  queue_.pop();
4521  }
4522  }
4523 private:
4524  inline Container& getContainer(void) {
4525  return this->c;
4526  }
4527 };
4529 template<typename T, typename Container = std::deque<T>>
4530 class IterableQueue : public IterableContainer<T, Container>, public std::queue<T, Container> {
4531 public:
4532  IterableQueue(std::queue<T, Container> queue_) {
4533  std::size_t count_ = 0;
4534  while (++count_ < base::consts::kMaxLogPerContainer && !queue_.empty()) {
4535  this->push(queue_.front());
4536  queue_.pop();
4537  }
4538  }
4539 private:
4540  inline Container& getContainer(void) {
4541  return this->c;
4542  }
4543 };
4545 template<typename T, typename Container = std::deque<T>>
4546 class IterableStack : public IterableContainer<T, Container>, public std::stack<T, Container> {
4547 public:
4548  IterableStack(std::stack<T, Container> stack_) {
4549  std::size_t count_ = 0;
4550  while (++count_ < base::consts::kMaxLogPerContainer && !stack_.empty()) {
4551  this->push(stack_.top());
4552  stack_.pop();
4553  }
4554  }
4555 private:
4556  inline Container& getContainer(void) {
4557  return this->c;
4558  }
4559 };
4560 } // namespace workarounds
4561 #endif // defined(ELPP_STL_LOGGING)
4562 // Log message builder
4564 public:
4565  MessageBuilder(void) : m_logger(nullptr), m_containerLogSeperator(ELPP_LITERAL("")) {}
4566  void initialize(Logger* logger) {
4567  m_logger = logger;
4568  m_containerLogSeperator = ELPP->hasFlag(LoggingFlag::NewLineForContainer) ?
4569  ELPP_LITERAL("\n ") : ELPP_LITERAL(", ");
4570  }
4571 
4572 # define ELPP_SIMPLE_LOG(LOG_TYPE)\
4573  inline MessageBuilder& operator<<(LOG_TYPE msg) {\
4574  m_logger->stream() << msg;\
4575  if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) {\
4576  m_logger->stream() << " ";\
4577  }\
4578  return *this;\
4579  }
4580 
4581  inline MessageBuilder& operator<<(const std::string& msg) {
4582  return operator<<(msg.c_str());
4583  }
4584  ELPP_SIMPLE_LOG(char)
4585  ELPP_SIMPLE_LOG(bool)
4586  ELPP_SIMPLE_LOG(signed short)
4587  ELPP_SIMPLE_LOG(unsigned short)
4588  ELPP_SIMPLE_LOG(signed int)
4589  ELPP_SIMPLE_LOG(unsigned int)
4590  ELPP_SIMPLE_LOG(signed long)
4591  ELPP_SIMPLE_LOG(unsigned long)
4592  ELPP_SIMPLE_LOG(float)
4593  ELPP_SIMPLE_LOG(double)
4594  ELPP_SIMPLE_LOG(char*)
4595  ELPP_SIMPLE_LOG(const char*)
4596  ELPP_SIMPLE_LOG(const void*)
4597  ELPP_SIMPLE_LOG(long double)
4598  inline MessageBuilder& operator<<(const std::wstring& msg) {
4599  return operator<<(msg.c_str());
4600  }
4601  inline MessageBuilder& operator<<(const wchar_t* msg) {
4602  if (msg == nullptr) {
4603  m_logger->stream() << base::consts::kNullPointer;
4604  return *this;
4605  }
4606 # if defined(ELPP_UNICODE)
4607  m_logger->stream() << msg;
4608 # else
4609  char* buff_ = base::utils::Str::wcharPtrToCharPtr(msg);
4610  m_logger->stream() << buff_;
4611  free(buff_);
4612 # endif
4613  if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) {
4614  m_logger->stream() << " ";
4615  }
4616  return *this;
4617  }
4618  // ostream manipulators
4619  inline MessageBuilder& operator<<(std::ostream& (*OStreamMani)(std::ostream&)) {
4620  m_logger->stream() << OStreamMani;
4621  return *this;
4622  }
4623 #define ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(temp) \
4624  template <typename T> \
4625  inline MessageBuilder& operator<<(const temp<T>& template_inst) { \
4626  return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
4627  }
4628 #define ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(temp) \
4629  template <typename T1, typename T2> \
4630  inline MessageBuilder& operator<<(const temp<T1, T2>& template_inst) { \
4631  return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
4632  }
4633 #define ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(temp) \
4634  template <typename T1, typename T2, typename T3> \
4635  inline MessageBuilder& operator<<(const temp<T1, T2, T3>& template_inst) { \
4636  return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
4637  }
4638 #define ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(temp) \
4639  template <typename T1, typename T2, typename T3, typename T4> \
4640  inline MessageBuilder& operator<<(const temp<T1, T2, T3, T4>& template_inst) { \
4641  return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
4642  }
4643 #define ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(temp) \
4644  template <typename T1, typename T2, typename T3, typename T4, typename T5> \
4645  inline MessageBuilder& operator<<(const temp<T1, T2, T3, T4, T5>& template_inst) { \
4646  return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
4647  }
4648 
4649 #if defined(ELPP_STL_LOGGING)
4657  template <class T, class Container>
4658  inline MessageBuilder& operator<<(const std::queue<T, Container>& queue_) {
4659  base::workarounds::IterableQueue<T, Container> iterableQueue_ =
4660  static_cast<base::workarounds::IterableQueue<T, Container> >(queue_);
4661  return writeIterator(iterableQueue_.begin(), iterableQueue_.end(), iterableQueue_.size());
4662  }
4663  template <class T, class Container>
4664  inline MessageBuilder& operator<<(const std::stack<T, Container>& stack_) {
4665  base::workarounds::IterableStack<T, Container> iterableStack_ =
4666  static_cast<base::workarounds::IterableStack<T, Container> >(stack_);
4667  return writeIterator(iterableStack_.begin(), iterableStack_.end(), iterableStack_.size());
4668  }
4669  template <class T, class Container, class Comparator>
4670  inline MessageBuilder& operator<<(const std::priority_queue<T, Container, Comparator>& priorityQueue_) {
4671  base::workarounds::IterablePriorityQueue<T, Container, Comparator> iterablePriorityQueue_ =
4672  static_cast<base::workarounds::IterablePriorityQueue<T, Container, Comparator> >(priorityQueue_);
4673  return writeIterator(iterablePriorityQueue_.begin(), iterablePriorityQueue_.end(), iterablePriorityQueue_.size());
4674  }
4675  template <class First, class Second>
4676  inline MessageBuilder& operator<<(const std::pair<First, Second>& pair_) {
4677  m_logger->stream() << ELPP_LITERAL("(");
4678  operator << (static_cast<First>(pair_.first));
4679  m_logger->stream() << ELPP_LITERAL(", ");
4680  operator << (static_cast<Second>(pair_.second));
4681  m_logger->stream() << ELPP_LITERAL(")");
4682  return *this;
4683  }
4684  template <std::size_t Size>
4685  inline MessageBuilder& operator<<(const std::bitset<Size>& bitset_) {
4686  m_logger->stream() << ELPP_LITERAL("[");
4687  operator << (bitset_.to_string());
4688  m_logger->stream() << ELPP_LITERAL("]");
4689  return *this;
4690  }
4691 # if defined(ELPP_LOG_STD_ARRAY)
4692  template <class T, std::size_t Size>
4693  inline MessageBuilder& operator<<(const std::array<T, Size>& array) {
4694  return writeIterator(array.begin(), array.end(), array.size());
4695  }
4696 # endif // defined(ELPP_LOG_STD_ARRAY)
4697 # if defined(ELPP_LOG_UNORDERED_MAP)
4698  ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(std::unordered_map)
4699  ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(std::unordered_multimap)
4700 # endif // defined(ELPP_LOG_UNORDERED_MAP)
4701 # if defined(ELPP_LOG_UNORDERED_SET)
4702  ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::unordered_set)
4703  ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::unordered_multiset)
4704 # endif // defined(ELPP_LOG_UNORDERED_SET)
4705 #endif // defined(ELPP_STL_LOGGING)
4706 #if defined(ELPP_QT_LOGGING)
4707  inline MessageBuilder& operator<<(const QString& msg) {
4708 # if defined(ELPP_UNICODE)
4709  m_logger->stream() << msg.toStdWString();
4710 # else
4711  m_logger->stream() << msg.toStdString();
4712 # endif // defined(ELPP_UNICODE)
4713  return *this;
4714  }
4715  inline MessageBuilder& operator<<(const QByteArray& msg) {
4716  return operator << (QString(msg));
4717  }
4718  inline MessageBuilder& operator<<(const QStringRef& msg) {
4719  return operator<<(msg.toString());
4720  }
4721  inline MessageBuilder& operator<<(qint64 msg) {
4722 # if defined(ELPP_UNICODE)
4723  m_logger->stream() << QString::number(msg).toStdWString();
4724 # else
4725  m_logger->stream() << QString::number(msg).toStdString();
4726 # endif // defined(ELPP_UNICODE)
4727  return *this;
4728  }
4729  inline MessageBuilder& operator<<(quint64 msg) {
4730 # if defined(ELPP_UNICODE)
4731  m_logger->stream() << QString::number(msg).toStdWString();
4732 # else
4733  m_logger->stream() << QString::number(msg).toStdString();
4734 # endif // defined(ELPP_UNICODE)
4735  return *this;
4736  }
4737  inline MessageBuilder& operator<<(QChar msg) {
4738  m_logger->stream() << msg.toLatin1();
4739  return *this;
4740  }
4741  inline MessageBuilder& operator<<(const QLatin1String& msg) {
4742  m_logger->stream() << msg.latin1();
4743  return *this;
4744  }
4751  template <typename First, typename Second>
4752  inline MessageBuilder& operator<<(const QPair<First, Second>& pair_) {
4753  m_logger->stream() << ELPP_LITERAL("(");
4754  operator << (static_cast<First>(pair_.first));
4755  m_logger->stream() << ELPP_LITERAL(", ");
4756  operator << (static_cast<Second>(pair_.second));
4757  m_logger->stream() << ELPP_LITERAL(")");
4758  return *this;
4759  }
4760  template <typename K, typename V>
4761  inline MessageBuilder& operator<<(const QMap<K, V>& map_) {
4762  m_logger->stream() << ELPP_LITERAL("[");
4763  QList<K> keys = map_.keys();
4764  typename QList<K>::const_iterator begin = keys.begin();
4765  typename QList<K>::const_iterator end = keys.end();
4766  int max_ = static_cast<int>(base::consts::kMaxLogPerContainer); // to prevent warning
4767  for (int index_ = 0; begin != end && index_ < max_; ++index_, ++begin) {
4768  m_logger->stream() << ELPP_LITERAL("(");
4769  operator << (static_cast<K>(*begin));
4770  m_logger->stream() << ELPP_LITERAL(", ");
4771  operator << (static_cast<V>(map_.value(*begin)));
4772  m_logger->stream() << ELPP_LITERAL(")");
4773  m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL(""));
4774  }
4775  if (begin != end) {
4776  m_logger->stream() << ELPP_LITERAL("...");
4777  }
4778  m_logger->stream() << ELPP_LITERAL("]");
4779  return *this;
4780  }
4781  template <typename K, typename V>
4782  inline MessageBuilder& operator<<(const QMultiMap<K, V>& map_) {
4783  operator << (static_cast<QMap<K, V>>(map_));
4784  return *this;
4785  }
4786  template <typename K, typename V>
4787  inline MessageBuilder& operator<<(const QHash<K, V>& hash_) {
4788  m_logger->stream() << ELPP_LITERAL("[");
4789  QList<K> keys = hash_.keys();
4790  typename QList<K>::const_iterator begin = keys.begin();
4791  typename QList<K>::const_iterator end = keys.end();
4792  int max_ = static_cast<int>(base::consts::kMaxLogPerContainer); // prevent type warning
4793  for (int index_ = 0; begin != end && index_ < max_; ++index_, ++begin) {
4794  m_logger->stream() << ELPP_LITERAL("(");
4795  operator << (static_cast<K>(*begin));
4796  m_logger->stream() << ELPP_LITERAL(", ");
4797  operator << (static_cast<V>(hash_.value(*begin)));
4798  m_logger->stream() << ELPP_LITERAL(")");
4799  m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL(""));
4800  }
4801  if (begin != end) {
4802  m_logger->stream() << ELPP_LITERAL("...");
4803  }
4804  m_logger->stream() << ELPP_LITERAL("]");
4805  return *this;
4806  }
4807  template <typename K, typename V>
4808  inline MessageBuilder& operator<<(const QMultiHash<K, V>& multiHash_) {
4809  operator << (static_cast<QHash<K, V>>(multiHash_));
4810  return *this;
4811  }
4812 #endif // defined(ELPP_QT_LOGGING)
4813 #if defined(ELPP_BOOST_LOGGING)
4814  ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::vector)
4815  ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::stable_vector)
4816  ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::list)
4817  ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::deque)
4818  ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(boost::container::map)
4819  ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(boost::container::flat_map)
4820  ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(boost::container::set)
4821  ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(boost::container::flat_set)
4822 #endif // defined(ELPP_BOOST_LOGGING)
4823 
4832 #define MAKE_CONTAINERELPP_FRIENDLY(ContainerType, SizeMethod, ElementInstance) \
4833  el::base::type::ostream_t& operator<<(el::base::type::ostream_t& ss, const ContainerType& container) {\
4834  const el::base::type::char_t* sep = ELPP->hasFlag(el::LoggingFlag::NewLineForContainer) ? \
4835  ELPP_LITERAL("\n ") : ELPP_LITERAL(", ");\
4836  ContainerType::const_iterator elem = container.begin();\
4837  ContainerType::const_iterator endElem = container.end();\
4838  std::size_t size_ = container.SizeMethod; \
4839  ss << ELPP_LITERAL("[");\
4840  for (std::size_t i = 0; elem != endElem && i < el::base::consts::kMaxLogPerContainer; ++i, ++elem) { \
4841  ss << ElementInstance;\
4842  ss << ((i < size_ - 1) ? sep : ELPP_LITERAL(""));\
4843  }\
4844  if (elem != endElem) {\
4845  ss << ELPP_LITERAL("...");\
4846  }\
4847  ss << ELPP_LITERAL("]");\
4848  return ss;\
4849  }
4850 #if defined(ELPP_WXWIDGETS_LOGGING)
4852 # define ELPP_WX_PTR_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), *(*elem))
4853 # define ELPP_WX_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), (*elem))
4854 # define ELPP_WX_HASH_MAP_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), \
4855  ELPP_LITERAL("(") << elem->first << ELPP_LITERAL(", ") << elem->second << ELPP_LITERAL(")")
4856 #else
4857 # define ELPP_WX_PTR_ENABLED(ContainerType)
4858 # define ELPP_WX_ENABLED(ContainerType)
4859 # define ELPP_WX_HASH_MAP_ENABLED(ContainerType)
4860 #endif // defined(ELPP_WXWIDGETS_LOGGING)
4861  // Other classes
4862  template <class Class>
4863  ELPP_SIMPLE_LOG(const Class&)
4864 #undef ELPP_SIMPLE_LOG
4865 #undef ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG
4866 #undef ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG
4867 #undef ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG
4868 #undef ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG
4869 #undef ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG
4870 private:
4871  Logger* m_logger;
4872  const base::type::char_t* m_containerLogSeperator;
4873 
4874  template<class Iterator>
4875  inline MessageBuilder& writeIterator(Iterator begin_, Iterator end_, std::size_t size_) {
4876  m_logger->stream() << ELPP_LITERAL("[");
4877  for (std::size_t i = 0; begin_ != end_ && i < base::consts::kMaxLogPerContainer; ++i, ++begin_) {
4878  operator << (*begin_);
4879  m_logger->stream() << ((i < size_ - 1) ? m_containerLogSeperator : ELPP_LITERAL(""));
4880  }
4881  if (begin_ != end_) {
4882  m_logger->stream() << ELPP_LITERAL("...");
4883  }
4884  m_logger->stream() << ELPP_LITERAL("]");
4885  if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) {
4886  m_logger->stream() << " ";
4887  }
4888  return *this;
4889  }
4890 };
4893 public:
4894  NullWriter(void) {}
4895 
4896  // Null manipulator
4897  inline NullWriter& operator<<(std::ostream& (*)(std::ostream&)) {
4898  return *this;
4899  }
4900 
4901  template <typename T>
4902  inline NullWriter& operator<<(const T&) {
4903  return *this;
4904  }
4905 };
4908 public:
4909  Writer(Level level, const char* file, unsigned long int line,
4910  const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog,
4911  base::type::VerboseLevel verboseLevel = 0) :
4912  m_level(level), m_file(file), m_line(line), m_func(func), m_verboseLevel(verboseLevel),
4913  m_proceed(false), m_dispatchAction(dispatchAction) {
4914  }
4915 
4916  virtual ~Writer(void) {
4917  processDispatch();
4918  }
4919 
4920  template <typename T>
4921  inline Writer& operator<<(const T& log) {
4922 #if ELPP_LOGGING_ENABLED
4923  if (m_proceed) {
4924  m_messageBuilder << log;
4925  }
4926 #endif // ELPP_LOGGING_ENABLED
4927  return *this;
4928  }
4929 
4930  inline Writer& operator<<(std::ostream& (*log)(std::ostream&)) {
4931 #if ELPP_LOGGING_ENABLED
4932  if (m_proceed) {
4933  m_messageBuilder << log;
4934  }
4935 #endif // ELPP_LOGGING_ENABLED
4936  return *this;
4937  }
4938 
4939  Writer& construct(Logger* logger, bool needLock = true) {
4940  m_logger = logger;
4941  initializeLogger(logger->id(), false, needLock);
4943  return *this;
4944  }
4945 
4946  Writer& construct(int count, const char* loggerIds, ...) {
4947  if (ELPP->hasFlag(LoggingFlag::MultiLoggerSupport)) {
4948  va_list loggersList;
4949  va_start(loggersList, loggerIds);
4950  const char* id = loggerIds;
4951  for (int i = 0; i < count; ++i) {
4952  m_loggerIds.push_back(std::string(id));
4953  id = va_arg(loggersList, const char*);
4954  }
4955  va_end(loggersList);
4957  } else {
4958  initializeLogger(std::string(loggerIds));
4959  }
4961  return *this;
4962  }
4963 protected:
4965  const char* m_file;
4966  const unsigned long int m_line;
4967  const char* m_func;
4973  std::vector<std::string> m_loggerIds;
4974  friend class el::Helpers;
4975 
4976  void initializeLogger(const std::string& loggerId, bool lookup = true, bool needLock = true) {
4977  if (lookup) {
4978  m_logger = ELPP->registeredLoggers()->get(loggerId, ELPP->hasFlag(LoggingFlag::CreateLoggerAutomatically));
4979  }
4980  if (m_logger == nullptr) {
4981  ELPP->acquireLock();
4982  if (!ELPP->registeredLoggers()->has(std::string(base::consts::kDefaultLoggerId))) {
4983  // Somehow default logger has been unregistered. Not good! Register again
4984  ELPP->registeredLoggers()->get(std::string(base::consts::kDefaultLoggerId));
4985  }
4986  ELPP->releaseLock(); // Need to unlock it for next writer
4987  Writer(Level::Debug, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId)
4988  << "Logger [" << loggerId << "] is not registered yet!";
4989  m_proceed = false;
4990  } else {
4991  if (needLock) {
4992  m_logger->acquireLock(); // This should not be unlocked by checking m_proceed because
4993  // m_proceed can be changed by lines below
4994  }
4995  if (ELPP->hasFlag(LoggingFlag::HierarchicalLogging)) {
4998  } else {
5000  }
5001  }
5002  }
5003 
5005 #if ELPP_LOGGING_ENABLED
5006  if (ELPP->hasFlag(LoggingFlag::MultiLoggerSupport)) {
5007  bool firstDispatched = false;
5008  base::type::string_t logMessage;
5009  std::size_t i = 0;
5010  do {
5011  if (m_proceed) {
5012  if (firstDispatched) {
5013  m_logger->stream() << logMessage;
5014  } else {
5015  firstDispatched = true;
5016  if (m_loggerIds.size() > 1) {
5017  logMessage = m_logger->stream().str();
5018  }
5019  }
5020  triggerDispatch();
5021  } else if (m_logger != nullptr) {
5022  m_logger->stream().str(ELPP_LITERAL(""));
5023  m_logger->releaseLock();
5024  }
5025  if (i + 1 < m_loggerIds.size()) {
5026  initializeLogger(m_loggerIds.at(i + 1));
5027  }
5028  } while (++i < m_loggerIds.size());
5029  } else {
5030  if (m_proceed) {
5031  triggerDispatch();
5032  } else if (m_logger != nullptr) {
5033  m_logger->stream().str(ELPP_LITERAL(""));
5034  m_logger->releaseLock();
5035  }
5036  }
5037 #else
5038  if (m_logger != nullptr) {
5039  m_logger->stream().str(ELPP_LITERAL(""));
5040  m_logger->releaseLock();
5041  }
5042 #endif // ELPP_LOGGING_ENABLED
5043  }
5044 
5045  void triggerDispatch(void) {
5046  if (m_proceed) {
5049  }
5050  if (m_logger != nullptr) {
5051  m_logger->stream().str(ELPP_LITERAL(""));
5052  m_logger->releaseLock();
5053  }
5054  if (m_proceed && m_level == Level::Fatal
5056  base::Writer(Level::Warning, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId)
5057  << "Aborting application. Reason: Fatal log at [" << m_file << ":" << m_line << "]";
5058  std::stringstream reasonStream;
5059  reasonStream << "Fatal log at [" << m_file << ":" << m_line << "]"
5060  << " If you wish to disable 'abort on fatal log' please use "
5061  << "el::Helpers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog)";
5062  base::utils::abort(1, reasonStream.str());
5063  }
5064  m_proceed = false;
5065  }
5066 };
5067 class PErrorWriter : public base::Writer {
5068 public:
5069  PErrorWriter(Level level, const char* file, unsigned long int line,
5070  const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog,
5071  base::type::VerboseLevel verboseLevel = 0) :
5072  base::Writer(level, file, line, func, dispatchAction, verboseLevel) {
5073  }
5074 
5075  virtual ~PErrorWriter(void) {
5076  if (m_proceed) {
5077 #if ELPP_COMPILER_MSVC
5078  char buff[256];
5079  strerror_s(buff, 256, errno);
5080  m_logger->stream() << ": " << buff << " [" << errno << "]";
5081 #else
5082  m_logger->stream() << ": " << strerror(errno) << " [" << errno << "]";
5083 #endif
5084  }
5085  }
5086 };
5087 } // namespace base
5088 // Logging from Logger class. Why this is here? Because we have Storage and Writer class available
5089 #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
5090  template <typename T, typename... Args>
5091  void Logger::log_(Level level, int vlevel, const char* s, const T& value, const Args&... args) {
5092  base::MessageBuilder b;
5093  b.initialize(this);
5094  while (*s) {
5095  if (*s == base::consts::kFormatSpecifierChar) {
5096  if (*(s + 1) == base::consts::kFormatSpecifierChar) {
5097  ++s;
5098  } else {
5099  if (*(s + 1) == base::consts::kFormatSpecifierCharValue) {
5100  ++s;
5101  b << value;
5102  log_(level, vlevel, ++s, args...);
5103  return;
5104  }
5105  }
5106  }
5107  b << *s++;
5108  }
5109  ELPP_INTERNAL_ERROR("Too many arguments provided. Unable to handle. Please provide more format specifiers", false);
5110  }
5111  template <typename T>
5112  inline void Logger::log_(Level level, int vlevel, const T& log) {
5113  if (level == Level::Verbose) {
5114  if (ELPP->vRegistry()->allowed(vlevel, __FILE__)) {
5115  base::Writer(Level::Verbose, "FILE", 0, "FUNCTION",
5116  base::DispatchAction::NormalLog, vlevel).construct(this, false) << log;
5117  } else {
5118  stream().str(ELPP_LITERAL(""));
5119  }
5120  } else {
5121  base::Writer(level, "FILE", 0, "FUNCTION").construct(this, false) << log;
5122  }
5123  }
5124  template <typename T, typename... Args>
5125  void Logger::log(Level level, const char* s, const T& value, const Args&... args) {
5126  base::threading::ScopedLock scopedLock(lock());
5127  log_(level, 0, s, value, args...);
5128  }
5129  template <typename T>
5130  inline void Logger::log(Level level, const T& log) {
5131  base::threading::ScopedLock scopedLock(lock());
5132  log_(level, 0, log);
5133  }
5134 # if ELPP_VERBOSE_LOG
5135  template <typename T, typename... Args>
5136  inline void Logger::verbose(int vlevel, const char* s, const T& value, const Args&... args) {
5137  base::threading::ScopedLock scopedLock(lock());
5138  log_(el::Level::Verbose, vlevel, s, value, args...);
5139  }
5140  template <typename T>
5141  inline void Logger::verbose(int vlevel, const T& log) {
5142  base::threading::ScopedLock scopedLock(lock());
5143  log_(el::Level::Verbose, vlevel, log);
5144  }
5145 # else
5146  template <typename T, typename... Args>
5147  inline void Logger::verbose(int, const char*, const T&, const Args&...) {
5148  return;
5149  }
5150  template <typename T>
5151  inline void Logger::verbose(int, const T&) {
5152  return;
5153  }
5154 # endif // ELPP_VERBOSE_LOG
5155 # define LOGGER_LEVEL_WRITERS(FUNCTION_NAME, LOG_LEVEL)\
5156  template <typename T, typename... Args>\
5157  inline void Logger::FUNCTION_NAME(const char* s, const T& value, const Args&... args) {\
5158  log(LOG_LEVEL, s, value, args...);\
5159  }\
5160  template <typename T>\
5161  inline void Logger::FUNCTION_NAME(const T& value) {\
5162  log(LOG_LEVEL, value);\
5163  }
5164 # define LOGGER_LEVEL_WRITERS_DISABLED(FUNCTION_NAME, LOG_LEVEL)\
5165  template <typename T, typename... Args>\
5166  inline void Logger::FUNCTION_NAME(const char*, const T&, const Args&...) {\
5167  return;\
5168  }\
5169  template <typename T>\
5170  inline void Logger::FUNCTION_NAME(const T&) {\
5171  return;\
5172  }
5173 
5174 # if ELPP_INFO_LOG
5175  LOGGER_LEVEL_WRITERS(info, Level::Info)
5176 # else
5177  LOGGER_LEVEL_WRITERS_DISABLED(info, Level::Info)
5178 # endif // ELPP_INFO_LOG
5179 # if ELPP_DEBUG_LOG
5180  LOGGER_LEVEL_WRITERS(debug, Level::Debug)
5181 # else
5182  LOGGER_LEVEL_WRITERS_DISABLED(debug, Level::Debug)
5183 # endif // ELPP_DEBUG_LOG
5184 # if ELPP_WARNING_LOG
5185  LOGGER_LEVEL_WRITERS(warn, Level::Warning)
5186 # else
5187  LOGGER_LEVEL_WRITERS_DISABLED(warn, Level::Warning)
5188 # endif // ELPP_WARNING_LOG
5189 # if ELPP_ERROR_LOG
5190  LOGGER_LEVEL_WRITERS(error, Level::Error)
5191 # else
5192  LOGGER_LEVEL_WRITERS_DISABLED(error, Level::Error)
5193 # endif // ELPP_ERROR_LOG
5194 # if ELPP_FATAL_LOG
5195  LOGGER_LEVEL_WRITERS(fatal, Level::Fatal)
5196 # else
5197  LOGGER_LEVEL_WRITERS_DISABLED(fatal, Level::Fatal)
5198 # endif // ELPP_FATAL_LOG
5199 # if ELPP_TRACE_LOG
5200  LOGGER_LEVEL_WRITERS(trace, Level::Trace)
5201 # else
5202  LOGGER_LEVEL_WRITERS_DISABLED(trace, Level::Trace)
5203 # endif // ELPP_TRACE_LOG
5204 # undef LOGGER_LEVEL_WRITERS
5205 # undef LOGGER_LEVEL_WRITERS_DISABLED
5206 #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
5207 #if ELPP_COMPILER_MSVC
5208 # define ELPP_VARIADIC_FUNC_MSVC(variadicFunction, variadicArgs) variadicFunction variadicArgs
5209 # define ELPP_VARIADIC_FUNC_MSVC_RUN(variadicFunction, ...) ELPP_VARIADIC_FUNC_MSVC(variadicFunction, (__VA_ARGS__))
5210 # define el_getVALength(...) ELPP_VARIADIC_FUNC_MSVC_RUN(el_resolveVALength, 0, ## __VA_ARGS__,\
5211  10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
5212 #else
5213 # if ELPP_COMPILER_CLANG
5214 # define el_getVALength(...) el_resolveVALength(0, __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
5215 # else
5216 # define el_getVALength(...) el_resolveVALength(0, ## __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
5217 # endif // ELPP_COMPILER_CLANG
5218 #endif // ELPP_COMPILER_MSVC
5219 #define el_resolveVALength(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
5220 #define ELPP_WRITE_LOG(writer, level, dispatchAction, ...) \
5221  writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
5222 #define ELPP_WRITE_LOG_IF(writer, condition, level, dispatchAction, ...) if (condition) \
5223  writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
5224 #define ELPP_WRITE_LOG_EVERY_N(writer, occasion, level, dispatchAction, ...) \
5225  if (ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion)) \
5226  writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
5227 #define ELPP_WRITE_LOG_AFTER_N(writer, n, level, dispatchAction, ...) \
5228  if (ELPP->validateAfterNCounter(__FILE__, __LINE__, n)) \
5229  writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
5230 #define ELPP_WRITE_LOG_N_TIMES(writer, n, level, dispatchAction, ...) \
5231  if (ELPP->validateNTimesCounter(__FILE__, __LINE__, n)) \
5232  writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
5233 #undef ELPP_CURR_FILE_PERFORMANCE_LOGGER
5234 #if defined(ELPP_PERFORMANCE_LOGGER)
5235 # define ELPP_CURR_FILE_PERFORMANCE_LOGGER ELPP_PERFORMANCE_LOGGER
5236 #else
5237 # define ELPP_CURR_FILE_PERFORMANCE_LOGGER el::base::consts::kPerformanceLoggerId
5238 #endif
5240 public:
5242  Checkpoint = 1, Complete = 2
5243  };
5244  // Do not use constructor, will run into multiple definition error, use init(PerformanceTracker*)
5245  explicit PerformanceTrackingData(DataType dataType) : m_performanceTracker(nullptr),
5246  m_dataType(dataType), m_file(""), m_line(0), m_func("") {}
5247  inline const std::string* blockName(void) const;
5248  inline const struct timeval* startTime(void) const;
5249  inline const struct timeval* endTime(void) const;
5250  inline const struct timeval* lastCheckpointTime(void) const;
5251  inline const base::PerformanceTracker* performanceTracker(void) const { return m_performanceTracker; }
5252  inline PerformanceTrackingData::DataType dataType(void) const { return m_dataType; }
5253  inline bool firstCheckpoint(void) const { return m_firstCheckpoint; }
5254  inline std::string checkpointId(void) const { return m_checkpointId; }
5255  inline const char* file(void) const { return m_file; }
5256  inline unsigned long int line(void) const { return m_line; }
5257  inline const char* func(void) const { return m_func; }
5258  inline const base::type::string_t* formattedTimeTaken() const { return &m_formattedTimeTaken; }
5259  inline const std::string& loggerId(void) const;
5260 private:
5261  base::PerformanceTracker* m_performanceTracker;
5262  base::type::string_t m_formattedTimeTaken;
5264  bool m_firstCheckpoint;
5265  std::string m_checkpointId;
5266  const char* m_file;
5267  unsigned long int m_line;
5268  const char* m_func;
5269  inline void init(base::PerformanceTracker* performanceTracker, bool firstCheckpoint = false) {
5270  m_performanceTracker = performanceTracker;
5271  m_firstCheckpoint = firstCheckpoint;
5272  }
5273 
5275 };
5276 namespace base {
5280 public:
5281  PerformanceTracker(const std::string& blockName,
5283  const std::string& loggerId = std::string(ELPP_CURR_FILE_PERFORMANCE_LOGGER),
5284  bool scopedLog = true, Level level = base::consts::kPerformanceTrackerDefaultLevel) :
5285  m_blockName(blockName), m_timestampUnit(timestampUnit), m_loggerId(loggerId), m_scopedLog(scopedLog),
5286  m_level(level), m_hasChecked(false), m_lastCheckpointId(std::string()), m_enabled(false) {
5287 #if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED
5288  // We store it locally so that if user happen to change configuration by the end of scope
5289  // or before calling checkpoint, we still depend on state of configuraton at time of construction
5290  el::Logger* loggerPtr = ELPP->registeredLoggers()->get(loggerId, false);
5291  m_enabled = loggerPtr != nullptr && loggerPtr->m_typedConfigurations->performanceTracking(m_level);
5292  if (m_enabled) {
5294  }
5295 #endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED
5296  }
5299  m_blockName(t.m_blockName), m_timestampUnit(t.m_timestampUnit), m_loggerId(t.m_loggerId), m_scopedLog(t.m_scopedLog),
5300  m_level(t.m_level), m_hasChecked(t.m_hasChecked), m_lastCheckpointId(t.m_lastCheckpointId), m_enabled(t.m_enabled),
5301  m_startTime(t.m_startTime), m_endTime(t.m_endTime), m_lastCheckpointTime(t.m_lastCheckpointTime) {
5302  }
5303  virtual ~PerformanceTracker(void) {
5304 #if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED
5305  if (m_enabled) {
5306  base::threading::ScopedLock scopedLock(lock());
5307  if (m_scopedLog) {
5309  base::type::string_t formattedTime = getFormattedTimeTaken();
5311  data.init(this);
5312  data.m_formattedTimeTaken = formattedTime;
5313  PerformanceTrackingCallback* callback = nullptr;
5314  for (const std::pair<std::string, base::type::PerformanceTrackingCallbackPtr>& h
5315  : ELPP->m_performanceTrackingCallbacks) {
5316  callback = h.second.get();
5317  if (callback != nullptr && callback->enabled()) {
5318  callback->acquireLock();
5319  callback->handle(&data);
5320  callback->releaseLock();
5321  }
5322  }
5323  }
5324  }
5325 #endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING)
5326  }
5328  void checkpoint(const std::string& id = std::string(), const char* file = __FILE__, unsigned long int line = __LINE__, const char* func = "") {
5329 #if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED
5330  if (m_enabled) {
5331  base::threading::ScopedLock scopedLock(lock());
5333  base::type::string_t formattedTime = m_hasChecked ? getFormattedTimeTaken(m_lastCheckpointTime) : ELPP_LITERAL("");
5335  data.init(this);
5336  data.m_checkpointId = id;
5337  data.m_file = file;
5338  data.m_line = line;
5339  data.m_func = func;
5340  data.m_formattedTimeTaken = formattedTime;
5341  PerformanceTrackingCallback* callback = nullptr;
5342  for (const std::pair<std::string, base::type::PerformanceTrackingCallbackPtr>& h
5343  : ELPP->m_performanceTrackingCallbacks) {
5344  callback = h.second.get();
5345  if (callback != nullptr && callback->enabled()) {
5346  callback->acquireLock();
5347  callback->handle(&data);
5348  callback->releaseLock();
5349  }
5350  }
5351  base::utils::DateTime::gettimeofday(&m_lastCheckpointTime);
5352  m_hasChecked = true;
5353  m_lastCheckpointId = id;
5354  }
5355 #endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED
5356  ELPP_UNUSED(id);
5357  ELPP_UNUSED(file);
5358  ELPP_UNUSED(line);
5359  ELPP_UNUSED(func);
5360  }
5361  inline Level level(void) const { return m_level; }
5362 private:
5363  std::string m_blockName;
5364  base::TimestampUnit m_timestampUnit;
5365  std::string m_loggerId;
5366  bool m_scopedLog;
5367  Level m_level;
5368  bool m_hasChecked;
5369  std::string m_lastCheckpointId;
5370  bool m_enabled;
5371  struct timeval m_startTime, m_endTime, m_lastCheckpointTime;
5372 
5373  PerformanceTracker(void);
5374 
5377 
5378  const inline base::type::string_t getFormattedTimeTaken() const {
5379  return getFormattedTimeTaken(m_startTime);
5380  }
5381 
5382  const base::type::string_t getFormattedTimeTaken(struct timeval startTime) const {
5383  if (ELPP->hasFlag(LoggingFlag::FixedTimeFormat)) {
5386  startTime, m_timestampUnit) << " " << base::consts::kTimeFormats[static_cast<base::type::EnumType>(m_timestampUnit)].unit;
5387  return ss.str();
5388  }
5390  startTime, m_timestampUnit), m_timestampUnit);
5391  }
5392 
5393  virtual inline void log(el::base::type::ostream_t& os) const {
5394  os << getFormattedTimeTaken();
5395  }
5396 };
5398 protected:
5399  void handle(const PerformanceTrackingData* data) {
5400  m_data = data;
5403  ss << ELPP_LITERAL("Executed [") << m_data->blockName()->c_str() << ELPP_LITERAL("] in [") << *m_data->formattedTimeTaken() << ELPP_LITERAL("]");
5404  } else {
5405  ss << ELPP_LITERAL("Performance checkpoint");
5406  if (!m_data->checkpointId().empty()) {
5407  ss << ELPP_LITERAL(" [") << m_data->checkpointId().c_str() << ELPP_LITERAL("]");
5408  }
5409  ss << ELPP_LITERAL(" for block [") << m_data->blockName()->c_str() << ELPP_LITERAL("] : [") << *m_data->performanceTracker();
5410  if (!ELPP->hasFlag(LoggingFlag::DisablePerformanceTrackingCheckpointComparison) && m_data->performanceTracker()->m_hasChecked) {
5411  ss << ELPP_LITERAL(" ([") << *m_data->formattedTimeTaken() << ELPP_LITERAL("] from ");
5412  if (m_data->performanceTracker()->m_lastCheckpointId.empty()) {
5413  ss << ELPP_LITERAL("last checkpoint");
5414  } else {
5415  ss << ELPP_LITERAL("checkpoint '") << m_data->performanceTracker()->m_lastCheckpointId.c_str() << ELPP_LITERAL("'");
5416  }
5417  ss << ELPP_LITERAL(")]");
5418  } else {
5419  ss << ELPP_LITERAL("]");
5420  }
5421  }
5422  el::base::Writer(m_data->performanceTracker()->level(), m_data->file(), m_data->line(), m_data->func()).construct(1, m_data->loggerId().c_str()) << ss.str();
5423  }
5424 private:
5425  const PerformanceTrackingData* m_data;
5426 };
5427 } // namespace base
5428 inline const std::string* PerformanceTrackingData::blockName() const {
5429  return const_cast<const std::string*>(&m_performanceTracker->m_blockName);
5430 }
5431 inline const struct timeval* PerformanceTrackingData::startTime() const {
5432  return const_cast<const struct timeval*>(&m_performanceTracker->m_startTime);
5433 }
5434 inline const struct timeval* PerformanceTrackingData::endTime() const {
5435  return const_cast<const struct timeval*>(&m_performanceTracker->m_endTime);
5436 }
5437 inline const struct timeval* PerformanceTrackingData::lastCheckpointTime() const {
5438  return const_cast<const struct timeval*>(&m_performanceTracker->m_lastCheckpointTime);
5439 }
5440 inline const std::string& PerformanceTrackingData::loggerId(void) const { return m_performanceTracker->m_loggerId; }
5441 namespace base {
5443 namespace debug {
5445 public:
5446  static const std::size_t kMaxStack = 64;
5447  static const std::size_t kStackStart = 2; // We want to skip c'tor and StackTrace::generateNew()
5449  public:
5450  StackTraceEntry(std::size_t index, const char* loc, const char* demang, const char* hex, const char* addr) {
5451  m_index = index;
5452  m_location = std::string(loc);
5453  m_demangled = std::string(demang);
5454  m_hex = std::string(hex);
5455  m_addr = std::string(addr);
5456  }
5457  StackTraceEntry(std::size_t index, char* loc) {
5458  m_index = index;
5459  m_location = std::string(loc);
5460  }
5461  std::size_t m_index;
5462  std::string m_location;
5463  std::string m_demangled;
5464  std::string m_hex;
5465  std::string m_addr;
5466  friend std::ostream& operator<<(std::ostream& ss, const StackTraceEntry& si) {
5467  ss << "[" << si.m_index << "] " << si.m_location << (si.m_demangled.empty() ? "" : ":") << si.m_demangled
5468  << (si.m_hex.empty() ? "" : "+") << si.m_hex << si.m_addr;
5469  return ss;
5470  }
5471 
5472  private:
5473  StackTraceEntry(void);
5474  };
5475 
5476  StackTrace(void) {
5477  generateNew();
5478  }
5479 
5480  virtual ~StackTrace(void) {
5481  }
5482 
5483  inline std::vector<StackTraceEntry>& getLatestStack(void) {
5484  return m_stack;
5485  }
5486 
5487  friend inline std::ostream& operator<<(std::ostream& os, const StackTrace& st) {
5488  std::vector<StackTraceEntry>::const_iterator it = st.m_stack.begin();
5489  while (it != st.m_stack.end()) {
5490  os << " " << *it++ << "\n";
5491  }
5492  return os;
5493  }
5494 
5495 private:
5496  std::vector<StackTraceEntry> m_stack;
5497 
5498  void generateNew(void) {
5499 #if ELPP_STACKTRACE
5500  m_stack.clear();
5501  void* stack[kMaxStack];
5502  std::size_t size = backtrace(stack, kMaxStack);
5503  char** strings = backtrace_symbols(stack, size);
5504  if (size > kStackStart) { // Skip StackTrace c'tor and generateNew
5505  for (std::size_t i = kStackStart; i < size; ++i) {
5506  char* mangName = nullptr;
5507  char* hex = nullptr;
5508  char* addr = nullptr;
5509  for (char* c = strings[i]; *c; ++c) {
5510  switch (*c) {
5511  case '(':
5512  mangName = c;
5513  break;
5514  case '+':
5515  hex = c;
5516  break;
5517  case ')':
5518  addr = c;
5519  break;
5520  }
5521  }
5522  // Perform demangling if parsed properly
5523  if (mangName != nullptr && hex != nullptr && addr != nullptr && mangName < hex) {
5524  *mangName++ = '\0';
5525  *hex++ = '\0';
5526  *addr++ = '\0';
5527  int status = 0;
5528  char* demangName = abi::__cxa_demangle(mangName, 0, 0, &status);
5529  // if demangling is successful, output the demangled function name
5530  if (status == 0) {
5531  // Success (see http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01696.html)
5532  StackTraceEntry entry(i - 1, strings[i], demangName, hex, addr);
5533  m_stack.push_back(entry);
5534  } else {
5535  // Not successful - we will use mangled name
5536  StackTraceEntry entry(i - 1, strings[i], mangName, hex, addr);
5537  m_stack.push_back(entry);
5538  }
5539  free(demangName);
5540  } else {
5541  StackTraceEntry entry(i - 1, strings[i]);
5542  m_stack.push_back(entry);
5543  }
5544  }
5545  }
5546  free(strings);
5547 #else
5548  ELPP_INTERNAL_INFO(1, "Stacktrace generation not supported for selected compiler");
5549 #endif // ELPP_STACKTRACE
5550  }
5551 };
5552 static std::string crashReason(int sig) {
5553  std::stringstream ss;
5554  bool foundReason = false;
5555  for (int i = 0; i < base::consts::kCrashSignalsCount; ++i) {
5556  if (base::consts::kCrashSignals[i].numb == sig) {
5557  ss << "Application has crashed due to [" << base::consts::kCrashSignals[i].name << "] signal";
5559  ss << std::endl <<
5560  " " << base::consts::kCrashSignals[i].brief << std::endl <<
5561  " " << base::consts::kCrashSignals[i].detail;
5562  }
5563  foundReason = true;
5564  }
5565  }
5566  if (!foundReason) {
5567  ss << "Application has crashed due to unknown signal [" << sig << "]";
5568  }
5569  return ss.str();
5570 }
5572 static void logCrashReason(int sig, bool stackTraceIfAvailable, Level level, const char* logger) {
5573  std::stringstream ss;
5574  ss << "CRASH HANDLED; ";
5575  ss << crashReason(sig);
5576 #if ELPP_STACKTRACE
5577  if (stackTraceIfAvailable) {
5578  ss << std::endl << " ======= Backtrace: =========" << std::endl << base::debug::StackTrace();
5579  }
5580 #else
5581  ELPP_UNUSED(stackTraceIfAvailable);
5582 #endif // ELPP_STACKTRACE
5584 }
5585 static inline void crashAbort(int sig) {
5586  base::utils::abort(sig);
5587 }
5591 static inline void defaultCrashHandler(int sig) {
5592  base::debug::logCrashReason(sig, true, Level::Fatal, base::consts::kDefaultLoggerId);
5593  base::debug::crashAbort(sig);
5594 }
5597 public:
5598  typedef void (*Handler)(int);
5599 
5600  explicit CrashHandler(bool useDefault) {
5601  if (useDefault) {
5602  setHandler(defaultCrashHandler);
5603  }
5604  }
5605  explicit CrashHandler(const Handler& cHandler) {
5606  setHandler(cHandler);
5607  }
5608  void setHandler(const Handler& cHandler) {
5609  m_handler = cHandler;
5610 #if defined(ELPP_HANDLE_SIGABRT)
5611  int i = 0; // SIGABRT is at base::consts::kCrashSignals[0]
5612 #else
5613  int i = 1;
5614 #endif // defined(ELPP_HANDLE_SIGABRT)
5615  for (; i < base::consts::kCrashSignalsCount; ++i) {
5616  m_handler = signal(base::consts::kCrashSignals[i].numb, cHandler);
5617  }
5618  }
5619 
5620 private:
5621  Handler m_handler;
5622 };
5623 } // namespace debug
5624 } // namespace base
5625 extern base::debug::CrashHandler elCrashHandler;
5626 #define MAKE_LOGGABLE(ClassType, ClassInstance, OutputStreamInstance) \
5627  el::base::type::ostream_t& operator<<(el::base::type::ostream_t& OutputStreamInstance, const ClassType& ClassInstance)
5628 class SysLogInitializer {
5630 public:
5631  SysLogInitializer(const char* processIdent, int options = 0, int facility = 0) {
5632 #if defined(ELPP_SYSLOG)
5633  openlog(processIdent, options, facility);
5634 #else
5635  ELPP_UNUSED(processIdent);
5637  ELPP_UNUSED(facility);
5638 #endif // defined(ELPP_SYSLOG)
5639  }
5640  virtual ~SysLogInitializer(void) {
5641 #if defined(ELPP_SYSLOG)
5642  closelog();
5643 #endif // defined(ELPP_SYSLOG)
5644  }
5645 };
5646 #define ELPP_INITIALIZE_SYSLOG(id, opt, fac) el::SysLogInitializer elSyslogInit(id, opt, fac)
5647 class Helpers : base::StaticClass {
5649 public:
5652  ELPP = storage;
5653  }
5656  return ELPP;
5657  }
5659  static inline void setArgs(int argc, char** argv) {
5660  ELPP->setApplicationArguments(argc, argv);
5661  }
5663  static inline void setArgs(int argc, const char** argv) {
5664  ELPP->setApplicationArguments(argc, const_cast<char**>(argv));
5665  }
5669  static inline void setCrashHandler(const el::base::debug::CrashHandler::Handler& crashHandler) {
5670  el::elCrashHandler.setHandler(crashHandler);
5671  }
5674  static inline void crashAbort(int sig, const char* sourceFile = "", unsigned int long line = 0) {
5675  std::stringstream ss;
5676  ss << base::debug::crashReason(sig).c_str();
5677  ss << " - [Called el::Helpers::crashAbort(" << sig << ")]";
5678  if (sourceFile != nullptr && strlen(sourceFile) > 0) {
5679  ss << " - Source: " << sourceFile;
5680  if (line > 0)
5681  ss << ":" << line;
5682  else
5683  ss << " (line number not specified)";
5684  }
5685  base::utils::abort(sig, ss.str());
5686  }
5692  static inline void logCrashReason(int sig, bool stackTraceIfAvailable = false,
5693  Level level = Level::Fatal, const char* logger = base::consts::kDefaultLoggerId) {
5694  el::base::debug::logCrashReason(sig, stackTraceIfAvailable, level, logger);
5695  }
5698  static inline void installPreRollOutCallback(const PreRollOutCallback& callback) {
5699  ELPP->setPreRollOutCallback(callback);
5700  }
5702  static inline void uninstallPreRollOutCallback(void) {
5703  ELPP->unsetPreRollOutCallback();
5704  }
5706  template <typename T>
5707  static inline bool installLogDispatchCallback(const std::string& id) {
5708  return ELPP->installLogDispatchCallback<T>(id);
5709  }
5711  template <typename T>
5712  static inline void uninstallLogDispatchCallback(const std::string& id) {
5713  ELPP->uninstallLogDispatchCallback<T>(id);
5714  }
5715  template <typename T>
5716  static inline T* logDispatchCallback(const std::string& id) {
5717  return ELPP->logDispatchCallback<T>(id);
5718  }
5720  template <typename T>
5721  static inline bool installPerformanceTrackingCallback(const std::string& id) {
5722  return ELPP->installPerformanceTrackingCallback<T>(id);
5723  }
5725  template <typename T>
5726  static inline void uninstallPerformanceTrackingCallback(const std::string& id) {
5727  ELPP->uninstallPerformanceTrackingCallback<T>(id);
5728  }
5729  template <typename T>
5730  static inline T* performanceTrackingCallback(const std::string& id) {
5731  return ELPP->performanceTrackingCallback<T>(id);
5732  }
5734  template <typename T>
5735  static std::string convertTemplateToStdString(const T& templ) {
5736  el::Logger* logger =
5737  ELPP->registeredLoggers()->get(el::base::consts::kDefaultLoggerId);
5738  if (logger == nullptr) {
5739  return std::string();
5740  }
5742  b.initialize(logger);
5743  logger->acquireLock();
5744  b << templ;
5745 #if defined(ELPP_UNICODE)
5746  std::string s = std::string(logger->stream().str().begin(), logger->stream().str().end());
5747 #else
5748  std::string s = logger->stream().str();
5749 #endif // defined(ELPP_UNICODE)
5750  logger->stream().str(ELPP_LITERAL(""));
5751  logger->releaseLock();
5752  return s;
5753  }
5756  return ELPP->commandLineArgs();
5757  }
5759  static inline void installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier) {
5760  ELPP->installCustomFormatSpecifier(customFormatSpecifier);
5761  }
5763  static inline bool uninstallCustomFormatSpecifier(const char* formatSpecifier) {
5764  return ELPP->uninstallCustomFormatSpecifier(formatSpecifier);
5765  }
5767  static inline bool hasCustomFormatSpecifier(const char* formatSpecifier) {
5768  return ELPP->hasCustomFormatSpecifier(formatSpecifier);
5769  }
5770  static inline void validateFileRolling(Logger* logger, Level level) {
5771  if (logger == nullptr) return;
5772  logger->m_typedConfigurations->validateFileRolling(level, ELPP->preRollOutCallback());
5773  }
5774 };
5777 public:
5779  static inline Logger* getLogger(const std::string& identity, bool registerIfNotAvailable = true) {
5780  base::threading::ScopedLock scopedLock(ELPP->lock());
5781  return ELPP->registeredLoggers()->get(identity, registerIfNotAvailable);
5782  }
5785  static inline bool unregisterLogger(const std::string& identity) {
5786  base::threading::ScopedLock scopedLock(ELPP->lock());
5787  return ELPP->registeredLoggers()->remove(identity);
5788  }
5790  static inline bool hasLogger(const std::string& identity) {
5791  base::threading::ScopedLock scopedLock(ELPP->lock());
5792  return ELPP->registeredLoggers()->has(identity);
5793  }
5795  static inline Logger* reconfigureLogger(Logger* logger, const Configurations& configurations) {
5796  if (!logger) return nullptr;
5797  logger->configure(configurations);
5798  return logger;
5799  }
5801  static inline Logger* reconfigureLogger(const std::string& identity, const Configurations& configurations) {
5802  return Loggers::reconfigureLogger(Loggers::getLogger(identity), configurations);
5803  }
5805  static inline Logger* reconfigureLogger(const std::string& identity, ConfigurationType configurationType,
5806  const std::string& value) {
5807  Logger* logger = Loggers::getLogger(identity);
5808  if (logger == nullptr) {
5809  return nullptr;
5810  }
5811  logger->configurations()->set(Level::Global, configurationType, value);
5812  logger->reconfigure();
5813  return logger;
5814  }
5816  static inline void reconfigureAllLoggers(const Configurations& configurations) {
5817  for (base::RegisteredLoggers::iterator it = ELPP->registeredLoggers()->begin();
5818  it != ELPP->registeredLoggers()->end(); ++it) {
5819  Loggers::reconfigureLogger(it->second, configurations);
5820  }
5821  }
5823  static inline void reconfigureAllLoggers(ConfigurationType configurationType, const std::string& value) {
5824  reconfigureAllLoggers(Level::Global, configurationType, value);
5825  }
5827  static inline void reconfigureAllLoggers(Level level, ConfigurationType configurationType,
5828  const std::string& value) {
5829  for (base::RegisteredLoggers::iterator it = ELPP->registeredLoggers()->begin();
5830  it != ELPP->registeredLoggers()->end(); ++it) {
5831  Logger* logger = it->second;
5832  logger->configurations()->set(level, configurationType, value);
5833  logger->reconfigure();
5834  }
5835  }
5837  static inline void setDefaultConfigurations(const Configurations& configurations, bool reconfigureExistingLoggers = false) {
5838  ELPP->registeredLoggers()->setDefaultConfigurations(configurations);
5839  if (reconfigureExistingLoggers) {
5840  Loggers::reconfigureAllLoggers(configurations);
5841  }
5842  }
5844  static inline const Configurations* defaultConfigurations(void) {
5845  return ELPP->registeredLoggers()->defaultConfigurations();
5846  }
5849  return ELPP->registeredLoggers()->logStreamsReference();
5850  }
5854  ELPP->registeredLoggers()->defaultConfigurations(),
5855  ELPP->registeredLoggers()->logStreamsReference());
5856  }
5859  static inline std::vector<std::string>* populateAllLoggerIds(std::vector<std::string>* targetList) {
5860  targetList->clear();
5861  for (base::RegisteredLoggers::iterator it = ELPP->registeredLoggers()->list().begin();
5862  it != ELPP->registeredLoggers()->list().end(); ++it) {
5863  targetList->push_back(it->first);
5864  }
5865  return targetList;
5866  }
5868  static void configureFromGlobal(const char* globalConfigurationFilePath) {
5869  std::ifstream gcfStream(globalConfigurationFilePath, std::ifstream::in);
5870  ELPP_ASSERT(gcfStream.is_open(), "Unable to open global configuration file [" << globalConfigurationFilePath
5871  << "] for parsing.");
5872  std::string line = std::string();
5873  std::stringstream ss;
5874  Logger* logger = nullptr;
5875  auto configure = [&](void) {
5876  ELPP_INTERNAL_INFO(8, "Configuring logger: '" << logger->id() << "' with configurations \n" << ss.str()
5877  << "\n--------------");
5878  Configurations c;
5879  c.parseFromText(ss.str());
5880  logger->configure(c);
5881  };
5882  while (gcfStream.good()) {
5883  std::getline(gcfStream, line);
5884  ELPP_INTERNAL_INFO(1, "Parsing line: " << line);
5885  base::utils::Str::trim(line);
5886  if (Configurations::Parser::isComment(line)) continue;
5887  Configurations::Parser::ignoreComments(&line);
5888  base::utils::Str::trim(line);
5889  if (line.size() > 2 && base::utils::Str::startsWith(line, std::string(base::consts::kConfigurationLoggerId))) {
5890  if (!ss.str().empty() && logger != nullptr) {
5891  configure();
5892  }
5893  ss.str(std::string(""));
5894  line = line.substr(2);
5895  base::utils::Str::trim(line);
5896  if (line.size() > 1) {
5897  ELPP_INTERNAL_INFO(1, "Getting logger: '" << line << "'");
5898  logger = getLogger(line);
5899  }
5900  } else {
5901  ss << line << "\n";
5902  }
5903  }
5904  if (!ss.str().empty() && logger != nullptr) {
5905  configure();
5906  }
5907  }
5912  static inline bool configureFromArg(const char* argKey) {
5913 #if defined(ELPP_DISABLE_CONFIGURATION_FROM_PROGRAM_ARGS)
5914  ELPP_UNUSED(argKey);
5915 #else
5916  if (!Helpers::commandLineArgs()->hasParamWithValue(argKey)) {
5917  return false;
5918  }
5919  configureFromGlobal(Helpers::commandLineArgs()->getParamValue(argKey));
5920 #endif // defined(ELPP_DISABLE_CONFIGURATION_FROM_PROGRAM_ARGS)
5921  return true;
5922  }
5924  static inline void flushAll(void) {
5925  ELPP->registeredLoggers()->flushAll();
5926  }
5928  static inline void addFlag(LoggingFlag flag) {
5929  ELPP->addFlag(flag);
5930  }
5932  static inline void removeFlag(LoggingFlag flag) {
5933  ELPP->removeFlag(flag);
5934  }
5936  static inline bool hasFlag(LoggingFlag flag) {
5937  return ELPP->hasFlag(flag);
5938  }
5941  public:
5942  ScopedAddFlag(LoggingFlag flag) : m_flag(flag) { Loggers::addFlag(m_flag); }
5944  private:
5945  LoggingFlag m_flag;
5946  };
5949  public:
5950  ScopedRemoveFlag(LoggingFlag flag) : m_flag(flag) { Loggers::removeFlag(m_flag); }
5952  private:
5953  LoggingFlag m_flag;
5954  };
5956  static inline void setLoggingLevel(Level level) {
5957  ELPP->setLoggingLevel(level);
5958  }
5960  static inline void setVerboseLevel(base::type::VerboseLevel level) {
5961  ELPP->vRegistry()->setLevel(level);
5962  }
5965  return ELPP->vRegistry()->level();
5966  }
5968  static inline void setVModules(const char* modules) {
5969  if (ELPP->vRegistry()->vModulesEnabled()) {
5970  ELPP->vRegistry()->setModules(modules);
5971  }
5972  }
5974  static inline void clearVModules(void) {
5975  ELPP->vRegistry()->clearModules();
5976  }
5977 };
5979 public:
5981  static inline const std::string version(void) { return std::string("9.80"); }
5983  static inline const std::string releaseDate(void) { return std::string("08-01-2015 0850hrs"); }
5984 };
5985 } // namespace el
5986 #undef VLOG_IS_ON
5987 #define VLOG_IS_ON(verboseLevel) (ELPP->vRegistry()->allowed(verboseLevel, __FILE__))
5989 #undef TIMED_BLOCK
5990 #undef TIMED_SCOPE
5991 #undef TIMED_FUNC
5992 #undef ELPP_MIN_UNIT
5993 #if defined(ELPP_PERFORMANCE_MICROSECONDS)
5994 # define ELPP_MIN_UNIT el::base::TimestampUnit::Microsecond
5995 #else
5996 # define ELPP_MIN_UNIT el::base::TimestampUnit::Millisecond
5997 #endif // (defined(ELPP_PERFORMANCE_MICROSECONDS))
5998 // Note: Do not surround this definition with null macro because of obj instance
6005 #define TIMED_SCOPE(obj, blockname) el::base::PerformanceTracker obj(blockname, ELPP_MIN_UNIT)
6006 #define TIMED_BLOCK(obj, blockName) for (struct { int i; el::base::PerformanceTracker timer; } obj = { 0, \
6007  el::base::PerformanceTracker(blockName, ELPP_MIN_UNIT) }; obj.i < 1; ++obj.i)
6008 #define TIMED_FUNC(obj) TIMED_SCOPE(obj, ELPP_FUNC)
6015 #undef PERFORMANCE_CHECKPOINT
6016 #undef PERFORMANCE_CHECKPOINT_WITH_ID
6017 #define PERFORMANCE_CHECKPOINT(obj) obj.checkpoint(std::string(), __FILE__, __LINE__, ELPP_FUNC)
6018 #define PERFORMANCE_CHECKPOINT_WITH_ID(obj, id) obj.checkpoint(id, __FILE__, __LINE__, ELPP_FUNC)
6019 #undef ELPP_COUNTER
6020 #undef ELPP_COUNTER_POS
6021 #define ELPP_COUNTER (ELPP->hitCounters()->getCounter(__FILE__, __LINE__))
6023 #define ELPP_COUNTER_POS (ELPP_COUNTER == nullptr ? -1 : ELPP_COUNTER->hitCounts())
6025 // Undef levels to support LOG(LEVEL)
6026 #undef INFO
6027 #undef WARNING
6028 #undef DEBUG
6029 #undef ERROR
6030 #undef FATAL
6031 #undef TRACE
6032 #undef VERBOSE
6033 // Undef existing
6034 #undef CINFO
6035 #undef CWARNING
6036 #undef CDEBUG
6037 #undef CFATAL
6038 #undef CERROR
6039 #undef CTRACE
6040 #undef CVERBOSE
6041 #undef CINFO_IF
6042 #undef CWARNING_IF
6043 #undef CDEBUG_IF
6044 #undef CERROR_IF
6045 #undef CFATAL_IF
6046 #undef CTRACE_IF
6047 #undef CVERBOSE_IF
6048 #undef CINFO_EVERY_N
6049 #undef CWARNING_EVERY_N
6050 #undef CDEBUG_EVERY_N
6051 #undef CERROR_EVERY_N
6052 #undef CFATAL_EVERY_N
6053 #undef CTRACE_EVERY_N
6054 #undef CVERBOSE_EVERY_N
6055 #undef CINFO_AFTER_N
6056 #undef CWARNING_AFTER_N
6057 #undef CDEBUG_AFTER_N
6058 #undef CERROR_AFTER_N
6059 #undef CFATAL_AFTER_N
6060 #undef CTRACE_AFTER_N
6061 #undef CVERBOSE_AFTER_N
6062 #undef CINFO_N_TIMES
6063 #undef CWARNING_N_TIMES
6064 #undef CDEBUG_N_TIMES
6065 #undef CERROR_N_TIMES
6066 #undef CFATAL_N_TIMES
6067 #undef CTRACE_N_TIMES
6068 #undef CVERBOSE_N_TIMES
6069 // Normal logs
6070 #if ELPP_INFO_LOG
6071 # define CINFO(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Info, dispatchAction, __VA_ARGS__)
6072 #else
6073 # define CINFO(writer, dispatchAction, ...) el::base::NullWriter()
6074 #endif // ELPP_INFO_LOG
6075 #if ELPP_WARNING_LOG
6076 # define CWARNING(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Warning, dispatchAction, __VA_ARGS__)
6077 #else
6078 # define CWARNING(writer, dispatchAction, ...) el::base::NullWriter()
6079 #endif // ELPP_WARNING_LOG
6080 #if ELPP_DEBUG_LOG
6081 # define CDEBUG(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Debug, dispatchAction, __VA_ARGS__)
6082 #else
6083 # define CDEBUG(writer, dispatchAction, ...) el::base::NullWriter()
6084 #endif // ELPP_DEBUG_LOG
6085 #if ELPP_ERROR_LOG
6086 # define CERROR(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Error, dispatchAction, __VA_ARGS__)
6087 #else
6088 # define CERROR(writer, dispatchAction, ...) el::base::NullWriter()
6089 #endif // ELPP_ERROR_LOG
6090 #if ELPP_FATAL_LOG
6091 # define CFATAL(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Fatal, dispatchAction, __VA_ARGS__)
6092 #else
6093 # define CFATAL(writer, dispatchAction, ...) el::base::NullWriter()
6094 #endif // ELPP_FATAL_LOG
6095 #if ELPP_TRACE_LOG
6096 # define CTRACE(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Trace, dispatchAction, __VA_ARGS__)
6097 #else
6098 # define CTRACE(writer, dispatchAction, ...) el::base::NullWriter()
6099 #endif // ELPP_TRACE_LOG
6100 #if ELPP_VERBOSE_LOG
6101 # define CVERBOSE(writer, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel)) writer(\
6102  el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
6103 #else
6104 # define CVERBOSE(writer, vlevel, dispatchAction, ...) el::base::NullWriter()
6105 #endif // ELPP_VERBOSE_LOG
6106 // Conditional logs
6107 #if ELPP_INFO_LOG
6108 # define CINFO_IF(writer, condition_, dispatchAction, ...) \
6109  ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Info, dispatchAction, __VA_ARGS__)
6110 #else
6111 # define CINFO_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
6112 #endif // ELPP_INFO_LOG
6113 #if ELPP_WARNING_LOG
6114 # define CWARNING_IF(writer, condition_, dispatchAction, ...)\
6115  ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Warning, dispatchAction, __VA_ARGS__)
6116 #else
6117 # define CWARNING_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
6118 #endif // ELPP_WARNING_LOG
6119 #if ELPP_DEBUG_LOG
6120 # define CDEBUG_IF(writer, condition_, dispatchAction, ...)\
6121  ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Debug, dispatchAction, __VA_ARGS__)
6122 #else
6123 # define CDEBUG_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
6124 #endif // ELPP_DEBUG_LOG
6125 #if ELPP_ERROR_LOG
6126 # define CERROR_IF(writer, condition_, dispatchAction, ...)\
6127  ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Error, dispatchAction, __VA_ARGS__)
6128 #else
6129 # define CERROR_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
6130 #endif // ELPP_ERROR_LOG
6131 #if ELPP_FATAL_LOG
6132 # define CFATAL_IF(writer, condition_, dispatchAction, ...)\
6133  ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Fatal, dispatchAction, __VA_ARGS__)
6134 #else
6135 # define CFATAL_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
6136 #endif // ELPP_FATAL_LOG
6137 #if ELPP_TRACE_LOG
6138 # define CTRACE_IF(writer, condition_, dispatchAction, ...)\
6139  ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Trace, dispatchAction, __VA_ARGS__)
6140 #else
6141 # define CTRACE_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
6142 #endif // ELPP_TRACE_LOG
6143 #if ELPP_VERBOSE_LOG
6144 # define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel) && (condition_)) writer( \
6145  el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
6146 #else
6147 # define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) el::base::NullWriter()
6148 #endif // ELPP_VERBOSE_LOG
6149 // Occasional logs
6150 #if ELPP_INFO_LOG
6151 # define CINFO_EVERY_N(writer, occasion, dispatchAction, ...)\
6152  ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Info, dispatchAction, __VA_ARGS__)
6153 #else
6154 # define CINFO_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
6155 #endif // ELPP_INFO_LOG
6156 #if ELPP_WARNING_LOG
6157 # define CWARNING_EVERY_N(writer, occasion, dispatchAction, ...)\
6158  ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Warning, dispatchAction, __VA_ARGS__)
6159 #else
6160 # define CWARNING_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
6161 #endif // ELPP_WARNING_LOG
6162 #if ELPP_DEBUG_LOG
6163 # define CDEBUG_EVERY_N(writer, occasion, dispatchAction, ...)\
6164  ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Debug, dispatchAction, __VA_ARGS__)
6165 #else
6166 # define CDEBUG_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
6167 #endif // ELPP_DEBUG_LOG
6168 #if ELPP_ERROR_LOG
6169 # define CERROR_EVERY_N(writer, occasion, dispatchAction, ...)\
6170  ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Error, dispatchAction, __VA_ARGS__)
6171 #else
6172 # define CERROR_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
6173 #endif // ELPP_ERROR_LOG
6174 #if ELPP_FATAL_LOG
6175 # define CFATAL_EVERY_N(writer, occasion, dispatchAction, ...)\
6176  ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Fatal, dispatchAction, __VA_ARGS__)
6177 #else
6178 # define CFATAL_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
6179 #endif // ELPP_FATAL_LOG
6180 #if ELPP_TRACE_LOG
6181 # define CTRACE_EVERY_N(writer, occasion, dispatchAction, ...)\
6182  ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Trace, dispatchAction, __VA_ARGS__)
6183 #else
6184 # define CTRACE_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
6185 #endif // ELPP_TRACE_LOG
6186 #if ELPP_VERBOSE_LOG
6187 # define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...)\
6188  CVERBOSE_IF(writer, ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion), vlevel, dispatchAction, __VA_ARGS__)
6189 #else
6190 # define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...) el::base::NullWriter()
6191 #endif // ELPP_VERBOSE_LOG
6192 // After N logs
6193 #if ELPP_INFO_LOG
6194 # define CINFO_AFTER_N(writer, n, dispatchAction, ...)\
6195  ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Info, dispatchAction, __VA_ARGS__)
6196 #else
6197 # define CINFO_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
6198 #endif // ELPP_INFO_LOG
6199 #if ELPP_WARNING_LOG
6200 # define CWARNING_AFTER_N(writer, n, dispatchAction, ...)\
6201  ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Warning, dispatchAction, __VA_ARGS__)
6202 #else
6203 # define CWARNING_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
6204 #endif // ELPP_WARNING_LOG
6205 #if ELPP_DEBUG_LOG
6206 # define CDEBUG_AFTER_N(writer, n, dispatchAction, ...)\
6207  ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Debug, dispatchAction, __VA_ARGS__)
6208 #else
6209 # define CDEBUG_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
6210 #endif // ELPP_DEBUG_LOG
6211 #if ELPP_ERROR_LOG
6212 # define CERROR_AFTER_N(writer, n, dispatchAction, ...)\
6213  ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Error, dispatchAction, __VA_ARGS__)
6214 #else
6215 # define CERROR_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
6216 #endif // ELPP_ERROR_LOG
6217 #if ELPP_FATAL_LOG
6218 # define CFATAL_AFTER_N(writer, n, dispatchAction, ...)\
6219  ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Fatal, dispatchAction, __VA_ARGS__)
6220 #else
6221 # define CFATAL_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
6222 #endif // ELPP_FATAL_LOG
6223 #if ELPP_TRACE_LOG
6224 # define CTRACE_AFTER_N(writer, n, dispatchAction, ...)\
6225  ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Trace, dispatchAction, __VA_ARGS__)
6226 #else
6227 # define CTRACE_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
6228 #endif // ELPP_TRACE_LOG
6229 #if ELPP_VERBOSE_LOG
6230 # define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...)\
6231  CVERBOSE_IF(writer, ELPP->validateAfterNCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__)
6232 #else
6233 # define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter()
6234 #endif // ELPP_VERBOSE_LOG
6235 // N Times logs
6236 #if ELPP_INFO_LOG
6237 # define CINFO_N_TIMES(writer, n, dispatchAction, ...)\
6238  ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Info, dispatchAction, __VA_ARGS__)
6239 #else
6240 # define CINFO_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
6241 #endif // ELPP_INFO_LOG
6242 #if ELPP_WARNING_LOG
6243 # define CWARNING_N_TIMES(writer, n, dispatchAction, ...)\
6244  ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Warning, dispatchAction, __VA_ARGS__)
6245 #else
6246 # define CWARNING_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
6247 #endif // ELPP_WARNING_LOG
6248 #if ELPP_DEBUG_LOG
6249 # define CDEBUG_N_TIMES(writer, n, dispatchAction, ...)\
6250  ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Debug, dispatchAction, __VA_ARGS__)
6251 #else
6252 # define CDEBUG_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
6253 #endif // ELPP_DEBUG_LOG
6254 #if ELPP_ERROR_LOG
6255 # define CERROR_N_TIMES(writer, n, dispatchAction, ...)\
6256  ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Error, dispatchAction, __VA_ARGS__)
6257 #else
6258 # define CERROR_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
6259 #endif // ELPP_ERROR_LOG
6260 #if ELPP_FATAL_LOG
6261 # define CFATAL_N_TIMES(writer, n, dispatchAction, ...)\
6262  ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Fatal, dispatchAction, __VA_ARGS__)
6263 #else
6264 # define CFATAL_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
6265 #endif // ELPP_FATAL_LOG
6266 #if ELPP_TRACE_LOG
6267 # define CTRACE_N_TIMES(writer, n, dispatchAction, ...)\
6268  ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Trace, dispatchAction, __VA_ARGS__)
6269 #else
6270 # define CTRACE_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
6271 #endif // ELPP_TRACE_LOG
6272 #if ELPP_VERBOSE_LOG
6273 # define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...)\
6274  CVERBOSE_IF(writer, ELPP->validateNTimesCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__)
6275 #else
6276 # define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter()
6277 #endif // ELPP_VERBOSE_LOG
6278 //
6279 // Custom Loggers - Requires (level, dispatchAction, loggerId/s)
6280 //
6281 // undef existing
6282 #undef CLOG
6283 #undef CLOG_VERBOSE
6284 #undef CVLOG
6285 #undef CLOG_IF
6286 #undef CLOG_VERBOSE_IF
6287 #undef CVLOG_IF
6288 #undef CLOG_EVERY_N
6289 #undef CVLOG_EVERY_N
6290 #undef CLOG_AFTER_N
6291 #undef CVLOG_AFTER_N
6292 #undef CLOG_N_TIMES
6293 #undef CVLOG_N_TIMES
6294 // Normal logs
6295 #define CLOG(LEVEL, ...)\
6296  C##LEVEL(el::base::Writer, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6297 #define CVLOG(vlevel, ...) CVERBOSE(el::base::Writer, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6298 // Conditional logs
6299 #define CLOG_IF(condition, LEVEL, ...)\
6300  C##LEVEL##_IF(el::base::Writer, condition, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6301 #define CVLOG_IF(condition, vlevel, ...)\
6302  CVERBOSE_IF(el::base::Writer, condition, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6303 // Hit counts based logs
6304 #define CLOG_EVERY_N(n, LEVEL, ...)\
6305  C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6306 #define CVLOG_EVERY_N(n, vlevel, ...)\
6307  CVERBOSE_EVERY_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6308 #define CLOG_AFTER_N(n, LEVEL, ...)\
6309  C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6310 #define CVLOG_AFTER_N(n, vlevel, ...)\
6311  CVERBOSE_AFTER_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6312 #define CLOG_N_TIMES(n, LEVEL, ...)\
6313  C##LEVEL##_N_TIMES(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6314 #define CVLOG_N_TIMES(n, vlevel, ...)\
6315  CVERBOSE_N_TIMES(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6316 //
6317 // Default Loggers macro using CLOG(), CLOG_VERBOSE() and CVLOG() macros
6318 //
6319 // undef existing
6320 #undef LOG
6321 #undef VLOG
6322 #undef LOG_IF
6323 #undef VLOG_IF
6324 #undef LOG_EVERY_N
6325 #undef VLOG_EVERY_N
6326 #undef LOG_AFTER_N
6327 #undef VLOG_AFTER_N
6328 #undef LOG_N_TIMES
6329 #undef VLOG_N_TIMES
6330 #undef ELPP_CURR_FILE_LOGGER_ID
6331 #if defined(ELPP_DEFAULT_LOGGER)
6332 # define ELPP_CURR_FILE_LOGGER_ID ELPP_DEFAULT_LOGGER
6333 #else
6334 # define ELPP_CURR_FILE_LOGGER_ID el::base::consts::kDefaultLoggerId
6335 #endif
6336 #undef ELPP_TRACE
6337 #define ELPP_TRACE CLOG(TRACE, ELPP_CURR_FILE_LOGGER_ID)
6338 // Normal logs
6339 #define LOG(LEVEL) CLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6340 #define VLOG(vlevel) CVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID)
6341 // Conditional logs
6342 #define LOG_IF(condition, LEVEL) CLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6343 #define VLOG_IF(condition, vlevel) CVLOG_IF(condition, vlevel, ELPP_CURR_FILE_LOGGER_ID)
6344 // Hit counts based logs
6345 #define LOG_EVERY_N(n, LEVEL) CLOG_EVERY_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6346 #define VLOG_EVERY_N(n, vlevel) CVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
6347 #define LOG_AFTER_N(n, LEVEL) CLOG_AFTER_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6348 #define VLOG_AFTER_N(n, vlevel) CVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
6349 #define LOG_N_TIMES(n, LEVEL) CLOG_N_TIMES(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6350 #define VLOG_N_TIMES(n, vlevel) CVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
6351 // Generic PLOG()
6352 #undef CPLOG
6353 #undef CPLOG_IF
6354 #undef PLOG
6355 #undef PLOG_IF
6356 #undef DCPLOG
6357 #undef DCPLOG_IF
6358 #undef DPLOG
6359 #undef DPLOG_IF
6360 #define CPLOG(LEVEL, ...)\
6361  C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6362 #define CPLOG_IF(condition, LEVEL, ...)\
6363  C##LEVEL##_IF(el::base::PErrorWriter, condition, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6364 #define DCPLOG(LEVEL, ...)\
6365  if (ELPP_DEBUG_LOG) C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__)
6366 #define DCPLOG_IF(condition, LEVEL, ...)\
6367  C##LEVEL##_IF(el::base::PErrorWriter, (ELPP_DEBUG_LOG) && (condition), el::base::DispatchAction::NormalLog, __VA_ARGS__)
6368 #define PLOG(LEVEL) CPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6369 #define PLOG_IF(condition, LEVEL) CPLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6370 #define DPLOG(LEVEL) DCPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6371 #define DPLOG_IF(condition, LEVEL) DCPLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6372 // Generic SYSLOG()
6373 #undef CSYSLOG
6374 #undef CSYSLOG_IF
6375 #undef CSYSLOG_EVERY_N
6376 #undef CSYSLOG_AFTER_N
6377 #undef CSYSLOG_N_TIMES
6378 #undef SYSLOG
6379 #undef SYSLOG_IF
6380 #undef SYSLOG_EVERY_N
6381 #undef SYSLOG_AFTER_N
6382 #undef SYSLOG_N_TIMES
6383 #undef DCSYSLOG
6384 #undef DCSYSLOG_IF
6385 #undef DCSYSLOG_EVERY_N
6386 #undef DCSYSLOG_AFTER_N
6387 #undef DCSYSLOG_N_TIMES
6388 #undef DSYSLOG
6389 #undef DSYSLOG_IF
6390 #undef DSYSLOG_EVERY_N
6391 #undef DSYSLOG_AFTER_N
6392 #undef DSYSLOG_N_TIMES
6393 #if defined(ELPP_SYSLOG)
6394 # define CSYSLOG(LEVEL, ...)\
6395  C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__)
6396 # define CSYSLOG_IF(condition, LEVEL, ...)\
6397  C##LEVEL##_IF(el::base::Writer, condition, el::base::DispatchAction::SysLog, __VA_ARGS__)
6398 # define CSYSLOG_EVERY_N(n, LEVEL, ...) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
6399 # define CSYSLOG_AFTER_N(n, LEVEL, ...) C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
6400 # define CSYSLOG_N_TIMES(n, LEVEL, ...) C##LEVEL##_N_TIMES(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
6401 # define SYSLOG(LEVEL) CSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId)
6402 # define SYSLOG_IF(condition, LEVEL) CSYSLOG_IF(condition, LEVEL, el::base::consts::kSysLogLoggerId)
6403 # define SYSLOG_EVERY_N(n, LEVEL) CSYSLOG_EVERY_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
6404 # define SYSLOG_AFTER_N(n, LEVEL) CSYSLOG_AFTER_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
6405 # define SYSLOG_N_TIMES(n, LEVEL) CSYSLOG_N_TIMES(n, LEVEL, el::base::consts::kSysLogLoggerId)
6406 # define DCSYSLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__)
6407 # define DCSYSLOG_IF(condition, LEVEL, ...)\
6408  C##LEVEL##_IF(el::base::Writer, (ELPP_DEBUG_LOG) && (condition), el::base::DispatchAction::SysLog, __VA_ARGS__)
6409 # define DCSYSLOG_EVERY_N(n, LEVEL, ...)\
6410  if (ELPP_DEBUG_LOG) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
6411 # define DCSYSLOG_AFTER_N(n, LEVEL, ...)\
6412  if (ELPP_DEBUG_LOG) C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
6413 # define DCSYSLOG_N_TIMES(n, LEVEL, ...)\
6414  if (ELPP_DEBUG_LOG) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
6415 # define DSYSLOG(LEVEL) DCSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId)
6416 # define DSYSLOG_IF(condition, LEVEL) DCSYSLOG_IF(condition, LEVEL, el::base::consts::kSysLogLoggerId)
6417 # define DSYSLOG_EVERY_N(n, LEVEL) DCSYSLOG_EVERY_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
6418 # define DSYSLOG_AFTER_N(n, LEVEL) DCSYSLOG_AFTER_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
6419 # define DSYSLOG_N_TIMES(n, LEVEL) DCSYSLOG_N_TIMES(n, LEVEL, el::base::consts::kSysLogLoggerId)
6420 #else
6421 # define CSYSLOG(LEVEL, ...) el::base::NullWriter()
6422 # define CSYSLOG_IF(condition, LEVEL, ...) el::base::NullWriter()
6423 # define CSYSLOG_EVERY_N(n, LEVEL, ...) el::base::NullWriter()
6424 # define CSYSLOG_AFTER_N(n, LEVEL, ...) el::base::NullWriter()
6425 # define CSYSLOG_N_TIMES(n, LEVEL, ...) el::base::NullWriter()
6426 # define SYSLOG(LEVEL) el::base::NullWriter()
6427 # define SYSLOG_IF(condition, LEVEL) el::base::NullWriter()
6428 # define SYSLOG_EVERY_N(n, LEVEL) el::base::NullWriter()
6429 # define SYSLOG_AFTER_N(n, LEVEL) el::base::NullWriter()
6430 # define SYSLOG_N_TIMES(n, LEVEL) el::base::NullWriter()
6431 # define DCSYSLOG(LEVEL, ...) el::base::NullWriter()
6432 # define DCSYSLOG_IF(condition, LEVEL, ...) el::base::NullWriter()
6433 # define DCSYSLOG_EVERY_N(n, LEVEL, ...) el::base::NullWriter()
6434 # define DCSYSLOG_AFTER_N(n, LEVEL, ...) el::base::NullWriter()
6435 # define DCSYSLOG_N_TIMES(n, LEVEL, ...) el::base::NullWriter()
6436 # define DSYSLOG(LEVEL) el::base::NullWriter()
6437 # define DSYSLOG_IF(condition, LEVEL) el::base::NullWriter()
6438 # define DSYSLOG_EVERY_N(n, LEVEL) el::base::NullWriter()
6439 # define DSYSLOG_AFTER_N(n, LEVEL) el::base::NullWriter()
6440 # define DSYSLOG_N_TIMES(n, LEVEL) el::base::NullWriter()
6441 #endif // defined(ELPP_SYSLOG)
6442 //
6443 // Custom Debug Only Loggers - Requires (level, loggerId/s)
6444 //
6445 // undef existing
6446 #undef DCLOG
6447 #undef DCVLOG
6448 #undef DCLOG_IF
6449 #undef DCVLOG_IF
6450 #undef DCLOG_EVERY_N
6451 #undef DCVLOG_EVERY_N
6452 #undef DCLOG_AFTER_N
6453 #undef DCVLOG_AFTER_N
6454 #undef DCLOG_N_TIMES
6455 #undef DCVLOG_N_TIMES
6456 // Normal logs
6457 #define DCLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG(LEVEL, __VA_ARGS__)
6458 #define DCLOG_VERBOSE(vlevel, ...) if (ELPP_DEBUG_LOG) CLOG_VERBOSE(vlevel, __VA_ARGS__)
6459 #define DCVLOG(vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG(vlevel, __VA_ARGS__)
6460 // Conditional logs
6461 #define DCLOG_IF(condition, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_IF(condition, LEVEL, __VA_ARGS__)
6462 #define DCVLOG_IF(condition, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_IF(condition, vlevel, __VA_ARGS__)
6463 // Hit counts based logs
6464 #define DCLOG_EVERY_N(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_EVERY_N(n, LEVEL, __VA_ARGS__)
6465 #define DCVLOG_EVERY_N(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_EVERY_N(n, vlevel, __VA_ARGS__)
6466 #define DCLOG_AFTER_N(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_AFTER_N(n, LEVEL, __VA_ARGS__)
6467 #define DCVLOG_AFTER_N(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_AFTER_N(n, vlevel, __VA_ARGS__)
6468 #define DCLOG_N_TIMES(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_N_TIMES(n, LEVEL, __VA_ARGS__)
6469 #define DCVLOG_N_TIMES(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_N_TIMES(n, vlevel, __VA_ARGS__)
6470 //
6471 // Default Debug Only Loggers macro using CLOG(), CLOG_VERBOSE() and CVLOG() macros
6472 //
6473 // undef existing
6474 #undef DLOG
6475 #undef DVLOG
6476 #undef DLOG_IF
6477 #undef DVLOG_IF
6478 #undef DLOG_EVERY_N
6479 #undef DVLOG_EVERY_N
6480 #undef DLOG_AFTER_N
6481 #undef DVLOG_AFTER_N
6482 #undef DLOG_N_TIMES
6483 #undef DVLOG_N_TIMES
6484 // Normal logs
6485 #define DLOG(LEVEL) DCLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6486 #define DVLOG(vlevel) DCVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID)
6487 // Conditional logs
6488 #define DLOG_IF(condition, LEVEL) DCLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6489 #define DVLOG_IF(condition, vlevel) DCVLOG_IF(condition, vlevel, ELPP_CURR_FILE_LOGGER_ID)
6490 // Hit counts based logs
6491 #define DLOG_EVERY_N(n, LEVEL) DCLOG_EVERY_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6492 #define DVLOG_EVERY_N(n, vlevel) DCVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
6493 #define DLOG_AFTER_N(n, LEVEL) DCLOG_AFTER_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6494 #define DVLOG_AFTER_N(n, vlevel) DCVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
6495 #define DLOG_N_TIMES(n, LEVEL) DCLOG_N_TIMES(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
6496 #define DVLOG_N_TIMES(n, vlevel) DCVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
6497 // Check macros
6498 #undef CCHECK
6499 #undef CPCHECK
6500 #undef CCHECK_EQ
6501 #undef CCHECK_NE
6502 #undef CCHECK_LT
6503 #undef CCHECK_GT
6504 #undef CCHECK_LE
6505 #undef CCHECK_GE
6506 #undef CCHECK_BOUNDS
6507 #undef CCHECK_NOTNULL
6508 #undef CCHECK_STRCASEEQ
6509 #undef CCHECK_STRCASENE
6510 #undef CHECK
6511 #undef PCHECK
6512 #undef CHECK_EQ
6513 #undef CHECK_NE
6514 #undef CHECK_LT
6515 #undef CHECK_GT
6516 #undef CHECK_LE
6517 #undef CHECK_GE
6518 #undef CHECK_BOUNDS
6519 #undef CHECK_NOTNULL
6520 #undef CHECK_STRCASEEQ
6521 #undef CHECK_STRCASENE
6522 #define CCHECK(condition, ...) CLOG_IF(!(condition), FATAL, __VA_ARGS__) << "Check failed: [" << #condition << "] "
6523 #define CPCHECK(condition, ...) CPLOG_IF(!(condition), FATAL, __VA_ARGS__) << "Check failed: [" << #condition << "] "
6524 #define CHECK(condition) CCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
6525 #define PCHECK(condition) CPCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
6526 #define CCHECK_EQ(a, b, ...) CCHECK(a == b, __VA_ARGS__)
6527 #define CCHECK_NE(a, b, ...) CCHECK(a != b, __VA_ARGS__)
6528 #define CCHECK_LT(a, b, ...) CCHECK(a < b, __VA_ARGS__)
6529 #define CCHECK_GT(a, b, ...) CCHECK(a > b, __VA_ARGS__)
6530 #define CCHECK_LE(a, b, ...) CCHECK(a <= b, __VA_ARGS__)
6531 #define CCHECK_GE(a, b, ...) CCHECK(a >= b, __VA_ARGS__)
6532 #define CCHECK_BOUNDS(val, min, max, ...) CCHECK(val >= min && val <= max, __VA_ARGS__)
6533 #define CHECK_EQ(a, b) CCHECK_EQ(a, b, ELPP_CURR_FILE_LOGGER_ID)
6534 #define CHECK_NE(a, b) CCHECK_NE(a, b, ELPP_CURR_FILE_LOGGER_ID)
6535 #define CHECK_LT(a, b) CCHECK_LT(a, b, ELPP_CURR_FILE_LOGGER_ID)
6536 #define CHECK_GT(a, b) CCHECK_GT(a, b, ELPP_CURR_FILE_LOGGER_ID)
6537 #define CHECK_LE(a, b) CCHECK_LE(a, b, ELPP_CURR_FILE_LOGGER_ID)
6538 #define CHECK_GE(a, b) CCHECK_GE(a, b, ELPP_CURR_FILE_LOGGER_ID)
6539 #define CHECK_BOUNDS(val, min, max) CCHECK_BOUNDS(val, min, max, ELPP_CURR_FILE_LOGGER_ID)
6540 namespace el {
6541 namespace base {
6542 namespace utils {
6543 template <typename T>
6544 static T* checkNotNull(T* ptr, const char* name, const char* loggers, ...) {
6545  CLOG_IF(ptr == nullptr, FATAL, loggers) << "Check failed: [" << name << " != nullptr]";
6546  return ptr;
6547 }
6548 } // namespace utils
6549 } // namespace base
6550 } // namespace el
6551 #define CCHECK_NOTNULL(ptr, ...) el::base::utils::checkNotNull(ptr, #ptr, __VA_ARGS__)
6552 #define CCHECK_STREQ(str1, str2, ...) CLOG_IF(!el::base::utils::Str::cStringEq(str1, str2), FATAL, __VA_ARGS__) \
6553  << "Check failed: [" << #str1 << " == " << #str2 << "] "
6554 #define CCHECK_STRNE(str1, str2, ...) CLOG_IF(el::base::utils::Str::cStringEq(str1, str2), FATAL, __VA_ARGS__) \
6555  << "Check failed: [" << #str1 << " != " << #str2 << "] "
6556 #define CCHECK_STRCASEEQ(str1, str2, ...) CLOG_IF(!el::base::utils::Str::cStringCaseEq(str1, str2), FATAL, __VA_ARGS__) \
6557  << "Check failed: [" << #str1 << " == " << #str2 << "] "
6558 #define CCHECK_STRCASENE(str1, str2, ...) CLOG_IF(el::base::utils::Str::cStringCaseEq(str1, str2), FATAL, __VA_ARGS__) \
6559  << "Check failed: [" << #str1 << " != " << #str2 << "] "
6560 #define CHECK_NOTNULL(ptr) CCHECK_NOTNULL(ptr, ELPP_CURR_FILE_LOGGER_ID)
6561 #define CHECK_STREQ(str1, str2) CCHECK_STREQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
6562 #define CHECK_STRNE(str1, str2) CCHECK_STRNE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
6563 #define CHECK_STRCASEEQ(str1, str2) CCHECK_STRCASEEQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
6564 #define CHECK_STRCASENE(str1, str2) CCHECK_STRCASENE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
6565 #undef DCCHECK
6566 #undef DCCHECK_EQ
6567 #undef DCCHECK_NE
6568 #undef DCCHECK_LT
6569 #undef DCCHECK_GT
6570 #undef DCCHECK_LE
6571 #undef DCCHECK_GE
6572 #undef DCCHECK_BOUNDS
6573 #undef DCCHECK_NOTNULL
6574 #undef DCCHECK_STRCASEEQ
6575 #undef DCCHECK_STRCASENE
6576 #undef DCPCHECK
6577 #undef DCHECK
6578 #undef DCHECK_EQ
6579 #undef DCHECK_NE
6580 #undef DCHECK_LT
6581 #undef DCHECK_GT
6582 #undef DCHECK_LE
6583 #undef DCHECK_GE
6584 #undef DCHECK_BOUNDS_
6585 #undef DCHECK_NOTNULL
6586 #undef DCHECK_STRCASEEQ
6587 #undef DCHECK_STRCASENE
6588 #undef DPCHECK
6589 #define DCCHECK(condition, ...) if (ELPP_DEBUG_LOG) CCHECK(condition, __VA_ARGS__)
6590 #define DCCHECK_EQ(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_EQ(a, b, __VA_ARGS__)
6591 #define DCCHECK_NE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_NE(a, b, __VA_ARGS__)
6592 #define DCCHECK_LT(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_LT(a, b, __VA_ARGS__)
6593 #define DCCHECK_GT(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_GT(a, b, __VA_ARGS__)
6594 #define DCCHECK_LE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_LE(a, b, __VA_ARGS__)
6595 #define DCCHECK_GE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_GE(a, b, __VA_ARGS__)
6596 #define DCCHECK_BOUNDS(val, min, max, ...) if (ELPP_DEBUG_LOG) CCHECK_BOUNDS(val, min, max, __VA_ARGS__)
6597 #define DCCHECK_NOTNULL(ptr, ...) if (ELPP_DEBUG_LOG) CCHECK_NOTNULL(ptr, __VA_ARGS__)
6598 #define DCCHECK_STREQ(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STREQ(str1, str2, __VA_ARGS__)
6599 #define DCCHECK_STRNE(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRNE(str1, str2, __VA_ARGS__)
6600 #define DCCHECK_STRCASEEQ(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRCASEEQ(str1, str2, __VA_ARGS__)
6601 #define DCCHECK_STRCASENE(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRCASENE(str1, str2, __VA_ARGS__)
6602 #define DCPCHECK(condition, ...) if (ELPP_DEBUG_LOG) CPCHECK(condition, __VA_ARGS__)
6603 #define DCHECK(condition) DCCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
6604 #define DCHECK_EQ(a, b) DCCHECK_EQ(a, b, ELPP_CURR_FILE_LOGGER_ID)
6605 #define DCHECK_NE(a, b) DCCHECK_NE(a, b, ELPP_CURR_FILE_LOGGER_ID)
6606 #define DCHECK_LT(a, b) DCCHECK_LT(a, b, ELPP_CURR_FILE_LOGGER_ID)
6607 #define DCHECK_GT(a, b) DCCHECK_GT(a, b, ELPP_CURR_FILE_LOGGER_ID)
6608 #define DCHECK_LE(a, b) DCCHECK_LE(a, b, ELPP_CURR_FILE_LOGGER_ID)
6609 #define DCHECK_GE(a, b) DCCHECK_GE(a, b, ELPP_CURR_FILE_LOGGER_ID)
6610 #define DCHECK_BOUNDS(val, min, max) DCCHECK_BOUNDS(val, min, max, ELPP_CURR_FILE_LOGGER_ID)
6611 #define DCHECK_NOTNULL(ptr) DCCHECK_NOTNULL(ptr, ELPP_CURR_FILE_LOGGER_ID)
6612 #define DCHECK_STREQ(str1, str2) DCCHECK_STREQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
6613 #define DCHECK_STRNE(str1, str2) DCCHECK_STRNE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
6614 #define DCHECK_STRCASEEQ(str1, str2) DCCHECK_STRCASEEQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
6615 #define DCHECK_STRCASENE(str1, str2) DCCHECK_STRCASENE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
6616 #define DPCHECK(condition) DCPCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
6617 #if defined(ELPP_DISABLE_DEFAULT_CRASH_HANDLING)
6618 # define ELPP_USE_DEF_CRASH_HANDLER false
6619 #else
6620 # define ELPP_USE_DEF_CRASH_HANDLER true
6621 #endif // defined(ELPP_DISABLE_DEFAULT_CRASH_HANDLING)
6622 #define ELPP_CRASH_HANDLER_INIT
6623 #define ELPP_INIT_EASYLOGGINGPP(val)\
6624  ELPP_INITI_BASIC_DECLR\
6625  namespace el {\
6626  namespace base {\
6627  el::base::type::StoragePointer elStorage(val);\
6628  }\
6629  el::base::debug::CrashHandler elCrashHandler(false);\
6630  }
6631 
6632 #if ELPP_ASYNC_LOGGING
6633 # define INITIALIZE_EASYLOGGINGPP\
6634  ELPP_INIT_EASYLOGGINGPP(new el::base::Storage(el::LogBuilderPtr(new el::base::DefaultLogBuilder()),\
6635  new el::base::AsyncDispatchWorker()))\
6636 
6637 #else
6638 # define INITIALIZE_EASYLOGGINGPP\
6639  ELPP_INIT_EASYLOGGINGPP(new el::base::Storage(el::LogBuilderPtr(new el::base::DefaultLogBuilder())))
6640 #endif // ELPP_ASYNC_LOGGING
6641 #define INITIALIZE_NULL_EASYLOGGINGPP\
6642  ELPP_INITI_BASIC_DECLR\
6643  namespace el {\
6644  namespace base {\
6645  el::base::type::StoragePointer elStorage;\
6646  }\
6647  el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\
6648  }
6649 // NOTE: no ELPP_INITI_BASIC_DECLR when sharing - causes double free corruption on external symbols
6650 #define SHARE_EASYLOGGINGPP(initializedStorage)\
6651  namespace el {\
6652  namespace base {\
6653  el::base::type::StoragePointer elStorage(initializedStorage);\
6654  }\
6655  el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\
6656  }
6657 
6658 #if defined(ELPP_UNICODE)
6659 # define START_EASYLOGGINGPP(argc, argv) el::Helpers::setArgs(argc, argv); std::locale::global(std::locale(""))
6660 #else
6661 # define START_EASYLOGGINGPP(argc, argv) el::Helpers::setArgs(argc, argv)
6662 #endif // defined(ELPP_UNICODE)
6663 #endif // EASYLOGGINGPP_H
void convertToColoredOutput(base::type::string_t *logLine, Level level)
Definition: easylogging++.h:3359
static bool unregisterLogger(const std::string &identity)
Unregisters logger - use it only when you know what you are doing, you may unregister loggers initial...
Definition: easylogging++.h:5785
struct el::base::consts::@40 kTimeFormats[]
const base::type::string_t & message(void) const
Definition: easylogging++.h:3838
char char_t
Definition: easylogging++.h:460
double value
Definition: easylogging++.h:814
void setArgs(int argc, const char **argv)
Sets arguments and parses them.
Definition: easylogging++.h:1737
virtual void updateDateFormat(std::size_t index, base::type::string_t &currFormat) ELPP_FINAL
Updates date time format if available in currFormat.
Definition: easylogging++.h:2239
void setLogBuilder(const LogBuilderPtr &logBuilder)
Definition: easylogging++.h:3510
const std::string & configurationFile(void) const
Gets configuration file used in parsing this configurations.
Definition: easylogging++.h:2592
Logger * get(const std::string &id, bool forceCreation=true)
Definition: easylogging++.h:3623
struct el::base::consts::@41 kCrashSignals[]
Abstract registry (aka repository) that provides basic interface for pointer repository specified by ...
Definition: easylogging++.h:1814
static ConfigurationType convertFromString(const char *configStr)
Converts from configStr to ConfigurationType.
Definition: easylogging++.h:651
LogFormat(Level level, const base::type::string_t &format)
Definition: easylogging++.h:2118
PerformanceTrackingData(DataType dataType)
Definition: easylogging++.h:5245
bool toFile(Level level)
Definition: easylogging++.h:2888
void flush(void)
Flushes logger to sync all log files for all levels.
Definition: easylogging++.h:3482
static std::string extractPathFromFilename(const std::string &fullPath, const char *seperator=base::consts::kFilePathSeperator)
Extracts path of filename with leading slash.
Definition: easylogging++.h:1179
void setModules(const char *modules)
Definition: easylogging++.h:3705
optional bool index
Definition: topics.proto:34
A milliseconds width class containing actual width and offset for date/time.
Definition: easylogging++.h:860
const std::string & value(void) const
Gets string based configuration value.
Definition: easylogging++.h:2394
#define ELPP_WRITE_LOG(writer, level, dispatchAction,...)
Definition: easylogging++.h:5220
virtual const_iterator cbegin(void) const ELPP_FINAL
Definition: easylogging++.h:1880
static void uninstallPerformanceTrackingCallback(const std::string &id)
Uninstalls post performance tracking handler.
Definition: easylogging++.h:5726
std::map< std::string, FileStreamPtr > LogStreamsReferenceMap
Definition: easylogging++.h:2853
Parser used internally to parse configurations from file or text.
Definition: easylogging++.h:2652
void addFlag(base::FormatFlags flag)
Definition: easylogging++.h:2317
void unregister(const T_Key &uniqKey)
Unregisters single entry mapped to specified unique key.
Definition: easylogging++.h:1976
PerformanceTrackingData::DataType dataType(void) const
Definition: easylogging++.h:5252
Determines whether or not corresponding level and logger of logging is enabled You may disable all lo...
friend std::ostream & operator<<(std::ostream &ss, const StackTraceEntry &si)
Definition: easylogging++.h:5466
Mutex wrapper used when multi-threading is disabled.
Definition: easylogging++.h:1041
static std::string & trim(std::string &str)
Trims string from left and right.
Definition: easylogging++.h:1271
Operating System helper static class used internally. You should not use it.
Definition: easylogging++.h:1418
static Logger * reconfigureLogger(const std::string &identity, ConfigurationType configurationType, const std::string &value)
Reconfigures logger&#39;s single configuration.
Definition: easylogging++.h:5805
base::type::EnumType flags(void) const
Definition: easylogging++.h:2223
static void installPreRollOutCallback(const PreRollOutCallback &callback)
Installs pre rollout callback, this callback is triggered when log file is about to be rolled out (ca...
Definition: easylogging++.h:5698
std::fstream fstream_t
Definition: easylogging++.h:463
Callback(void)
Definition: easylogging++.h:3323
Configuration(const Configuration &c)
Definition: easylogging++.h:2360
virtual base::type::string_t build(const LogMessage *logMessage, bool appendNewLine) const =0
SysLogInitializer(const char *processIdent, int options=0, int facility=0)
Definition: easylogging++.h:5631
Determines whether or not performance tracking is enabled.
virtual void releaseLock(void) ELPP_FINAL
Definition: easylogging++.h:1073
Configuration(Level level, ConfigurationType configurationType, const std::string &value)
Full constructor used to sets value of configuration.
Definition: easylogging++.h:2377
Used to find configuration from configuration (pointers) repository. Avoid using it.
Definition: easylogging++.h:2412
const char * m_func
Definition: easylogging++.h:4967
void lock(void)
Definition: easylogging++.h:1044
bool hasParamWithValue(const char *paramKey) const
Returns true if arguments contain paramKey with a value (seperated by &#39;=&#39;)
Definition: easylogging++.h:1771
Creates logger automatically when not available.
base::threading::internal::NoScopedLock< base::threading::Mutex > ScopedLock
Definition: easylogging++.h:1067
static void removeFlag(LoggingFlag flag)
Removes logging flag used internally.
Definition: easylogging++.h:5932
bool hasParam(const char *paramKey) const
Return true if arguments has a param (not having a value) i,e without &#39;=&#39;.
Definition: easylogging++.h:1780
static void buildStrippedFilename(const char *filename, char buff[], std::size_t limit=base::consts::kSourceFilenameMaxLength)
builds stripped filename and puts it in buff
Definition: easylogging++.h:1191
void flushAll(void)
Definition: easylogging++.h:3663
unsigned long int lineNumber(void) const
Definition: easylogging++.h:3227
void setHandler(const Handler &cHandler)
Definition: easylogging++.h:5608
Container::const_iterator const_iterator
Definition: easylogging++.h:1817
def init
Definition: monitor.py:136
static bool hasFlag(LoggingFlag flag)
Determines whether or not certain flag is active.
Definition: easylogging++.h:5936
void setLoggingLevel(Level level)
Definition: easylogging++.h:4059
Information representing errors in application but application will keep running. ...
tuple app
Definition: mock_server.py:7
virtual ~Logger(void)
Definition: easylogging++.h:3418
static std::string & rtrim(std::string &str)
Trim string from end.
Definition: easylogging++.h:1264
std::string m_demangled
Definition: easylogging++.h:5463
ELPP_EXPORT base::type::StoragePointer elStorage
Definition: easylogging++.h:4166
LogMessage(Level level, const std::string &file, unsigned long int line, const std::string &func, base::type::VerboseLevel verboseLevel, Logger *logger)
Definition: easylogging++.h:3827
Represents log format containing flags and date format. This is used internally to start initial log...
Definition: easylogging++.h:2108
NoCopy(void)
Definition: easylogging++.h:482
Definition: easylogging++.h:3351
T_Ptr * get(const T_Key &uniqKey)
Gets pointer from repository. If none found, nullptr is returned.
Definition: easylogging++.h:1985
void flush(Level level, base::type::fstream_t *fs)
Definition: easylogging++.h:3492
static base::type::EnumType castToInt(Level level)
Casts level to int, useful for iterating through enum.
Definition: easylogging++.h:530
void checkpoint(const std::string &id=std::string(), const char *file=__FILE__, unsigned long int line=__LINE__, const char *func="")
A checkpoint for current performanceTracker block.
Definition: easylogging++.h:5328
Writer & construct(int count, const char *loggerIds,...)
Definition: easylogging++.h:4946
static const base::type::EnumType kMaxValid
Represents maximum valid level. This is used internally and you should not need it.
Definition: easylogging++.h:528
unsigned short EnumType
Definition: easylogging++.h:471
std::ostream ostream_t
Definition: easylogging++.h:464
static const std::string releaseDate(void)
Release date of current version.
Definition: easylogging++.h:5983
virtual void log(el::base::type::ostream_t &os) const
Definition: easylogging++.h:2231
std::size_t hitCounts(void) const
Definition: easylogging++.h:3231
bool allowed(base::type::VerboseLevel vlevel, const char *file)
Definition: easylogging++.h:3777
virtual const_iterator cend(void) const ELPP_FINAL
Definition: easylogging++.h:1885
const unsigned long int m_line
Definition: easylogging++.h:4966
MessageBuilder & operator<<(std::ostream &(*OStreamMani)(std::ostream &))
Definition: easylogging++.h:4619
bool validateAfterNCounter(const char *filename, unsigned long int lineNumber, std::size_t n)
Definition: easylogging++.h:3968
virtual ~Configurations(void)
Definition: easylogging++.h:2460
virtual ~LogFormat(void)
Definition: easylogging++.h:2147
std::vector< std::string > m_loggerIds
Definition: easylogging++.h:4973
LogDispatcher(bool proceed, LogMessage &&logMessage, base::DispatchAction dispatchAction)
Definition: easylogging++.h:4452
Definition: easylogging++.h:3347
bool enabled(Level level) const
Definition: easylogging++.h:3514
friend base::type::ostream_t & operator<<(base::type::ostream_t &os, const RegistryWithPred &sr)
Definition: easylogging++.h:2036
static bool uninstallCustomFormatSpecifier(const char *formatSpecifier)
Uninstalls user defined format specifier and handler.
Definition: easylogging++.h:5763
bool try_lock(void)
Definition: easylogging++.h:1045
Predicate(Level level, ConfigurationType configurationType)
Definition: easylogging++.h:2414
static bool startsWith(const std::string &str, const std::string &start)
Determines whether or not str starts with specified string.
Definition: easylogging++.h:1279
#define ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(temp)
Definition: easylogging++.h:4628
bool validateNTimes(const char *filename, unsigned long int lineNumber, std::size_t n)
Validates counter for hits are &lt;= n, i.e, registers new if does not exist otherwise updates original ...
Definition: easylogging++.h:3296
static const std::size_t kStackStart
Definition: easylogging++.h:5447
Informational events most useful for developers to debug application.
static Level convertFromString(const char *levelStr)
Converts from levelStr to Level.
Definition: easylogging++.h:554
void set(Level level, ConfigurationType configurationType, const std::string &value)
Sets value of configuration for specified level.
Definition: easylogging++.h:2553
base::RegisteredLoggers * registeredLoggers(void) const
Definition: easylogging++.h:3980
static std::string & replaceAll(std::string &str, char replaceWhat, char replaceWith)
Replaces all instances of replaceWhat with &#39;replaceWith&#39;. Original variable is changed for performanc...
Definition: easylogging++.h:1296
Severe error information that will presumably abort application.
friend base::type::ostream_t & operator<<(base::type::ostream_t &os, const CommandLineArgs &c)
Definition: easylogging++.h:1791
Main entry point of each logging.
Definition: easylogging++.h:4907
static void setDefaultConfigurations(const Configurations &configurations, bool reconfigureExistingLoggers=false)
Sets default configurations. This configuration is used for future (and conditionally for existing) l...
Definition: easylogging++.h:5837
static Level castFromInt(base::type::EnumType l)
Casts int(ushort) to level, useful for iterating through enum.
Definition: easylogging++.h:534
Base of thread safe class, this class is inheritable-only.
Definition: easylogging++.h:1070
bool parseFromFile(const std::string &configurationFile, Configurations *base=nullptr)
Parses configuration from file.
Definition: easylogging++.h:2469
std::shared_ptr< LogBuilder > LogBuilderPtr
Definition: easylogging++.h:3370
static base::type::fstream_t * newFileStream(const std::string &filename)
Creates new out file stream for specified filename.
Definition: easylogging++.h:1087
void setGlobally(ConfigurationType configurationType, const std::string &value)
Sets configuration for all levels.
Definition: easylogging++.h:2579
NullWriter(void)
Definition: easylogging++.h:4894
Handles unexpected crashes.
Definition: easylogging++.h:5596
const std::string & filename(Level level)
Definition: easylogging++.h:2892
Base of Easylogging++ friendly class.
Definition: easylogging++.h:2096
static std::string getEnvironmentVariable(const char *variableName, const char *defaultVal, const char *alternativeBashCommand=nullptr)
Gets environment variable. This is cross-platform and CRT safe (for VC++)
Definition: easylogging++.h:1490
LoggingFlag
Flags used while writing logs. This flags are set by user.
Definition: easylogging++.h:688
bool operator==(const char *formatSpecifier)
Definition: easylogging++.h:2341
Makes sure we have new line for each container log entry.
Level level(void) const
Definition: easylogging++.h:5361
#define ELPP_STRLEN
Definition: easylogging++.h:454
virtual void log(el::base::type::ostream_t &os) const
Definition: easylogging++.h:2405
Disables comparing performance tracker&#39;s checkpoints.
std::string m_hex
Definition: easylogging++.h:5464
const char * file(void) const
Definition: easylogging++.h:5255
static bool termSupportsColor(void)
Whether or not terminal supports colors.
Definition: easylogging++.h:1542
void setFlags(base::type::EnumType flags)
Definition: easylogging++.h:4014
Definition: easylogging++.h:4367
HitCounter(void)
Definition: easylogging++.h:3181
Definition: easylogging++.h:3239
static char * convertAndAddToBuff(std::size_t n, int len, char *buf, const char *bufLim, bool zeroPadded=true)
Definition: easylogging++.h:1374
bool hasFlag(base::FormatFlags flag) const
Definition: easylogging++.h:2227
base::DispatchAction dispatchAction(void) const
Definition: easylogging++.h:3338
Definition: easylogging++.h:3825
const char * formatSpecifier(void) const
Definition: easylogging++.h:2339
const std::string & loggerId(void) const
Definition: easylogging++.h:5440
virtual ~PErrorWriter(void)
Definition: easylogging++.h:5075
bool hasFlag(LoggingFlag flag) const
Definition: easylogging++.h:4006
NoScopedLock(Mutex &)
Definition: easylogging++.h:1052
virtual void updateFormatSpec(void) ELPP_FINAL
Updates level from format. This is so that we dont have to do it at log-writing-time. It uses m_format and m_level.
Definition: easylogging++.h:2267
virtual ~StackTrace(void)
Definition: easylogging++.h:5480
virtual void registerNew(T_Ptr *ptr) ELPP_FINAL
Definition: easylogging++.h:2068
static const Configurations * defaultConfigurations(void)
Returns current default.
Definition: easylogging++.h:5844
virtual iterator end(void) ELPP_FINAL
Definition: easylogging++.h:1874
static const base::type::EnumType kMinValid
Represents minimum valid level. Useful when iterating through enum.
Definition: easylogging++.h:526
RegistryWithPred(const RegistryWithPred &sr)
Copy constructor that is useful for base classes. Try to avoid this constructor, use move constructor...
Definition: easylogging++.h:2018
Represents unknown level.
const base::type::string_t & format(void) const
Definition: easylogging++.h:2215
void setArgs(int argc, char **argv)
Sets arguments and parses them.
Definition: easylogging++.h:1741
void resetLocation(const char *filename, unsigned long int lineNumber)
Resets location of current hit counter.
Definition: easylogging++.h:3210
virtual ~Storage(void)
Definition: easylogging++.h:3945
bool toStandardOutput(Level level)
Definition: easylogging++.h:2896
Writer & operator<<(const T &log)
Definition: easylogging++.h:4921
struct timeval * endTime(void) const
Definition: easylogging++.h:5434
virtual void unregisterAll(void) ELPP_FINAL
Unregisters all the pointers from current repository.
Definition: easylogging++.h:1960
T * performanceTrackingCallback(const std::string &id)
Definition: easylogging++.h:4088
Level
Represents enumeration for severity level used to determine level of logging.
Definition: easylogging++.h:502
const std::string * blockName(void) const
Definition: easylogging++.h:5428
AbstractRegistry(AbstractRegistry &&sr)
Move constructor that is useful for base classes.
Definition: easylogging++.h:1823
#define ELPP_INTERNAL_ERROR(msg, pe)
Definition: easylogging++.h:149
RegistryWithPred< T_Ptr, Pred >::iterator iterator
Definition: easylogging++.h:2007
const std::map< std::string, base::type::VerboseLevel > & modules(void) const
Definition: easylogging++.h:3795
Definition: easylogging++.h:5239
void clearModules(void)
Definition: easylogging++.h:3700
static std::string getDateTime(const char *format, const base::MillisecondsWidth *msWidth)
Gets current date and time with milliseconds.
Definition: easylogging++.h:1599
const char * name
Definition: easylogging++.h:827
virtual ~Registry(void)
Definition: easylogging++.h:1955
const char * brief
Definition: easylogging++.h:828
static std::string convertTemplateToStdString(const T &templ)
Converts template to std::string - useful for loggable classes to log containers within log(std::ostr...
Definition: easylogging++.h:5735
static void setCrashHandler(const el::base::debug::CrashHandler::Handler &crashHandler)
Overrides default crash handler and installs custom handler.
Definition: easylogging++.h:5669
T * logDispatchCallback(const std::string &id)
Definition: easylogging++.h:4073
virtual void unregister(T_Ptr *&ptr) ELPP_FINAL
Definition: easylogging++.h:2053
void(* Handler)(int)
Definition: easylogging++.h:5598
bool uninstallCustomFormatSpecifier(const char *formatSpecifier)
Definition: easylogging++.h:4044
virtual ~Configuration(void)
Definition: easylogging++.h:2373
optional string msg
Definition: topics.proto:7
const LogMessage * logMessage(void) const
Definition: easylogging++.h:3337
FormatFlags
Format flags used to determine specifiers that are active for performance improvements.
Definition: easylogging++.h:854
static void setVerboseLevel(base::type::VerboseLevel level)
Sets verbose level on the fly.
Definition: easylogging++.h:5960
bool operator==(const MillisecondsWidth &msWidth)
Definition: easylogging++.h:864
virtual ~Writer(void)
Definition: easylogging++.h:4916
HitCounter(const char *filename, unsigned long int lineNumber)
Definition: easylogging++.h:3187
Writer & construct(Logger *logger, bool needLock=true)
Definition: easylogging++.h:4939
static bool createPath(const std::string &path)
Creates specified path on file system.
Definition: easylogging++.h:1139
Determines log file (full path) to write logs to for correponding level and logger.
virtual ~ThreadSafe(void)
Definition: easylogging++.h:1077
base::RegisteredHitCounters * hitCounters(void) const
Definition: easylogging++.h:3976
Configuration & operator=(const Configuration &c)
Definition: easylogging++.h:2366
void installCustomFormatSpecifier(const CustomFormatSpecifier &customFormatSpecifier)
Definition: easylogging++.h:4036
Writes nothing - Used when certain log is disabled.
Definition: easylogging++.h:4892
int m_width
Definition: easylogging++.h:865
static const base::LogStreamsReferenceMap * logStreamsReference(void)
Returns log stream reference pointer if needed by user.
Definition: easylogging++.h:5848
static bool installPerformanceTrackingCallback(const std::string &id)
Installs post performance tracking callback, this callback is triggered when performance tracking is ...
Definition: easylogging++.h:5721
Level level(void) const
Definition: easylogging++.h:2207
Container::iterator iterator
Definition: easylogging++.h:1816
static void forEachConfigType(base::type::EnumType *startIndex, const std::function< bool(void)> &fn)
Applies specified function to each configuration type starting from startIndex.
Definition: easylogging++.h:677
static std::size_t getSizeOfFile(base::type::fstream_t *fs)
Gets size of file provided in stream.
Definition: easylogging++.h:1108
Loggers repository.
Definition: easylogging++.h:3603
virtual ~LogBuilder(void)
Definition: easylogging++.h:3357
Represents performanceTracker block of code that conditionally adds performance status to log either ...
Definition: easylogging++.h:5279
void setFromArgs(const base::utils::CommandLineArgs *commandLineArgs)
Definition: easylogging++.h:3799
Adds spaces b/w logs that separated by left-shift operator.
virtual ~NoScopedLock(void)
Definition: easylogging++.h:1054
bool hasConfiguration(ConfigurationType configurationType)
Determines whether or not specified configuration type exists in the repository.
Definition: easylogging++.h:2515
Internal helper class that prevent copy constructor for class.
Definition: easylogging++.h:480
String utilities helper class used internally. You should not use it.
Definition: easylogging++.h:1222
CommandLineArgs(int argc, const char **argv)
Definition: easylogging++.h:1729
virtual ~Loggable(void)
Definition: easylogging++.h:2098
Makes sure if -vmodule is used and does not specifies a module, then verbose logging is allowed via t...
void initialize(Logger *logger)
Definition: easylogging++.h:4566
Information that can be highly useful and vary with verbose logging level.
static const std::string getBashOutput(const char *command)
Runs command on terminal and returns the output.
Definition: easylogging++.h:1460
const char * m_file
Definition: easylogging++.h:4965
Determines format of logging corresponding level and logger.
const base::MillisecondsWidth & millisecondsWidth(Level level=Level::Global)
Definition: easylogging++.h:2904
static void setStorage(base::type::StoragePointer storage)
Shares logging repository (base::Storage)
Definition: easylogging++.h:5651
RegisteredLoggers(const LogBuilderPtr &defaultLogBuilder)
Definition: easylogging++.h:3605
Predicate(const char *filename, unsigned long int lineNumber)
Definition: easylogging++.h:3241
CustomFormatSpecifier(const char *formatSpecifier, const FormatSpecifierValueResolver &resolver)
Definition: easylogging++.h:2337
struct timeval * startTime(void) const
Definition: easylogging++.h:5431
Disable VModules extensions.
static void installCustomFormatSpecifier(const CustomFormatSpecifier &customFormatSpecifier)
Installs user defined format specifier and handler.
Definition: easylogging++.h:5759
Definition: easylogging++.h:5397
static Logger * reconfigureLogger(Logger *logger, const Configurations &configurations)
Reconfigures specified logger with new configurations.
Definition: easylogging++.h:5795
#define ELPP
Definition: easylogging++.h:4167
virtual ~AbstractRegistry(void)
Definition: easylogging++.h:1865
static void crashAbort(int sig, const char *sourceFile="", unsigned int long line=0)
Abort due to crash with signal in parameter.
Definition: easylogging++.h:5674
friend el::base::type::ostream_t & operator<<(el::base::type::ostream_t &os, const Loggable &loggable)
Definition: easylogging++.h:2101
static std::vector< std::string > * populateAllLoggerIds(std::vector< std::string > *targetList)
Populates all logger IDs in current repository.
Definition: easylogging++.h:5859
bool validateEveryNCounter(const char *filename, unsigned long int lineNumber, std::size_t occasion)
Definition: easylogging++.h:3964
static void reconfigureAllLoggers(Level level, ConfigurationType configurationType, const std::string &value)
Reconfigures single configuration for all the loggers for specified level.
Definition: easylogging++.h:5827
bool parseFromText(const std::string &configurationsString, Configurations *base=nullptr)
Parse configurations from configuration string.
Definition: easylogging++.h:2491
#define ELPP_ASYNC_LOGGING
Definition: easylogging++.h:220
virtual std::size_t size(void) const ELPP_FINAL
Definition: easylogging++.h:1895
static void gettimeofday(struct timeval *tv)
Cross platform gettimeofday for Windows and unix platform. This can be used to determine current mill...
Definition: easylogging++.h:1568
base::TypedConfigurations * typedConfigurations(void)
Definition: easylogging++.h:3469
void addFlag(LoggingFlag flag)
Definition: easylogging++.h:3998
Writer & operator<<(std::ostream &(*log)(std::ostream &))
Definition: easylogging++.h:4930
A pointer registry mechanism to manage memory and provide search functionalities. (predicate version)...
Definition: easylogging++.h:2005
virtual void deepCopy(const AbstractRegistry< T_Ptr, Container > &)=0
TypedConfigurations(Configurations *configurations, base::LogStreamsReferenceMap *logStreamsReference)
Constructor to initialize (construct) the object off el::Configurations.
Definition: easylogging++.h:2865
base::type::EnumType flags(void) const
Definition: easylogging++.h:4010
#define ELPP_CURR_FILE_PERFORMANCE_LOGGER
Definition: easylogging++.h:5237
bool hasCustomFormatSpecifier(const char *formatSpecifier)
Definition: easylogging++.h:4030
static char * clearBuff(char buff[], std::size_t lim)
Definition: easylogging++.h:1395
static bool hasLogger(const std::string &identity)
Whether or not logger with id is registered.
Definition: easylogging++.h:5790
virtual void log(el::base::type::ostream_t &os) const
Definition: easylogging++.h:3422
const base::PerformanceTracker * performanceTracker(void) const
Definition: easylogging++.h:5251
static bool cStringCaseEq(const char *s1, const char *s2)
Compares cstring equality (case-insensitive) - uses toupper(char) Dont use strcasecmp because of CRT ...
Definition: easylogging++.h:1353
static void uninstallLogDispatchCallback(const std::string &id)
Uninstalls log dispatch callback.
Definition: easylogging++.h:5712
Registry & operator=(const Registry &sr)
Assignment operator that unregisters all the existing registeries and deeply copies each of repo elem...
Definition: easylogging++.h:1947
string id
Definition: requests.proto:15
virtual void handle(const T *handlePtr)=0
Preserves time format and does not convert it to sec, hour etc (performance tracking only) ...
#define ELPP_ASSERT(expr, msg)
Definition: easylogging++.h:120
void clear(void)
Clears repository so that all the configurations are unset.
Definition: easylogging++.h:2584
PErrorWriter(Level level, const char *file, unsigned long int line, const char *func, base::DispatchAction dispatchAction=base::DispatchAction::NormalLog, base::type::VerboseLevel verboseLevel=0)
Definition: easylogging++.h:5069
~ScopedAddFlag(void)
Definition: easylogging++.h:5943
Registry< T_Ptr, T_Key >::const_iterator const_iterator
Definition: easylogging++.h:1932
const base::utils::CommandLineArgs * commandLineArgs(void) const
Definition: easylogging++.h:3994
static base::type::EnumType castToInt(ConfigurationType configurationType)
Casts configuration type to int, useful for iterating through enum.
Definition: easylogging++.h:626
void initializeLogger(const std::string &loggerId, bool lookup=true, bool needLock=true)
Definition: easylogging++.h:4976
static bool cStringEq(const char *s1, const char *s2)
Compares cstring equality - uses strcmp.
Definition: easylogging++.h:1345
Definition: easylogging++.h:5444
bool enabled(void) const
Definition: easylogging++.h:3324
static std::string & toUpper(std::string &str)
Converts string to uppercase.
Definition: easylogging++.h:1339
bool has(const std::string &id)
Definition: easylogging++.h:3650
void setLevel(base::type::VerboseLevel level)
Sets verbose level. Accepted range is 0-9.
Definition: easylogging++.h:3686
Definition: easylogging++.h:3334
HitCounter(const HitCounter &hitCounter)
Definition: easylogging++.h:3193
Static class that contains helper functions for el::ConfigurationType.
Definition: easylogging++.h:619
bool operator!=(const AbstractRegistry< T_Ptr, Container > &other)
Definition: easylogging++.h:1843
Definition: easylogging++.h:5067
const char * filename(void) const
Definition: easylogging++.h:3223
bool isFlushNeeded(Level level)
Definition: easylogging++.h:3502
virtual void unregisterAll(void)=0
Unregisters all the pointers from current repository.
virtual void log(el::base::type::ostream_t &) const =0
static const char * convertToString(ConfigurationType configurationType)
Converts configuration type to associated const char*.
Definition: easylogging++.h:635
static const base::type::EnumType kMinValid
Represents minimum valid configuration type. Useful when iterating through enum.
Definition: easylogging++.h:622
bool installPerformanceTrackingCallback(const std::string &id)
Definition: easylogging++.h:4078
#define ELPP_LITERAL(txt)
Definition: easylogging++.h:453
def build
Definition: wscript:9
std::string s_currentHost
Definition: easylogging++.h:1549
void unsetPreRollOutCallback(void)
Definition: easylogging++.h:4022
bool operator()(const HitCounter *counter)
Definition: easylogging++.h:3245
TypedConfigurations(const TypedConfigurations &other)
Definition: easylogging++.h:2871
static void setArgs(int argc, const char **argv)
Sets application arguments and figures out whats active for logging and whats not.
Definition: easylogging++.h:5663
Storage(const LogBuilderPtr &defaultLogBuilder)
Definition: easylogging++.h:3907
static bool isDigit(char c)
Checks if character is digit. Dont use libc implementation of it to prevent locale issues...
Definition: easylogging++.h:1225
void reconfigure(void)
Reconfigures logger using existing configurations.
Definition: easylogging++.h:3448
Adds flag and removes it when scope goes out.
Definition: easylogging++.h:5940
void unregister(Logger *&logger)
Definition: easylogging++.h:3654
void setEnabled(bool enabled)
Definition: easylogging++.h:3325
A pointer registry mechanism to manage memory and provide search functionalities. (non-predicate vers...
Definition: easylogging++.h:1929
struct timeval * lastCheckpointTime(void) const
Definition: easylogging++.h:5437
RegistryWithPred & operator=(const RegistryWithPred &sr)
Assignment operator that unregisters all the existing registeries and deeply copies each of repo elem...
Definition: easylogging++.h:2028
Definition: easylogging++.h:4563
const char * func(void) const
Definition: easylogging++.h:5257
CrashHandler(const Handler &cHandler)
Definition: easylogging++.h:5605
Configurations(const std::string &configurationFile, bool useDefaultsForRemaining=true, Configurations *base=nullptr)
Constructor used to set configurations using configuration file.
Definition: easylogging++.h:2451
static bool parseFromFile(const std::string &configurationFile, Configurations *sender, Configurations *base=nullptr)
Parses configuration from file.
Definition: easylogging++.h:2661
static std::string currentUser(void)
Gets current username.
Definition: easylogging++.h:1513
#define ELPP_UNUSED(x)
Definition: easylogging++.h:177
tuple Args
Definition: test_command.py:17
Static helpers to deal with loggers and their configurations.
Definition: easylogging++.h:5776
PerformanceTracker(const PerformanceTracker &t)
Copy constructor.
Definition: easylogging++.h:5298
base::VRegistry * vRegistry(void) const
Definition: easylogging++.h:3984
bool installLogDispatchCallback(const std::string &id)
Definition: easylogging++.h:4064
bool validateEveryN(const char *filename, unsigned long int lineNumber, std::size_t n)
Validates counter for every N, i.e, registers new if does not exist otherwise updates original one...
Definition: easylogging++.h:3266
Configurations(void)
Default constructor with empty repository.
Definition: easylogging++.h:2440
ScopedAddFlag(LoggingFlag flag)
Definition: easylogging++.h:5942
base::threading::internal::NoMutex Mutex
Definition: easylogging++.h:1066
std::size_t size(void) const
Returns total number of arguments. This exclude argv[0].
Definition: easylogging++.h:1788
MillisecondsWidth(void)
Definition: easylogging++.h:862
static void flushAll(void)
Flushes all loggers for all levels - Be careful if you dont know how many loggers are registered...
Definition: easylogging++.h:5924
const std::string & parentApplicationName(void) const
Definition: easylogging++.h:3457
friend std::ostream & operator<<(std::ostream &os, const StackTrace &st)
Definition: easylogging++.h:5487
Definition: easylogging++.h:5448
Configurations with data types.
Definition: easylogging++.h:2860
bool performanceTracking(Level level=Level::Global)
Definition: easylogging++.h:2908
static bool isValidId(const std::string &id)
Definition: easylogging++.h:3473
base::type::VerboseLevel verboseLevel(void) const
Definition: easylogging++.h:3836
static void setLoggingLevel(Level level)
Sets hierarchy for logging. Needs to enable logging flag (HierarchicalLogging)
Definition: easylogging++.h:5956
virtual ~TypedConfigurations(void)
Definition: easylogging++.h:2877
static void forEachLevel(base::type::EnumType *startIndex, const std::function< bool(void)> &fn)
Applies specified function to each level starting from startIndex.
Definition: easylogging++.h:577
virtual void unregisterAll(void) ELPP_FINAL
Unregisters all the pointers from current repository.
Definition: easylogging++.h:2044
void setPreRollOutCallback(const PreRollOutCallback &callback)
Definition: easylogging++.h:4018
MessageBuilder & operator<<(const wchar_t *msg)
Definition: easylogging++.h:4601
static void reconfigureAllLoggers(const Configurations &configurations)
Reconfigures all the existing loggers with new configurations.
Definition: easylogging++.h:5816
virtual ~CommandLineArgs(void)
Definition: easylogging++.h:1735
const base::type::char_t * unit
Definition: easylogging++.h:815
void unlock(void)
Definition: easylogging++.h:1046
static const char * convertToString(Level level)
Converts level to associated const char*.
Definition: easylogging++.h:539
def options
Definition: wscript:19
virtual void acquireLock(void) ELPP_FINAL
Definition: easylogging++.h:1072
Specifies milliseconds width. Width can be within range (1-6)
Make terminal output colorful for supported terminals.
HitCounter & operator=(const HitCounter &hitCounter)
Definition: easylogging++.h:3199
Repository for hit counters used across the application.
Definition: easylogging++.h:3262
void removeFlag(LoggingFlag flag)
Definition: easylogging++.h:4002
bool empty(void) const
Returns true if no params available. This exclude argv[0].
Definition: easylogging++.h:1784
#define STRTOK(a, b, c)
Definition: easylogging++.h:202
Logger(const std::string &id, base::LogStreamsReferenceMap *logStreamsReference)
Definition: easylogging++.h:3376
virtual ~SysLogInitializer(void)
Definition: easylogging++.h:5640
ConfigurationType configurationType(void) const
Gets configuration type of current configuration.
Definition: easylogging++.h:2389
LogFormat(void)
Definition: easylogging++.h:2110
User-provided custom format specifier.
Definition: easylogging++.h:2335
tuple logger
Definition: dispatcher.py:13
void validateHitCounts(std::size_t n)
Validates hit counts and resets it if necessary.
Definition: easylogging++.h:3216
Useful when application has potentially harmful situtaions.
Definition: easylogging++.h:1083
static std::string & replaceAll(std::string &str, const std::string &replaceWhat, const std::string &replaceWith)
Replaces all instances of &#39;replaceWhat&#39; with &#39;replaceWith&#39;. (String version) Replaces in place...
Definition: easylogging++.h:1306
Writer(Level level, const char *file, unsigned long int line, const char *func, base::DispatchAction dispatchAction=base::DispatchAction::NormalLog, base::type::VerboseLevel verboseLevel=0)
Definition: easylogging++.h:4909
static std::string & ltrim(std::string &str)
Trims string from start.
Definition: easylogging++.h:1257
void handle(const LogDispatchData *data)
Definition: easylogging++.h:4170
int numb
Definition: easylogging++.h:826
std::string string_t
Definition: easylogging++.h:461
When handling crashes by default, detailed crash reason will be logged as well.
DispatchAction
Action to be taken for dispatching.
Definition: easylogging++.h:3316
Enables strict file rolling.
static void clearVModules(void)
Clears vmodules.
Definition: easylogging++.h:5974
static base::TypedConfigurations defaultTypedConfigurations(void)
Default typed configuration based on existing defaultConf.
Definition: easylogging++.h:5852
std::size_t maxLogFileSize(Level level)
Definition: easylogging++.h:2916
static base::type::StoragePointer storage()
Definition: easylogging++.h:5655
static void logCrashReason(int sig, bool stackTraceIfAvailable=false, Level level=Level::Fatal, const char *logger=base::consts::kDefaultLoggerId)
Logs reason of crash as per sig.
Definition: easylogging++.h:5692
static void uninstallPreRollOutCallback(void)
Uninstalls pre rollout callback.
Definition: easylogging++.h:5702
static const base::type::EnumType kMaxValid
Represents maximum valid configuration type. This is used internally and you should not need it...
Definition: easylogging++.h:624
NullWriter & operator<<(const T &)
Definition: easylogging++.h:4902
def configure
Definition: radgen_tool.py:63
const char * detail
Definition: easylogging++.h:829
unsigned int m_offset
Definition: easylogging++.h:865
std::vector< StackTraceEntry > & getLatestStack(void)
Definition: easylogging++.h:5483
void setRemainingToDefault(void)
Lets you set the remaining configurations to default.
Definition: easylogging++.h:2627
virtual Container & list(void) ELPP_FINAL
Returns underlying container by reference.
Definition: easylogging++.h:1900
PerformanceTracker(const std::string &blockName, base::TimestampUnit timestampUnit=base::TimestampUnit::Millisecond, const std::string &loggerId=std::string(ELPP_CURR_FILE_PERFORMANCE_LOGGER), bool scopedLog=true, Level level=base::consts::kPerformanceTrackerDefaultLevel)
Definition: easylogging++.h:5281
Removes flag and add it when scope goes out.
Definition: easylogging++.h:5948
static T * logDispatchCallback(const std::string &id)
Definition: easylogging++.h:5716
bool firstCheckpoint(void) const
Definition: easylogging++.h:5253
std::string checkpointId(void) const
Definition: easylogging++.h:5254
Level level(void) const
Gets level of current configuration.
Definition: easylogging++.h:2384
MessageBuilder & operator<<(const std::string &msg)
Definition: easylogging++.h:4581
Logger(const Logger &logger)
Definition: easylogging++.h:3395
const std::string & dateTimeFormat(void) const
Definition: easylogging++.h:2219
static Logger * reconfigureLogger(const std::string &identity, const Configurations &configurations)
Reconfigures logger with new configurations after looking it up using identity.
Definition: easylogging++.h:5801
LogBuilder * logBuilder(void) const
Definition: easylogging++.h:3506
Flushes log with every log-entry (performance sensative) - Disabled by default.
const Configurations * configurations(void) const
Definition: easylogging++.h:2880
void configure(const Configurations &configurations)
Configures the logger using specified configurations.
Definition: easylogging++.h:3427
static unsigned long long getTimeDifference(const struct timeval &endTime, const struct timeval &startTime, base::TimestampUnit timestampUnit)
Gets time difference in milli/micro second depending on timestampUnit.
Definition: easylogging++.h:1628
Thread-safe Configuration repository.
Definition: easylogging++.h:2437
static void replaceFirstWithEscape(base::type::string_t &str, const base::type::string_t &replaceWhat, const base::type::string_t &replaceWith)
Definition: easylogging++.h:1317
CommandLineArgs(int argc, char **argv)
Definition: easylogging++.h:1732
std::string s_currentUser
Definition: easylogging++.h:1548
#define ELPP_EXPORT
Definition: easylogging++.h:189
Mainly useful to represent current progress of application.
#define ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(temp)
Definition: easylogging++.h:4643
void setValue(const std::string &value)
Set string based configuration value.
Definition: easylogging++.h:2401
bool enabled(Level level)
Definition: easylogging++.h:2884
std::string m_location
Definition: easylogging++.h:5462
void set(Configuration *conf)
Sets single configuration based on other single configuration.
Definition: easylogging++.h:2563
bool validateAfterN(const char *filename, unsigned long int lineNumber, std::size_t n)
Validates counter for hits &gt;= N, i.e, registers new if does not exist otherwise updates original one...
Definition: easylogging++.h:3279
Dispatches log messages.
Definition: easylogging++.h:4450
static char * addToBuff(const char *str, char *buf, const char *bufLim)
Definition: easylogging++.h:1389
static std::string currentHost(void)
Gets current host name or computer name.
Definition: easylogging++.h:1529
static void reconfigureAllLoggers(ConfigurationType configurationType, const std::string &value)
Reconfigures single configuration for all the loggers.
Definition: easylogging++.h:5823
std::shared_ptr< base::Storage > StoragePointer
Definition: easylogging++.h:472
Configurations * configurations(void)
Definition: easylogging++.h:3465
virtual ~RegisteredLoggers(void)
Definition: easylogging++.h:3610
bool operator==(const AbstractRegistry< T_Ptr, Container > &other)
Definition: easylogging++.h:1831
TimestampUnit
Enum to represent timestamp unit.
Definition: easylogging++.h:850
Command line arguments for application if specified using el::Helpers::setArgs(..) or START_EASYLOGGI...
Definition: easylogging++.h:1724
Configurations * defaultConfigurations(void)
Definition: easylogging++.h:3619
PreRollOutCallback & preRollOutCallback(void)
Definition: easylogging++.h:4026
void triggerDispatch(void)
Definition: easylogging++.h:5045
#define ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(temp)
Definition: easylogging++.h:4633
NoMutex(void)
Definition: easylogging++.h:1043
static char * wcharPtrToCharPtr(const wchar_t *line)
Converst wchar* to char* NOTE: Need to free return value after use!
Definition: easylogging++.h:1403
void setDefaultConfigurations(const Configurations &configurations)
Definition: easylogging++.h:3614
base::DispatchAction m_dispatchAction
Definition: easylogging++.h:4972
Definition: easylogging++.h:4168
base::MessageBuilder m_messageBuilder
Definition: easylogging++.h:4971
Specifies number of log entries to hold until we flush pending log data.
bool validateNTimesCounter(const char *filename, unsigned long int lineNumber, std::size_t n)
Definition: easylogging++.h:3972
std::string m_addr
Definition: easylogging++.h:5465
static const std::size_t kMaxStack
Definition: easylogging++.h:5446
static void setVModules(const char *modules)
Sets vmodules as specified (on the fly)
Definition: easylogging++.h:5968
static void addFlag(LoggingFlag flag)
Adds logging flag used internally.
Definition: easylogging++.h:5928
Logger & operator=(const Logger &logger)
Definition: easylogging++.h:3406
Definition: easylogging++.h:3355
static void validateFileRolling(Logger *logger, Level level)
Definition: easylogging++.h:5770
Level level(void) const
Definition: easylogging++.h:3832
Logger * m_logger
Definition: easylogging++.h:4969
int VerboseLevel
Definition: easylogging++.h:473
static void buildBaseFilename(const std::string &fullPath, char buff[], std::size_t limit=base::consts::kSourceFilenameMaxLength, const char *seperator=base::consts::kFilePathSeperator)
builds base filename and puts it in buff
Definition: easylogging++.h:1204
AbstractRegistry(void)
Default constructor.
Definition: easylogging++.h:1820
NullWriter & operator<<(std::ostream &(*)(std::ostream &))
Definition: easylogging++.h:4897
optional bool error
Definition: requests.proto:11
base::debug::CrashHandler elCrashHandler
Definition: easylogging++.h:5625
LogFormat(LogFormat &&logFormat)
Definition: easylogging++.h:2131
static const el::base::utils::CommandLineArgs * commandLineArgs(void)
Returns command line arguments (pointer) provided to easylogging++.
Definition: easylogging++.h:5755
bool vModulesEnabled(void)
Whether or not vModules enabled.
Definition: easylogging++.h:3815
void setFromBase(Configurations *base)
Sets configuration based-off an existing configurations.
Definition: easylogging++.h:2501
std::function< void(const char *, std::size_t)> PreRollOutCallback
Definition: easylogging++.h:846
const std::string & func(void) const
Definition: easylogging++.h:3835
~ScopedRemoveFlag(void)
Definition: easylogging++.h:5951
virtual iterator begin(void) ELPP_FINAL
Definition: easylogging++.h:1869
Level m_level
Definition: easylogging++.h:4964
#define ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(temp)
Definition: easylogging++.h:4623
std::size_t m_index
Definition: easylogging++.h:5461
bool operator==(const LogFormat &other)
Definition: easylogging++.h:2150
static Logger * getLogger(const std::string &identity, bool registerIfNotAvailable=true)
Gets existing or registers new logger.
Definition: easylogging++.h:5779
Logger(const std::string &id, const Configurations &configurations, base::LogStreamsReferenceMap *logStreamsReference)
Definition: easylogging++.h:3385
StackTraceEntry(std::size_t index, const char *loc, const char *demang, const char *hex, const char *addr)
Definition: easylogging++.h:5450
LogFormat & operator=(const LogFormat &logFormat)
Definition: easylogging++.h:2139
void parseFromFormat(const base::type::string_t &userFormat)
Updates format to be used while logging.
Definition: easylogging++.h:2157
#define ELPP_COUT
Definition: easylogging++.h:458
void dispatch(void)
Definition: easylogging++.h:4458
base::LogStreamsReferenceMap * logStreamsReference(void)
Definition: easylogging++.h:3659
base::type::VerboseLevel m_verboseLevel
Definition: easylogging++.h:4968
const FormatSpecifierValueResolver & resolver(void) const
Definition: easylogging++.h:2340
Definition: easylogging++.h:409
unsigned long int line(void) const
Definition: easylogging++.h:5256
static base::type::string_t formatTime(unsigned long long time, base::TimestampUnit timestampUnit)
Formats time to get unit accordingly, units like second if &gt; 1000 or minutes if &gt; 60000 etc...
Definition: easylogging++.h:1611
virtual ~HitCounter(void)
Definition: easylogging++.h:3206
base::type::VerboseLevel level(void) const
Definition: easylogging++.h:3696
VRegistry(base::type::VerboseLevel level, base::type::EnumType *pFlags)
Definition: easylogging++.h:3682
const base::HitCounter * getCounter(const char *filename, unsigned long int lineNumber)
Gets hit counter registered at specified position.
Definition: easylogging++.h:3310
#define ELPP_COUT_LINE(logLine)
Definition: easylogging++.h:469
virtual const Container & list(void) const ELPP_FINAL
Returns underlying container by constant reference.
Definition: easylogging++.h:1905
CommandLineArgs(void)
Definition: easylogging++.h:1726
Generic level that represents all the levels. Useful when setting global configuration for all levels...
static bool configureFromArg(const char *argKey)
Configures loggers using command line arg. Ensure you have already set command line args...
Definition: easylogging++.h:5912
Registry< T_Ptr, T_Key >::iterator iterator
Definition: easylogging++.h:1931
Configuration * get(const T &arg1, const T2 arg2)
Gets pointer from repository with speicifed arguments. Arguments are passed to predicate in order to ...
Definition: easylogging++.h:2075
virtual void registerNew(const T_Key &uniqKey, T_Ptr *ptr) ELPP_FINAL
Registers new registry to repository.
Definition: easylogging++.h:1970
def debug
Print a debug log to stdout.
Definition: ctdPyUtils.py:60
StackTrace(void)
Definition: easylogging++.h:5476
static bool pathExists(const char *path, bool considerFile=false)
Determines whether or not provided path exist in current file system.
Definition: easylogging++.h:1120
bool hasConfiguration(Level level, ConfigurationType configurationType)
Determines whether or not specified configuration type exists for specified level.
Definition: easylogging++.h:2530
Whether or not to write corresponding log to log file.
Represents single configuration that has representing level, configuration type and a string based va...
Definition: easylogging++.h:2358
const base::LogFormat & logFormat(Level level)
Definition: easylogging++.h:2900
Internal helper class that makes all default constructors private.
Definition: easylogging++.h:491
CrashHandler(bool useDefault)
Definition: easylogging++.h:5600
void uninstallLogDispatchCallback(const std::string &id)
Definition: easylogging++.h:4069
#define STRCAT(a, b, len)
Definition: easylogging++.h:204
virtual ~RegistryWithPred(void)
Definition: easylogging++.h:2013
static bool wildCardMatch(const char *str, const char *pattern)
Matches wildcards, &#39;*&#39; and &#39;?&#39; only supported.
Definition: easylogging++.h:1230
virtual ~PerformanceTracker(void)
Definition: easylogging++.h:5303
StackTraceEntry(std::size_t index, char *loc)
Definition: easylogging++.h:5457
MillisecondsWidth(int width)
Definition: easylogging++.h:863
ScopedRemoveFlag(LoggingFlag flag)
Definition: easylogging++.h:5950
Whether or not to write corresponding level and logger log to standard output. By standard output mea...
Class that keeps record of current line hit for occasional logging.
Definition: easylogging++.h:3179
Represents a logger holding ID and configurations we need to write logs.
Definition: easylogging++.h:3374
ConfigurationType
Represents enumeration of ConfigurationType used to configure or access certain aspect of logging...
Definition: easylogging++.h:589
base::type::string_t build(const LogMessage *logMessage, bool appendNewLine) const
Definition: easylogging++.h:4369
Logger * logger(void) const
Definition: easylogging++.h:3837
DataType
Definition: easylogging++.h:5241
AbstractRegistry & operator=(AbstractRegistry &&sr)
Assignment move operator.
Definition: easylogging++.h:1856
Registry(const Registry &sr)
Copy constructor that is useful for base classes. Try to avoid this constructor, use move constructor...
Definition: easylogging++.h:1937
unsigned long int line(void) const
Definition: easylogging++.h:3834
Lock guard wrapper used when multi-threading is disabled.
Definition: easylogging++.h:1050
static void configureFromGlobal(const char *globalConfigurationFilePath)
Sets configurations from global configuration file.
Definition: easylogging++.h:5868
static base::type::VerboseLevel verboseLevel(void)
Gets current verbose level.
Definition: easylogging++.h:5964
static const std::string version(void)
Current version number.
Definition: easylogging++.h:5981
void increment(void)
Definition: easylogging++.h:3235
RegistryWithPred< T_Ptr, Pred >::const_iterator const_iterator
Definition: easylogging++.h:2008
base::type::fstream_t * fileStream(Level level)
Definition: easylogging++.h:2912
static bool contains(const char *str, char c)
Returns true if c exist in str.
Definition: easylogging++.h:1366
void processDispatch()
Definition: easylogging++.h:5004
#define ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(temp)
Definition: easylogging++.h:4638
std::stringstream stringstream_t
Definition: easylogging++.h:462
#define STRCPY(a, b, len)
Definition: easylogging++.h:205
#define CLOG_IF(condition, LEVEL,...)
Definition: easylogging++.h:6299
void uninstallPerformanceTrackingCallback(const std::string &id)
Definition: easylogging++.h:4083
LogDispatchData()
Definition: easylogging++.h:3336
#define ELPP_INTERNAL_INFO(lvl, msg)
Definition: easylogging++.h:163
static bool endsWith(const std::string &str, const std::string &end)
Determines whether or not str ends with specified string.
Definition: easylogging++.h:1287
Static class that contains helper functions for el::Level.
Definition: easylogging++.h:523
std::string const
Definition: Test{{cookiecutter.device_name}}.cpp:209
void setParentApplicationName(const std::string &parentApplicationName)
Definition: easylogging++.h:3461
bool m_proceed
Definition: easylogging++.h:4970
void reinitDeepCopy(const AbstractRegistry< T_Ptr, Container > &sr)
Definition: easylogging++.h:1914
const std::string & file(void) const
Definition: easylogging++.h:3833
optional string name
Definition: topics.proto:50
const std::string & id(void) const
Definition: easylogging++.h:3453
static T * performanceTrackingCallback(const std::string &id)
Definition: easylogging++.h:5730
std::function< const char *(void)> FormatSpecifierValueResolver
Resolving function for format specifier.
Definition: easylogging++.h:2331
#define ELPP_SIMPLE_LOG(LOG_TYPE)
Definition: easylogging++.h:4572
std::shared_ptr< base::type::fstream_t > FileStreamPtr
Definition: easylogging++.h:2852
Enables hierarchical logging.
Registry(void)
Definition: easylogging++.h:1934
static bool parseFromText(const std::string &configurationsString, Configurations *sender, Configurations *base=nullptr)
Parse configurations from configuration string.
Definition: easylogging++.h:2688
#define ELPP_FINAL
Definition: easylogging++.h:213
Definition: easylogging++.h:5978
std::shared_ptr< PerformanceTrackingCallback > PerformanceTrackingCallbackPtr
Definition: easylogging++.h:475
MessageBuilder(void)
Definition: easylogging++.h:4565
ThreadSafe(void)
Definition: easylogging++.h:1076
static bool hasCustomFormatSpecifier(const char *formatSpecifier)
Returns true if custom format specifier is installed.
Definition: easylogging++.h:5767
const base::type::string_t & userFormat(void) const
Definition: easylogging++.h:2211
Supports use of multiple logging in same macro, e.g, CLOG(INFO, &quot;default&quot;, &quot;network&quot;) ...
Static helpers for developers.
Definition: easylogging++.h:5648
std::size_t logFlushThreshold(Level level)
Definition: easylogging++.h:2920
bool operator()(const Configuration *conf) const
Definition: easylogging++.h:2419
static ConfigurationType castFromInt(base::type::EnumType c)
Casts int(ushort) to configurationt type, useful for iterating through enum.
Definition: easylogging++.h:630
void handle(const PerformanceTrackingData *data)
Definition: easylogging++.h:5399
std::shared_ptr< LogDispatchCallback > LogDispatchCallbackPtr
Definition: easylogging++.h:474
Information that can be useful to back-trace certain events - mostly useful than debug logs...
const char * getParamValue(const char *paramKey) const
Returns value of arguments.
Definition: easylogging++.h:1776
RegistryWithPred(void)
Definition: easylogging++.h:2010
virtual base::threading::Mutex & lock(void) ELPP_FINAL
Definition: easylogging++.h:1074
LogFormat(const LogFormat &logFormat)
Definition: easylogging++.h:2123
Specifies log file max size.
Represents registries for verbose logging.
Definition: easylogging++.h:3680
void setToDefault(void)
Sets configurations to &quot;factory based&quot; configurations.
Definition: easylogging++.h:2597
static void setArgs(int argc, char **argv)
Sets application arguments and figures out whats active for logging and whats not.
Definition: easylogging++.h:5659
Easylogging++ management storage.
Definition: easylogging++.h:3902
const base::type::string_t * formattedTimeTaken() const
Definition: easylogging++.h:5258
const std::vector< CustomFormatSpecifier > * customFormatSpecifiers(void) const
Definition: easylogging++.h:4055
bool s_termSupportsColor
Definition: easylogging++.h:1550
Allows to disable application abortion when logged using FATAL level.
virtual bool empty(void) const ELPP_FINAL
Definition: easylogging++.h:1890
static bool installLogDispatchCallback(const std::string &id)
Installs post log dispatch callback, this callback is triggered when log is dispatched.
Definition: easylogging++.h:5707