ZeroErr
Loading...
Searching...
No Matches
log.h
Go to the documentation of this file.
1#pragma once
2
3// libc++ offers compatibility-only transitive includes through C++20.
4// Suppress those while loading our explicit dependencies, then restore the
5// caller's setting. This does not change standard-library types or ABI.
6#pragma push_macro("_LIBCPP_REMOVE_TRANSITIVE_INCLUDES")
7#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
8#define _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
9#endif
10
12
15
16#include "zeroerr/dbg.h"
17#include "zeroerr/format.h"
18#include "zeroerr/print.h"
19
21#include <iosfwd>
22#include <cstddef>
23#include <map>
24#include "zeroerr/string.h"
25#include <utility>
26#include <vector>
27
29
30extern const char* ZEROERR_LOG_CATEGORY;
31
32namespace zeroerr {
33
34// clang-format off
35#define ZEROERR_INFO(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_INFO_(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
36#define ZEROERR_LOG(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_LOG_(LOG_l, __VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
37#define ZEROERR_WARN(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_LOG_(WARN_l, __VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
38#define ZEROERR_ERROR(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_LOG_(ERROR_l, __VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
39#define ZEROERR_FATAL(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_LOG_(FATAL_l, __VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
40// clang-format on
41
42#ifdef ZEROERR_USE_SHORT_LOG_MACRO
43
44#ifdef INFO
45#undef INFO
46#endif
47
48#ifdef LOG
49#undef LOG
50#endif
51
52#ifdef WARN
53#undef WARN
54#endif
55
56#ifdef ERR
57#undef ERR
58#endif
59
60#ifdef FATAL
61#undef FATAL
62#endif
63
64#ifdef VERBOSE
65#undef VERBOSE
66#endif
67
68#define INFO(...) ZEROERR_INFO(__VA_ARGS__)
69#define LOG(...) ZEROERR_LOG(__VA_ARGS__)
70#define WARN(...) ZEROERR_WARN(__VA_ARGS__)
71#define ERR(...) ZEROERR_ERROR(__VA_ARGS__)
72#define FATAL(...) ZEROERR_FATAL(__VA_ARGS__)
73#define VERBOSE(v) ZEROERR_VERBOSE(v)
74
75#define LOG_GET(func, id, name, type) ZEROERR_LOG_GET(func, id, name, type)
76
77#endif // ZEROERR_USE_SHORT_LOG_MACRO
78
79#define ZEROERR_LOG_IF(condition, ACTION, ...) \
80 do { \
81 if (condition) ACTION(__VA_ARGS__); \
82 } while (0)
83
84
85#define INFO_IF(cond, ...) ZEROERR_LOG_IF(cond, ZEROERR_INFO, __VA_ARGS__)
86#define LOG_IF(cond, ...) ZEROERR_LOG_IF(cond, ZEROERR_LOG, __VA_ARGS__)
87#define WARN_IF(cond, ...) ZEROERR_LOG_IF(cond, ZEROERR_WARN, __VA_ARGS__)
88#define ERR_IF(cond, ...) ZEROERR_LOG_IF(cond, ZEROERR_ERROR, __VA_ARGS__)
89#define FATAL_IF(cond, ...) ZEROERR_LOG_IF(cond, ZEROERR_FATAL, __VA_ARGS__)
90
91
92#define ZEROERR_LOG_EVERY_(n, ACTION, ...) \
93 do { \
94 static unsigned counter = 0; \
95 if (counter == 0) { \
96 counter = n; \
97 ACTION(__VA_ARGS__); \
98 } \
99 --counter; \
100 } while (0)
101
102
103#define INFO_EVERY_(n, ...) ZEROERR_LOG_EVERY_(n, ZEROERR_INFO, __VA_ARGS__)
104#define LOG_EVERY_(n, ...) ZEROERR_LOG_EVERY_(n, ZEROERR_LOG, __VA_ARGS__)
105#define WARN_EVERY_(n, ...) ZEROERR_LOG_EVERY_(n, ZEROERR_WARN, __VA_ARGS__)
106#define ERR_EVERY_(n, ...) ZEROERR_LOG_EVERY_(n, ZEROERR_ERROR, __VA_ARGS__)
107#define FATAL_EVERY_(n, ...) ZEROERR_LOG_EVERY_(n, ZEROERR_FATAL, __VA_ARGS__)
108
109
110#define ZEROERR_LOG_IF_EVERY_(n, cond, ACTION, ...) \
111 do { \
112 if (cond) { \
113 static unsigned counter = 0; \
114 if (counter == 0) { \
115 counter = n; \
116 ACTION(__VA_ARGS__); \
117 } \
118 --counter; \
119 } \
120 } while (0)
121
122#define INFO_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_INFO, __VA_ARGS__)
123#define LOG_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_LOG, __VA_ARGS__)
124#define WARN_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_WARN, __VA_ARGS__)
125#define ERR_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_ERROR, __VA_ARGS__)
126#define FATAL_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_FATAL, __VA_ARGS__)
127
128#define ZEROERR_LOG_FIRST(cond, ACTION, ...) \
129 do { \
130 static bool first = true; \
131 if (first && (cond)) { \
132 first = false; \
133 ACTION(__VA_ARGS__); \
134 } \
135 } while (0)
136
137#define INFO_FIRST(cond, ...) ZEROERR_LOG_FIRST(cond, ZEROERR_INFO, __VA_ARGS__)
138#define LOG_FIRST(cond, ...) ZEROERR_LOG_FIRST(cond, ZEROERR_LOG, __VA_ARGS__)
139#define WARN_FIRST(cond, ...) ZEROERR_LOG_FIRST(cond, ZEROERR_WARN, __VA_ARGS__)
140#define ERR_FIRST(cond, ...) ZEROERR_LOG_FIRST(cond, ZEROERR_ERROR, __VA_ARGS__)
141#define FATAL_FIRST(cond, ...) ZEROERR_LOG_FIRST(cond, ZEROERR_FATAL, __VA_ARGS__)
142
143#define ZEROERR_LOG_FIRST_(n, cond, ACTION, ...) \
144 do { \
145 static unsigned counter = n; \
146 if (counter && (cond)) { \
147 counter--; \
148 ACTION(__VA_ARGS__); \
149 } \
150 } while (0)
151
152#define INFO_FIRST_(n, cond, ...) ZEROERR_LOG_FIRST_(n, cond, ZEROERR_INFO, __VA_ARGS__)
153#define LOG_FIRST_(n, cond, ...) ZEROERR_LOG_FIRST_(n, cond, ZEROERR_LOG, __VA_ARGS__)
154#define WARN_FIRST_(n, cond, ...) ZEROERR_LOG_FIRST_(n, cond, ZEROERR_WARN, __VA_ARGS__)
155#define ERR_FIRST_(n, cond, ...) ZEROERR_LOG_FIRST_(n, cond, ZEROERR_ERROR, __VA_ARGS__)
156#define FATAL_FIRST_(n, cond, ...) ZEROERR_LOG_FIRST_(n, cond, ZEROERR_FATAL, __VA_ARGS__)
157
158#ifdef _DEBUG
159#define DLOG(ACTION, ...) ZEROERR_EXPAND(ACTION(__VA_ARGS__))
160#else
161#define DLOG(ACTION, ...)
162#endif
163
164extern int _ZEROERR_G_VERBOSE;
165
166#define ZEROERR_VERBOSE(v) if (zeroerr::_ZEROERR_G_VERBOSE >= (v))
167
168#define ZEROERR_LOG_(severity, message, ...) \
169 do { \
170 ZEROERR_G_CONTEXT_SCOPE(true); \
171 auto msg = zeroerr::makeLogRecord(__VA_ARGS__); \
172 \
173 static zeroerr::LogInfo log_info{__FILE__, \
174 __func__, \
175 message, \
176 ZEROERR_LOG_CATEGORY, \
177 __LINE__, \
178 sizeof(msg.entry), \
179 zeroerr::LogSeverity::severity}; \
180 msg.entry.info = &log_info; \
181 msg.stream.write(std::move(msg.entry)); \
182 } while (0)
183
184#define ZEROERR_INFO_(...) \
185 ZEROERR_INFO_IMPL(ZEROERR_NAMEGEN(_capture_), ZEROERR_NAMEGEN(_capture_), __VA_ARGS__)
186
187#define ZEROERR_INFO_IMPL(mb_name, v_name, ...) \
188 auto v_name = zeroerr::MakeContextScope([&](zeroerr::StringBuffer& _capture_name) { \
189 zeroerr::Printer print(_capture_name); \
190 print.isQuoted = false; \
191 print(__VA_ARGS__); \
192 })
193
194#ifdef ZEROERR_G_CONTEXT_SCOPE
195#undef ZEROERR_G_CONTEXT_SCOPE
196#endif
197
198#define ZEROERR_G_CONTEXT_SCOPE(x) \
199 if (x) { \
200 for (auto* zeroerr_context_scope : zeroerr::_ZEROERR_G_CONTEXT_SCOPE_VECTOR) { \
201 zeroerr_context_scope->str(zeroerr::getStderrPrinter().os); \
202 } \
203 }
204
205#ifdef ZEROERR_PRINT_ASSERT_DEFAULT_PRINTER
206#undef ZEROERR_PRINT_ASSERT_DEFAULT_PRINTER
207#endif
208
209#define ZEROERR_PRINT_ASSERT_DEFAULT_PRINTER(cond, level, ...) \
210 ZEROERR_LOG_IF(cond, level, __VA_ARGS__)
211
212
213// This macro can access the log in memory
214#define ZEROERR_LOG_GET(func, id, name, type) \
215 zeroerr::LogStream::getDefault().getLog<type>(#func, id, #name)
216
217
218namespace detail {
219
220template <typename T, unsigned... I>
221zeroerr::String gen_str(const char* msg, const T& args, seq<I...>) {
222 return format(msg, std::get<I>(args)...);
223}
224
225template <typename T>
226zeroerr::String gen_str(const char* msg, const T&, seq<>) {
227 return msg;
228}
229
230} // namespace detail
231
232
234 INFO_l, // it will not write to file if no other log related
238 FATAL_l, // it will contain a stack trace
239};
240
266struct LogInfo {
267 const char* filename;
268 const char* function;
269 const char* message;
270 const char* category;
271 unsigned line;
272 unsigned size;
274 std::map<zeroerr::String, int> names;
275
276 LogInfo(const char* filename, const char* function, const char* message, const char* category,
277 unsigned line, unsigned size, LogSeverity severity);
278};
279
280struct LogMessage;
281typedef zeroerr::String (*LogCustomCallback)(const LogMessage&, bool colorful);
282
286extern void setLogLevel(LogSeverity level);
287
291extern void setLogCategory(const char* categories);
292
296extern void setLogCustomCallback(LogCustomCallback callback);
297
301extern void suspendLog();
302
306extern void resumeLog();
307
316struct alignas(std::max_align_t) LogMessage {
317 // time is assigned when the log message is created
318 LogMessage();
319
320 // convert the log message to a string
321 virtual zeroerr::String str() const = 0;
322
323 // get the raw data pointer of the field with the name
324 virtual void* getRawLog(zeroerr::String name) const = 0;
325
326 // a map of the data indexing by the field name
327 // for example: log("print {i}", 1);
328 // a map of {"i": "1"} will be returned
329 virtual std::map<zeroerr::String, zeroerr::String> getData() const = 0;
330
331 // meta data of this log message
332 const LogInfo* info = nullptr;
333
334 virtual ~LogMessage() = default;
335
336 // recorded wall time
338};
339
340
347template <typename... T>
349 std::tuple<T...> args;
350 LogMessageImpl(T... args) : LogMessage(), args(std::move(args)...) {}
351
352 zeroerr::String str() const override {
353 return gen_str(info->message, args, detail::gen_seq<sizeof...(T)>{});
354 }
355
356 // This is a helper class to get the raw pointer of the tuple
357 struct GetTuplePtr {
358 void* ptr = nullptr;
359 template <typename H>
360 void operator()(H& v) {
361 ptr = (void*)&v;
362 }
363 };
364
365 void* getRawLog(zeroerr::String name) const override {
366 GetTuplePtr f;
367 detail::visit_at(args, info->names.at(name), f);
368 return f.ptr;
369 }
370
372 std::map<zeroerr::String, zeroerr::String> data;
375
377 print.isCompact = true;
378 print.line_break = "";
379 }
380
381 template <typename H>
382 void operator()(H& v) {
383 data[name] = print(v);
384 }
385 };
386
387 std::map<zeroerr::String, zeroerr::String> getData() const override {
388 PrintTupleData printer;
389 for (auto it = info->names.begin(); it != info->names.end(); ++it) {
390 printer.name = it->first;
391 detail::visit_at(args, it->second, printer);
392 }
393 return printer.data;
394 }
395};
396
397struct DataBlock;
398class LogStream;
399
400class Logger {
401public:
402 virtual ~Logger() = default;
403 virtual void flush(DataBlock*) = 0;
404};
405
411
431public:
432 LogIterator() : p(nullptr), q(nullptr) {}
433 LogIterator(LogStream& stream, zeroerr::String message = "", zeroerr::String function_name = "",
434 int line = -1);
435 LogIterator(const LogIterator& rhs) : p(rhs.p), q(rhs.q) {}
437 p = rhs.p;
438 q = rhs.q;
439 return *this;
440 }
441
444 LogIterator tmp = *this;
445 ++*this;
446 return tmp;
447 }
448
449 template <typename T>
451 void* data = q->getRawLog(name);
452 if (data) return *(T*)(data);
453 return T{};
454 }
455
456 bool operator==(const LogIterator& rhs) const { return p == rhs.p && q == rhs.q; }
457 bool operator!=(const LogIterator& rhs) const { return !(*this == rhs); }
458
459 LogMessage& get() const { return *q; }
460 LogMessage& operator*() const { return *q; }
461 LogMessage* operator->() const { return q; }
462
463 void check_at_safe_pos();
464
465 friend class LogStream;
466
467protected:
468 bool check_filter();
469 void next();
470
473
476 int line_filter = -1;
477};
478
488public:
489 LogStream();
490 virtual ~LogStream();
491
493 enum LogMode { ASYNC, SYNC };
500
501
523 // Low-level API: callers must externally synchronize metadata assignment
524 // and flush. Prefer LOG/ZEROERR_LOG for concurrent producers.
525 template <typename... T>
526 PushResult push(T&&... args) {
527 static_assert(alignof(LogMessageImpl<detail::to_store_type_t<T>...>) <= alignof(std::max_align_t),
528 "Over-aligned log arguments are not supported");
529 ZEROERR_LOCK(*mutex);
530 unsigned size = sizeof(LogMessageImpl<detail::to_store_type_t<T>...>);
531 void* p = alloc_block(size);
532 LogMessage* msg =
533 new (p) LogMessageImpl<detail::to_store_type_t<T>...>(std::forward<T>(args)...);
534 commit_block(ZEROERR_LOAD(m_last), size);
535 return {msg, size, *this};
536 }
537
538
539 // Construct arguments before acquiring the stream lock. Publish only complete
540 // records, so a concurrent flush cannot observe partially initialized data.
541 template <typename... T>
542 void write(LogMessageImpl<T...>&& message) {
543 static_assert(alignof(LogMessageImpl<T...>) <= alignof(std::max_align_t),
544 "Over-aligned log arguments are not supported");
545 ZEROERR_LOCK(*mutex);
546 void* storage = alloc_block(sizeof(message));
547 new (storage) LogMessageImpl<T...>(std::move(message));
548 auto* last = ZEROERR_LOAD(m_last);
549 commit_block(last, sizeof(message));
550 if (flush_mode == FLUSH_AT_ONCE) flush_unlocked();
551 }
552
564 template <typename T>
565 T getLog(zeroerr::String func, unsigned line, zeroerr::String name) {
566 void* data = getRawLog(func, line, name);
567 if (data) return *(T*)(data);
568 return T{};
569 }
570
582 template <typename T>
584 void* data = getRawLog(func, msg, name);
585 if (data) return *(T*)(data);
586 return T{};
587 }
588
589 LogIterator begin(zeroerr::String message = "", zeroerr::String function_name = "", int line = -1) {
590 return LogIterator(*this, message, function_name, line);
591 }
593 LogIterator current(zeroerr::String message = "", zeroerr::String function_name = "", int line = -1);
594
595 void flush();
597 DirMode mode3 = SINGLE_FILE);
598 void setStdoutLogger();
599 void setStderrLogger();
600
601 static LogStream& getDefault();
602
603 void setFlushAtOnce() { flush_mode = FLUSH_AT_ONCE; }
604 void setFlushWhenFull() { flush_mode = FLUSH_WHEN_FULL; }
605 void setFlushManually() { flush_mode = FLUSH_MANUALLY; }
606 void setAsyncLog() { log_mode = ASYNC; }
607 void setSyncLog() { log_mode = SYNC; }
608
609 FlushMode getFlushMode() const { return flush_mode; }
610 void setFlushMode(FlushMode mode) { flush_mode = mode; }
611 LogMode getLogMode() const { return log_mode; }
612 void setLogMode(LogMode mode) { log_mode = mode; }
613
614 // Compatibility flag; publication now always uses the stream mutex.
615 bool use_lock_free = true;
616
617 friend class LogIterator;
618
619private:
620 DataBlock* first;
621 ZEROERR_ATOMIC(DataBlock*) m_last;
622 Logger* logger = nullptr;
623 FlushMode flush_mode = FLUSH_AT_ONCE;
624 LogMode log_mode = SYNC;
625#ifndef ZEROERR_NO_THREAD_SAFE
626 detail::Mutex* mutex;
627#endif
628
629 // The implementation of alloc objects by giving a size
630 void* alloc_block(unsigned size);
631 void commit_block(DataBlock* block, unsigned size);
632 void flush_unlocked();
633
634
635 // The implementation of getLog which returns a raw pointer
636 // This way can reduce the overhead of code generation by template
637 void* getRawLog(zeroerr::String func, unsigned line, zeroerr::String name);
638 void* getRawLog(zeroerr::String func, zeroerr::String msg, zeroerr::String name);
639};
640
641
642// A temporary owns argument storage while producers prepare records in parallel.
643template <typename... T>
650
651template <typename... T>
652LogRecord<T...> makeLogRecord(LogStream& stream, T&&... args) {
653 return LogRecord<T...>(stream, std::forward<T>(args)...);
654}
655
656template <typename... T>
657LogRecord<T...> makeLogRecord(T&&... args) {
658 return LogRecord<T...>(LogStream::getDefault(), std::forward<T>(args)...);
659}
660
661template <typename... T>
662PushResult log(T&&... args) {
663 return LogStream::getDefault().push(std::forward<T>(args)...);
664}
665
666template <typename... T>
667PushResult log(LogStream& stream, T&&... args) {
668 return stream.push(std::forward<T>(args)...);
669}
670
671
678public:
683 virtual void str(zeroerr::StringBuffer& os) const = 0;
684};
685
686extern thread_local std::vector<IContextScope*> _ZEROERR_G_CONTEXT_SCOPE_VECTOR;
687
694template <typename F>
696public:
697 ContextScope(F f) : f_(f) { _ZEROERR_G_CONTEXT_SCOPE_VECTOR.push_back(this); }
699
700 virtual void str(zeroerr::StringBuffer& os) const override { return f_(os); }
701
702protected:
703 F f_;
704};
705
712template <typename F>
714 return ContextScope<F>(f);
715}
716
717
718} // namespace zeroerr
719
721
722#pragma pop_macro("_LIBCPP_REMOVE_TRANSITIVE_INCLUDES")
Template implementation of context scope.
Definition log.h:695
ContextScope(F f)
Definition log.h:697
virtual void str(zeroerr::StringBuffer &os) const override
Output context information to a stream.
Definition log.h:700
F f_
Definition log.h:703
~ContextScope()
Definition log.h:698
ContextScope is a helper class created in each basic block where you use INFO(). The context scope ca...
Definition log.h:677
virtual void str(zeroerr::StringBuffer &os) const =0
Output context information to a stream.
LogIterator is a class to iterate the log messages.
Definition log.h:430
void check_at_safe_pos()
Definition log.cpp:186
DataBlock * p
Definition log.h:471
LogIterator & operator++()
Definition log.cpp:206
int line_filter
Definition log.h:476
LogIterator(const LogIterator &rhs)
Definition log.h:435
LogIterator operator++(int)
Definition log.h:443
LogMessage & operator*() const
Definition log.h:460
LogIterator()
Definition log.h:432
zeroerr::String message_filter
Definition log.h:475
LogMessage & get() const
Definition log.h:459
bool operator!=(const LogIterator &rhs) const
Definition log.h:457
LogMessage * q
Definition log.h:472
bool operator==(const LogIterator &rhs) const
Definition log.h:456
friend class LogStream
Definition log.h:465
bool check_filter()
Definition log.cpp:213
LogIterator & operator=(const LogIterator &rhs)
Definition log.h:436
T get(zeroerr::String name)
Definition log.h:450
zeroerr::String function_name_filter
Definition log.h:474
void next()
Definition log.cpp:193
LogMessage * operator->() const
Definition log.h:461
LogStream is a class to manage the log messages.
Definition log.h:487
void setFlushMode(FlushMode mode)
Definition log.h:610
void setFlushManually()
Definition log.h:605
LogIterator current(zeroerr::String message="", zeroerr::String function_name="", int line=-1)
Definition log.cpp:125
void write(LogMessageImpl< T... > &&message)
Definition log.h:542
void setLogMode(LogMode mode)
Definition log.h:612
void setFlushWhenFull()
Definition log.h:604
LogMode
Definition log.h:493
@ SYNC
Definition log.h:493
@ ASYNC
Definition log.h:493
virtual ~LogStream()
Definition log.cpp:89
void flush()
Definition log.cpp:133
void setAsyncLog()
Definition log.h:606
LogStream()
Definition log.cpp:81
FlushMode
Definition log.h:492
@ FLUSH_AT_ONCE
Definition log.h:492
@ FLUSH_MANUALLY
Definition log.h:492
@ FLUSH_WHEN_FULL
Definition log.h:492
T getLog(zeroerr::String func, zeroerr::String msg, zeroerr::String name)
get a log message from the stream
Definition log.h:583
LogIterator begin(zeroerr::String message="", zeroerr::String function_name="", int line=-1)
Definition log.h:589
void setSyncLog()
Definition log.h:607
void setFileLogger(zeroerr::String name, DirMode mode1=SINGLE_FILE, DirMode mode2=SINGLE_FILE, DirMode mode3=SINGLE_FILE)
Definition log.cpp:404
LogMode getLogMode() const
Definition log.h:611
PushResult push(T &&... args)
push a log message to the stream
Definition log.h:526
bool use_lock_free
Definition log.h:615
DirMode
Definition log.h:494
@ SPLIT_BY_SEVERITY
Definition log.h:497
@ SPLIT_BY_CATEGORY
Definition log.h:498
@ DAILY_FILE
Definition log.h:496
@ SINGLE_FILE
Definition log.h:495
void setStderrLogger()
Definition log.cpp:421
void setFlushAtOnce()
Definition log.h:603
FlushMode getFlushMode() const
Definition log.h:609
T getLog(zeroerr::String func, unsigned line, zeroerr::String name)
get a log message from the stream
Definition log.h:565
void setStdoutLogger()
Definition log.cpp:416
friend class LogIterator
Definition log.h:617
LogIterator end()
Definition log.h:592
static LogStream & getDefault()
Definition log.cpp:399
Definition log.h:400
virtual void flush(DataBlock *)=0
virtual ~Logger()=default
Definition buffer.h:7
Definition string.h:41
Definition threadsafe.h:36
#define ZEROERR_SUPPRESS_COMMON_WARNINGS_POP
Definition config.h:283
#define ZEROERR_SUPPRESS_COMMON_WARNINGS_PUSH
Definition config.h:235
const char * ZEROERR_LOG_CATEGORY
Definition log.cpp:20
STL namespace.
void visit_at(T &tup, size_t idx, F &&fun)
Definition typetraits.h:306
zeroerr::String gen_str(const char *msg, const T &args, seq< I... >)
Definition log.h:221
typename to_store_type< T >::type to_store_type_t
Definition typetraits.h:285
Definition assert_text.cpp:5
void suspendLog()
suspend the log to flush to the file
Definition log.cpp:454
std::vector< IContextScope * > _ZEROERR_G_CONTEXT_SCOPE_VECTOR
Definition log.cpp:27
void setLogCustomCallback(LogCustomCallback callback)
set the log custom callback, this can support custom format of the log message
Definition log.cpp:31
zeroerr::String(* LogCustomCallback)(const LogMessage &, bool colorful)
Definition log.h:281
LogSeverity
Definition log.h:233
@ FATAL_l
Definition log.h:238
@ WARN_l
Definition log.h:236
@ LOG_l
Definition log.h:235
@ INFO_l
Definition log.h:234
@ ERROR_l
Definition log.h:237
PushResult log(T &&... args)
Definition log.h:662
void resumeLog()
resume the log to flush to the file
Definition log.cpp:459
void setLogLevel(LogSeverity level)
set the log level
Definition log.cpp:433
ContextScope< F > MakeContextScope(const F &f)
Helper function to create a context scope.
Definition log.h:713
ZEROERR_DIAGNOSTIC_NOINLINE zeroerr::String format(const char *fmt, T &&... args)
Format a string with arguments.
Definition format.h:27
void setLogCategory(const char *categories)
set the log category
Definition log.cpp:435
int _ZEROERR_G_VERBOSE
Definition log.cpp:25
LogRecord< T... > makeLogRecord(LogStream &stream, T &&... args)
Definition log.h:652
Definition log.cpp:59
LogInfo is a struct to store the meta data of the log message.
Definition log.h:266
LogSeverity severity
Definition log.h:273
const char * category
Definition log.h:270
const char * filename
Definition log.h:267
unsigned line
Definition log.h:271
LogInfo(const char *filename, const char *function, const char *message, const char *category, unsigned line, unsigned size, LogSeverity severity)
Definition log.cpp:34
unsigned size
Definition log.h:272
std::map< zeroerr::String, int > names
Definition log.h:274
const char * function
Definition log.h:268
const char * message
Definition log.h:269
void * ptr
Definition log.h:358
void operator()(H &v)
Definition log.h:360
zeroerr::String name
Definition log.h:374
Printer print
Definition log.h:373
std::map< zeroerr::String, zeroerr::String > data
Definition log.h:372
void operator()(H &v)
Definition log.h:382
LogMessageImpl is the implementation of the LogMessage.
Definition log.h:348
void * getRawLog(zeroerr::String name) const override
Definition log.h:365
LogMessageImpl(T... args)
Definition log.h:350
std::tuple< T... > args
Definition log.h:349
zeroerr::String str() const override
Definition log.h:352
std::map< zeroerr::String, zeroerr::String > getData() const override
Definition log.h:387
LogMessage is a class to store the log message.
Definition log.h:316
virtual std::map< zeroerr::String, zeroerr::String > getData() const =0
virtual ~LogMessage()=default
virtual zeroerr::String str() const =0
virtual void * getRawLog(zeroerr::String name) const =0
Timestamp time
Definition log.h:337
const LogInfo * info
Definition log.h:332
LogMessage()
Definition log.cpp:497
Definition log.h:644
LogStream & stream
Definition log.h:645
LogMessageImpl< detail::to_store_type_t< T >... > entry
Definition log.h:646
LogRecord(LogStream &stream, T &&... args)
Definition log.h:647
A functor class Printer for printing a value of any type.
Definition print.h:87
Definition log.h:406
LogStream & stream
Definition log.h:409
LogMessage * log
Definition log.h:407
unsigned size
Definition log.h:408
Definition time.h:15
Definition typetraits.h:77
Definition typetraits.h:74
Definition dbg.h:21
#define ZEROERR_LOAD(x)
Definition threadsafe.h:32
#define ZEROERR_ATOMIC(x)
Definition threadsafe.h:31
#define ZEROERR_LOCK(x)
Definition threadsafe.h:30