Multiple substring interceptors (#13)
* #feat 增强Fatal级别的底色,修改logging类的方法 * 更新版本号 * 加入test脚本 * fix:conanfile * test action * 修复错别字 * add test on windows action * fix test on windows action * fix action on windows * fix * fix 内存分配错误 * fix msvc 不支持中文注释,删除中文注释 * test on windows and test chinese char * ersion 0.2.4 * feature:根据文件大小分割日志 * fix:内存泄露 * fix:使用char偏移单位 * add english brief * 修改api函数名,加入Default关键字,减除歧义 * Multiple substring interceptors
This commit is contained in:
		
							
								
								
									
										113
									
								
								README.en.md
									
									
									
									
									
								
							
							
						
						
									
										113
									
								
								README.en.md
									
									
									
									
									
								
							| @@ -20,21 +20,23 @@ conan create . | |||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ## usage | ## usage | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ### console log  | ### console log  | ||||||
| ```c | ```c | ||||||
| #include "logging.h" | #include "logging.h" | ||||||
|  |  | ||||||
| int main() { | int main() { | ||||||
|     Logger *logger = newLogger("testLogger", LOG_DEBUG); |     Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG); | ||||||
|  |  | ||||||
|     logger->info("This is an info message"); |     log_info("This is an info message"); | ||||||
|     logger->error("This is an error message%s", "123"); |     log_error("This is an error message%s", "123"); | ||||||
|     logger->fatal("This is an fatal message"); |     log_fatal("This is an fatal message"); | ||||||
|     logger->debug("This is a debug message"); |     log_debug("This is a debug message"); | ||||||
|     logger->warning("This is a warning message%s", "123"); |     log_warning("This is a warning message%s", "123"); | ||||||
|  |  | ||||||
|     destroyLogger(); |     destroyDefaultLogger(); | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| ``` | ``` | ||||||
| @@ -45,16 +47,16 @@ int main() { | |||||||
| #include "logging/logging-handler.h" | #include "logging/logging-handler.h" | ||||||
|  |  | ||||||
| int main() { | int main() { | ||||||
|     Logger *logger = newLogger("testLogger", LOG_DEBUG); |     Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG); | ||||||
|     logger->addHandler(loggingFileHandler("test1", 1024*1024)); |     logger->addHandler(loggingFileHandler("test1", 1024*1024)); | ||||||
|  |  | ||||||
|     logger->info("This is an info message"); |     log_info("This is an info message"); | ||||||
|     logger->error("This is an error message%s", "123"); |     log_error("This is an error message%s", "123"); | ||||||
|     logger->fatal("This is an fatal message"); |     log_fatal("This is an fatal message"); | ||||||
|     logger->debug("This is a debug message"); |     log_debug("This is a debug message"); | ||||||
|     logger->warning("This is a warning message%s", "123"); |     log_warning("This is a warning message%s", "123"); | ||||||
|  |  | ||||||
|     destroyLogger(); |     destroyDefaultLogger(); | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| ``` | ``` | ||||||
| @@ -71,21 +73,21 @@ Redirects intercepted logs to a dedicated file processor | |||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  |  | ||||||
| int main() { | int main() { | ||||||
|     Logger  *logger = newLogger("testLogger", LOG_DEBUG); |     Logger  *logger = newDefaultLogger("testLogger", LOG_DEBUG); | ||||||
|  |  | ||||||
|     logger->info("This is an info message"); |     log_info("This is an info message"); | ||||||
|     logger->error("This is an error message%s", "123"); |     log_error("This is an error message%s", "123"); | ||||||
|     logger->fatal("This is an fatal message"); |     log_fatal("This is an fatal message"); | ||||||
|     logger->debug("This is a debug message"); |     log_debug("This is a debug message"); | ||||||
|     logger->warning("This is a warning message%s", "123"); |     log_warning("This is a warning message%s", "123"); | ||||||
|  |  | ||||||
|     char *test1[]         = {"123", "tt"}; |     char *test1[]         = {"123", "tt", NULL}; | ||||||
|  |  | ||||||
|     log_Interceptor *tint = loggingSubStringInterceptor( |     log_Interceptor *tint = loggingSubStringInterceptor( | ||||||
|         test1, |         test1, | ||||||
|         2, |  | ||||||
|         LOG_DEBUG, |         LOG_DEBUG, | ||||||
|         loggingFileHandler("test_interceptor", 1024 * 1024)); |         loggingFileHandler("test_interceptor", 1024 * 1024), | ||||||
|  |         true); | ||||||
|  |  | ||||||
|     logger->addInterceptor(tint); |     logger->addInterceptor(tint); | ||||||
|  |  | ||||||
| @@ -93,16 +95,65 @@ int main() { | |||||||
|     printf("Interceptor added\n"); |     printf("Interceptor added\n"); | ||||||
|     printf("\n"); |     printf("\n"); | ||||||
|  |  | ||||||
|     logger->info("This is an info message"); |     log_info("This is an info message"); | ||||||
|     logger->error("This is an error message%s", "123"); |     log_error("This is an error message%s", "123"); | ||||||
|     logger->fatal("This is an fatal message"); |     log_fatal("This is an fatal message"); | ||||||
|     logger->debug("This is a debug message"); |     log_debug("This is a debug message"); | ||||||
|     logger->warning("This is a warning message%s", "123"); |     log_warning("This is a warning message%s", "123"); | ||||||
|  |  | ||||||
|     destroyLogger(); |     destroyDefaultLogger(); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | #### Multiple substring interceptors | ||||||
|  | ```c | ||||||
|  | #include "logging.h" | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <time.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"); | ||||||
|  |  | ||||||
|  |     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; |     return 0; | ||||||
| } | } | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										124
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										124
									
								
								README.md
									
									
									
									
									
								
							| @@ -22,31 +22,24 @@ conan create . | |||||||
| ```shell | ```shell | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ## 安装 |  | ||||||
| - conan安装使用 |  | ||||||
| ```shell |  | ||||||
| conan create . --build=missing |  | ||||||
| ``` |  | ||||||
| - cmake安装使用 |  | ||||||
| ```shell |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ## 使用方法 | ## 使用方法 | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ### 控制台日志 | ### 控制台日志 | ||||||
| ```c | ```c | ||||||
| #include "logging.h" | #include "logging.h" | ||||||
|  |  | ||||||
| int main() { | int main() { | ||||||
|     Logger *logger = newLogger("testLogger", LOG_DEBUG); |     Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG); | ||||||
|  |  | ||||||
|     logger->info("This is an info message"); |     log_info("This is an info message"); | ||||||
|     logger->error("This is an error message%s", "123"); |     log_error("This is an error message%s", "123"); | ||||||
|     logger->fatal("This is an fatal message"); |     log_fatal("This is an fatal message"); | ||||||
|     logger->debug("This is a debug message"); |     log_debug("This is a debug message"); | ||||||
|     logger->warning("This is a warning message%s", "123"); |     log_warning("This is a warning message%s", "123"); | ||||||
|  |  | ||||||
|     destroyLogger(); |     destroyDefaultLogger(); | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| ``` | ``` | ||||||
| @@ -57,16 +50,16 @@ int main() { | |||||||
| #include "logging/logging-handler.h" | #include "logging/logging-handler.h" | ||||||
|  |  | ||||||
| int main() { | int main() { | ||||||
|     Logger *logger = newLogger("testLogger", LOG_DEBUG); |     Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG); | ||||||
|     logger->addHandler(loggingFileHandler("test1", 1024*1024)); |     logger->addHandler(loggingFileHandler("test1", 1024*1024)); | ||||||
|  |  | ||||||
|     logger->info("This is an info message"); |     log_info("This is an info message"); | ||||||
|     logger->error("This is an error message%s", "123"); |     log_error("This is an error message%s", "123"); | ||||||
|     logger->fatal("This is an fatal message"); |     log_fatal("This is an fatal message"); | ||||||
|     logger->debug("This is a debug message"); |     log_debug("This is a debug message"); | ||||||
|     logger->warning("This is a warning message%s", "123"); |     log_warning("This is a warning message%s", "123"); | ||||||
|  |  | ||||||
|     destroyLogger(); |     destroyDefaultLogger(); | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| ``` | ``` | ||||||
| @@ -77,28 +70,28 @@ int main() { | |||||||
| > 拦截器的作用:可以将拦截到的日志重定向到拦截器的专属处理器中 | > 拦截器的作用:可以将拦截到的日志重定向到拦截器的专属处理器中 | ||||||
|  |  | ||||||
|  |  | ||||||
| #### 例子 | #### 单个子串拦截器 | ||||||
| 将拦截到的日志重定向到专属文件处理器中 | 将拦截到的日志重定向到专属文件处理器中 | ||||||
| ```c | ```c | ||||||
| #include "logging.h" | #include "logging.h" | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  |  | ||||||
| int main() { | int main() { | ||||||
|     Logger  *logger = newLogger("testLogger", LOG_DEBUG); |     Logger  *logger = newDefaultLogger("testLogger", LOG_DEBUG); | ||||||
|  |  | ||||||
|     logger->info("This is an info message"); |     log_info("This is an info message"); | ||||||
|     logger->error("This is an error message%s", "123"); |     log_error("This is an error message%s", "123"); | ||||||
|     logger->fatal("This is an fatal message"); |     log_fatal("This is an fatal message"); | ||||||
|     logger->debug("This is a debug message"); |     log_debug("This is a debug message"); | ||||||
|     logger->warning("This is a warning message%s", "123"); |     log_warning("This is a warning message%s", "123"); | ||||||
|  |  | ||||||
|     char *test1[]         = {"123", "tt"}; |     char *test1[]         = {"123", "tt", NULL}; | ||||||
|  |  | ||||||
|     log_Interceptor *tint = loggingSubStringInterceptor( |     log_Interceptor *tint = loggingSubStringInterceptor( | ||||||
|         test1, |         test1, | ||||||
|         2, |  | ||||||
|         LOG_DEBUG, |         LOG_DEBUG, | ||||||
|         loggingFileHandler("test_interceptor", 1024 * 1024)); |         loggingFileHandler("test_interceptor", 1024 * 1024), | ||||||
|  |         true); | ||||||
|  |  | ||||||
|     logger->addInterceptor(tint); |     logger->addInterceptor(tint); | ||||||
|  |  | ||||||
| @@ -106,16 +99,65 @@ int main() { | |||||||
|     printf("Interceptor added\n"); |     printf("Interceptor added\n"); | ||||||
|     printf("\n"); |     printf("\n"); | ||||||
|  |  | ||||||
|     logger->info("This is an info message"); |     log_info("This is an info message"); | ||||||
|     logger->error("This is an error message%s", "123"); |     log_error("This is an error message%s", "123"); | ||||||
|     logger->fatal("This is an fatal message"); |     log_fatal("This is an fatal message"); | ||||||
|     logger->debug("This is a debug message"); |     log_debug("This is a debug message"); | ||||||
|     logger->warning("This is a warning message%s", "123"); |     log_warning("This is a warning message%s", "123"); | ||||||
|  |  | ||||||
|     destroyLogger(); |     destroyDefaultLogger(); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | #### 多个子串拦截器 | ||||||
|  | ```c | ||||||
|  | #include "logging.h" | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <time.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"); | ||||||
|  |  | ||||||
|  |     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; |     return 0; | ||||||
| } | } | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -17,38 +17,35 @@ typedef struct Logger { | |||||||
|     log_Handler     *handler; |     log_Handler     *handler; | ||||||
|     log_Interceptor *interceptor; |     log_Interceptor *interceptor; | ||||||
|     const char      *name; |     const char      *name; | ||||||
|     void (*fatal)(const char *format, ...); |  | ||||||
|     void (*error)(const char *format, ...); |  | ||||||
|     void (*warning)(const char *format, ...); |  | ||||||
|     void (*info)(const char *format, ...); |  | ||||||
|     void (*debug)(const char *format, ...); |  | ||||||
|  |  | ||||||
|     bool (*addHandler)(log_Handler *handler); |     bool (*addHandler)(log_Handler *handler); | ||||||
|     bool (*addInterceptor)(log_Interceptor *Interceptor); |     bool (*addInterceptor)(log_Interceptor *Interceptor); | ||||||
| } Logger; | } Logger; | ||||||
|  |  | ||||||
|  | void log_fatal(const char *format, ...); | ||||||
|  | void log_error(const char *format, ...); | ||||||
|  | void log_warning(const char *format, ...); | ||||||
|  | void log_info(const char *format, ...); | ||||||
|  | void log_debug(const char *format, ...); | ||||||
|  |  | ||||||
| /** | /** | ||||||
| * @brief 创建日志对象,日志对象为单例模式,后续可通过getDefaultLogger方法获取, | * @brief | ||||||
|  | 创建默认日志对象,日志对象为单例模式,后续可通过getDefaultLogger方法获取, | ||||||
|         重复调用该方法不会创建新的日志对象,只会返回默认日志对象,并且会修改默认日志对象的名称和等级 |         重复调用该方法不会创建新的日志对象,只会返回默认日志对象,并且会修改默认日志对象的名称和等级 | ||||||
| * @param name 日志名称 | * @param name 日志名称 | ||||||
| * @param level 日志等级 | * @param level 日志等级 | ||||||
| * @return Logger* 日志对象指针 | * @return Logger* 日志对象指针 | ||||||
| */ | */ | ||||||
| Logger *newLogger(const char *name, log_level level); | Logger *newDefaultLogger(const char *name, log_level level); | ||||||
| /** |  | ||||||
|  * @brief 设置日志等级 |  | ||||||
|  * @param logger 日志对象 |  | ||||||
|  * @param level 日志等级 |  | ||||||
|  */ |  | ||||||
| log_status setLevel(Logger *logger, log_level level); |  | ||||||
| /** | /** | ||||||
|  * @brief 获取默认日志对象 |  * @brief 获取默认日志对象 | ||||||
|  */ |  */ | ||||||
| Logger *getDefaultLogger(void); | Logger *getDefaultLogger(void); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @brief 销毁日志对象,该方法会销毁默认日志对象 |  * @brief 销毁日志对象,该方法会销毁默认日志对象 | ||||||
|  */ |  */ | ||||||
| log_status destroyLogger(void); | log_status destroyDefaultLogger(void); | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,6 +3,11 @@ | |||||||
|  |  | ||||||
| #include "logging-core.h" | #include "logging-core.h" | ||||||
| #include "logging-handler.h" | #include "logging-handler.h" | ||||||
|  | #include <stdbool.h> | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| extern "C" { | extern "C" { | ||||||
| @@ -11,9 +16,13 @@ extern "C" { | |||||||
| typedef struct log_Interceptor { | typedef struct log_Interceptor { | ||||||
|     log_level    level; |     log_level    level; | ||||||
|     log_Handler *handler; |     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); |     void (*_free)(struct log_Interceptor *Interceptor); | ||||||
|  |     struct log_Interceptor *next; | ||||||
| } log_Interceptor; | } log_Interceptor; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -25,9 +34,13 @@ typedef struct log_Interceptor { | |||||||
|  * @return log_Interceptor * |  * @return log_Interceptor * | ||||||
|  */ |  */ | ||||||
| log_Interceptor *loggingSubStringInterceptor(char        *keywords[], | log_Interceptor *loggingSubStringInterceptor(char        *keywords[], | ||||||
|                                              int          count, |  | ||||||
|                                              log_level    level, |                                              log_level    level, | ||||||
|                                              log_Handler *handler); |                                              log_Handler *handler, | ||||||
|  |                                              bool         jump_out); | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,10 +3,12 @@ | |||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  | #include <time.h> | ||||||
|  |  | ||||||
| static log_Interceptor *G_interceptor = NULL; | typedef struct keywords_s { | ||||||
|  |     char              *key; | ||||||
| static char **G_keywords              = NULL; |     struct keywords_s *next; | ||||||
|  | } keywords_t; | ||||||
|  |  | ||||||
| static void get_next(char *str, int *next) { | static void get_next(char *str, int *next) { | ||||||
|     next[1] = 0; |     next[1] = 0; | ||||||
| @@ -22,6 +24,8 @@ static void get_next(char *str, int *next) { | |||||||
| } | } | ||||||
|  |  | ||||||
| static bool kmp_search(char *substr, char *master) { | static bool kmp_search(char *substr, char *master) { | ||||||
|  |     if(substr == NULL)return true;  //空串全匹配 | ||||||
|  |     if(master == NULL)return false; | ||||||
|     int  i         = 0; |     int  i         = 0; | ||||||
|     int  j         = 0; |     int  j         = 0; | ||||||
|     int  substrlen = strlen(substr); |     int  substrlen = strlen(substr); | ||||||
| @@ -49,62 +53,75 @@ static bool kmp_search(char *substr, char *master) { | |||||||
|         return false; |         return false; | ||||||
| } | } | ||||||
|  |  | ||||||
| static bool _disposeSubstring(char *level, const char *message, ...) { | static bool _disposeSubstring(log_Interceptor *interceptor, | ||||||
|  |                               char            *level, | ||||||
|  |                               const char      *message, | ||||||
|  |                               ...) { | ||||||
|     int         count   = 0; |     int         count   = 0; | ||||||
|  |     keywords_t *keyword = (keywords_t *)(interceptor + 1); | ||||||
|  |  | ||||||
|     if (G_keywords == NULL) { |     if (keyword->key == NULL && keyword->next == NULL) | ||||||
|         return false; |         return false; | ||||||
|     } |  | ||||||
|  |  | ||||||
|     while (G_keywords[count] != NULL) { |     while (keyword != NULL) { | ||||||
|         if (kmp_search(G_keywords[count], (char *)message)) { |         if (kmp_search(keyword->key, (char *)message)) | ||||||
|             return true; |             return true; | ||||||
|         } |         keyword = keyword->next; | ||||||
|         count++; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return false; |     return false; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void _freeSubstring(log_Interceptor *interceptor) { | static void _freeSubstring(log_Interceptor *interceptor) { | ||||||
|     if (G_keywords != NULL) { |     keywords_t *it_keyword = | ||||||
|         int sum = 0; |         (keywords_t *)(interceptor + 1); // it_keyword 不是起始地址,请勿free | ||||||
|         while (G_keywords[sum] != NULL) { |     keywords_t *keyword = it_keyword->next; | ||||||
|             free(G_keywords[sum]); |     keywords_t *next    = NULL; | ||||||
|             sum++; |  | ||||||
|         } |     while (keyword != NULL) { | ||||||
|         free(G_keywords[sum]); |         next = keyword->next; | ||||||
|         free(G_keywords); |         free(keyword->key); | ||||||
|         G_keywords = NULL; |         free(keyword); | ||||||
|  |         keyword = next; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (interceptor->handler != NULL) { |     if (interceptor->handler != NULL) { | ||||||
|         interceptor->handler->_free(interceptor->handler); |         interceptor->handler->_free(interceptor->handler); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (interceptor != NULL) |     if (it_keyword->key != NULL) | ||||||
|  |         free(it_keyword->key); | ||||||
|     free(interceptor); |     free(interceptor); | ||||||
| } | } | ||||||
|  |  | ||||||
| log_Interceptor *loggingSubStringInterceptor(char        *keywords[], | log_Interceptor *loggingSubStringInterceptor(char        *keywords[], | ||||||
|                                              int          count, |  | ||||||
|                                              log_level    level, |                                              log_level    level, | ||||||
|                                              log_Handler *handler) { |                                              log_Handler *handler, | ||||||
|  |                                              bool         jump_out) { | ||||||
|     log_Interceptor *interceptor = |     log_Interceptor *interceptor = | ||||||
|         (log_Interceptor *)malloc(sizeof(log_Interceptor)); |         (log_Interceptor *)malloc(sizeof(log_Interceptor) + sizeof(keywords_t)); | ||||||
|     interceptor->_dispose = _disposeSubstring; |     interceptor->_dispose = _disposeSubstring; | ||||||
|     interceptor->handler  = handler; |     interceptor->handler  = handler; | ||||||
|     interceptor->level    = level; |     interceptor->level    = level; | ||||||
|  |     interceptor->jump_out = jump_out; | ||||||
|     interceptor->_free    = _freeSubstring; |     interceptor->_free    = _freeSubstring; | ||||||
|  |  | ||||||
|     G_keywords            = (char **)malloc((sizeof(G_keywords) * (count + 1))); |     keywords_t *keyword   = (keywords_t *)(interceptor + 1); | ||||||
|  |     keyword->key          = NULL; | ||||||
|     for (int i = 0; i < count; i++) { |     int count             = 0; | ||||||
|         G_keywords[i] = (char *)malloc(strlen(keywords[i]) + 1); |     if (keywords[count] != NULL) { | ||||||
|         strcpy(G_keywords[i], keywords[i]); |         keyword->key = strdup(keywords[count]); | ||||||
|  |         count++; | ||||||
|  |         keyword->next = NULL; | ||||||
|     } |     } | ||||||
|     G_keywords[count] = NULL; |  | ||||||
|  |  | ||||||
|     G_interceptor     = interceptor; |     while (keywords[count] != NULL) { | ||||||
|     return G_interceptor; |         keyword->next = (keywords_t *)malloc(sizeof(keywords_t)); | ||||||
|  |         keyword       = keyword->next; | ||||||
|  |         keyword->key  = strdup(keywords[count]); | ||||||
|  |         count++; | ||||||
|  |     } | ||||||
|  |     keyword->next = NULL; | ||||||
|  |  | ||||||
|  |     return interceptor; | ||||||
| } | } | ||||||
							
								
								
									
										109
									
								
								src/logging.c
									
									
									
									
									
								
							
							
						
						
									
										109
									
								
								src/logging.c
									
									
									
									
									
								
							| @@ -43,44 +43,27 @@ static bool addInterceptor(log_Interceptor *Interceptor) { | |||||||
|     } |     } | ||||||
|     if (G_LOGGER->interceptor == NULL) { |     if (G_LOGGER->interceptor == NULL) { | ||||||
|         G_LOGGER->interceptor       = Interceptor; |         G_LOGGER->interceptor       = Interceptor; | ||||||
|  |         G_LOGGER->interceptor->next = NULL; | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     G_LOGGER->interceptor->_free(G_LOGGER->interceptor); |     log_Interceptor *it = G_LOGGER->interceptor; | ||||||
|     G_LOGGER->interceptor = Interceptor; |     while (it->next != NULL) { | ||||||
|  |         it = it->next; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     it->next          = Interceptor; | ||||||
|  |     Interceptor->next = NULL; | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| /** | static void output_to_handler(log_Handler *handler, | ||||||
|  * @brief 内部日志打印处理核心函数 |                               char        *level, | ||||||
|  * @param level 日志等级 |                               const char  *color, | ||||||
|  * @param color 应用的颜色 |                               const char  *message) { | ||||||
|  * @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; |  | ||||||
|     } |  | ||||||
|     char timeStr[20]; |     char timeStr[20]; | ||||||
|     getTimeStr(timeStr); |     getTimeStr(timeStr); | ||||||
|     char logStr[LOG_BUFFER_SIZE]; |     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) |     if (handler->apply_color) | ||||||
|         sprintf(logStr, |         sprintf(logStr, | ||||||
|                 "[%s]: %s %s%s%s %s\n", |                 "[%s]: %s %s%s%s %s\n", | ||||||
| @@ -101,62 +84,92 @@ _builtin_log(char *level, const char *color, const char *message, ...) { | |||||||
|     handler->output(handler, logStr); |     handler->output(handler, logStr); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void fatal(const char *message, ...) { | /** | ||||||
|  |  * @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) { |     if (G_LOGGER->level >= LOG_ERROR) { | ||||||
|         char    logStr[LOG_BUFFER_SIZE]; |         char    logStr[LOG_BUFFER_SIZE]; | ||||||
|         va_list args; |         va_list args; | ||||||
|         va_start(args, message); |         va_start(args, message); | ||||||
|         vsprintf(logStr, message, args); |         vsprintf(logStr, message, args); | ||||||
|         va_end(args); |         va_end(args); | ||||||
|         _builtin_log("Fatal", RED_B, logStr, args); |         _builtin_cope("Fatal", RED_B, logStr); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| static void error(const char *message, ...) { | void log_error(const char *message, ...) { | ||||||
|     if (G_LOGGER->level >= LOG_ERROR) { |     if (G_LOGGER->level >= LOG_ERROR) { | ||||||
|         char    logStr[LOG_BUFFER_SIZE]; |         char    logStr[LOG_BUFFER_SIZE]; | ||||||
|         va_list args; |         va_list args; | ||||||
|         va_start(args, message); |         va_start(args, message); | ||||||
|         vsprintf(logStr, message, args); |         vsprintf(logStr, message, args); | ||||||
|         va_end(args); |         va_end(args); | ||||||
|         _builtin_log("Error", RED, logStr, args); |         _builtin_cope("Error", RED, logStr); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| static void warning(const char *message, ...) { | void log_warning(const char *message, ...) { | ||||||
|     if (G_LOGGER->level >= LOG_WARNING) { |     if (G_LOGGER->level >= LOG_WARNING) { | ||||||
|         char    logStr[LOG_BUFFER_SIZE]; |         char    logStr[LOG_BUFFER_SIZE]; | ||||||
|         va_list args; |         va_list args; | ||||||
|         va_start(args, message); |         va_start(args, message); | ||||||
|         vsprintf(logStr, message, args); |         vsprintf(logStr, message, args); | ||||||
|         va_end(args); |         va_end(args); | ||||||
|         _builtin_log("Warning", YELLOW, logStr, args); |         _builtin_cope("Warning", YELLOW, logStr); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| static void info(const char *message, ...) { | void log_info(const char *message, ...) { | ||||||
|     if (G_LOGGER->level >= LOG_INFO) { |     if (G_LOGGER->level >= LOG_INFO) { | ||||||
|         char    logStr[LOG_BUFFER_SIZE]; |         char    logStr[LOG_BUFFER_SIZE]; | ||||||
|         va_list args; |         va_list args; | ||||||
|         va_start(args, message); |         va_start(args, message); | ||||||
|         vsprintf(logStr, message, args); |         vsprintf(logStr, message, args); | ||||||
|         va_end(args); |         va_end(args); | ||||||
|         _builtin_log("Info", GREEN, logStr, args); |         _builtin_cope("Info", GREEN, logStr); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| static void debug(const char *message, ...) { | void log_debug(const char *message, ...) { | ||||||
|     if (G_LOGGER->level >= LOG_DEBUG) { |     if (G_LOGGER->level >= LOG_DEBUG) { | ||||||
|         char    logStr[LOG_BUFFER_SIZE]; |         char    logStr[LOG_BUFFER_SIZE]; | ||||||
|         va_list args; |         va_list args; | ||||||
|         va_start(args, message); |         va_start(args, message); | ||||||
|         vsprintf(logStr, message, args); |         vsprintf(logStr, message, args); | ||||||
|         va_end(args); |         va_end(args); | ||||||
|         _builtin_log("Debug", CYAN, logStr, args); |         _builtin_cope("Debug", CYAN, logStr); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| Logger *newLogger(const char *name, log_level level) { | Logger *newDefaultLogger(const char *name, log_level level) { | ||||||
|     if (G_LOGGER != NULL) { |     if (G_LOGGER != NULL) { | ||||||
|         G_LOGGER->name  = name; |         G_LOGGER->name  = name; | ||||||
|         G_LOGGER->level = level; |         G_LOGGER->level = level; | ||||||
| @@ -165,12 +178,6 @@ Logger *newLogger(const char *name, log_level level) { | |||||||
|  |  | ||||||
|     Logger *logger         = (Logger *)malloc(sizeof(Logger)); |     Logger *logger         = (Logger *)malloc(sizeof(Logger)); | ||||||
|  |  | ||||||
|     logger->fatal          = fatal; |  | ||||||
|     logger->error          = error; |  | ||||||
|     logger->warning        = warning; |  | ||||||
|     logger->info           = info; |  | ||||||
|     logger->debug          = debug; |  | ||||||
|  |  | ||||||
|     logger->addHandler     = addHandler; |     logger->addHandler     = addHandler; | ||||||
|     logger->addInterceptor = addInterceptor; |     logger->addInterceptor = addInterceptor; | ||||||
|  |  | ||||||
| @@ -186,14 +193,20 @@ Logger *newLogger(const char *name, log_level level) { | |||||||
| /** | /** | ||||||
|  * @brief 销毁日志对象 |  * @brief 销毁日志对象 | ||||||
|  */ |  */ | ||||||
| log_status destroyLogger(void) { | log_status destroyDefaultLogger(void) { | ||||||
|     if (G_LOGGER != NULL) { |     if (G_LOGGER != NULL) { | ||||||
|         if (G_LOGGER->handler != NULL) { |         if (G_LOGGER->handler != NULL) { | ||||||
|             G_LOGGER->handler->_free(G_LOGGER->handler); |             G_LOGGER->handler->_free(G_LOGGER->handler); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (G_LOGGER->interceptor != NULL) { |         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); |         free(G_LOGGER); | ||||||
|   | |||||||
| @@ -1,35 +1,47 @@ | |||||||
| #include "logging.h" | #include "logging.h" | ||||||
|  | #include <stdbool.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  | #include <time.h> | ||||||
|  |  | ||||||
| int main() { | int main() { | ||||||
|     Logger  *logger = newLogger("testLogger", LOG_DEBUG); |     Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG); | ||||||
|  |  | ||||||
|     logger->info("This is an info message"); |     log_info("This is an info message"); | ||||||
|     logger->error("This is an error message%s", "123"); |     log_error("This is an error message%s", "123"); | ||||||
|     logger->fatal("This is an fatal message"); |     log_fatal("This is an fatal message"); | ||||||
|     logger->debug("This is a debug message"); |     log_debug("This is a debug message"); | ||||||
|     logger->warning("This is a warning message%s", "123"); |     log_warning("This is a warning message%s", "123"); | ||||||
|  |  | ||||||
|     char *test1[]         = {"123", "tt"}; |     char *test1[]         = {"This",NULL}; | ||||||
|  |  | ||||||
|     log_Interceptor *tint = loggingSubStringInterceptor( |     log_Interceptor *tint = loggingSubStringInterceptor( | ||||||
|         test1, |         test1, | ||||||
|         2, |  | ||||||
|         LOG_DEBUG, |         LOG_DEBUG, | ||||||
|         loggingFileHandler("test_interceptor", 1024 * 1024)); |         loggingFileHandler("test_interceptor", 1024 * 1024), | ||||||
|  |         false); | ||||||
|  |  | ||||||
|     logger->addInterceptor(tint); |     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("\n"); | ||||||
|     printf("Interceptor added\n"); |     printf("Interceptor added\n"); | ||||||
|     printf("\n"); |     printf("\n"); | ||||||
|  |  | ||||||
|     logger->info("This is an info message"); |     log_info("This is an info message"); | ||||||
|     logger->error("This is an error message%s", "123"); |     log_error("This is an error message%s", "123"); | ||||||
|     logger->fatal("This is an fatal message"); |     log_fatal("This is an fatal message"); | ||||||
|     logger->debug("This is a debug message"); |     log_debug("This is a debug message"); | ||||||
|     logger->warning("This is a warning message%s", "123"); |     log_warning("This is a warning message%s", "123"); | ||||||
|  |  | ||||||
|     destroyLogger(); |     destroyDefaultLogger(); | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| @@ -1,14 +1,14 @@ | |||||||
| #include "logging.h" | #include "logging.h" | ||||||
|  |  | ||||||
| int main() { | int main() { | ||||||
|     Logger *logger = newLogger("testLogger", LOG_DEBUG); |     Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG); | ||||||
|  |  | ||||||
|     logger->info("This is an info message"); |     log_info("This is an info message"); | ||||||
|     logger->error("This is an error message%s", "123"); |     log_error("This is an error message%s", "123"); | ||||||
|     logger->fatal("This is an fatal message"); |     log_fatal("This is an fatal message"); | ||||||
|     logger->debug("This is a debug message"); |     log_debug("This is a debug message"); | ||||||
|     logger->warning("This is a warning message%s", "123"); |     log_warning("This is a warning message%s", "123"); | ||||||
|  |  | ||||||
|     destroyLogger(); |     destroyDefaultLogger(); | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
		Reference in New Issue
	
	Block a user