#include void log_default_handler(log_level_t level, const char* module, const char* file, int line, const char* message) { const char* level_str; switch (level) { case LOG_LEVEL_DEBUG: level_str = "DEBUG"; break; case LOG_LEVEL_INFO: level_str = "INFO "; break; case LOG_LEVEL_WARN: level_str = "WARN "; break; case LOG_LEVEL_ERROR: level_str = "ERROR"; break; case LOG_LEVEL_FATAL: level_str = "FATAL"; break; case LOG_LEVEL_TRACE: level_str = "TRACE"; break; default: level_str = "NOTSET"; break; } /// @note: 定义 __LOG_NO_COLOR__ 会取消颜色输出 #ifndef __LOG_NO_COLOR__ const char* color_code; switch (level) { case LOG_LEVEL_DEBUG: color_code = ANSI_FG_CYAN; break; case LOG_LEVEL_INFO: color_code = ANSI_FG_GREEN; break; case LOG_LEVEL_TRACE: color_code = ANSI_FG_BLUE; break; case LOG_LEVEL_WARN: color_code = ANSI_FG_YELLOW; break; case LOG_LEVEL_ERROR: color_code = ANSI_FG_RED; break; case LOG_LEVEL_FATAL: color_code = ANSI_FG_RED ANSI_UNDERLINED; break; // 增强对比度 default: color_code = ANSI_NONE; } log_printf(ANSI_BOLD "%s[%s] - %s - %s:%d | %s" ANSI_NONE "\n", color_code, level_str, module, file, line, message); #else log_printf("[%s] %s:%d | %s: %s\n", level_str, file, line, module, message); #endif // for clangd warning // clang-analyzer-deadcode.DeadStores (void)color_code; (void)level_str; if (level & LOG_LEVEL_FATAL) { log_exit(-LOG_LEVEL_FATAL); } } logger_t logger_root = { .name = "root", .level = LOG_LEVEL_ALL, .handler = log_default_handler, }; void init_logger(logger_t* logger, const char* name) { logger->name = name; logger->handler = log_default_handler; log_set_level(logger, LOG_LEVEL_ALL); } logger_t* log_get(const char* name) { return &logger_root; } void log_set_level(logger_t* logger, log_level_t level) { if (logger) logger->level = level; else logger_root.level = level; } void log_set_handler(logger_t* logger, log_handler handler) { if (logger) logger->handler = handler; else logger_root.handler = handler; } void logger_destroy(logger_t* logger) { return; }