ZeroErr
log.h
Go to the documentation of this file.
1 #pragma once
3 
6 
7 #include "zeroerr/dbg.h"
8 #include "zeroerr/format.h"
9 #include "zeroerr/print.h"
10 
11 #include <chrono>
12 #include <map>
13 #include <string>
14 #include <vector>
15 
17 
18 extern const char* ZEROERR_LOG_CATEGORY;
19 
20 namespace std {
21 class mutex;
22 }
23 
24 namespace zeroerr {
25 
26 // clang-format off
27 #define ZEROERR_INFO(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_INFO_(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
28 #define ZEROERR_LOG(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_LOG_(LOG_l, __VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
29 #define ZEROERR_WARN(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_LOG_(WARN_l, __VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
30 #define ZEROERR_ERROR(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_LOG_(ERROR_l, __VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
31 #define ZEROERR_FATAL(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_LOG_(FATAL_l, __VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
32 // clang-format on
33 
34 #ifdef ZEROERR_USE_SHORT_LOG_MACRO
35 
36 #ifdef INFO
37 #undef INFO
38 #endif
39 
40 #ifdef LOG
41 #undef LOG
42 #endif
43 
44 #ifdef WARN
45 #undef WARN
46 #endif
47 
48 #ifdef ERR
49 #undef ERR
50 #endif
51 
52 #ifdef FATAL
53 #undef FATAL
54 #endif
55 
56 #ifdef VERBOSE
57 #undef VERBOSE
58 #endif
59 
60 #define INFO(...) ZEROERR_INFO(__VA_ARGS__)
61 #define LOG(...) ZEROERR_LOG(__VA_ARGS__)
62 #define WARN(...) ZEROERR_WARN(__VA_ARGS__)
63 #define ERR(...) ZEROERR_ERROR(__VA_ARGS__)
64 #define FATAL(...) ZEROERR_FATAL(__VA_ARGS__)
65 #define VERBOSE(v) ZEROERR_VERBOSE(v)
66 
67 #define LOG_GET(func, id, name, type) ZEROERR_LOG_GET(func, id, name, type)
68 
69 #endif // ZEROERR_USE_SHORT_LOG_MACRO
70 
71 #define ZEROERR_LOG_IF(condition, ACTION, ...) \
72  do { \
73  if (condition) ACTION(__VA_ARGS__); \
74  } while (0)
75 
76 
77 #define INFO_IF(cond, ...) ZEROERR_LOG_IF(cond, ZEROERR_INFO, __VA_ARGS__)
78 #define LOG_IF(cond, ...) ZEROERR_LOG_IF(cond, ZEROERR_LOG, __VA_ARGS__)
79 #define WARN_IF(cond, ...) ZEROERR_LOG_IF(cond, ZEROERR_WARN, __VA_ARGS__)
80 #define ERR_IF(cond, ...) ZEROERR_LOG_IF(cond, ZEROERR_ERROR, __VA_ARGS__)
81 #define FATAL_IF(cond, ...) ZEROERR_LOG_IF(cond, ZEROERR_FATAL, __VA_ARGS__)
82 
83 
84 #define ZEROERR_LOG_EVERY_(n, ACTION, ...) \
85  do { \
86  unsigned counter = 0; \
87  if (counter == 0) { \
88  counter = n; \
89  ACTION(__VA_ARGS__); \
90  } \
91  --counter; \
92  } while (0)
93 
94 
95 #define INFO_EVERY_(n, ...) ZEROERR_LOG_EVERY_(n, ZEROERR_INFO, __VA_ARGS__)
96 #define LOG_EVERY_(n, ...) ZEROERR_LOG_EVERY_(n, ZEROERR_LOG, __VA_ARGS__)
97 #define WARN_EVERY_(n, ...) ZEROERR_LOG_EVERY_(n, ZEROERR_WARN, __VA_ARGS__)
98 #define ERR_EVERY_(n, ...) ZEROERR_LOG_EVERY_(n, ZEROERR_ERROR, __VA_ARGS__)
99 #define FATAL_EVERY_(n, ...) ZEROERR_LOG_EVERY_(n, ZEROERR_FATAL, __VA_ARGS__)
100 
101 
102 #define ZEROERR_LOG_IF_EVERY_(n, cond, ACTION, ...) \
103  do { \
104  unsigned counter = 0; \
105  if (counter == 0 && (cond)) { \
106  counter = n; \
107  ACTION(__VA_ARGS__); \
108  } \
109  --counter; \
110  } while (0)
111 
112 #define INFO_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_INFO, __VA_ARGS__)
113 #define LOG_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_LOG, __VA_ARGS__)
114 #define WARN_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_WARN, __VA_ARGS__)
115 #define ERR_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_ERROR, __VA_ARGS__)
116 #define FATAL_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_FATAL, __VA_ARGS__)
117 
118 #define ZEROERR_LOG_FIRST(cond, ACTION, ...) \
119  do { \
120  bool first = true; \
121  if (first && (cond)) { \
122  first = false; \
123  ACTION(__VA_ARGS__); \
124  } \
125  } while (0)
126 
127 #define INFO_FIRST(cond, ...) ZEROERR_LOG_FIRST(cond, ZEROERR_INFO, __VA_ARGS__)
128 #define LOG_FIRST(cond, ...) ZEROERR_LOG_FIRST(cond, ZEROERR_LOG, __VA_ARGS__)
129 #define WARN_FIRST(cond, ...) ZEROERR_LOG_FIRST(cond, ZEROERR_WARN, __VA_ARGS__)
130 #define ERR_FIRST(cond, ...) ZEROERR_LOG_FIRST(cond, ZEROERR_ERROR, __VA_ARGS__)
131 #define FATAL_FIRST(cond, ...) ZEROERR_LOG_FIRST(cond, ZEROERR_FATAL, __VA_ARGS__)
132 
133 #define ZEROERR_LOG_FIRST_(n, cond, ACTION, ...) \
134  do { \
135  unsigned counter = n; \
136  if (n-- && (cond)) { \
137  ACTION(__VA_ARGS__); \
138  } \
139  } while (0)
140 
141 #define INFO_FIRST_(n, cond, ...) ZEROERR_LOG_FIRST_(n, cond, ZEROERR_INFO, __VA_ARGS__)
142 #define LOG_FIRST_(n, cond, ...) ZEROERR_LOG_FIRST_(n, cond, ZEROERR_LOG, __VA_ARGS__)
143 #define WARN_FIRST_(n, cond, ...) ZEROERR_LOG_FIRST_(n, cond, ZEROERR_WARN, __VA_ARGS__)
144 #define ERR_FIRST_(n, cond, ...) ZEROERR_LOG_FIRST_(n, cond, ZEROERR_ERROR, __VA_ARGS__)
145 #define FATAL_FIRST_(n, cond, ...) ZEROERR_LOG_FIRST_(n, cond, ZEROERR_FATAL, __VA_ARGS__)
146 
147 #ifdef _DEBUG
148 #define DLOG(ACTION, ...) ZEROERR_EXPAND(ACTION(__VA_ARGS__))
149 #else
150 #define DLOG(ACTION, ...)
151 #endif
152 
153 extern int _ZEROERR_G_VERBOSE;
154 
155 #define ZEROERR_VERBOSE(v) if (zeroerr::_ZEROERR_G_VERBOSE >= (v))
156 
157 #define ZEROERR_LOG_(severity, message, ...) \
158  do { \
159  ZEROERR_G_CONTEXT_SCOPE(true); \
160  auto msg = zeroerr::log(__VA_ARGS__); \
161  \
162  static zeroerr::LogInfo log_info{__FILE__, \
163  __func__, \
164  message, \
165  ZEROERR_LOG_CATEGORY, \
166  __LINE__, \
167  msg.size, \
168  zeroerr::LogSeverity::severity}; \
169  msg.log->info = &log_info; \
170  if (msg.stream.getFlushMode() == zeroerr::LogStream::FlushMode::FLUSH_AT_ONCE) \
171  msg.stream.flush(); \
172  } while (0)
173 
174 #define ZEROERR_INFO_(...) \
175  ZEROERR_INFO_IMPL(ZEROERR_NAMEGEN(_capture_), ZEROERR_NAMEGEN(_capture_), __VA_ARGS__)
176 
177 #define ZEROERR_INFO_IMPL(mb_name, v_name, ...) \
178  auto v_name = zeroerr::MakeContextScope([&](std::ostream& _capture_name) { \
179  Printer print(_capture_name); \
180  print.isQuoted = false; \
181  print(__VA_ARGS__); \
182  })
183 
184 #ifdef ZEROERR_G_CONTEXT_SCOPE
185 #undef ZEROERR_G_CONTEXT_SCOPE
186 #endif
187 
188 #define ZEROERR_G_CONTEXT_SCOPE(x) \
189  if (x) { \
190  for (auto* i : zeroerr::_ZEROERR_G_CONTEXT_SCOPE_VECTOR) { \
191  i->str(std::cerr); \
192  } \
193  }
194 
195 #ifdef ZEROERR_PRINT_ASSERT_DEFAULT_PRINTER
196 #undef ZEROERR_PRINT_ASSERT_DEFAULT_PRINTER
197 #endif
198 
199 #define ZEROERR_PRINT_ASSERT_DEFAULT_PRINTER(cond, level, ...) \
200  ZEROERR_LOG_IF(cond, level, __VA_ARGS__)
201 
202 
203 // This macro can access the log in memory
204 #define ZEROERR_LOG_GET(func, id, name, type) \
205  zeroerr::LogStream::getDefault().getLog<type>(#func, id, #name)
206 
207 
208 namespace detail {
209 
210 template <typename T, unsigned... I>
211 std::string gen_str(const char* msg, const T& args, seq<I...>) {
212  return format(msg, std::get<I>(args)...);
213 }
214 
215 template <typename T>
216 std::string gen_str(const char* msg, const T&, seq<>) {
217  return msg;
218 }
219 
220 } // namespace detail
221 
222 
224  INFO_l, // it will not write to file if no other log related
228  FATAL_l, // it will contain a stack trace
229 };
230 
256 struct LogInfo {
257  const char* filename;
258  const char* function;
259  const char* message;
260  const char* category;
261  unsigned line;
262  unsigned size;
264  std::map<std::string, int> names;
265 
266  LogInfo(const char* filename, const char* function, const char* message, const char* category,
267  unsigned line, unsigned size, LogSeverity severity);
268 };
269 
270 struct LogMessage;
271 typedef std::string (*LogCustomCallback)(const LogMessage&, bool colorful);
272 
276 extern void setLogLevel(LogSeverity level);
277 
281 extern void setLogCategory(const char* categories);
282 
286 extern void setLogCustomCallback(LogCustomCallback callback);
287 
291 extern void suspendLog();
292 
296 extern void resumeLog();
297 
306 struct LogMessage {
307  // time is assigned when the log message is created
308  LogMessage() { time = std::chrono::system_clock::now(); }
309 
310  // convert the log message to a string
311  virtual std::string str() const = 0;
312 
313  // get the raw data pointer of the field with the name
314  virtual void* getRawLog(std::string name) const = 0;
315 
316  // a map of the data indexing by the field name
317  // for example: log("print {i}", 1);
318  // a map of {"i": "1"} will be returned
319  virtual std::map<std::string, std::string> getData() const = 0;
320 
321  // meta data of this log message
322  const LogInfo* info;
323 
324  // recorded wall time
325  std::chrono::system_clock::time_point time;
326 };
327 
328 
335 template <typename... T>
336 struct LogMessageImpl final : LogMessage {
337  std::tuple<T...> args;
339 
340  std::string str() const override {
341  return gen_str(info->message, args, detail::gen_seq<sizeof...(T)>{});
342  }
343 
344  // This is a helper class to get the raw pointer of the tuple
345  struct GetTuplePtr {
346  void* ptr = nullptr;
347  template <typename H>
348  void operator()(H& v) {
349  ptr = (void*)&v;
350  }
351  };
352 
353  void* getRawLog(std::string name) const override {
354  GetTuplePtr f;
355  detail::visit_at(args, info->names.at(name), f);
356  return f.ptr;
357  }
358 
359  struct PrintTupleData {
360  std::map<std::string, std::string> data;
362  std::string name;
363 
365  print.isCompact = true;
366  print.line_break = "";
367  }
368 
369  template <typename H>
370  void operator()(H& v) {
371  data[name] = print(v);
372  }
373  };
374 
375  std::map<std::string, std::string> getData() const override {
376  PrintTupleData printer;
377  for (auto it = info->names.begin(); it != info->names.end(); ++it) {
378  printer.name = it->first;
379  detail::visit_at(args, it->second, printer);
380  }
381  return printer.data;
382  }
383 };
384 
385 struct DataBlock;
386 class LogStream;
387 
388 class Logger {
389 public:
390  virtual ~Logger() = default;
391  virtual void flush(DataBlock*) = 0;
392 };
393 
394 struct PushResult {
396  unsigned size;
398 };
399 
418 class LogIterator {
419 public:
420  LogIterator() : p(nullptr), q(nullptr) {}
421  LogIterator(LogStream& stream, std::string message = "", std::string function_name = "",
422  int line = -1);
423  LogIterator(const LogIterator& rhs) : p(rhs.p), q(rhs.q) {}
425  p = rhs.p;
426  q = rhs.q;
427  return *this;
428  }
429 
432  LogIterator tmp = *this;
433  ++*this;
434  return tmp;
435  }
436 
437  template <typename T>
438  T get(std::string name) {
439  void* data = q->getRawLog(name);
440  if (data) return *(T*)(data);
441  return T{};
442  }
443 
444  bool operator==(const LogIterator& rhs) const { return p == rhs.p && q == rhs.q; }
445  bool operator!=(const LogIterator& rhs) const { return !(*this == rhs); }
446 
447  LogMessage& get() const { return *q; }
448  LogMessage& operator*() const { return *q; }
449  LogMessage* operator->() const { return q; }
450 
451  void check_at_safe_pos();
452 
453  friend class LogStream;
454 
455 protected:
456  bool check_filter();
457  void next();
458 
461 
462  std::string function_name_filter;
463  std::string message_filter;
464  int line_filter = -1;
465 };
466 
475 class LogStream {
476 public:
477  LogStream();
478  virtual ~LogStream();
479 
481  enum LogMode { ASYNC, SYNC };
482  enum DirMode {
486  SPLIT_BY_CATEGORY = 1 << 2
487  };
488 
489 
511  template <typename... T>
512  PushResult push(T&&... args) {
513  // unsigned size = sizeof(LogMessageImpl<T...>);
514  unsigned size = sizeof(LogMessageImpl<detail::to_store_type_t<T>...>);
515  void* p;
516  if (use_lock_free)
517  p = alloc_block_lockfree(size);
518  else
519  p = alloc_block(size);
520  // LogMessage* msg = new (p) LogMessageImpl<T...>(std::forward<T>(args)...);
521  LogMessage* msg = new (p) LogMessageImpl<detail::to_store_type_t<T>...>(args...);
522  return {msg, size, *this};
523  }
524 
525 
537  template <typename T>
538  T getLog(std::string func, unsigned line, std::string name) {
539  void* data = getRawLog(func, line, name);
540  if (data) return *(T*)(data);
541  return T{};
542  }
543 
555  template <typename T>
556  T getLog(std::string func, std::string msg, std::string name) {
557  void* data = getRawLog(func, msg, name);
558  if (data) return *(T*)(data);
559  return T{};
560  }
561 
562  LogIterator begin(std::string message = "", std::string function_name = "", int line = -1) {
563  return LogIterator(*this, message, function_name, line);
564  }
565  LogIterator end() { return LogIterator(); }
566  LogIterator current(std::string message = "", std::string function_name = "", int line = -1);
567 
568  void flush();
569  void setFileLogger(std::string name, DirMode mode1 = SINGLE_FILE, DirMode mode2 = SINGLE_FILE,
570  DirMode mode3 = SINGLE_FILE);
571  void setStdoutLogger();
572  void setStderrLogger();
573 
574  static LogStream& getDefault();
575 
576  void setFlushAtOnce() { flush_mode = FLUSH_AT_ONCE; }
577  void setFlushWhenFull() { flush_mode = FLUSH_WHEN_FULL; }
578  void setFlushManually() { flush_mode = FLUSH_MANUALLY; }
579  void setAsyncLog() { log_mode = ASYNC; }
580  void setSyncLog() { log_mode = SYNC; }
581 
582  FlushMode getFlushMode() const { return flush_mode; }
583  void setFlushMode(FlushMode mode) { flush_mode = mode; }
584  LogMode getLogMode() const { return log_mode; }
585  void setLogMode(LogMode mode) { log_mode = mode; }
586 
587  bool use_lock_free = true;
588 
589  friend class LogIterator;
590 
591 private:
592  DataBlock *first, *prepare;
593  ZEROERR_ATOMIC(DataBlock*) m_last;
594  Logger* logger = nullptr;
595  FlushMode flush_mode = FLUSH_AT_ONCE;
596  LogMode log_mode = SYNC;
597 #ifndef ZEROERR_NO_THREAD_SAFE
598  std::mutex* mutex;
599 #endif
600 
601  // The implementation of alloc objects by giving a size
602  void* alloc_block(unsigned size);
603  void* alloc_block_lockfree(unsigned size);
604 
605  // The implementation of getLog which returns a raw pointer
606  // This way can reduce the overhead of code generation by template
607  void* getRawLog(std::string func, unsigned line, std::string name);
608  void* getRawLog(std::string func, std::string msg, std::string name);
609 };
610 
611 
612 template <typename... T>
613 PushResult log(T&&... args) {
614  return LogStream::getDefault().push(std::forward<T>(args)...);
615 }
616 
617 template <typename... T>
618 PushResult log(LogStream& stream, T&&... args) {
619  return stream.push(std::forward<T>(args)...);
620 }
621 
622 
629 public:
630  virtual void str(std::ostream& os) const = 0;
631 };
632 
633 extern thread_local std::vector<IContextScope*> _ZEROERR_G_CONTEXT_SCOPE_VECTOR;
634 
635 template <typename F>
636 class ContextScope : public IContextScope {
637 public:
638  ContextScope(F f) : f_(f) { _ZEROERR_G_CONTEXT_SCOPE_VECTOR.push_back(this); }
640 
641  virtual void str(std::ostream& os) const override { return f_(os); }
642 
643 protected:
644  F f_;
645 };
646 
647 template <typename F>
649  return ContextScope<F>(f);
650 }
651 
652 
653 } // namespace zeroerr
654 
Definition: log.h:636
ContextScope(F f)
Definition: log.h:638
F f_
Definition: log.h:644
virtual void str(std::ostream &os) const override
Definition: log.h:641
~ContextScope()
Definition: log.h:639
ContextScope is a helper class created in each basic block where you use INFO(). The context scope ca...
Definition: log.h:628
virtual void str(std::ostream &os) const =0
LogIterator is a class to iterate the log messages.
Definition: log.h:418
void check_at_safe_pos()
Definition: log.cpp:182
DataBlock * p
Definition: log.h:459
LogIterator & operator++()
Definition: log.cpp:202
LogMessage & get() const
Definition: log.h:447
int line_filter
Definition: log.h:464
LogMessage & operator*() const
Definition: log.h:448
LogIterator(const LogIterator &rhs)
Definition: log.h:423
std::string message_filter
Definition: log.h:463
LogIterator operator++(int)
Definition: log.h:431
std::string function_name_filter
Definition: log.h:462
LogIterator()
Definition: log.h:420
LogIterator & operator=(const LogIterator &rhs)
Definition: log.h:424
bool operator!=(const LogIterator &rhs) const
Definition: log.h:445
LogMessage * q
Definition: log.h:460
bool operator==(const LogIterator &rhs) const
Definition: log.h:444
T get(std::string name)
Definition: log.h:438
bool check_filter()
Definition: log.cpp:209
void next()
Definition: log.cpp:189
LogMessage * operator->() const
Definition: log.h:449
LogStream is a class to manage the log messages.
Definition: log.h:475
LogIterator begin(std::string message="", std::string function_name="", int line=-1)
Definition: log.h:562
void setFlushMode(FlushMode mode)
Definition: log.h:583
void setFlushManually()
Definition: log.h:578
T getLog(std::string func, unsigned line, std::string name)
get a log message from the stream
Definition: log.h:538
void setLogMode(LogMode mode)
Definition: log.h:585
void setFlushWhenFull()
Definition: log.h:577
void setFileLogger(std::string name, DirMode mode1=SINGLE_FILE, DirMode mode2=SINGLE_FILE, DirMode mode3=SINGLE_FILE)
Definition: log.cpp:377
LogMode
Definition: log.h:481
@ SYNC
Definition: log.h:481
@ ASYNC
Definition: log.h:481
virtual ~LogStream()
Definition: log.cpp:72
void flush()
Definition: log.cpp:140
void setAsyncLog()
Definition: log.h:579
LogStream()
Definition: log.cpp:63
FlushMode
Definition: log.h:480
@ FLUSH_AT_ONCE
Definition: log.h:480
@ FLUSH_MANUALLY
Definition: log.h:480
@ FLUSH_WHEN_FULL
Definition: log.h:480
void setSyncLog()
Definition: log.h:580
LogIterator current(std::string message="", std::string function_name="", int line=-1)
Definition: log.cpp:132
LogMode getLogMode() const
Definition: log.h:584
PushResult push(T &&... args)
push a log message to the stream
Definition: log.h:512
bool use_lock_free
Definition: log.h:587
DirMode
Definition: log.h:482
@ SPLIT_BY_SEVERITY
Definition: log.h:485
@ SPLIT_BY_CATEGORY
Definition: log.h:486
@ DAILY_FILE
Definition: log.h:484
@ SINGLE_FILE
Definition: log.h:483
void setStderrLogger()
Definition: log.cpp:394
void setFlushAtOnce()
Definition: log.h:576
FlushMode getFlushMode() const
Definition: log.h:582
void setStdoutLogger()
Definition: log.cpp:389
friend class LogIterator
Definition: log.h:589
LogIterator end()
Definition: log.h:565
T getLog(std::string func, std::string msg, std::string name)
get a log message from the stream
Definition: log.h:556
static LogStream & getDefault()
Definition: log.cpp:372
Definition: log.h:388
virtual void flush(DataBlock *)=0
virtual ~Logger()=default
#define ZEROERR_SUPPRESS_COMMON_WARNINGS_POP
Definition: config.h:265
#define ZEROERR_SUPPRESS_COMMON_WARNINGS_PUSH
Definition: config.h:218
ZEROERR_SUPPRESS_COMMON_WARNINGS_PUSH const char * ZEROERR_LOG_CATEGORY
Definition: log.cpp:13
std::string gen_str(const char *msg, const T &args, seq< I... >)
Definition: log.h:211
typename to_store_type< T >::type to_store_type_t
Definition: typetraits.h:171
std::string gen_str(const char *msg, const T &, seq<>)
Definition: log.h:216
void visit_at(const std::tuple< Ts... > &tup, size_t idx, F &&fun)
Definition: typetraits.h:192
Definition: benchmark.cpp:17
void suspendLog()
suspend the log to flush to the file
Definition: log.cpp:427
thread_local std::vector< IContextScope * > _ZEROERR_G_CONTEXT_SCOPE_VECTOR
Definition: log.cpp:20
void setLogCustomCallback(LogCustomCallback callback)
set the log custom callback, this can support custom format of the log message
Definition: log.cpp:24
LogSeverity
Definition: log.h:223
@ FATAL_l
Definition: log.h:228
@ WARN_l
Definition: log.h:226
@ LOG_l
Definition: log.h:225
@ INFO_l
Definition: log.h:224
@ ERROR_l
Definition: log.h:227
PushResult log(T &&... args)
Definition: log.h:613
void resumeLog()
resume the log to flush to the file
Definition: log.cpp:432
void setLogLevel(LogSeverity level)
set the log level
Definition: log.cpp:406
ContextScope< F > MakeContextScope(const F &f)
Definition: log.h:648
std::string format(const char *fmt, T... args)
Format a string with arguments.
Definition: format.h:25
std::string(* LogCustomCallback)(const LogMessage &, bool colorful)
Definition: log.h:271
void setLogCategory(const char *categories)
set the log category
Definition: log.cpp:408
int _ZEROERR_G_VERBOSE
Definition: log.cpp:18
Definition: log.cpp:52
LogInfo is a struct to store the meta data of the log message.
Definition: log.h:256
LogSeverity severity
Definition: log.h:263
std::map< std::string, int > names
Definition: log.h:264
const char * category
Definition: log.h:260
const char * filename
Definition: log.h:257
unsigned line
Definition: log.h:261
LogInfo(const char *filename, const char *function, const char *message, const char *category, unsigned line, unsigned size, LogSeverity severity)
Definition: log.cpp:27
unsigned size
Definition: log.h:262
const char * message
Definition: log.h:259
void * ptr
Definition: log.h:346
void operator()(H &v)
Definition: log.h:348
PrintTupleData()
Definition: log.h:364
Printer print
Definition: log.h:361
std::map< std::string, std::string > data
Definition: log.h:360
std::string name
Definition: log.h:362
void operator()(H &v)
Definition: log.h:370
LogMessageImpl is the implementation of the LogMessage.
Definition: log.h:336
void * getRawLog(std::string name) const override
Definition: log.h:353
LogMessageImpl(T... args)
Definition: log.h:338
std::tuple< T... > args
Definition: log.h:337
std::map< std::string, std::string > getData() const override
Definition: log.h:375
std::string str() const override
Definition: log.h:340
LogMessage is a class to store the log message.
Definition: log.h:306
std::chrono::system_clock::time_point time
Definition: log.h:325
virtual std::string str() const =0
const LogInfo * info
Definition: log.h:322
virtual std::map< std::string, std::string > getData() const =0
LogMessage()
Definition: log.h:308
virtual void * getRawLog(std::string name) const =0
A functor class Printer for printing a value of any type.
Definition: print.h:80
bool isCompact
Definition: print.h:122
const char * line_break
Definition: print.h:125
Definition: log.h:394
LogStream & stream
Definition: log.h:397
LogMessage * log
Definition: log.h:395
unsigned size
Definition: log.h:396
Definition: typetraits.h:58
Definition: typetraits.h:55
#define ZEROERR_ATOMIC(x)
Definition: threadsafe.h:16