NexusForce 1.0.0
A rigorously engineered full-stack C++ backend library.
载入中...
搜索中...
未找到
logger.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_LOGGING_LOGGER_HPP__
2#define NEFORCE_CORE_LOGGING_LOGGER_HPP__
3
14
17#include "NeForce/core/memory/bounded_queue.hpp"
19NEFORCE_BEGIN_NAMESPACE__
20
25
26class logger_registry;
27
43class NEFORCE_API logger : public enable_shared_from_this<logger> {
44 friend class logger_registry;
45
46public:
50 static constexpr log_level INHERIT = static_cast<log_level>(255);
51
52private:
53 string name_;
54 log_level explicit_level_{INHERIT};
55 log_level effective_level_{log_level::INFO};
56 logger* parent_{nullptr};
57 vector<shared_ptr<logger>> children_;
58
59 vector<shared_ptr<log_sink>> sinks_;
60 mutex sinks_mutex_;
61
62 atomic<bool> async_{false};
63 shared_ptr<thread_pool> thread_pool_;
64 atomic<overflow_policy> overflow_{overflow_policy::block};
65 static constexpr size_t DEFAULT_QUEUE_SIZE = 8192;
66 bounded_queue<log_event> async_queue_{DEFAULT_QUEUE_SIZE};
67 mutex queue_mutex_;
68 condition_variable queue_cv_;
69 atomic<bool> drain_scheduled_{false};
70 atomic<bool> running_{false};
71
72 atomic<bool> flush_requested_{false};
73 mutex flush_mutex_;
74 condition_variable flush_cv_;
75
76 function<bool(const log_event&)> filter_;
77 mutex filter_mutex_;
78
79 shared_ptr<unordered_map<string, string>> context_data_{
80 make_shared<unordered_map<string, string>>()};
81 mutable mutex context_mutex_;
82
83 atomic<int64_t> auto_flush_ms_{0};
84 timestamp last_auto_flush_{timestamp::now()};
85
86 void update_effective_level();
87 void propagate_effective_level(log_level new_effective);
88
89 void enqueue_async(log_event&& event);
90
91 void submit_drain();
92 void drain_events();
93
94 void register_child(shared_ptr<logger> child);
95
96 void process_event_direct(const log_event& event);
97
98 void check_auto_flush();
99
100public:
101 ~logger();
102
107 explicit logger(string name);
108
109 logger(const logger&) = delete;
110 logger& operator=(const logger&) = delete;
111 logger(logger&&) = delete;
112 logger& operator=(logger&&) = delete;
113
115 NEFORCE_NODISCARD const string& name() const noexcept { return name_; }
116
118 NEFORCE_NODISCARD logger* parent() const noexcept { return parent_; }
119
125
127 NEFORCE_NODISCARD log_level level() const noexcept { return explicit_level_; }
128
130 NEFORCE_NODISCARD log_level effective_level() const noexcept { return effective_level_; }
131
137 NEFORCE_NODISCARD bool should_log(log_level level) const noexcept {
138 return level >= effective_level_ && level < log_level::OFF;
139 }
140
146
151
158 void enable_async(shared_ptr<thread_pool> pool = nullptr, size_t queue_size = 8192,
160
163
165 NEFORCE_NODISCARD bool is_async() const noexcept { return async_.load(memory_order_acquire); }
166
171 void set_filter(function<bool(const log_event&)> filter);
172
178 void add_context(const string& key, string value);
179
184 void remove_context(const string& key);
185
188
193 void set_auto_flush(int64_t interval_ms) { auto_flush_ms_.store(interval_ms, memory_order_release); }
194
201 void log(log_level level, string msg, source_location loc);
202
204 void trace(string msg, source_location loc) { log(log_level::TRACE, move(msg), loc); }
205
207 void debug(string msg, source_location loc) { log(log_level::DEBUG, move(msg), loc); }
208
210 void info(string msg, source_location loc) { log(log_level::INFO, move(msg), loc); }
211
213 void warn(string msg, source_location loc) { log(log_level::WARN, move(msg), loc); }
214
216 void error(string msg, source_location loc) { log(log_level::ERROR, move(msg), loc); }
217
219 void fatal(string msg, source_location loc) { log(log_level::FATAL, move(msg), loc); }
220
222 void flush();
223};
224
225
233class NEFORCE_API logger_registry {
234private:
235 shared_ptr<logger> root_;
237 mutex mutex_;
238
239 logger_registry();
240 shared_ptr<logger> create_logger(const string& name);
241
242public:
244 static logger_registry& instance();
245
246 logger_registry(const logger_registry&) = delete;
247 logger_registry& operator=(const logger_registry&) = delete;
248
253 NEFORCE_NODISCARD shared_ptr<logger> root_logger();
254
260 shared_ptr<logger> get_logger(const string& name);
261
266 NEFORCE_NODISCARD shared_ptr<logger> default_logger() { return root_logger(); }
267
269 void flush_all();
270};
271
272
274
276#define NEFORCE_LOG_GET_LOGGER() _NEFORCE logger_registry::instance().default_logger()
277
279#define NEFORCE_LOG_BODY(level, msg) \
280 do { \
281 auto _l = NEFORCE_LOG_GET_LOGGER(); \
282 if (_l->should_log(level)) { \
283 _l->log(level, msg, _NEFORCE source_location::current()); \
284 } \
285 } while (false)
286
288#define NEFORCE_LOGF_BODY(level, msg, ...) \
289 do { \
290 auto _l = NEFORCE_LOG_GET_LOGGER(); \
291 if (_l->should_log(level)) { \
292 _l->log(level, _NEFORCE format(msg, __VA_ARGS__), _NEFORCE source_location::current()); \
293 } \
294 } while (false)
295
297#define NEFORCE_LOGGER_LOG_BODY(level, name, msg) \
298 do { \
299 auto _l = _NEFORCE logger_registry::instance().get_logger(name); \
300 if (_l->should_log(level)) { \
301 _l->log(level, msg, _NEFORCE source_location::current()); \
302 } \
303 } while (false)
304
306#define NEFORCE_LOGGER_LOGF_BODY(level, name, msg, ...) \
307 do { \
308 auto _l = _NEFORCE logger_registry::instance().get_logger(name); \
309 if (_l->should_log(level)) { \
310 _l->log(level, _NEFORCE format(msg, __VA_ARGS__), _NEFORCE source_location::current()); \
311 } \
312 } while (false)
313
315
316
324
325// ---- TRACE ----
326#if NEFORCE_ACTIVE_LOG_LEVEL <= NEFORCE_LOG_LEVEL_TRACE
331# define NEFORCE_LOG_TRACE(msg) NEFORCE_LOG_BODY(_NEFORCE log_level::TRACE, msg)
337# define NEFORCE_LOGF_TRACE(msg, ...) NEFORCE_LOGF_BODY(_NEFORCE log_level::TRACE, msg, __VA_ARGS__)
343# define NEFORCE_LOG_TRACE_IF(cond, msg) \
344 do { \
345 if (cond) \
346 NEFORCE_LOG_BODY(_NEFORCE log_level::TRACE, msg); \
347 } while (false)
348
353# define NEFORCE_LOG_TRACE_EVERY_N(n, msg) \
354 do { \
355 static size_t _c = 0; \
356 if (++_c % n == 1) \
357 NEFORCE_LOG_BODY(_NEFORCE log_level::TRACE, msg); \
358 } while (false)
359
364# define NEFORCE_LOG_TRACE_FIRST_N(n, msg) \
365 do { \
366 static size_t _c = 0; \
367 if (_c++ < n) \
368 NEFORCE_LOG_BODY(_NEFORCE log_level::TRACE, msg); \
369 } while (false)
370#else
371# define NEFORCE_LOG_TRACE(msg) ((void) 0)
372# define NEFORCE_LOGF_TRACE(msg, ...) ((void) 0)
373# define NEFORCE_LOG_TRACE_IF(cond, msg) ((void) 0)
374# define NEFORCE_LOG_TRACE_EVERY_N(n, msg) ((void) 0)
375# define NEFORCE_LOG_TRACE_FIRST_N(n, msg) ((void) 0)
376#endif
377
378// ---- DEBUG ----
379#if NEFORCE_ACTIVE_LOG_LEVEL <= NEFORCE_LOG_LEVEL_DEBUG
384# define NEFORCE_LOG_DEBUG(msg) NEFORCE_LOG_BODY(_NEFORCE log_level::DEBUG, msg)
390# define NEFORCE_LOGF_DEBUG(msg, ...) NEFORCE_LOGF_BODY(_NEFORCE log_level::DEBUG, msg, __VA_ARGS__)
396# define NEFORCE_LOG_DEBUG_IF(cond, msg) \
397 do { \
398 if (cond) \
399 NEFORCE_LOG_BODY(_NEFORCE log_level::DEBUG, msg); \
400 } while (false)
401
406# define NEFORCE_LOG_DEBUG_EVERY_N(n, msg) \
407 do { \
408 static size_t _c = 0; \
409 if (++_c % n == 1) \
410 NEFORCE_LOG_BODY(_NEFORCE log_level::DEBUG, msg); \
411 } while (false)
412
417# define NEFORCE_LOG_DEBUG_FIRST_N(n, msg) \
418 do { \
419 static size_t _c = 0; \
420 if (_c++ < n) \
421 NEFORCE_LOG_BODY(_NEFORCE log_level::DEBUG, msg); \
422 } while (false)
423#else
424# define NEFORCE_LOG_DEBUG(msg) ((void) 0)
425# define NEFORCE_LOGF_DEBUG(msg, ...) ((void) 0)
426# define NEFORCE_LOG_DEBUG_IF(cond, msg) ((void) 0)
427# define NEFORCE_LOG_DEBUG_EVERY_N(n, msg) ((void) 0)
428# define NEFORCE_LOG_DEBUG_FIRST_N(n, msg) ((void) 0)
429#endif
430
431// ---- INFO ----
432#if NEFORCE_ACTIVE_LOG_LEVEL <= NEFORCE_LOG_LEVEL_INFO
437# define NEFORCE_LOG_INFO(msg) NEFORCE_LOG_BODY(_NEFORCE log_level::INFO, msg)
443# define NEFORCE_LOGF_INFO(msg, ...) NEFORCE_LOGF_BODY(_NEFORCE log_level::INFO, msg, __VA_ARGS__)
449# define NEFORCE_LOG_INFO_IF(cond, msg) \
450 do { \
451 if (cond) \
452 NEFORCE_LOG_BODY(_NEFORCE log_level::INFO, msg); \
453 } while (false)
454
459# define NEFORCE_LOG_INFO_EVERY_N(n, msg) \
460 do { \
461 static size_t _c = 0; \
462 if (++_c % n == 1) \
463 NEFORCE_LOG_BODY(_NEFORCE log_level::INFO, msg); \
464 } while (false)
465
470# define NEFORCE_LOG_INFO_FIRST_N(n, msg) \
471 do { \
472 static size_t _c = 0; \
473 if (_c++ < n) \
474 NEFORCE_LOG_BODY(_NEFORCE log_level::INFO, msg); \
475 } while (false)
476#else
477# define NEFORCE_LOG_INFO(msg) ((void) 0)
478# define NEFORCE_LOGF_INFO(msg, ...) ((void) 0)
479# define NEFORCE_LOG_INFO_IF(cond, msg) ((void) 0)
480# define NEFORCE_LOG_INFO_EVERY_N(n, msg) ((void) 0)
481# define NEFORCE_LOG_INFO_FIRST_N(n, msg) ((void) 0)
482#endif
483
484// ---- WARN ----
485#if NEFORCE_ACTIVE_LOG_LEVEL <= NEFORCE_LOG_LEVEL_WARN
490# define NEFORCE_LOG_WARN(msg) NEFORCE_LOG_BODY(_NEFORCE log_level::WARN, msg)
496# define NEFORCE_LOGF_WARN(msg, ...) NEFORCE_LOGF_BODY(_NEFORCE log_level::WARN, msg, __VA_ARGS__)
502# define NEFORCE_LOG_WARN_IF(cond, msg) \
503 do { \
504 if ((cond)) \
505 NEFORCE_LOG_BODY(_NEFORCE log_level::WARN, msg); \
506 } while (false)
507
512# define NEFORCE_LOG_WARN_EVERY_N(n, msg) \
513 do { \
514 static size_t _c = 0; \
515 if (++_c % n == 1) \
516 NEFORCE_LOG_BODY(_NEFORCE log_level::WARN, msg); \
517 } while (false)
518
523# define NEFORCE_LOG_WARN_FIRST_N(n, msg) \
524 do { \
525 static size_t _c = 0; \
526 if (_c++ < n) \
527 NEFORCE_LOG_BODY(_NEFORCE log_level::WARN, msg); \
528 } while (false)
529#else
530# define NEFORCE_LOG_WARN(msg) ((void) 0)
531# define NEFORCE_LOGF_WARN(msg, ...) ((void) 0)
532# define NEFORCE_LOG_WARN_IF(cond, msg) ((void) 0)
533# define NEFORCE_LOG_WARN_EVERY_N(n, msg) ((void) 0)
534# define NEFORCE_LOG_WARN_FIRST_N(n, msg) ((void) 0)
535#endif
536
537// ---- ERROR ----
538#if NEFORCE_ACTIVE_LOG_LEVEL <= NEFORCE_LOG_LEVEL_ERROR
543# define NEFORCE_LOG_ERROR(msg) NEFORCE_LOG_BODY(_NEFORCE log_level::ERROR, msg)
549# define NEFORCE_LOGF_ERROR(msg, ...) NEFORCE_LOGF_BODY(_NEFORCE log_level::ERROR, msg, __VA_ARGS__)
555# define NEFORCE_LOG_ERROR_IF(cond, msg) \
556 do { \
557 if (cond) \
558 NEFORCE_LOG_BODY(_NEFORCE log_level::ERROR, msg); \
559 } while (false)
560
565# define NEFORCE_LOG_ERROR_EVERY_N(n, msg) \
566 do { \
567 static size_t _c = 0; \
568 if (++_c % n == 1) \
569 NEFORCE_LOG_BODY(_NEFORCE log_level::ERROR, msg); \
570 } while (false)
571
576# define NEFORCE_LOG_ERROR_FIRST_N(n, msg) \
577 do { \
578 static size_t _c = 0; \
579 if (_c++ < n) \
580 NEFORCE_LOG_BODY(_NEFORCE log_level::ERROR, msg); \
581 } while (false)
582#else
583# define NEFORCE_LOG_ERROR(msg) ((void) 0)
584# define NEFORCE_LOGF_ERROR(msg, ...) ((void) 0)
585# define NEFORCE_LOG_ERROR_IF(cond, msg) ((void) 0)
586# define NEFORCE_LOG_ERROR_EVERY_N(n, msg) ((void) 0)
587# define NEFORCE_LOG_ERROR_FIRST_N(n, msg) ((void) 0)
588#endif
589
590// ---- FATAL ----
591#if NEFORCE_ACTIVE_LOG_LEVEL <= NEFORCE_LOG_LEVEL_FATAL
596# define NEFORCE_LOG_FATAL(msg) NEFORCE_LOG_BODY(_NEFORCE log_level::FATAL, msg)
602# define NEFORCE_LOGF_FATAL(msg, ...) NEFORCE_LOGF_BODY(_NEFORCE log_level::FATAL, msg, __VA_ARGS__)
608# define NEFORCE_LOG_FATAL_IF(cond, msg) \
609 do { \
610 if (cond) \
611 NEFORCE_LOG_BODY(_NEFORCE log_level::FATAL, msg); \
612 } while (false)
613
618# define NEFORCE_LOG_FATAL_EVERY_N(n, msg) \
619 do { \
620 static size_t _c = 0; \
621 if (++_c % n == 1) \
622 NEFORCE_LOG_BODY(_NEFORCE log_level::FATAL, msg); \
623 } while (false)
624
629# define NEFORCE_LOG_FATAL_FIRST_N(n, msg) \
630 do { \
631 static size_t _c = 0; \
632 if (_c++ < n) \
633 NEFORCE_LOG_BODY(_NEFORCE log_level::FATAL, msg); \
634 } while (false)
635#else
636# define NEFORCE_LOG_FATAL(msg) ((void) 0)
637# define NEFORCE_LOGF_FATAL(msg, ...) ((void) 0)
638# define NEFORCE_LOG_FATAL_IF(cond, msg) ((void) 0)
639# define NEFORCE_LOG_FATAL_EVERY_N(n, msg) ((void) 0)
640# define NEFORCE_LOG_FATAL_FIRST_N(n, msg) ((void) 0)
641#endif
642 // 根 Logger 日志宏
644
645
653
654// ---- TRACE (named) ----
655#if NEFORCE_ACTIVE_LOG_LEVEL <= NEFORCE_LOG_LEVEL_TRACE
661# define NEFORCE_LOGGER_LOG_TRACE(name, msg) NEFORCE_LOGGER_LOG_BODY(_NEFORCE log_level::TRACE, name, msg)
668# define NEFORCE_LOGGER_LOGF_TRACE(name, msg, ...) \
669 NEFORCE_LOGGER_LOGF_BODY(_NEFORCE log_level::TRACE, name, msg, __VA_ARGS__)
670#else
671# define NEFORCE_LOGGER_LOG_TRACE(name, msg) ((void) 0)
672# define NEFORCE_LOGGER_LOGF_TRACE(name, msg, ...) ((void) 0)
673#endif
674
675// ---- DEBUG (named) ----
676#if NEFORCE_ACTIVE_LOG_LEVEL <= NEFORCE_LOG_LEVEL_DEBUG
682# define NEFORCE_LOGGER_LOG_DEBUG(name, msg) NEFORCE_LOGGER_LOG_BODY(_NEFORCE log_level::DEBUG, name, msg)
689# define NEFORCE_LOGGER_LOGF_DEBUG(name, msg, ...) \
690 NEFORCE_LOGGER_LOGF_BODY(_NEFORCE log_level::DEBUG, name, msg, __VA_ARGS__)
691#else
692# define NEFORCE_LOGGER_LOG_DEBUG(name, msg) ((void) 0)
693# define NEFORCE_LOGGER_LOGF_DEBUG(name, msg, ...) ((void) 0)
694#endif
695
696// ---- INFO (named) ----
697#if NEFORCE_ACTIVE_LOG_LEVEL <= NEFORCE_LOG_LEVEL_INFO
703# define NEFORCE_LOGGER_LOG_INFO(name, msg) NEFORCE_LOGGER_LOG_BODY(_NEFORCE log_level::INFO, name, msg)
710# define NEFORCE_LOGGER_LOGF_INFO(name, msg, ...) \
711 NEFORCE_LOGGER_LOGF_BODY(_NEFORCE log_level::INFO, name, msg, __VA_ARGS__)
712#else
713# define NEFORCE_LOGGER_LOG_INFO(name, msg) ((void) 0)
714# define NEFORCE_LOGGER_LOGF_INFO(name, msg, ...) ((void) 0)
715#endif
716
717// ---- WARN (named) ----
718#if NEFORCE_ACTIVE_LOG_LEVEL <= NEFORCE_LOG_LEVEL_WARN
724# define NEFORCE_LOGGER_LOG_WARN(name, msg) NEFORCE_LOGGER_LOG_BODY(_NEFORCE log_level::WARN, name, msg)
731# define NEFORCE_LOGGER_LOGF_WARN(name, msg, ...) \
732 NEFORCE_LOGGER_LOGF_BODY(_NEFORCE log_level::WARN, name, msg, __VA_ARGS__)
733#else
734# define NEFORCE_LOGGER_LOG_WARN(name, msg) ((void) 0)
735# define NEFORCE_LOGGER_LOGF_WARN(name, msg, ...) ((void) 0)
736#endif
737
738// ---- ERROR (named) ----
739#if NEFORCE_ACTIVE_LOG_LEVEL <= NEFORCE_LOG_LEVEL_ERROR
745# define NEFORCE_LOGGER_LOG_ERROR(name, msg) NEFORCE_LOGGER_LOG_BODY(_NEFORCE log_level::ERROR, name, msg)
752# define NEFORCE_LOGGER_LOGF_ERROR(name, msg, ...) \
753 NEFORCE_LOGGER_LOGF_BODY(_NEFORCE log_level::ERROR, name, msg, __VA_ARGS__)
754#else
755# define NEFORCE_LOGGER_LOG_ERROR(name, msg) ((void) 0)
756# define NEFORCE_LOGGER_LOGF_ERROR(name, msg, ...) ((void) 0)
757#endif
758
759// ---- FATAL (named) ----
760#if NEFORCE_ACTIVE_LOG_LEVEL <= NEFORCE_LOG_LEVEL_FATAL
766# define NEFORCE_LOGGER_LOG_FATAL(name, msg) NEFORCE_LOGGER_LOG_BODY(_NEFORCE log_level::FATAL, name, msg)
773# define NEFORCE_LOGGER_LOGF_FATAL(name, msg, ...) \
774 NEFORCE_LOGGER_LOGF_BODY(_NEFORCE log_level::FATAL, name, msg, __VA_ARGS__)
775#else
776# define NEFORCE_LOGGER_LOG_FATAL(name, msg) ((void) 0)
777# define NEFORCE_LOGGER_LOGF_FATAL(name, msg, ...) ((void) 0)
778#endif
779 // 命名 Logger 日志宏
781
782
788#define NEFORCE_GET_LOGGER(name) _NEFORCE logger_registry::instance().get_logger(name)
789
794#define NEFORCE_ROOT_LOGGER() _NEFORCE logger_registry::instance().root_logger()
795
796 // Logging
798
799NEFORCE_END_NAMESPACE__
800#endif // NEFORCE_CORE_LOGGING_LOGGER_HPP__
函数包装器主模板声明
static logger_registry & instance()
获取全局唯一实例
void flush_all()
刷新所有已注册的 Logger
shared_ptr< logger > get_logger(const string &name)
获取或创建指定名称的 Logger
shared_ptr< logger > root_logger()
获取根 Logger(名称为空字符串)
shared_ptr< logger > default_logger()
获取默认 Logger(即根 Logger)
void trace(string msg, source_location loc)
TRACE 级别快捷方法
void add_context(const string &key, string value)
添加上下文键值对
void enable_async(shared_ptr< thread_pool > pool=nullptr, size_t queue_size=8192, overflow_policy policy=overflow_policy::block)
启用异步模式
void add_sink(shared_ptr< log_sink > sink)
添加输出目标
static constexpr log_level INHERIT
特殊级别值:表示继承父 logger 的级别
void error(string msg, source_location loc)
ERROR 级别快捷方法
void remove_context(const string &key)
移除上下文键
bool should_log(log_level level) const noexcept
检查指定级别是否应该输出
void set_auto_flush(int64_t interval_ms)
设置自动刷新间隔
logger(string name)
构造指定名称的 Logger
void flush()
刷新所有 sink
void log(log_level level, string msg, source_location loc)
记录一条日志
log_level level() const noexcept
void set_filter(function< bool(const log_event &)> filter)
设置自定义过滤器
void set_level(log_level level)
设置级别(不影响子 logger 的显式级别)
log_level effective_level() const noexcept
void clear_context()
清除所有上下文
void debug(string msg, source_location loc)
DEBUG 级别快捷方法
const string & name() const noexcept
void clear_sinks()
清除所有输出目标
void disable_async()
切换回同步模式,排空队列中的所有事件
void warn(string msg, source_location loc)
WARN 级别快捷方法
logger * parent() const noexcept
bool is_async() const noexcept
void info(string msg, source_location loc)
INFO 级别快捷方法
void fatal(string msg, source_location loc)
FATAL 级别快捷方法
非递归互斥锁
共享智能指针类模板
static timestamp now() noexcept
获取当前时间戳
long int64_t
64位有符号整数类型
log_level
日志级别枚举
overflow_policy
异步队列溢出策略
@ OFF
关闭所有日志
@ block
阻塞等待直到队列有空间
constexpr auto memory_order_release
释放内存顺序常量
constexpr auto memory_order_acquire
获取内存顺序常量
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
日志输出目标
function< float(float)> function
缓动函数类型:输入归一化时间 [0,1],输出进度 [0,1]
队列容器适配器
日志事件结构体
线程池实现