ZeroErr
Loading...
Searching...
No Matches
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 <iosfwd>
13#include <map>
14#include <string>
15#include <vector>
16
18
19extern const char* ZEROERR_LOG_CATEGORY;
20
21namespace zeroerr {
22
23// clang-format off
24#define ZEROERR_INFO(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_INFO_(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
25#define ZEROERR_LOG(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_LOG_(LOG_l, __VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
26#define ZEROERR_WARN(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_LOG_(WARN_l, __VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
27#define ZEROERR_ERROR(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_LOG_(ERROR_l, __VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
28#define ZEROERR_FATAL(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_LOG_(FATAL_l, __VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
29// clang-format on
30
31#ifdef ZEROERR_USE_SHORT_LOG_MACRO
32
33#ifdef INFO
34#undef INFO
35#endif
36
37#ifdef LOG
38#undef LOG
39#endif
40
41#ifdef WARN
42#undef WARN
43#endif
44
45#ifdef ERR
46#undef ERR
47#endif
48
49#ifdef FATAL
50#undef FATAL
51#endif
52
53#ifdef VERBOSE
54#undef VERBOSE
55#endif
56
57#define INFO(...) ZEROERR_INFO(__VA_ARGS__)
58#define LOG(...) ZEROERR_LOG(__VA_ARGS__)
59#define WARN(...) ZEROERR_WARN(__VA_ARGS__)
60#define ERR(...) ZEROERR_ERROR(__VA_ARGS__)
61#define FATAL(...) ZEROERR_FATAL(__VA_ARGS__)
62#define VERBOSE(v) ZEROERR_VERBOSE(v)
63
64#define LOG_GET(func, id, name, type) ZEROERR_LOG_GET(func, id, name, type)
65
66#endif // ZEROERR_USE_SHORT_LOG_MACRO
67
68#define ZEROERR_LOG_IF(condition, ACTION, ...) \
69 do { \
70 if (condition) ACTION(__VA_ARGS__); \
71 } while (0)
72
73
74#define INFO_IF(cond, ...) ZEROERR_LOG_IF(cond, ZEROERR_INFO, __VA_ARGS__)
75#define LOG_IF(cond, ...) ZEROERR_LOG_IF(cond, ZEROERR_LOG, __VA_ARGS__)
76#define WARN_IF(cond, ...) ZEROERR_LOG_IF(cond, ZEROERR_WARN, __VA_ARGS__)
77#define ERR_IF(cond, ...) ZEROERR_LOG_IF(cond, ZEROERR_ERROR, __VA_ARGS__)
78#define FATAL_IF(cond, ...) ZEROERR_LOG_IF(cond, ZEROERR_FATAL, __VA_ARGS__)
79
80
81#define ZEROERR_LOG_EVERY_(n, ACTION, ...) \
82 do { \
83 static unsigned counter = 0; \
84 if (counter == 0) { \
85 counter = n; \
86 ACTION(__VA_ARGS__); \
87 } \
88 --counter; \
89 } while (0)
90
91
92#define INFO_EVERY_(n, ...) ZEROERR_LOG_EVERY_(n, ZEROERR_INFO, __VA_ARGS__)
93#define LOG_EVERY_(n, ...) ZEROERR_LOG_EVERY_(n, ZEROERR_LOG, __VA_ARGS__)
94#define WARN_EVERY_(n, ...) ZEROERR_LOG_EVERY_(n, ZEROERR_WARN, __VA_ARGS__)
95#define ERR_EVERY_(n, ...) ZEROERR_LOG_EVERY_(n, ZEROERR_ERROR, __VA_ARGS__)
96#define FATAL_EVERY_(n, ...) ZEROERR_LOG_EVERY_(n, ZEROERR_FATAL, __VA_ARGS__)
97
98
99#define ZEROERR_LOG_IF_EVERY_(n, cond, ACTION, ...) \
100 do { \
101 if (cond) { \
102 static unsigned counter = 0; \
103 if (counter == 0) { \
104 counter = n; \
105 ACTION(__VA_ARGS__); \
106 } \
107 --counter; \
108 } \
109 } while (0)
110
111#define INFO_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_INFO, __VA_ARGS__)
112#define LOG_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_LOG, __VA_ARGS__)
113#define WARN_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_WARN, __VA_ARGS__)
114#define ERR_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_ERROR, __VA_ARGS__)
115#define FATAL_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_FATAL, __VA_ARGS__)
116
117#define ZEROERR_LOG_FIRST(cond, ACTION, ...) \
118 do { \
119 static bool first = true; \
120 if (first && (cond)) { \
121 first = false; \
122 ACTION(__VA_ARGS__); \
123 } \
124 } while (0)
125
126#define INFO_FIRST(cond, ...) ZEROERR_LOG_FIRST(cond, ZEROERR_INFO, __VA_ARGS__)
127#define LOG_FIRST(cond, ...) ZEROERR_LOG_FIRST(cond, ZEROERR_LOG, __VA_ARGS__)
128#define WARN_FIRST(cond, ...) ZEROERR_LOG_FIRST(cond, ZEROERR_WARN, __VA_ARGS__)
129#define ERR_FIRST(cond, ...) ZEROERR_LOG_FIRST(cond, ZEROERR_ERROR, __VA_ARGS__)
130#define FATAL_FIRST(cond, ...) ZEROERR_LOG_FIRST(cond, ZEROERR_FATAL, __VA_ARGS__)
131
132#define ZEROERR_LOG_FIRST_(n, cond, ACTION, ...) \
133 do { \
134 static unsigned counter = n; \
135 if (counter && (cond)) { \
136 counter--; \
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
153extern 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
208namespace detail {
209
210template <typename T, unsigned... I>
211std::string gen_str(const char* msg, const T& args, seq<I...>) {
212 return format(msg, std::get<I>(args)...);
213}
214
215template <typename T>
216std::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
256struct 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
270struct LogMessage;
271typedef std::string (*LogCustomCallback)(const LogMessage&, bool colorful);
272
276extern void setLogLevel(LogSeverity level);
277
281extern void setLogCategory(const char* categories);
282
286extern void setLogCustomCallback(LogCustomCallback callback);
287
291extern void suspendLog();
292
296extern void resumeLog();
297
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
335template <typename... T>
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
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
385struct DataBlock;
386class LogStream;
387
388class Logger {
389public:
390 virtual ~Logger() = default;
391 virtual void flush(DataBlock*) = 0;
392};
393
399
419public:
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
455protected:
456 bool check_filter();
457 void next();
458
461
463 std::string message_filter;
464 int line_filter = -1;
465};
466
476public:
477 LogStream();
478 virtual ~LogStream();
479
481 enum LogMode { ASYNC, SYNC };
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 }
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
591private:
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
612template <typename... T>
613PushResult log(T&&... args) {
614 return LogStream::getDefault().push(std::forward<T>(args)...);
615}
616
617template <typename... T>
618PushResult log(LogStream& stream, T&&... args) {
619 return stream.push(std::forward<T>(args)...);
620}
621
622
629public:
630 virtual void str(std::ostream& os) const = 0;
631};
632
633extern thread_local std::vector<IContextScope*> _ZEROERR_G_CONTEXT_SCOPE_VECTOR;
634
635template <typename F>
637public:
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
643protected:
644 F f_;
645};
646
647template <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:187
DataBlock * p
Definition log.h:459
LogIterator & operator++()
Definition log.cpp:207
int line_filter
Definition log.h:464
LogIterator(const LogIterator &rhs)
Definition log.h:423
std::string message_filter
Definition log.h:463
LogIterator operator++(int)
Definition log.h:431
LogMessage & operator*() const
Definition log.h:448
std::string function_name_filter
Definition log.h:462
LogIterator()
Definition log.h:420
LogMessage & get() const
Definition log.h:447
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:214
LogIterator & operator=(const LogIterator &rhs)
Definition log.h:424
void next()
Definition log.cpp:194
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:382
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:399
void setFlushAtOnce()
Definition log.h:576
FlushMode getFlushMode() const
Definition log.h:582
void setStdoutLogger()
Definition log.cpp:394
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:377
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:192
void visit_at(const std::tuple< Ts... > &tup, size_t idx, F &&fun)
Definition typetraits.h:213
Definition benchmark.cpp:17
void suspendLog()
suspend the log to flush to the file
Definition log.cpp:432
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:437
void setLogLevel(LogSeverity level)
set the log level
Definition log.cpp:411
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:413
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
unsigned size
Definition log.h:262
const char * function
Definition log.h:258
const char * message
Definition log.h:259
void * ptr
Definition log.h:346
void operator()(H &v)
Definition log.h:348
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
LogMessageImpl(T... args)
Definition log.h:338
std::map< std::string, std::string > getData() const override
Definition log.h:375
void * getRawLog(std::string name) const override
Definition log.h:353
std::tuple< T... > args
Definition log.h:337
std::string str() const override
Definition log.h:340
LogMessage is a class to store the log message.
Definition log.h:306
virtual void * getRawLog(std::string name) const =0
std::chrono::system_clock::time_point time
Definition log.h:325
virtual std::map< std::string, std::string > getData() const =0
virtual std::string str() const =0
const LogInfo * info
Definition log.h:322
LogMessage()
Definition log.h:308
A functor class Printer for printing a value of any type.
Definition print.h:62
bool isCompact
Definition print.h:104
const char * line_break
Definition print.h:107
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:63
Definition typetraits.h:60
#define ZEROERR_ATOMIC(x)
Definition threadsafe.h:22