From 8ac539eb792aa893a5549e3d838edb9015d21d2f Mon Sep 17 00:00:00 2001 From: youmetme <321640253@qq.com> Date: Mon, 15 Sep 2025 10:16:09 +0800 Subject: [PATCH 1/5] =?UTF-8?q?refactor:=20=E9=9A=90=E8=97=8F=E5=8E=9F?= =?UTF-8?q?=E5=A7=8B=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/logging.h | 30 +++++++++++++++--------------- src/logging.c | 10 +++++----- tests/test-filter.c | 20 ++++++++++---------- tests/test-log-file.c | 10 +++++----- tests/test-simple.c | 10 +++++----- 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/include/logging.h b/include/logging.h index 230e4ec..8823d58 100644 --- a/include/logging.h +++ b/include/logging.h @@ -12,16 +12,16 @@ extern "C" { #endif -#define Log_fatal(format, ...) \ - log_fatal(__FILE__, __LINE__, format, ##__VA_ARGS__) -#define Log_error(format, ...) \ - log_error(__FILE__, __LINE__, format, ##__VA_ARGS__) -#define Log_warning(format, ...) \ - log_warning(__FILE__, __LINE__, format, ##__VA_ARGS__) -#define Log_info(format, ...) \ - log_info(__FILE__, __LINE__, format, ##__VA_ARGS__) -#define Log_debug(format, ...) \ - log_debug(__FILE__, __LINE__, format, ##__VA_ARGS__) +#define log_fatal(format, ...) \ + _log_fatal(__FILE__, __LINE__, format, ##__VA_ARGS__) +#define log_error(format, ...) \ + _log_error(__FILE__, __LINE__, format, ##__VA_ARGS__) +#define log_warning(format, ...) \ + _log_warning(__FILE__, __LINE__, format, ##__VA_ARGS__) +#define log_info(format, ...) \ + _log_info(__FILE__, __LINE__, format, ##__VA_ARGS__) +#define log_debug(format, ...) \ + _log_debug(__FILE__, __LINE__, format, ##__VA_ARGS__) typedef struct Logger { log_level level; @@ -32,11 +32,11 @@ typedef struct Logger { bool (*addFilter)(log_filter *filter); } Logger; -void log_fatal(const char *file, int line, const char *format, ...); -void log_error(const char *file, int line, const char *format, ...); -void log_warning(const char *file, int line, const char *format, ...); -void log_info(const char *file, int line, const char *format, ...); -void log_debug(const char *file, int line, const char *format, ...); +void _log_fatal(const char *file, int line, const char *format, ...); +void _log_error(const char *file, int line, const char *format, ...); +void _log_warning(const char *file, int line, const char *format, ...); +void _log_info(const char *file, int line, const char *format, ...); +void _log_debug(const char *file, int line, const char *format, ...); /** * @brief diff --git a/src/logging.c b/src/logging.c index 45e925f..b01ca42 100644 --- a/src/logging.c +++ b/src/logging.c @@ -144,7 +144,7 @@ static void log_cope(log_level level_e, output_to_handler(handler, level, color, message); } -void log_fatal(const char *file, int line, const char *message, ...) { +void _log_fatal(const char *file, int line, const char *message, ...) { if (G_LOGGER->level >= LOG_ERROR) { char logStr[LOG_BUFFER_SIZE]; char finalLogStr[LOG_BUFFER_SIZE * 2]; @@ -158,7 +158,7 @@ void log_fatal(const char *file, int line, const char *message, ...) { } } -void log_error(const char *file, int line, const char *message, ...) { +void _log_error(const char *file, int line, const char *message, ...) { if (G_LOGGER->level >= LOG_ERROR) { char logStr[LOG_BUFFER_SIZE]; char finalLogStr[LOG_BUFFER_SIZE * 2]; @@ -172,7 +172,7 @@ void log_error(const char *file, int line, const char *message, ...) { } } -void log_warning(const char *file, int line, const char *message, ...) { +void _log_warning(const char *file, int line, const char *message, ...) { if (G_LOGGER->level >= LOG_WARNING) { char logStr[LOG_BUFFER_SIZE]; char finalLogStr[LOG_BUFFER_SIZE * 2]; @@ -186,7 +186,7 @@ void log_warning(const char *file, int line, const char *message, ...) { } } -void log_info(const char *file, int line, const char *message, ...) { +void _log_info(const char *file, int line, const char *message, ...) { if (G_LOGGER->level >= LOG_INFO) { char logStr[LOG_BUFFER_SIZE]; char finalLogStr[LOG_BUFFER_SIZE * 2]; @@ -200,7 +200,7 @@ void log_info(const char *file, int line, const char *message, ...) { } } -void log_debug(const char *file, int line, const char *message, ...) { +void _log_debug(const char *file, int line, const char *message, ...) { if (G_LOGGER->level >= LOG_DEBUG) { char logStr[LOG_BUFFER_SIZE]; char finalLogStr[LOG_BUFFER_SIZE * 2]; diff --git a/tests/test-filter.c b/tests/test-filter.c index 813425d..b282ed1 100644 --- a/tests/test-filter.c +++ b/tests/test-filter.c @@ -8,11 +8,11 @@ int main() { Logger *logger = newDefaultLogger(__FILE__, LOG_DEBUG); - Log_info("This is an info message"); - Log_error("This is an error message%s", "123"); - Log_fatal("This is an fatal message"); - Log_debug("This is a debug message"); - Log_warning("This is a warning message%s", "123"); + log_info("This is an info message"); + log_error("This is an error message%s", "123"); + log_fatal("This is an fatal message"); + log_debug("This is a debug message"); + log_warning("This is a warning message%s", "123"); char *test1[] = {"This", NULL}; @@ -38,11 +38,11 @@ int main() { printf("filter added\n"); printf("\n"); - Log_info("This is an info message"); - Log_error("This is an error message%s", "123"); - Log_fatal("This is an fatal message"); - Log_debug("This is a debug message"); - Log_warning("This is a warning message%s", "123"); + log_info("This is an info message"); + log_error("This is an error message%s", "123"); + log_fatal("This is an fatal message"); + log_debug("This is a debug message"); + log_warning("This is a warning message%s", "123"); destroyDefaultLogger(); return 0; diff --git a/tests/test-log-file.c b/tests/test-log-file.c index a9753c2..3b04534 100644 --- a/tests/test-log-file.c +++ b/tests/test-log-file.c @@ -6,11 +6,11 @@ int main() { log_Handler *hander = loggingHandlerFile("test_log", 1024 * 1024 * 10); logger->addHandler(hander); - Log_info("This is an info message"); - Log_error("This is an error message%s", "123"); - Log_fatal("This is an fatal message"); - Log_debug("This is a debug message"); - Log_warning("This is a warning message%s", "123"); + log_info("This is an info message"); + log_error("This is an error message%s", "123"); + log_fatal("This is an fatal message"); + log_debug("This is a debug message"); + log_warning("This is a warning message%s", "123"); destroyDefaultLogger(); return 0; diff --git a/tests/test-simple.c b/tests/test-simple.c index 3f7e460..5744e2c 100644 --- a/tests/test-simple.c +++ b/tests/test-simple.c @@ -3,11 +3,11 @@ int main() { Logger *logger = newDefaultLogger(__FILE__, LOG_DEBUG); - Log_info("This is an info message"); - Log_error("This is an error message%s", "123"); - Log_fatal("This is an fatal message"); - Log_debug("This is a debug message"); - Log_warning("This is a warning message%s", "123"); + log_info("This is an info message"); + log_error("This is an error message%s", "123"); + log_fatal("This is an fatal message"); + log_debug("This is a debug message"); + log_warning("This is a warning message%s", "123"); destroyDefaultLogger(); return 0; From 9fce78a59e98770ea5ea3fbba4016292bc94b755 Mon Sep 17 00:00:00 2001 From: youmetme <321640253@qq.com> Date: Mon, 15 Sep 2025 13:35:16 +0800 Subject: [PATCH 2/5] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E7=B3=BB=E7=BB=9F=EF=BC=8C=E6=94=AF=E6=8C=81=E5=A4=9A?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/logging.h | 79 ++++++++++----- src/logging.c | 225 +++++++++++++++++++++++++++++------------- tests/test-filter.c | 26 ++--- tests/test-log-file.c | 14 +-- tests/test-simple.c | 12 +-- 5 files changed, 237 insertions(+), 119 deletions(-) diff --git a/include/logging.h b/include/logging.h index 8823d58..d3f14d9 100644 --- a/include/logging.h +++ b/include/logging.h @@ -3,6 +3,7 @@ #include #include +#include #include "logging/logging-core.h" #include "logging/logging-filter.h" @@ -12,51 +13,77 @@ extern "C" { #endif -#define log_fatal(format, ...) \ - _log_fatal(__FILE__, __LINE__, format, ##__VA_ARGS__) -#define log_error(format, ...) \ - _log_error(__FILE__, __LINE__, format, ##__VA_ARGS__) -#define log_warning(format, ...) \ - _log_warning(__FILE__, __LINE__, format, ##__VA_ARGS__) -#define log_info(format, ...) \ - _log_info(__FILE__, __LINE__, format, ##__VA_ARGS__) -#define log_debug(format, ...) \ - _log_debug(__FILE__, __LINE__, format, ##__VA_ARGS__) +// 默认日志器宏 +#define Log_fatal(format, ...) \ + _log_fatal(NULL, __FILE__, __LINE__, format, ##__VA_ARGS__) +#define Log_error(format, ...) \ + _log_error(NULL, __FILE__, __LINE__, format, ##__VA_ARGS__) +#define Log_warning(format, ...) \ + _log_warning(NULL, __FILE__, __LINE__, format, ##__VA_ARGS__) +#define Log_info(format, ...) \ + _log_info(NULL, __FILE__, __LINE__, format, ##__VA_ARGS__) +#define Log_debug(format, ...) \ + _log_debug(NULL, __FILE__, __LINE__, format, ##__VA_ARGS__) + +// 日志器宏 +#define log_fatal(logger, format, ...) \ + _log_fatal(logger, __FILE__, __LINE__, format, ##__VA_ARGS__) +#define log_error(logger, format, ...) \ + _log_error(logger, __FILE__, __LINE__, format, ##__VA_ARGS__) +#define log_warning(logger, format, ...) \ + _log_warning(logger, __FILE__, __LINE__, format, ##__VA_ARGS__) +#define log_info(logger, format, ...) \ + _log_info(logger, __FILE__, __LINE__, format, ##__VA_ARGS__) +#define log_debug(logger, format, ...) \ + _log_debug(logger, __FILE__, __LINE__, format, ##__VA_ARGS__) typedef struct Logger { log_level level; log_Handler *handler; log_filter *filter; const char *name; - bool (*addHandler)(log_Handler *handler); - bool (*addFilter)(log_filter *filter); } Logger; -void _log_fatal(const char *file, int line, const char *format, ...); -void _log_error(const char *file, int line, const char *format, ...); -void _log_warning(const char *file, int line, const char *format, ...); -void _log_info(const char *file, int line, const char *format, ...); -void _log_debug(const char *file, int line, const char *format, ...); +bool addHandler(Logger *logger, log_Handler *handler); +bool addFilter(Logger *logger, log_filter *filter); + +void _log_fatal( + Logger *logger, const char *file, int line, const char *format, ...); +void _log_error( + Logger *logger, const char *file, int line, const char *format, ...); +void _log_warning( + Logger *logger, const char *file, int line, const char *format, ...); +void _log_info( + Logger *logger, const char *file, int line, const char *format, ...); +void _log_debug( + Logger *logger, const char *file, int line, const char *format, ...); /** -* @brief -创建默认日志对象,日志对象为单例模式,后续可通过getDefaultLogger方法获取, - 重复调用该方法不会创建新的日志对象,只会返回默认日志对象,并且会修改默认日志对象的名称和等级 -* @param name 日志名称 -* @param level 日志等级 -* @return Logger* 日志对象指针 -*/ -Logger *newDefaultLogger(const char *name, log_level level); + * @brief 初始化默认日志对象 + * @param name 日志名称 + * @param level 日志等级 + */ +void initDefaultLogger(const char *name, log_level level); /** * @brief 获取默认日志对象 + * @return 默认日志对象 */ Logger *getDefaultLogger(void); +Logger *getLogger(const char *name, log_level level); + /** * @brief 销毁日志对象,该方法会销毁默认日志对象 */ -log_status destroyDefaultLogger(void); +void destroyDefaultLogger(void); + +/** + * @brief 销毁日志对象 + * @param logger 日志对象 + * @return void + */ +void destroyLogger(Logger *logger); #ifdef __cplusplus } diff --git a/src/logging.c b/src/logging.c index b01ca42..ff05ef0 100644 --- a/src/logging.c +++ b/src/logging.c @@ -24,17 +24,17 @@ static Logger *G_LOGGER = NULL; // 全局日志对象,唯一实例 * @brief 为日志添加一个handler * @param handler 处理器对象 */ -static bool addHandler(log_Handler *handler) { - if (G_LOGGER == NULL || handler == NULL) { +bool addHandler(Logger *logger, log_Handler *handler) { + if (logger == NULL || handler == NULL) { return false; } - if (G_LOGGER->handler == NULL) { - G_LOGGER->handler = handler; + if (logger->handler == NULL) { + logger->handler = handler; return true; } - G_LOGGER->handler->_free(G_LOGGER->handler); - G_LOGGER->handler = handler; + logger->handler->_free(logger->handler); + logger->handler = handler; return true; } @@ -42,21 +42,17 @@ static bool addHandler(log_Handler *handler) { * @brief 为日志添加一个filter * @param filter 过滤器对象 */ -/** - * @brief 为日志添加一个filter - * @param filter 过滤器对象 - */ -static bool addFilter(log_filter *filter) { - if (G_LOGGER == NULL || filter == NULL) { +bool addFilter(Logger *logger, log_filter *filter) { + if (logger == NULL || filter == NULL) { return false; } - if (G_LOGGER->filter == NULL) { - G_LOGGER->filter = filter; - G_LOGGER->filter->next = NULL; + if (logger->filter == NULL) { + logger->filter = filter; + logger->filter->next = NULL; return true; } - log_filter *it = G_LOGGER->filter; + log_filter *it = logger->filter; while (it->next != NULL) { it = it->next; } @@ -80,18 +76,26 @@ static bool addFilter(log_filter *filter) { * @param color 应用的颜色 * @param message 日志内容 */ -static void output_to_handler(log_Handler *handler, - char *level, - const char *color, - const char *message) { +static void output_to_handler(Logger *logger, + char *level, + const char *color, + const char *message) { + Logger *_logger = NULL; + + if (logger != NULL) { + _logger = logger; + } else { + _logger = G_LOGGER; + } + char timeStr[20]; getTimeStr(timeStr); char logStr[LOG_BUFFER_SIZE * 2]; - if (handler->apply_color) { + if (_logger->handler->apply_color) { snprintf(logStr, LOG_BUFFER_SIZE * 2, "[%s]: %s %s%s%s %s\n", - G_LOGGER->name, + _logger->name, timeStr, color, level, @@ -101,13 +105,13 @@ static void output_to_handler(log_Handler *handler, snprintf(logStr, LOG_BUFFER_SIZE * 2, "[%s]: %s %s %s\n", - G_LOGGER->name, + _logger->name, timeStr, level, message); } - handler->output(handler, logStr); + _logger->handler->output(_logger->handler, logStr); } /** @@ -118,34 +122,49 @@ static void output_to_handler(log_Handler *handler, * @param ... 格式化参数列表 * @return */ -static void log_cope(log_level level_e, - char *level, - const char *color, - const char *message) { - if (G_LOGGER == NULL) { +static void +log_cope(Logger *logger, char *level, const char *color, const char *message) { + Logger *_logger = NULL; + + if (logger != NULL) { + _logger = logger; + } else { + _logger = G_LOGGER; + } + + if (_logger == NULL) { return; } - if (G_LOGGER->handler == NULL) { + if (_logger->handler == NULL) { return; } - log_filter *it = G_LOGGER->filter; - log_Handler *handler = G_LOGGER->handler; + log_filter *it = _logger->filter; + log_Handler *handler = _logger->handler; while (it != NULL) { - if (it->_dispose(it, level_e, message)) { - output_to_handler(it->handler, level, color, message); + if (it->_dispose(it, _logger->level, message)) { + output_to_handler(_logger, level, color, message); if (it->jump_out) { return; } } it = it->next; } - output_to_handler(handler, level, color, message); + output_to_handler(_logger, level, color, message); } -void _log_fatal(const char *file, int line, const char *message, ...) { - if (G_LOGGER->level >= LOG_ERROR) { +void _log_fatal( + Logger *logger, const char *file, int line, const char *message, ...) { + Logger *_logger = NULL; + + if (logger != NULL) { + _logger = logger; + } else { + _logger = G_LOGGER; + } + + if (_logger->level >= LOG_ERROR) { char logStr[LOG_BUFFER_SIZE]; char finalLogStr[LOG_BUFFER_SIZE * 2]; va_list args; @@ -154,12 +173,21 @@ void _log_fatal(const char *file, int line, const char *message, ...) { va_end(args); snprintf( finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr); - log_cope(LOG_FATAL, "Fatal", RED_B, finalLogStr); + log_cope(_logger, "Fatal", RED_B, finalLogStr); } } -void _log_error(const char *file, int line, const char *message, ...) { - if (G_LOGGER->level >= LOG_ERROR) { +void _log_error( + Logger *logger, const char *file, int line, const char *message, ...) { + Logger *_logger = NULL; + + if (logger != NULL) { + _logger = logger; + } else { + _logger = G_LOGGER; + } + + if (_logger->level >= LOG_ERROR) { char logStr[LOG_BUFFER_SIZE]; char finalLogStr[LOG_BUFFER_SIZE * 2]; va_list args; @@ -168,12 +196,21 @@ void _log_error(const char *file, int line, const char *message, ...) { va_end(args); snprintf( finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr); - log_cope(LOG_ERROR, "Error", RED, finalLogStr); + log_cope(_logger, "Error", RED, finalLogStr); } } -void _log_warning(const char *file, int line, const char *message, ...) { - if (G_LOGGER->level >= LOG_WARNING) { +void _log_warning( + Logger *logger, const char *file, int line, const char *message, ...) { + Logger *_logger = NULL; + + if (logger != NULL) { + _logger = logger; + } else { + _logger = G_LOGGER; + } + + if (_logger->level >= LOG_WARNING) { char logStr[LOG_BUFFER_SIZE]; char finalLogStr[LOG_BUFFER_SIZE * 2]; va_list args; @@ -182,12 +219,21 @@ void _log_warning(const char *file, int line, const char *message, ...) { va_end(args); snprintf( finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr); - log_cope(LOG_WARNING, "Warning", YELLOW, finalLogStr); + log_cope(_logger, "Warning", YELLOW, finalLogStr); } } -void _log_info(const char *file, int line, const char *message, ...) { - if (G_LOGGER->level >= LOG_INFO) { +void _log_info( + Logger *logger, const char *file, int line, const char *message, ...) { + Logger *_logger = NULL; + + if (logger != NULL) { + _logger = logger; + } else { + _logger = G_LOGGER; + } + + if (_logger->level >= LOG_INFO) { char logStr[LOG_BUFFER_SIZE]; char finalLogStr[LOG_BUFFER_SIZE * 2]; va_list args; @@ -196,12 +242,21 @@ void _log_info(const char *file, int line, const char *message, ...) { va_end(args); snprintf( finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr); - log_cope(LOG_INFO, "Info", GREEN, finalLogStr); + log_cope(_logger, "Info", GREEN, finalLogStr); } } -void _log_debug(const char *file, int line, const char *message, ...) { - if (G_LOGGER->level >= LOG_DEBUG) { +void _log_debug( + Logger *logger, const char *file, int line, const char *message, ...) { + Logger *_logger = NULL; + + if (logger != NULL) { + _logger = logger; + } else { + _logger = G_LOGGER; + } + + if (_logger->level >= LOG_DEBUG) { char logStr[LOG_BUFFER_SIZE]; char finalLogStr[LOG_BUFFER_SIZE * 2]; va_list args; @@ -210,35 +265,59 @@ void _log_debug(const char *file, int line, const char *message, ...) { va_end(args); snprintf( finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr); - log_cope(LOG_DEBUG, "Debug", CYAN, finalLogStr); + log_cope(_logger, "Debug", CYAN, finalLogStr); } } -Logger *newDefaultLogger(const char *name, log_level level) { +/** + * @brief 初始化默认日志器 + * @param name 日志器名称 + * @param level 日志等级 + * @return 日志器对象 + */ +void initDefaultLogger(const char *name, log_level level) { if (G_LOGGER != NULL) { G_LOGGER->name = name; G_LOGGER->level = level; - return G_LOGGER; } - Logger *logger = (Logger *)malloc(sizeof(Logger)); + Logger *logger = (Logger *)malloc(sizeof(Logger)); - logger->addHandler = addHandler; - logger->addFilter = addFilter; + logger->level = level; + logger->handler = loggingHandlerConsole(); + logger->name = name; + logger->filter = NULL; - logger->level = level; - logger->handler = loggingHandlerConsole(); - logger->name = name; - logger->filter = NULL; + G_LOGGER = logger; +} - G_LOGGER = logger; - return G_LOGGER; +Logger *getDefaultLogger(void) { return G_LOGGER; } + +/** + * @brief 获取日志器对象 + * @param name 日志器名称 + * @param level 日志等级 + * @return 日志器对象 + */ +Logger *getLogger(const char *name, log_level level) { + if (name == NULL) { + return NULL; + } + + Logger *logger = (Logger *)malloc(sizeof(Logger)); + + logger->level = level; + logger->handler = loggingHandlerConsole(); + logger->name = name; + logger->filter = NULL; + + return logger; } /** * @brief 销毁日志对象 */ -log_status destroyDefaultLogger(void) { +void destroyDefaultLogger(void) { if (G_LOGGER != NULL) { if (G_LOGGER->handler != NULL) { G_LOGGER->handler->_free(G_LOGGER->handler); @@ -257,12 +336,24 @@ log_status destroyDefaultLogger(void) { free(G_LOGGER); G_LOGGER = NULL; } - return L_OK; } -Logger *getDefaultLogger(void) { - if (G_LOGGER == NULL) { - return NULL; +void destroyLogger(Logger *logger) { + if (logger != NULL) { + if (logger->handler != NULL) { + logger->handler->_free(logger->handler); + } + + if (logger->filter != NULL) { + log_filter *it = logger->filter; + log_filter *next = NULL; + while (it != NULL) { + next = it->next; + it->_free(it); + it = next; + } + } + + free(logger); } - return G_LOGGER; } \ No newline at end of file diff --git a/tests/test-filter.c b/tests/test-filter.c index b282ed1..2394298 100644 --- a/tests/test-filter.c +++ b/tests/test-filter.c @@ -6,13 +6,13 @@ #include int main() { - Logger *logger = newDefaultLogger(__FILE__, LOG_DEBUG); + initDefaultLogger("test-filter", LOG_DEBUG); - log_info("This is an info message"); - log_error("This is an error message%s", "123"); - log_fatal("This is an fatal message"); - log_debug("This is a debug message"); - log_warning("This is a warning message%s", "123"); + Log_info("This is an info message"); + Log_error("This is an error message%s", "123"); + Log_fatal("This is an fatal message"); + Log_debug("This is a debug message"); + Log_warning("This is a warning message%s", "123"); char *test1[] = {"This", NULL}; @@ -22,7 +22,7 @@ int main() { loggingHandlerFile("test_interceptor", 1024 * 1024), false); - logger->addFilter(tint); + addFilter(getDefaultLogger(), tint); char *test2[] = {"123", NULL}; @@ -32,17 +32,17 @@ int main() { loggingHandlerFile("test_interceptor1", 1024 * 1024), true); - logger->addFilter(tint1); + addFilter(getDefaultLogger(), tint1); printf("\n"); printf("filter added\n"); printf("\n"); - log_info("This is an info message"); - log_error("This is an error message%s", "123"); - log_fatal("This is an fatal message"); - log_debug("This is a debug message"); - log_warning("This is a warning message%s", "123"); + Log_info("This is an info message"); + Log_error("This is an error message%s", "123"); + Log_fatal("This is an fatal message"); + Log_debug("This is a debug message"); + Log_warning("This is a warning message%s", "123"); destroyDefaultLogger(); return 0; diff --git a/tests/test-log-file.c b/tests/test-log-file.c index 3b04534..0f0e98c 100644 --- a/tests/test-log-file.c +++ b/tests/test-log-file.c @@ -2,15 +2,15 @@ #include "logging/logging-handler.h" int main() { - Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG); + initDefaultLogger("testLogger", LOG_DEBUG); log_Handler *hander = loggingHandlerFile("test_log", 1024 * 1024 * 10); - logger->addHandler(hander); + addHandler(getDefaultLogger(), hander); - log_info("This is an info message"); - log_error("This is an error message%s", "123"); - log_fatal("This is an fatal message"); - log_debug("This is a debug message"); - log_warning("This is a warning message%s", "123"); + Log_info("This is an info message"); + Log_error("This is an error message%s", "123"); + Log_fatal("This is an fatal message"); + Log_debug("This is a debug message"); + Log_warning("This is a warning message%s", "123"); destroyDefaultLogger(); return 0; diff --git a/tests/test-simple.c b/tests/test-simple.c index 5744e2c..994246d 100644 --- a/tests/test-simple.c +++ b/tests/test-simple.c @@ -1,13 +1,13 @@ #include "logging.h" int main() { - Logger *logger = newDefaultLogger(__FILE__, LOG_DEBUG); + initDefaultLogger("simple", LOG_DEBUG); - log_info("This is an info message"); - log_error("This is an error message%s", "123"); - log_fatal("This is an fatal message"); - log_debug("This is a debug message"); - log_warning("This is a warning message%s", "123"); + Log_info("This is an info message"); + Log_error("This is an error message%s", "123"); + Log_fatal("This is an fatal message"); + Log_debug("This is a debug message"); + Log_warning("This is a warning message%s", "123"); destroyDefaultLogger(); return 0; From c5c625f50e9672ce77e838ffa63d3e68e3c3cd38 Mon Sep 17 00:00:00 2001 From: youmetme <321640253@qq.com> Date: Fri, 17 Oct 2025 14:55:41 +0800 Subject: [PATCH 3/5] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E7=B3=BB=E7=BB=9F=EF=BC=8C=E7=BB=9F=E4=B8=80=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E6=8E=A5=E5=8F=A3=E5=B9=B6=E6=B7=BB=E5=8A=A0map?= =?UTF-8?q?=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/logging.h | 45 +++---- include/logging/logging-core.h | 8 ++ src/logging.c | 235 ++++++++++----------------------- src/utils/logging-map.c | 124 +++++++++++++++++ src/utils/logging-map.h | 37 ++++++ tests/CMakeLists.txt | 8 ++ tests/test-filter.c | 2 - tests/test-log-file.c | 1 - tests/test-map.c | 17 +++ tests/test-simple.c | 2 - 10 files changed, 284 insertions(+), 195 deletions(-) create mode 100644 src/utils/logging-map.c create mode 100644 src/utils/logging-map.h create mode 100644 tests/test-map.c diff --git a/include/logging.h b/include/logging.h index d3f14d9..174b4e8 100644 --- a/include/logging.h +++ b/include/logging.h @@ -15,27 +15,27 @@ extern "C" { // 默认日志器宏 #define Log_fatal(format, ...) \ - _log_fatal(NULL, __FILE__, __LINE__, format, ##__VA_ARGS__) + logMessage(NULL, LOG_FATAL, __FILE__, __LINE__, format, ##__VA_ARGS__) #define Log_error(format, ...) \ - _log_error(NULL, __FILE__, __LINE__, format, ##__VA_ARGS__) + logMessage(NULL, LOG_ERROR, __FILE__, __LINE__, format, ##__VA_ARGS__) #define Log_warning(format, ...) \ - _log_warning(NULL, __FILE__, __LINE__, format, ##__VA_ARGS__) + logMessage(NULL, LOG_WARNING, __FILE__, __LINE__, format, ##__VA_ARGS__) #define Log_info(format, ...) \ - _log_info(NULL, __FILE__, __LINE__, format, ##__VA_ARGS__) + logMessage(NULL, LOG_INFO, __FILE__, __LINE__, format, ##__VA_ARGS__) #define Log_debug(format, ...) \ - _log_debug(NULL, __FILE__, __LINE__, format, ##__VA_ARGS__) + logMessage(NULL, LOG_DEBUG, __FILE__, __LINE__, format, ##__VA_ARGS__) // 日志器宏 #define log_fatal(logger, format, ...) \ - _log_fatal(logger, __FILE__, __LINE__, format, ##__VA_ARGS__) + logMessage(logger, LOG_FATAL, __FILE__, __LINE__, format, ##__VA_ARGS__) #define log_error(logger, format, ...) \ - _log_error(logger, __FILE__, __LINE__, format, ##__VA_ARGS__) + logMessage(logger, LOG_ERROR, __FILE__, __LINE__, format, ##__VA_ARGS__) #define log_warning(logger, format, ...) \ - _log_warning(logger, __FILE__, __LINE__, format, ##__VA_ARGS__) + logMessage(logger, LOG_WARNING, __FILE__, __LINE__, format, ##__VA_ARGS__) #define log_info(logger, format, ...) \ - _log_info(logger, __FILE__, __LINE__, format, ##__VA_ARGS__) + logMessage(logger, LOG_INFO, __FILE__, __LINE__, format, ##__VA_ARGS__) #define log_debug(logger, format, ...) \ - _log_debug(logger, __FILE__, __LINE__, format, ##__VA_ARGS__) + logMessage(logger, LOG_DEBUG, __FILE__, __LINE__, format, ##__VA_ARGS__) typedef struct Logger { log_level level; @@ -47,24 +47,19 @@ typedef struct Logger { bool addHandler(Logger *logger, log_Handler *handler); bool addFilter(Logger *logger, log_filter *filter); -void _log_fatal( - Logger *logger, const char *file, int line, const char *format, ...); -void _log_error( - Logger *logger, const char *file, int line, const char *format, ...); -void _log_warning( - Logger *logger, const char *file, int line, const char *format, ...); -void _log_info( - Logger *logger, const char *file, int line, const char *format, ...); -void _log_debug( - Logger *logger, const char *file, int line, const char *format, ...); +void logMessage(Logger *logger, + log_level level, + const char *file, + int line, + const char *message, + ...); /** - * @brief 初始化默认日志对象 - * @param name 日志名称 - * @param level 日志等级 + * @brief 创建一个日志句柄对象 + * @param name 日志器名称 + * @return 日志句柄对象 */ -void initDefaultLogger(const char *name, log_level level); - +Logger *newLogger(const char *name); /** * @brief 获取默认日志对象 * @return 默认日志对象 diff --git a/include/logging/logging-core.h b/include/logging/logging-core.h index 8bcb614..4ec27f9 100644 --- a/include/logging/logging-core.h +++ b/include/logging/logging-core.h @@ -13,6 +13,14 @@ typedef enum { LOG_DEBUG, } log_level; +static const char *LOG_LEVEL_STR[] = { + "FATAL", + "ERROR", + "WARNING", + "INFO", + "DEBUG", +}; + typedef enum { L_ERROR, L_OK, diff --git a/src/logging.c b/src/logging.c index ff05ef0..1929b23 100644 --- a/src/logging.c +++ b/src/logging.c @@ -1,6 +1,7 @@ #include "logging.h" #include "logging/logging-core.h" #include "logging/logging-handler.h" +#include "utils/logging-map.h" #include "utils/logging-utils.h" #include #include @@ -18,7 +19,7 @@ #define LOG_BUFFER_SIZE 4096 // 日志缓冲区大小,单个日志长度不能超过该值 -static Logger *G_LOGGER = NULL; // 全局日志对象,唯一实例 +static Logger *ROOT_LOGGER = NULL; // 根日志对象,唯一实例 /** * @brief 为日志添加一个handler @@ -80,22 +81,15 @@ static void output_to_handler(Logger *logger, char *level, const char *color, const char *message) { - Logger *_logger = NULL; - - if (logger != NULL) { - _logger = logger; - } else { - _logger = G_LOGGER; - } char timeStr[20]; getTimeStr(timeStr); char logStr[LOG_BUFFER_SIZE * 2]; - if (_logger->handler->apply_color) { + if (logger->handler->apply_color) { snprintf(logStr, LOG_BUFFER_SIZE * 2, "[%s]: %s %s%s%s %s\n", - _logger->name, + logger->name, timeStr, color, level, @@ -105,13 +99,13 @@ static void output_to_handler(Logger *logger, snprintf(logStr, LOG_BUFFER_SIZE * 2, "[%s]: %s %s %s\n", - _logger->name, + logger->name, timeStr, level, message); } - _logger->handler->output(_logger->handler, logStr); + logger->handler->output(logger->handler, logStr); } /** @@ -124,174 +118,105 @@ static void output_to_handler(Logger *logger, */ static void log_cope(Logger *logger, char *level, const char *color, const char *message) { - Logger *_logger = NULL; - - if (logger != NULL) { - _logger = logger; - } else { - _logger = G_LOGGER; - } - - if (_logger == NULL) { + if (logger == NULL) { return; } - if (_logger->handler == NULL) { + if (logger->handler == NULL) { return; } - log_filter *it = _logger->filter; - log_Handler *handler = _logger->handler; + log_filter *it = logger->filter; + log_Handler *handler = logger->handler; while (it != NULL) { - if (it->_dispose(it, _logger->level, message)) { - output_to_handler(_logger, level, color, message); + if (it->_dispose(it, logger->level, message)) { + output_to_handler(logger, level, color, message); if (it->jump_out) { return; } } it = it->next; } - output_to_handler(_logger, level, color, message); + output_to_handler(logger, level, color, message); } -void _log_fatal( - Logger *logger, const char *file, int line, const char *message, ...) { +void logMessage(Logger *logger, + log_level level, + const char *file, + int line, + const char *message, + ...) { Logger *_logger = NULL; - - if (logger != NULL) { - _logger = logger; + if (logger == NULL) { + if (ROOT_LOGGER == NULL) { + ROOT_LOGGER = newLogger("ROOT"); // 创建根日志对象 + } + _logger = ROOT_LOGGER; } else { - _logger = G_LOGGER; + _logger = logger; // 使用传入的日志对象 } - if (_logger->level >= LOG_ERROR) { - char logStr[LOG_BUFFER_SIZE]; - char finalLogStr[LOG_BUFFER_SIZE * 2]; + if (_logger->level >= level) { + char logStr + [LOG_BUFFER_SIZE]; // 定义一个缓冲区,用于存储格式化后的日志字符串 + char finalLogStr[LOG_BUFFER_SIZE * + 2]; // 定义一个缓冲区,用于存储最终输出的日志字符串 va_list args; va_start(args, message); vsprintf(logStr, message, args); va_end(args); snprintf( finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr); - log_cope(_logger, "Fatal", RED_B, finalLogStr); - } -} -void _log_error( - Logger *logger, const char *file, int line, const char *message, ...) { - Logger *_logger = NULL; - - if (logger != NULL) { - _logger = logger; - } else { - _logger = G_LOGGER; - } - - if (_logger->level >= LOG_ERROR) { - char logStr[LOG_BUFFER_SIZE]; - char finalLogStr[LOG_BUFFER_SIZE * 2]; - va_list args; - va_start(args, message); - vsprintf(logStr, message, args); - va_end(args); - snprintf( - finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr); - log_cope(_logger, "Error", RED, finalLogStr); - } -} - -void _log_warning( - Logger *logger, const char *file, int line, const char *message, ...) { - Logger *_logger = NULL; - - if (logger != NULL) { - _logger = logger; - } else { - _logger = G_LOGGER; - } - - if (_logger->level >= LOG_WARNING) { - char logStr[LOG_BUFFER_SIZE]; - char finalLogStr[LOG_BUFFER_SIZE * 2]; - va_list args; - va_start(args, message); - vsprintf(logStr, message, args); - va_end(args); - snprintf( - finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr); - log_cope(_logger, "Warning", YELLOW, finalLogStr); - } -} - -void _log_info( - Logger *logger, const char *file, int line, const char *message, ...) { - Logger *_logger = NULL; - - if (logger != NULL) { - _logger = logger; - } else { - _logger = G_LOGGER; - } - - if (_logger->level >= LOG_INFO) { - char logStr[LOG_BUFFER_SIZE]; - char finalLogStr[LOG_BUFFER_SIZE * 2]; - va_list args; - va_start(args, message); - vsprintf(logStr, message, args); - va_end(args); - snprintf( - finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr); - log_cope(_logger, "Info", GREEN, finalLogStr); - } -} - -void _log_debug( - Logger *logger, const char *file, int line, const char *message, ...) { - Logger *_logger = NULL; - - if (logger != NULL) { - _logger = logger; - } else { - _logger = G_LOGGER; - } - - if (_logger->level >= LOG_DEBUG) { - char logStr[LOG_BUFFER_SIZE]; - char finalLogStr[LOG_BUFFER_SIZE * 2]; - va_list args; - va_start(args, message); - vsprintf(logStr, message, args); - va_end(args); - snprintf( - finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr); - log_cope(_logger, "Debug", CYAN, finalLogStr); + switch (level) { + case LOG_DEBUG: + log_cope(_logger, "Debug", BLUE, finalLogStr); + break; + case LOG_INFO: + log_cope(_logger, "Info", GREEN, finalLogStr); + break; + case LOG_WARNING: + log_cope(_logger, "Warning", YELLOW, finalLogStr); + break; + case LOG_ERROR: + log_cope(_logger, "Error", RED, finalLogStr); + break; + case LOG_FATAL: + log_cope(_logger, "Fatal", RED_B, finalLogStr); + break; + default: + break; + } } } /** - * @brief 初始化默认日志器 + * @brief 创建一个日志句柄 * @param name 日志器名称 - * @param level 日志等级 * @return 日志器对象 */ -void initDefaultLogger(const char *name, log_level level) { - if (G_LOGGER != NULL) { - G_LOGGER->name = name; - G_LOGGER->level = level; +Logger *newLogger(const char *name) { + Logger *logger = (Logger *)malloc(sizeof(Logger)); + if (logger == NULL) { + return NULL; } - Logger *logger = (Logger *)malloc(sizeof(Logger)); - - logger->level = level; + logger->level = LOG_INFO; logger->handler = loggingHandlerConsole(); logger->name = name; logger->filter = NULL; - G_LOGGER = logger; + return logger; } -Logger *getDefaultLogger(void) { return G_LOGGER; } +Logger *getDefaultLogger(void) { + if (ROOT_LOGGER != NULL) { + return ROOT_LOGGER; + } + + ROOT_LOGGER = newLogger("ROOT"); + return ROOT_LOGGER; +} /** * @brief 获取日志器对象 @@ -314,30 +239,6 @@ Logger *getLogger(const char *name, log_level level) { return logger; } -/** - * @brief 销毁日志对象 - */ -void destroyDefaultLogger(void) { - if (G_LOGGER != NULL) { - if (G_LOGGER->handler != NULL) { - G_LOGGER->handler->_free(G_LOGGER->handler); - } - - if (G_LOGGER->filter != NULL) { - log_filter *it = G_LOGGER->filter; - log_filter *next = NULL; - while (it != NULL) { - next = it->next; - it->_free(it); - it = next; - } - } - - free(G_LOGGER); - G_LOGGER = NULL; - } -} - void destroyLogger(Logger *logger) { if (logger != NULL) { if (logger->handler != NULL) { @@ -353,7 +254,11 @@ void destroyLogger(Logger *logger) { it = next; } } - free(logger); } -} \ No newline at end of file +} + +/** + * @brief 销毁日志对象 + */ +void destroyDefaultLogger(void) { destroyLogger(ROOT_LOGGER); } \ No newline at end of file diff --git a/src/utils/logging-map.c b/src/utils/logging-map.c new file mode 100644 index 0000000..8aa5bba --- /dev/null +++ b/src/utils/logging-map.c @@ -0,0 +1,124 @@ +#include "logging-map.h" + +#include +#include + +/* 哈希函数:FNV-1a */ +static uint32_t hash_bytes(const void *data, size_t len) { + const uint8_t *p = data; + uint32_t h = 2166136261u; + while (len--) { + h ^= *p++; + h *= 16777619u; + } + return h; +} + +/* 创建空 map */ +Map *map_create(size_t key_len, size_t value_len) { + Map *m = calloc(1, sizeof(*m)); + m->key_len = key_len; + m->value_len = value_len; + m->bucket_cap = 8; /* 初始桶数 */ + m->bucket = calloc(m->bucket_cap, sizeof(Node *)); + return m; +} + +/* 根据 key 找到桶下标 */ +static size_t bucket_index(Map *m, const void *key) { + uint32_t h = hash_bytes(key, m->key_len); + return h & (m->bucket_cap - 1); /* 要求 bucket_cap 是 2 的幂 */ +} + +/* 在桶链中线性查找 */ +static Node *find_in_chain(Node *head, const void *key, size_t key_len) { + for (; head; head = head->next) { + if (memcmp(head->kv, key, key_len) == 0) { + return head; + } + } + return NULL; +} + +/* 扩容:2× 桶数,重新哈希所有节点 */ +static void map_resize(Map *m) { + size_t new_cap = m->bucket_cap * 2; + Node **new_bucket = calloc(new_cap, sizeof(Node *)); + + for (size_t i = 0; i < m->bucket_cap; ++i) { + Node *node = m->bucket[i]; + while (node) { + Node *next = node->next; + size_t idx = hash_bytes(node->kv, m->key_len) & (new_cap - 1); + node->next = new_bucket[idx]; + new_bucket[idx] = node; + node = next; + } + } + free(m->bucket); + m->bucket = new_bucket; + m->bucket_cap = new_cap; +} + +/* 插入或覆盖 */ +void map_put(Map *m, const void *key, const void *value) { + if (m->size * 4 >= m->bucket_cap * 3) { /* 装载因子 0.75 */ + map_resize(m); + } + + size_t idx = bucket_index(m, key); + Node *node = find_in_chain(m->bucket[idx], key, m->key_len); + + if (node) { /* 覆盖旧值 */ + memcpy(node->kv + m->key_len, value, m->value_len); + return; + } + + /* 新建节点 */ + node = malloc(sizeof(*node)); + node->kv = malloc(m->key_len + m->value_len); + node->next = m->bucket[idx]; + memcpy(node->kv, key, m->key_len); + memcpy(node->kv + m->key_len, value, m->value_len); + m->bucket[idx] = node; + ++m->size; +} + +/* 查找 */ +void *map_get(Map *m, const void *key) { + size_t idx = bucket_index(m, key); + Node *node = find_in_chain(m->bucket[idx], key, m->key_len); + return node ? (node->kv + m->key_len) : NULL; +} + +/* 删除 */ +bool map_erase(Map *m, const void *key) { + size_t idx = bucket_index(m, key); + Node **link = &m->bucket[idx]; + for (; *link; link = &(*link)->next) { + if (memcmp((*link)->kv, key, m->key_len) == 0) { + Node *to_del = *link; + *link = to_del->next; + free(to_del->kv); + free(to_del); + --m->size; + return true; + } + } + return false; +} + +/* 销毁 */ +void map_destroy(Map *m) { + for (size_t i = 0; i < m->bucket_cap; ++i) { + Node *node = m->bucket[i]; + while (node) { + Node *next = node->next; + free(node->kv); + free(node); + node = next; + } + } + free(m->bucket); + free(m); +} \ No newline at end of file diff --git a/src/utils/logging-map.h b/src/utils/logging-map.h new file mode 100644 index 0000000..14a1e92 --- /dev/null +++ b/src/utils/logging-map.h @@ -0,0 +1,37 @@ +#ifndef __LOGGING_MAP_H__ +#define __LOGGING_MAP_H__ + +#include +#include +#include + +typedef struct Node { + struct Node *next; + uint8_t *kv; /* key 在前 value 在后 */ +} Node; + +struct Map { + size_t key_len, value_len; + size_t bucket_cap; + size_t size; /* 当前元素个数 */ + Node **bucket; /* 指针数组 */ +}; + +typedef struct Map Map; + +/* 创建空 map:key_len/value_len 以字节为单位 */ +Map *map_create(size_t key_len, size_t value_len); + +/* 插入或覆盖: 必须指向 key_len 字节;同理 value */ +void map_put(Map *m, const void *key, const void *value); + +/* 查找:找到返回 value 指针;未找到返回 NULL */ +void *map_get(Map *m, const void *key); + +/* 删除:返回 true 表示确实删掉了 */ +bool map_erase(Map *m, const void *key); + +/* 销毁并释放所有内存 */ +void map_destroy(Map *m); + +#endif /* __LOGGING_MAP_H__ */ \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0baacea..f2f9869 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,6 +2,8 @@ project(test) enable_testing() +include_directories(${CMAKE_SOURCE_DIR}/src) + #测试简单基本应用 add_executable(${PROJECT_NAME}simple test-simple.c) target_link_libraries(${PROJECT_NAME}simple logging) @@ -17,3 +19,9 @@ add_test(test_file ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}file${CMAKE_EXECUT add_executable(${PROJECT_NAME}filter test-filter.c) target_link_libraries(${PROJECT_NAME}filter logging) add_test(test_filter ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}filter${CMAKE_EXECUTEABLE_SUFFIX}) + + +#测试工具map +add_executable(${PROJECT_NAME}map test-map.c) +target_link_libraries(${PROJECT_NAME}map logging) +add_test(test_map ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}map${CMAKE_EXECUTEABLE_SUFFIX}) \ No newline at end of file diff --git a/tests/test-filter.c b/tests/test-filter.c index 2394298..74babda 100644 --- a/tests/test-filter.c +++ b/tests/test-filter.c @@ -6,8 +6,6 @@ #include int main() { - initDefaultLogger("test-filter", LOG_DEBUG); - Log_info("This is an info message"); Log_error("This is an error message%s", "123"); Log_fatal("This is an fatal message"); diff --git a/tests/test-log-file.c b/tests/test-log-file.c index 0f0e98c..0cb136e 100644 --- a/tests/test-log-file.c +++ b/tests/test-log-file.c @@ -2,7 +2,6 @@ #include "logging/logging-handler.h" int main() { - initDefaultLogger("testLogger", LOG_DEBUG); log_Handler *hander = loggingHandlerFile("test_log", 1024 * 1024 * 10); addHandler(getDefaultLogger(), hander); diff --git a/tests/test-map.c b/tests/test-map.c new file mode 100644 index 0000000..2253ce0 --- /dev/null +++ b/tests/test-map.c @@ -0,0 +1,17 @@ +#include "utils/logging-map.h" + +int main(int argc, char *argv[]) { + (void)argc; + (void)argv; + + Map *map = map_create(0, sizeof(int)); + + const char *keys[] = {"key1", "key2", "key3", "key4", "key5"}; + + for (int i = 0; i < 5; i++) { + map_put(map, keys[i], &i); + } + + map_destroy(map); + return 0; +} \ No newline at end of file diff --git a/tests/test-simple.c b/tests/test-simple.c index 994246d..42a5a07 100644 --- a/tests/test-simple.c +++ b/tests/test-simple.c @@ -1,8 +1,6 @@ #include "logging.h" int main() { - initDefaultLogger("simple", LOG_DEBUG); - Log_info("This is an info message"); Log_error("This is an error message%s", "123"); Log_fatal("This is an fatal message"); From 5540a9169a232dce0e71d02b9fb20faf5d6b2115 Mon Sep 17 00:00:00 2001 From: youmetme <321640253@qq.com> Date: Sat, 18 Oct 2025 08:50:43 +0800 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E7=B3=BB=E7=BB=9F=EF=BC=8C=E6=B7=BB=E5=8A=A0=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E5=99=A8=E7=BC=93=E5=AD=98=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/logging.h | 2 +- src/logging.c | 34 +++++++++++++++++++-- src/utils/logging-map.c | 65 ++++++++++++++++++++++++++--------------- src/utils/logging-map.h | 20 +++++++++---- tests/CMakeLists.txt | 4 +++ tests/test-logs.c | 24 +++++++++++++++ tests/test-map.c | 26 +++++++++++++++-- 7 files changed, 139 insertions(+), 36 deletions(-) create mode 100644 tests/test-logs.c diff --git a/include/logging.h b/include/logging.h index 174b4e8..af9fa6b 100644 --- a/include/logging.h +++ b/include/logging.h @@ -66,7 +66,7 @@ Logger *newLogger(const char *name); */ Logger *getDefaultLogger(void); -Logger *getLogger(const char *name, log_level level); +Logger *getLogger(const char *name); /** * @brief 销毁日志对象,该方法会销毁默认日志对象 diff --git a/src/logging.c b/src/logging.c index 1929b23..310ef49 100644 --- a/src/logging.c +++ b/src/logging.c @@ -21,6 +21,8 @@ static Logger *ROOT_LOGGER = NULL; // 根日志对象,唯一实例 +static Map *LOGGER_MAP = NULL; // 日志对象映射表 + /** * @brief 为日志添加一个handler * @param handler 处理器对象 @@ -201,11 +203,17 @@ Logger *newLogger(const char *name) { return NULL; } + if (LOGGER_MAP == NULL) { + LOGGER_MAP = map_create(sizeof(Logger **)); + } + logger->level = LOG_INFO; logger->handler = loggingHandlerConsole(); logger->name = name; logger->filter = NULL; + map_put(LOGGER_MAP, name, &logger); + return logger; } @@ -224,18 +232,28 @@ Logger *getDefaultLogger(void) { * @param level 日志等级 * @return 日志器对象 */ -Logger *getLogger(const char *name, log_level level) { +Logger *getLogger(const char *name) { if (name == NULL) { return NULL; } + if (LOGGER_MAP == NULL) { + LOGGER_MAP = map_create(sizeof(Logger **)); + } + + Logger **cache_logger_ptr = (Logger **)map_get(LOGGER_MAP, name); + if (cache_logger_ptr != NULL) { + return *cache_logger_ptr; + } Logger *logger = (Logger *)malloc(sizeof(Logger)); - logger->level = level; + logger->level = LOG_INFO; logger->handler = loggingHandlerConsole(); logger->name = name; logger->filter = NULL; + map_put(LOGGER_MAP, name, &logger); + return logger; } @@ -258,7 +276,17 @@ void destroyLogger(Logger *logger) { } } +static void +__destroyLoggerForeach(const char *key, void *value, void *user_data) { + (void)user_data; + (void)key; + destroyLogger(*(Logger **)value); +} + /** * @brief 销毁日志对象 */ -void destroyDefaultLogger(void) { destroyLogger(ROOT_LOGGER); } \ No newline at end of file +void destroyDefaultLogger(void) { + map_foreach(LOGGER_MAP, __destroyLoggerForeach, NULL); + map_destroy(LOGGER_MAP); +} \ No newline at end of file diff --git a/src/utils/logging-map.c b/src/utils/logging-map.c index 8aa5bba..91776f4 100644 --- a/src/utils/logging-map.c +++ b/src/utils/logging-map.c @@ -15,9 +15,8 @@ static uint32_t hash_bytes(const void *data, size_t len) { } /* 创建空 map */ -Map *map_create(size_t key_len, size_t value_len) { +Map *map_create(size_t value_len) { Map *m = calloc(1, sizeof(*m)); - m->key_len = key_len; m->value_len = value_len; m->bucket_cap = 8; /* 初始桶数 */ m->bucket = calloc(m->bucket_cap, sizeof(Node *)); @@ -25,15 +24,16 @@ Map *map_create(size_t key_len, size_t value_len) { } /* 根据 key 找到桶下标 */ -static size_t bucket_index(Map *m, const void *key) { - uint32_t h = hash_bytes(key, m->key_len); +static size_t bucket_index(Map *m, const char *key) { + size_t len = strlen(key); + uint32_t h = hash_bytes(key, len); return h & (m->bucket_cap - 1); /* 要求 bucket_cap 是 2 的幂 */ } /* 在桶链中线性查找 */ -static Node *find_in_chain(Node *head, const void *key, size_t key_len) { +static Node *find_in_chain(Node *head, const char *key) { for (; head; head = head->next) { - if (memcmp(head->kv, key, key_len) == 0) { + if (strcmp(head->key, key) == 0) { return head; } } @@ -48,8 +48,9 @@ static void map_resize(Map *m) { for (size_t i = 0; i < m->bucket_cap; ++i) { Node *node = m->bucket[i]; while (node) { - Node *next = node->next; - size_t idx = hash_bytes(node->kv, m->key_len) & (new_cap - 1); + Node *next = node->next; + size_t idx = + hash_bytes(node->key, strlen(node->key)) & (new_cap - 1); node->next = new_bucket[idx]; new_bucket[idx] = node; node = next; @@ -61,45 +62,47 @@ static void map_resize(Map *m) { } /* 插入或覆盖 */ -void map_put(Map *m, const void *key, const void *value) { +void map_put(Map *m, const char *key, const void *value) { if (m->size * 4 >= m->bucket_cap * 3) { /* 装载因子 0.75 */ map_resize(m); } size_t idx = bucket_index(m, key); - Node *node = find_in_chain(m->bucket[idx], key, m->key_len); + Node *node = find_in_chain(m->bucket[idx], key); if (node) { /* 覆盖旧值 */ - memcpy(node->kv + m->key_len, value, m->value_len); + memcpy(node->value, value, m->value_len); return; } /* 新建节点 */ - node = malloc(sizeof(*node)); - node->kv = malloc(m->key_len + m->value_len); - node->next = m->bucket[idx]; - memcpy(node->kv, key, m->key_len); - memcpy(node->kv + m->key_len, value, m->value_len); + node = malloc(sizeof(*node)); + node->value = malloc(m->value_len); + node->next = m->bucket[idx]; + node->key = malloc(strlen(key) + 1); + memcpy(node->key, key, strlen(key) + 1); + memcpy(node->value, value, m->value_len); m->bucket[idx] = node; ++m->size; } /* 查找 */ -void *map_get(Map *m, const void *key) { +void *map_get(Map *m, const char *key) { size_t idx = bucket_index(m, key); - Node *node = find_in_chain(m->bucket[idx], key, m->key_len); - return node ? (node->kv + m->key_len) : NULL; + Node *node = find_in_chain(m->bucket[idx], key); + return node ? node->value : NULL; } /* 删除 */ -bool map_erase(Map *m, const void *key) { +bool map_erase(Map *m, const char *key) { size_t idx = bucket_index(m, key); Node **link = &m->bucket[idx]; for (; *link; link = &(*link)->next) { - if (memcmp((*link)->kv, key, m->key_len) == 0) { + if (strcmp((*link)->key, key) == 0) { Node *to_del = *link; *link = to_del->next; - free(to_del->kv); + free(to_del->key); + free(to_del->value); free(to_del); --m->size; return true; @@ -114,11 +117,27 @@ void map_destroy(Map *m) { Node *node = m->bucket[i]; while (node) { Node *next = node->next; - free(node->kv); + free(node->key); + free(node->value); free(node); node = next; } } free(m->bucket); free(m); +} + +/* 遍历 */ +void map_foreach(Map *m, + void (*callback)(const char *key, + void *value, + void *user_data), + void *user_data) { + for (size_t i = 0; i < m->bucket_cap; ++i) { + Node *node = m->bucket[i]; + while (node) { + callback(node->key, node->value, user_data); + node = node->next; + } + } } \ No newline at end of file diff --git a/src/utils/logging-map.h b/src/utils/logging-map.h index 14a1e92..cae31d7 100644 --- a/src/utils/logging-map.h +++ b/src/utils/logging-map.h @@ -7,11 +7,12 @@ typedef struct Node { struct Node *next; - uint8_t *kv; /* key 在前 value 在后 */ + char *key; + void *value; } Node; struct Map { - size_t key_len, value_len; + size_t value_len; size_t bucket_cap; size_t size; /* 当前元素个数 */ Node **bucket; /* 指针数组 */ @@ -20,16 +21,23 @@ struct Map { typedef struct Map Map; /* 创建空 map:key_len/value_len 以字节为单位 */ -Map *map_create(size_t key_len, size_t value_len); +Map *map_create(size_t value_len); /* 插入或覆盖: 必须指向 key_len 字节;同理 value */ -void map_put(Map *m, const void *key, const void *value); +void map_put(Map *m, const char *key, const void *value); /* 查找:找到返回 value 指针;未找到返回 NULL */ -void *map_get(Map *m, const void *key); +void *map_get(Map *m, const char *key); /* 删除:返回 true 表示确实删掉了 */ -bool map_erase(Map *m, const void *key); +bool map_erase(Map *m, const char *key); + +/* 遍历: 遍历所有元素*/ +void map_foreach(Map *m, + void (*callback)(const char *key, + void *value, + void *user_data), + void *user_data); /* 销毁并释放所有内存 */ void map_destroy(Map *m); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f2f9869..010d63b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -20,6 +20,10 @@ add_executable(${PROJECT_NAME}filter test-filter.c) target_link_libraries(${PROJECT_NAME}filter logging) add_test(test_filter ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}filter${CMAKE_EXECUTEABLE_SUFFIX}) +#测试多log多次获取 +add_executable(${PROJECT_NAME}logs test-logs.c) +target_link_libraries(${PROJECT_NAME}logs logging) +add_test(test_logs ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}logs${CMAKE_EXECUTEABLE_SUFFIX}) #测试工具map add_executable(${PROJECT_NAME}map test-map.c) diff --git a/tests/test-logs.c b/tests/test-logs.c new file mode 100644 index 0000000..bf17fcd --- /dev/null +++ b/tests/test-logs.c @@ -0,0 +1,24 @@ +#include "logging.h" +#include "logging/logging-core.h" +#include + +int main() { + Logger *t1 = getLogger("Test1"); + t1->level = LOG_ERROR; + + Logger *t2 = getLogger("Test2"); + t2->level = LOG_DEBUG; + + Logger *t11 = getLogger("Test1"); + + if (t1 == t11) { + printf("t1 and t11 are the same\n"); + printf("t1 log level: %s", LOG_LEVEL_STR[t11->level]); + } else { + printf("t1 and t11 are different\n"); + return 1; + } + + destroyDefaultLogger(); + return 0; +} \ No newline at end of file diff --git a/tests/test-map.c b/tests/test-map.c index 2253ce0..a04ddc2 100644 --- a/tests/test-map.c +++ b/tests/test-map.c @@ -1,17 +1,37 @@ #include "utils/logging-map.h" +#include +#include +#include + +void foreach_callback(const char *key, void *value, void *user_data) { + (void)user_data; + printf("foreach key: %s, value: %d\n", key, *(int *)value); +} int main(int argc, char *argv[]) { (void)argc; (void)argv; - Map *map = map_create(0, sizeof(int)); + Map *map = map_create(sizeof(int)); - const char *keys[] = {"key1", "key2", "key3", "key4", "key5"}; + const char *keys[] = {"key1", "key22", "key33", "key44", "key55"}; for (int i = 0; i < 5; i++) { + printf("put key %s,value %d\n", keys[i], i); map_put(map, keys[i], &i); } + for (int i = 0; i < 5; i++) { + int *value = map_get(map, keys[i]); + printf("get value: %d\n", *value); + if (*value != i) { + return 1; + } + } + + map_foreach(map, foreach_callback, NULL); + map_destroy(map); + return 0; -} \ No newline at end of file +} From ca20d51edb126e3fec3aa35aec49635eb4bce6a9 Mon Sep 17 00:00:00 2001 From: youmetme <321640253@qq.com> Date: Sat, 18 Oct 2025 09:04:08 +0800 Subject: [PATCH 5/5] =?UTF-8?q?refactor:=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E7=A4=BA=E4=BE=8B=EF=BC=8C=E7=AE=80=E5=8C=96=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E4=BD=BF=E7=94=A8=E6=96=B9=E5=BC=8F=E5=B9=B6=E5=8D=87?= =?UTF-8?q?=E7=BA=A7=E7=89=88=E6=9C=AC=E8=87=B31.0.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.en.md | 111 +++++++++++++++---------------------------------- README.md | 71 +++++++------------------------ conanfile.py | 2 +- pyproject.toml | 2 +- 4 files changed, 50 insertions(+), 136 deletions(-) diff --git a/README.en.md b/README.en.md index 7102038..270e53d 100644 --- a/README.en.md +++ b/README.en.md @@ -32,13 +32,11 @@ cmake --install . #include "logging.h" int main() { - Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG); - - log_info("This is an info message"); - log_error("This is an error message%s", "123"); - log_fatal("This is an fatal message"); - log_debug("This is a debug message"); - log_warning("This is a warning message%s", "123"); + Log_info("This is an info message"); + Log_error("This is an error message%s", "123"); + Log_fatal("This is an fatal message"); + Log_debug("This is a debug message"); + Log_warning("This is a warning message%s", "123"); destroyDefaultLogger(); return 0; @@ -51,14 +49,14 @@ int main() { #include "logging/logging-handler.h" int main() { - Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG); - logger->addHandler(loggingHandlerFile("test1", 1024*1024)); + log_Handler *hander = loggingHandlerFile("test_log", 1024 * 1024 * 10); + addHandler(getDefaultLogger(), hander); - log_info("This is an info message"); - log_error("This is an error message%s", "123"); - log_fatal("This is an fatal message"); - log_debug("This is a debug message"); - log_warning("This is a warning message%s", "123"); + Log_info("This is an info message"); + Log_error("This is an error message%s", "123"); + Log_fatal("This is an fatal message"); + Log_debug("This is a debug message"); + Log_warning("This is a warning message%s", "123"); destroyDefaultLogger(); return 0; @@ -69,92 +67,51 @@ int main() { > Support adding custom filters, currently with built-in substring filters > The function of an filter is to redirect filtered logs to the filter's dedicated processor - -#### example -Redirects filtered logs to a dedicated file processor -```c -#include "logging.h" -#include - -int main() { - Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG); - - log_info("This is an info message"); - log_error("This is an error message%s", "123"); - log_fatal("This is an fatal message"); - log_debug("This is a debug message"); - log_warning("This is a warning message%s", "123"); - - char *test1[] = {"123", "tt", NULL}; - - log_filter *tint = loggingFilterSubStr( - test1, - LOG_DEBUG, - loggingHandlerFile("test_interceptor", 1024 * 1024), - true); - - logger->addFilter(tint); - - printf("\n"); - printf("filter added\n"); - printf("\n"); - - log_info("This is an info message"); - log_error("This is an error message%s", "123"); - log_fatal("This is an fatal message"); - log_debug("This is a debug message"); - log_warning("This is a warning message%s", "123"); - - destroyDefaultLogger(); - return 0; -} -``` - #### Multiple substring filters ```c #include "logging.h" +#include "logging/logging-core.h" +#include "logging/logging-filter.h" #include #include #include int main() { - Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG); + Log_info("This is an info message"); + Log_error("This is an error message%s", "123"); + Log_fatal("This is an fatal message"); + Log_debug("This is a debug message"); + Log_warning("This is a warning message%s", "123"); - log_info("This is an info message"); - log_error("This is an error message%s", "123"); - log_fatal("This is an fatal message"); - log_debug("This is a debug message"); - log_warning("This is a warning message%s", "123"); + char *test1[] = {"This", NULL}; - char *test1[] = {"This",NULL}; + log_filter *tint = + loggingFilterSubStr(test1, + LOG_DEBUG, + loggingHandlerFile("test_interceptor", 1024 * 1024), + false); - log_filter *tint = loggingFilterSubStr( - test1, - LOG_DEBUG, - loggingHandlerFile("test_interceptor", 1024 * 1024), - false); + addFilter(getDefaultLogger(), tint); - logger->addFilter(tint); - - char *test2[] = {"123",NULL}; + char *test2[] = {"123", NULL}; log_filter *tint1 = loggingFilterSubStr( test2, - LOG_DEBUG, + LOG_ERROR, loggingHandlerFile("test_interceptor1", 1024 * 1024), true); - logger->addFilter(tint1); + addFilter(getDefaultLogger(), tint1); printf("\n"); printf("filter added\n"); printf("\n"); - log_info("This is an info message"); - log_error("This is an error message%s", "123"); - log_fatal("This is an fatal message"); - log_debug("This is a debug message"); - log_warning("This is a warning message%s", "123"); + Log_info("This is an info message"); + Log_error("This is an error message%s", "123"); + Log_fatal("This is an fatal message"); + Log_debug("This is a debug message"); + Log_warning("This is a warning message%s", "123"); destroyDefaultLogger(); return 0; diff --git a/README.md b/README.md index 882fa4b..6c4742f 100644 --- a/README.md +++ b/README.md @@ -47,8 +47,6 @@ cmake --install . #include "logging.h" int main() { - Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG); - Log_info("This is an info message"); Log_error("This is an error message%s", "123"); Log_fatal("This is an fatal message"); @@ -66,8 +64,8 @@ int main() { #include "logging/logging-handler.h" int main() { - Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG); - logger->addHandler(loggingHandlerFile("test1", 1024*1024)); + log_Handler *hander = loggingHandlerFile("test_log", 1024 * 1024 * 10); + addHandler(getDefaultLogger(), hander); Log_info("This is an info message"); Log_error("This is an error message%s", "123"); @@ -85,82 +83,41 @@ int main() { > 过滤器的作用:可以将过滤到的日志重定向到过滤器的专属处理器中 - -#### 单个子串过滤器 -将过滤到的日志重定向到专属处理器中 -```c -#include "logging.h" -#include - -int main() { - Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG); - - Log_info("This is an info message"); - Log_error("This is an error message%s", "123"); - Log_fatal("This is an fatal message"); - Log_debug("This is a debug message"); - Log_warning("This is a warning message%s", "123"); - - char *test1[] = {"123", "tt", NULL}; - - log_filter *tint = loggingFilterSubStr( - test1, - LOG_DEBUG, - loggingHandlerFile("test_interceptor", 1024 * 1024), - true); - - logger->addFilter(tint); - - printf("\n"); - printf("filter added\n"); - printf("\n"); - - Log_info("This is an info message"); - Log_error("This is an error message%s", "123"); - Log_fatal("This is an fatal message"); - Log_debug("This is a debug message"); - Log_warning("This is a warning message%s", "123"); - - destroyDefaultLogger(); - return 0; -} -``` - #### 多个子串过滤器 ```c #include "logging.h" +#include "logging/logging-core.h" +#include "logging/logging-filter.h" #include #include #include int main() { - Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG); - Log_info("This is an info message"); Log_error("This is an error message%s", "123"); Log_fatal("This is an fatal message"); Log_debug("This is a debug message"); Log_warning("This is a warning message%s", "123"); - char *test1[] = {"This",NULL}; + char *test1[] = {"This", NULL}; - log_filter *tint = loggingFilterSubStr( - test1, - LOG_DEBUG, - loggingHandlerFile("test_interceptor", 1024 * 1024), - false); + log_filter *tint = + loggingFilterSubStr(test1, + LOG_DEBUG, + loggingHandlerFile("test_interceptor", 1024 * 1024), + false); - logger->addFilter(tint); + addFilter(getDefaultLogger(), tint); - char *test2[] = {"123",NULL}; + char *test2[] = {"123", NULL}; log_filter *tint1 = loggingFilterSubStr( test2, - LOG_DEBUG, + LOG_ERROR, loggingHandlerFile("test_interceptor1", 1024 * 1024), true); - logger->addFilter(tint1); + addFilter(getDefaultLogger(), tint1); printf("\n"); printf("filter added\n"); diff --git a/conanfile.py b/conanfile.py index 5153e40..feb387b 100644 --- a/conanfile.py +++ b/conanfile.py @@ -5,7 +5,7 @@ import os class loggingRecipe(ConanFile): name = "logging" - version = "0.5.1" + version = "1.0.0" license = "MIT" author = "321640253@qq.com" url = "https://github.com/WangZhongDian/logging.git" diff --git a/pyproject.toml b/pyproject.toml index 8f41d9e..629cc91 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "logging" -version = "0.1.0" +version = "1.0.0" description = "Add your description here" readme = "README.md" requires-python = ">=3.12"