1#ifndef NEFORCE_CORE_LOGGING_LOGGER_HPP__
2#define NEFORCE_CORE_LOGGING_LOGGER_HPP__
17#include "NeForce/core/memory/bounded_queue.hpp"
19NEFORCE_BEGIN_NAMESPACE__
44 friend class logger_registry;
56 logger* parent_{
nullptr};
57 vector<shared_ptr<logger>> children_;
59 vector<shared_ptr<log_sink>> sinks_;
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};
68 condition_variable queue_cv_;
69 atomic<bool> drain_scheduled_{
false};
70 atomic<bool> running_{
false};
72 atomic<bool> flush_requested_{
false};
74 condition_variable flush_cv_;
76 function<bool(
const log_event&)> filter_;
79 shared_ptr<unordered_map<string, string>> context_data_{
80 make_shared<unordered_map<string, string>>()};
81 mutable mutex context_mutex_;
83 atomic<int64_t> auto_flush_ms_{0};
86 void update_effective_level();
87 void propagate_effective_level(log_level new_effective);
89 void enqueue_async(log_event&& event);
94 void register_child(shared_ptr<logger> child);
96 void process_event_direct(
const log_event& event);
98 void check_auto_flush();
115 NEFORCE_NODISCARD
const string&
name() const noexcept {
return name_; }
233class NEFORCE_API logger_registry {
246 logger_registry(
const logger_registry&) =
delete;
247 logger_registry& operator=(
const logger_registry&) =
delete;
276#define NEFORCE_LOG_GET_LOGGER() _NEFORCE logger_registry::instance().default_logger()
279#define NEFORCE_LOG_BODY(level, msg) \
281 auto _l = NEFORCE_LOG_GET_LOGGER(); \
282 if (_l->should_log(level)) { \
283 _l->log(level, msg, _NEFORCE source_location::current()); \
288#define NEFORCE_LOGF_BODY(level, msg, ...) \
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()); \
297#define NEFORCE_LOGGER_LOG_BODY(level, name, msg) \
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()); \
306#define NEFORCE_LOGGER_LOGF_BODY(level, name, msg, ...) \
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()); \
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) \
346 NEFORCE_LOG_BODY(_NEFORCE log_level::TRACE, msg); \
353# define NEFORCE_LOG_TRACE_EVERY_N(n, msg) \
355 static size_t _c = 0; \
357 NEFORCE_LOG_BODY(_NEFORCE log_level::TRACE, msg); \
364# define NEFORCE_LOG_TRACE_FIRST_N(n, msg) \
366 static size_t _c = 0; \
368 NEFORCE_LOG_BODY(_NEFORCE log_level::TRACE, msg); \
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)
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) \
399 NEFORCE_LOG_BODY(_NEFORCE log_level::DEBUG, msg); \
406# define NEFORCE_LOG_DEBUG_EVERY_N(n, msg) \
408 static size_t _c = 0; \
410 NEFORCE_LOG_BODY(_NEFORCE log_level::DEBUG, msg); \
417# define NEFORCE_LOG_DEBUG_FIRST_N(n, msg) \
419 static size_t _c = 0; \
421 NEFORCE_LOG_BODY(_NEFORCE log_level::DEBUG, msg); \
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)
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) \
452 NEFORCE_LOG_BODY(_NEFORCE log_level::INFO, msg); \
459# define NEFORCE_LOG_INFO_EVERY_N(n, msg) \
461 static size_t _c = 0; \
463 NEFORCE_LOG_BODY(_NEFORCE log_level::INFO, msg); \
470# define NEFORCE_LOG_INFO_FIRST_N(n, msg) \
472 static size_t _c = 0; \
474 NEFORCE_LOG_BODY(_NEFORCE log_level::INFO, msg); \
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)
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) \
505 NEFORCE_LOG_BODY(_NEFORCE log_level::WARN, msg); \
512# define NEFORCE_LOG_WARN_EVERY_N(n, msg) \
514 static size_t _c = 0; \
516 NEFORCE_LOG_BODY(_NEFORCE log_level::WARN, msg); \
523# define NEFORCE_LOG_WARN_FIRST_N(n, msg) \
525 static size_t _c = 0; \
527 NEFORCE_LOG_BODY(_NEFORCE log_level::WARN, msg); \
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)
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) \
558 NEFORCE_LOG_BODY(_NEFORCE log_level::ERROR, msg); \
565# define NEFORCE_LOG_ERROR_EVERY_N(n, msg) \
567 static size_t _c = 0; \
569 NEFORCE_LOG_BODY(_NEFORCE log_level::ERROR, msg); \
576# define NEFORCE_LOG_ERROR_FIRST_N(n, msg) \
578 static size_t _c = 0; \
580 NEFORCE_LOG_BODY(_NEFORCE log_level::ERROR, msg); \
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)
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) \
611 NEFORCE_LOG_BODY(_NEFORCE log_level::FATAL, msg); \
618# define NEFORCE_LOG_FATAL_EVERY_N(n, msg) \
620 static size_t _c = 0; \
622 NEFORCE_LOG_BODY(_NEFORCE log_level::FATAL, msg); \
629# define NEFORCE_LOG_FATAL_FIRST_N(n, msg) \
631 static size_t _c = 0; \
633 NEFORCE_LOG_BODY(_NEFORCE log_level::FATAL, msg); \
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)
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__)
671# define NEFORCE_LOGGER_LOG_TRACE(name, msg) ((void) 0)
672# define NEFORCE_LOGGER_LOGF_TRACE(name, msg, ...) ((void) 0)
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__)
692# define NEFORCE_LOGGER_LOG_DEBUG(name, msg) ((void) 0)
693# define NEFORCE_LOGGER_LOGF_DEBUG(name, msg, ...) ((void) 0)
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__)
713# define NEFORCE_LOGGER_LOG_INFO(name, msg) ((void) 0)
714# define NEFORCE_LOGGER_LOGF_INFO(name, msg, ...) ((void) 0)
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__)
734# define NEFORCE_LOGGER_LOG_WARN(name, msg) ((void) 0)
735# define NEFORCE_LOGGER_LOGF_WARN(name, msg, ...) ((void) 0)
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__)
755# define NEFORCE_LOGGER_LOG_ERROR(name, msg) ((void) 0)
756# define NEFORCE_LOGGER_LOGF_ERROR(name, msg, ...) ((void) 0)
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__)
776# define NEFORCE_LOGGER_LOG_FATAL(name, msg) ((void) 0)
777# define NEFORCE_LOGGER_LOGF_FATAL(name, msg, ...) ((void) 0)
788#define NEFORCE_GET_LOGGER(name) _NEFORCE logger_registry::instance().get_logger(name)
794#define NEFORCE_ROOT_LOGGER() _NEFORCE logger_registry::instance().root_logger()
799NEFORCE_END_NAMESPACE__
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 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
获取当前时间戳
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]
enable_shared_from_this() noexcept=default