diff --git a/README.en.md b/README.en.md index b66dd97..9a3cb74 100644 --- a/README.en.md +++ b/README.en.md @@ -20,6 +20,8 @@ conan create . ``` ## usage +![](docs/img/2024-09-21-11-44-25.png) +![](docs/img/2024-09-21-11-44-06.png) ### console log ```c @@ -79,13 +81,13 @@ int main() { log_debug("This is a debug message"); log_warning("This is a warning message%s", "123"); - char *test1[] = {"123", "tt"}; + char *test1[] = {"123", "tt", NULL}; log_Interceptor *tint = loggingSubStringInterceptor( test1, - 2, LOG_DEBUG, - loggingFileHandler("test_interceptor", 1024 * 1024)); + loggingFileHandler("test_interceptor", 1024 * 1024), + true); logger->addInterceptor(tint); @@ -103,6 +105,55 @@ int main() { return 0; } ``` -![](docs/img/2024-09-21-11-44-25.png) -![](docs/img/2024-09-21-11-44-06.png) + +#### Multiple substring interceptors +```c +#include "logging.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}; + + log_Interceptor *tint = loggingSubStringInterceptor( + test1, + LOG_DEBUG, + loggingFileHandler("test_interceptor", 1024 * 1024), + false); + + logger->addInterceptor(tint); + + char *test2[] = {"123",NULL}; + + log_Interceptor *tint1 = loggingSubStringInterceptor( + test2, + LOG_DEBUG, + loggingFileHandler("test_interceptor1", 1024 * 1024), + true); + + logger->addInterceptor(tint1); + + printf("\n"); + printf("Interceptor 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; +} +``` diff --git a/README.md b/README.md index 04f5194..654007a 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ conan create . ``` ## 使用方法 +![](docs/img/2024-09-21-11-44-25.png) +![](docs/img/2024-09-21-11-44-06.png) ### 控制台日志 ```c @@ -68,7 +70,7 @@ int main() { > 拦截器的作用:可以将拦截到的日志重定向到拦截器的专属处理器中 -#### 例子 +#### 单个子串拦截器 将拦截到的日志重定向到专属文件处理器中 ```c #include "logging.h" @@ -83,13 +85,13 @@ int main() { log_debug("This is a debug message"); log_warning("This is a warning message%s", "123"); - char *test1[] = {"123", "tt"}; + char *test1[] = {"123", "tt", NULL}; log_Interceptor *tint = loggingSubStringInterceptor( test1, - 2, LOG_DEBUG, - loggingFileHandler("test_interceptor", 1024 * 1024)); + loggingFileHandler("test_interceptor", 1024 * 1024), + true); logger->addInterceptor(tint); @@ -107,6 +109,55 @@ int main() { return 0; } ``` -![](docs/img/2024-09-21-11-44-25.png) -![](docs/img/2024-09-21-11-44-06.png) + +#### 多个子串拦截器 +```c +#include "logging.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}; + + log_Interceptor *tint = loggingSubStringInterceptor( + test1, + LOG_DEBUG, + loggingFileHandler("test_interceptor", 1024 * 1024), + false); + + logger->addInterceptor(tint); + + char *test2[] = {"123",NULL}; + + log_Interceptor *tint1 = loggingSubStringInterceptor( + test2, + LOG_DEBUG, + loggingFileHandler("test_interceptor1", 1024 * 1024), + true); + + logger->addInterceptor(tint1); + + printf("\n"); + printf("Interceptor 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; +} +``` diff --git a/include/logging/logging-interceptor.h b/include/logging/logging-interceptor.h index 543b16a..7bc1ff0 100644 --- a/include/logging/logging-interceptor.h +++ b/include/logging/logging-interceptor.h @@ -3,6 +3,7 @@ #include "logging-core.h" #include "logging-handler.h" +#include #ifdef __cplusplus extern "C" { @@ -11,9 +12,13 @@ extern "C" { typedef struct log_Interceptor { log_level level; log_Handler *handler; - bool (*_dispose)(char *level, const char *message, ...); + bool jump_out; + bool (*_dispose)(struct log_Interceptor *Interceptor, + char *level, + const char *message, + ...); void (*_free)(struct log_Interceptor *Interceptor); - + struct log_Interceptor *next; } log_Interceptor; /** @@ -25,9 +30,9 @@ typedef struct log_Interceptor { * @return log_Interceptor * */ log_Interceptor *loggingSubStringInterceptor(char *keywords[], - int count, log_level level, - log_Handler *handler); + log_Handler *handler, + bool jump_out); #ifdef __cplusplus } diff --git a/src/interceptor/logging-interceptor-substr.c b/src/interceptor/logging-interceptor-substr.c index f21dc10..b1226b0 100644 --- a/src/interceptor/logging-interceptor-substr.c +++ b/src/interceptor/logging-interceptor-substr.c @@ -3,10 +3,12 @@ #include #include #include +#include -static log_Interceptor *G_interceptor = NULL; - -static char **G_keywords = NULL; +typedef struct keywords_s { + char *key; + struct keywords_s *next; +} keywords_t; static void get_next(char *str, int *next) { next[1] = 0; @@ -22,6 +24,8 @@ static void get_next(char *str, int *next) { } static bool kmp_search(char *substr, char *master) { + if(substr == NULL)return true; //空串全匹配 + if(master == NULL)return false; int i = 0; int j = 0; int substrlen = strlen(substr); @@ -49,62 +53,75 @@ static bool kmp_search(char *substr, char *master) { return false; } -static bool _disposeSubstring(char *level, const char *message, ...) { - int count = 0; +static bool _disposeSubstring(log_Interceptor *interceptor, + char *level, + const char *message, + ...) { + int count = 0; + keywords_t *keyword = (keywords_t *)(interceptor + 1); - if (G_keywords == NULL) { + if (keyword->key == NULL && keyword->next == NULL) return false; - } - while (G_keywords[count] != NULL) { - if (kmp_search(G_keywords[count], (char *)message)) { + while (keyword != NULL) { + if (kmp_search(keyword->key, (char *)message)) return true; - } - count++; + keyword = keyword->next; } return false; } static void _freeSubstring(log_Interceptor *interceptor) { - if (G_keywords != NULL) { - int sum = 0; - while (G_keywords[sum] != NULL) { - free(G_keywords[sum]); - sum++; - } - free(G_keywords[sum]); - free(G_keywords); - G_keywords = NULL; + keywords_t *it_keyword = + (keywords_t *)(interceptor + 1); // it_keyword 不是起始地址,请勿free + keywords_t *keyword = it_keyword->next; + keywords_t *next = NULL; + + while (keyword != NULL) { + next = keyword->next; + free(keyword->key); + free(keyword); + keyword = next; } if (interceptor->handler != NULL) { interceptor->handler->_free(interceptor->handler); } - if (interceptor != NULL) - free(interceptor); + if (it_keyword->key != NULL) + free(it_keyword->key); + free(interceptor); } log_Interceptor *loggingSubStringInterceptor(char *keywords[], - int count, log_level level, - log_Handler *handler) { + log_Handler *handler, + bool jump_out) { log_Interceptor *interceptor = - (log_Interceptor *)malloc(sizeof(log_Interceptor)); + (log_Interceptor *)malloc(sizeof(log_Interceptor) + sizeof(keywords_t)); interceptor->_dispose = _disposeSubstring; interceptor->handler = handler; interceptor->level = level; + interceptor->jump_out = jump_out; interceptor->_free = _freeSubstring; - G_keywords = (char **)malloc((sizeof(G_keywords) * (count + 1))); - - for (int i = 0; i < count; i++) { - G_keywords[i] = (char *)malloc(strlen(keywords[i]) + 1); - strcpy(G_keywords[i], keywords[i]); + keywords_t *keyword = (keywords_t *)(interceptor + 1); + keyword->key = NULL; + int count = 0; + if (keywords[count] != NULL) { + keyword->key = strdup(keywords[count]); + count++; + keyword->next = NULL; } - G_keywords[count] = NULL; - G_interceptor = interceptor; - return G_interceptor; + while (keywords[count] != NULL) { + keyword->next = (keywords_t *)malloc(sizeof(keywords_t)); + keyword = keyword->next; + keyword->key = strdup(keywords[count]); + count++; + } + keyword->next = NULL; + + return interceptor; } \ No newline at end of file diff --git a/src/logging.c b/src/logging.c index 4bce8b0..352e8a8 100644 --- a/src/logging.c +++ b/src/logging.c @@ -42,45 +42,28 @@ static bool addInterceptor(log_Interceptor *Interceptor) { return false; } if (G_LOGGER->interceptor == NULL) { - G_LOGGER->interceptor = Interceptor; + G_LOGGER->interceptor = Interceptor; + G_LOGGER->interceptor->next = NULL; return true; } - G_LOGGER->interceptor->_free(G_LOGGER->interceptor); - G_LOGGER->interceptor = Interceptor; + log_Interceptor *it = G_LOGGER->interceptor; + while (it->next != NULL) { + it = it->next; + } + + it->next = Interceptor; + Interceptor->next = NULL; return true; } -/** - * @brief 内部日志打印处理核心函数 - * @param level 日志等级 - * @param color 应用的颜色 - * @param message 日志内容 - * @param ... 格式化参数列表 - * @return - */ -static void -_builtin_log(char *level, const char *color, const char *message, ...) { - if (G_LOGGER == NULL) { - return; - } - if (G_LOGGER->handler == NULL) { - return; - } +static void output_to_handler(log_Handler *handler, + char *level, + const char *color, + const char *message) { char timeStr[20]; getTimeStr(timeStr); char logStr[LOG_BUFFER_SIZE]; - - log_Handler *handler = G_LOGGER->handler; - - if (G_LOGGER->interceptor != NULL) { - if (G_LOGGER->interceptor->_dispose(level, message)) { - if (G_LOGGER->interceptor->handler != NULL) { - handler = G_LOGGER->interceptor->handler; - } - } - } - if (handler->apply_color) sprintf(logStr, "[%s]: %s %s%s%s %s\n", @@ -101,6 +84,36 @@ _builtin_log(char *level, const char *color, const char *message, ...) { handler->output(handler, logStr); } +/** + * @brief 内部日志打印处理核心函数 + * @param level 日志等级 + * @param color 应用的颜色 + * @param message 日志内容 + * @param ... 格式化参数列表 + * @return + */ +static void _builtin_cope(char *level, const char *color, const char *message) { + if (G_LOGGER == NULL) { + return; + } + if (G_LOGGER->handler == NULL) { + return; + } + + log_Interceptor *it = G_LOGGER->interceptor; + log_Handler *handler = G_LOGGER->handler; + + while (it != NULL) { + if (it->_dispose(it, level, message)) { + output_to_handler(it->handler, level, color, message); + if (it->jump_out) + return; + } + it = it->next; + } + output_to_handler(handler, level, color, message); +} + void log_fatal(const char *message, ...) { if (G_LOGGER->level >= LOG_ERROR) { char logStr[LOG_BUFFER_SIZE]; @@ -108,7 +121,7 @@ void log_fatal(const char *message, ...) { va_start(args, message); vsprintf(logStr, message, args); va_end(args); - _builtin_log("Fatal", RED_B, logStr, args); + _builtin_cope("Fatal", RED_B, logStr); } } @@ -119,7 +132,7 @@ void log_error(const char *message, ...) { va_start(args, message); vsprintf(logStr, message, args); va_end(args); - _builtin_log("Error", RED, logStr, args); + _builtin_cope("Error", RED, logStr); } } @@ -130,7 +143,7 @@ void log_warning(const char *message, ...) { va_start(args, message); vsprintf(logStr, message, args); va_end(args); - _builtin_log("Warning", YELLOW, logStr, args); + _builtin_cope("Warning", YELLOW, logStr); } } @@ -141,7 +154,7 @@ void log_info(const char *message, ...) { va_start(args, message); vsprintf(logStr, message, args); va_end(args); - _builtin_log("Info", GREEN, logStr, args); + _builtin_cope("Info", GREEN, logStr); } } @@ -152,7 +165,7 @@ void log_debug(const char *message, ...) { va_start(args, message); vsprintf(logStr, message, args); va_end(args); - _builtin_log("Debug", CYAN, logStr, args); + _builtin_cope("Debug", CYAN, logStr); } } @@ -187,7 +200,13 @@ log_status destroyDefaultLogger(void) { } if (G_LOGGER->interceptor != NULL) { - G_LOGGER->interceptor->_free(G_LOGGER->interceptor); + log_Interceptor *it = G_LOGGER->interceptor; + log_Interceptor *next = NULL; + while (it != NULL) { + next = it->next; + it->_free(it); + it = next; + } } free(G_LOGGER); diff --git a/tests/test_interceptor.c b/tests/test_interceptor.c index 028e35b..64728bb 100644 --- a/tests/test_interceptor.c +++ b/tests/test_interceptor.c @@ -1,8 +1,10 @@ #include "logging.h" +#include #include +#include int main() { - Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG); + Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG); log_info("This is an info message"); log_error("This is an error message%s", "123"); @@ -10,16 +12,26 @@ int main() { log_debug("This is a debug message"); log_warning("This is a warning message%s", "123"); - char *test1[] = {"123", "tt"}; + char *test1[] = {"This",NULL}; log_Interceptor *tint = loggingSubStringInterceptor( test1, - 2, LOG_DEBUG, - loggingFileHandler("test_interceptor", 1024 * 1024)); + loggingFileHandler("test_interceptor", 1024 * 1024), + false); logger->addInterceptor(tint); + char *test2[] = {"123",NULL}; + + log_Interceptor *tint1 = loggingSubStringInterceptor( + test2, + LOG_DEBUG, + loggingFileHandler("test_interceptor1", 1024 * 1024), + true); + + logger->addInterceptor(tint1); + printf("\n"); printf("Interceptor added\n"); printf("\n");