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 <map>
13#include <string>
14#include <vector>
15
17
18extern const char* ZEROERR_LOG_CATEGORY;
19
20namespace std {
21class mutex;
22}
23
24namespace 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
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
STL namespace.
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:206
void visit_at(const std::tuple< Ts... > &tup, size_t idx, F &&fun)
Definition typetraits.h:227
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:63
bool isCompact
Definition print.h:105
const char * line_break
Definition print.h:108
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:77
Definition typetraits.h:74
#define ZEROERR_ATOMIC(x)
Definition threadsafe.h:22