Compare commits
	
		
			10 Commits
		
	
	
		
			bd72ed874b
			...
			96a417ba93
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 96a417ba93 | |||
| d2a2b933a5 | |||
| 2608dfa078 | |||
| a823bab944 | |||
| 03e05051ea | |||
| d22ce6956e | |||
| dcd6ba0106 | |||
| 20a1ec9033 | |||
| ad0fa169ef | |||
| addf2cb751 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -2,3 +2,4 @@ | ||||
| .vscode/** | ||||
| bin | ||||
| build | ||||
| CMakeUserPresets.json | ||||
|   | ||||
| @@ -11,11 +11,15 @@ set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin) | ||||
|  | ||||
| include_directories(${CMAKE_SOURCE_DIR}/include) | ||||
|  | ||||
| # add_library(${PROJECT_NAME} ${SRC}) | ||||
| # add_library(${PROJECT_NAME} SHARED ${SRC}) | ||||
|  | ||||
|  | ||||
| add_executable(${PROJECT_NAME}main main.c ${SRC}) | ||||
|  | ||||
| if (SHARED) | ||||
|     add_library(${PROJECT_NAME} SHARED ${SRC}) | ||||
| else() | ||||
|     add_library(${PROJECT_NAME} ${SRC}) | ||||
| endif() | ||||
|  | ||||
| if (SKIPTEST) | ||||
| else() | ||||
|     add_executable(test_simple ${CMAKE_SOURCE_DIR}/test_package/test_simple.c ${SRC}) | ||||
|     add_executable(test_interceptor ${CMAKE_SOURCE_DIR}/test_package/test_interceptor.c ${SRC}) | ||||
| endif() | ||||
|  | ||||
|   | ||||
							
								
								
									
										21
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| MIT License | ||||
|  | ||||
| Copyright (c) 2024 youmetme | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
							
								
								
									
										101
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										101
									
								
								README.md
									
									
									
									
									
								
							| @@ -0,0 +1,101 @@ | ||||
| # C语言日志库logging | ||||
|  | ||||
| ## 简介 | ||||
|  | ||||
| logging是一个轻量级的简单易用C语言日志库,支持日志级别、日志格式、日志输出、日志文件等功能。 | ||||
|  | ||||
| ## 功能 | ||||
|  | ||||
| - 支持日志级别:DEBUG、INFO、WARN、ERROR、FATAL | ||||
| - 支持日志格式:时间戳、日志级别、日志内容 | ||||
| - 支持日志输出:控制台、文件 | ||||
| - 支持日志文件:自动创建、自动滚动、自动删除(未完成) | ||||
|  | ||||
| ## 使用方法 | ||||
|  | ||||
| ### 控制台日志 | ||||
| ```c | ||||
| #include "logging.h" | ||||
|  | ||||
| int main() { | ||||
|     Logging *log = createLogging(); // 创建日志对象 | ||||
|  | ||||
|     Logger *logger = log->getLogger("testLogger",LOG_DEBUG); //获取日志控制器 | ||||
|  | ||||
|     logger->addHandler(consoleHandler("test")); //为日志对象添加控制台处理器 | ||||
|  | ||||
|     logger->info("This is an info message"); | ||||
|     logger->error("你好,这是一个错误消息%s", "123"); | ||||
|     logger->fatal("This is an fatal message"); | ||||
|     logger->debug("This is a debug message"); | ||||
|     logger->warning("This is a warning message%s", "123"); | ||||
|  | ||||
|     destroyLogging(log); | ||||
|     return 0; | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ### 文件日志 | ||||
| ```c | ||||
| #include "logging.h" | ||||
|  | ||||
| int main() { | ||||
|     // Your code goes here | ||||
|     Logging *log = createLogging(); | ||||
|     Logger *logger = log->getLogger("testLogger",LOG_DEBUG); | ||||
|      | ||||
|     logger->addHandler(consoleHandler("test"));   //为日志对象添加文件处理器 | ||||
|  | ||||
|     logger->info("This is an info message"); | ||||
|     logger->error("你好,这是一个错误消息%s", "123"); | ||||
|     logger->fatal("This is an fatal message"); | ||||
|     logger->debug("This is a debug message"); | ||||
|     logger->warning("This is a warning message%s", "123"); | ||||
|  | ||||
|     destroyLogging(log); | ||||
|     return 0; | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ### 日志拦截器 | ||||
| > 支持添加自定义的拦截器, 目前内置了子串拦截器 | ||||
|  | ||||
| > 拦截器的作用:可以将拦截到的日志重定向到拦截器的专属处理器中 | ||||
|  | ||||
|  | ||||
| #### 例子 | ||||
| 将拦截到的日志重定向到专属文件处理器中 | ||||
| ```c | ||||
| #include "logging.h" | ||||
|  | ||||
|  | ||||
| int main() { | ||||
|     Logging *log = createLogging(); | ||||
|     Logger *logger = log->getLogger("testLogger",LOG_DEBUG); | ||||
|     logger->addHandler(consoleHandler("test")); | ||||
|  | ||||
|     logger->info("This is an info message"); | ||||
|     logger->error("你好,这是一个错误消息%s", "123"); | ||||
|     logger->fatal("This is an fatal message"); | ||||
|     logger->debug("This is a debug message"); | ||||
|     logger->warning("This is a warning message%s", "123"); | ||||
|  | ||||
|     char *test1[] = {"123", "你好"};//要拦截的字符串 | ||||
|     //添加拦截器,将拦截到的日志重定向到拦截器的专属处理器中 | ||||
|     log_Interceptor * tint = substringInterceptor(test1,2,LOG_DEBUG,fileHandler("被拦截"));  | ||||
|     logger->addInterceptor(tint); | ||||
|     printf("Interceptor added\n"); | ||||
|  | ||||
|     logger->info("This is an info message"); | ||||
|     logger->error("你好,这是一个错误消息%s", "123"); | ||||
|     logger->fatal("This is an fatal message"); | ||||
|  | ||||
|     logger->debug("This is a debug message"); | ||||
|     logger->warning("This is a warning message%s", "123"); | ||||
|  | ||||
|     destroyLogging(log); | ||||
|     return 0; | ||||
| } | ||||
| ``` | ||||
| .png) | ||||
|  | ||||
|   | ||||
							
								
								
									
										66
									
								
								conanfile.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								conanfile.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| from conan import ConanFile | ||||
| from conan.tools.cmake import CMake, CMakeToolchain, CMakeDeps, cmake_layout | ||||
| from conan.tools.files import copy, get | ||||
| from conan.tools.build import check_min_cppstd | ||||
| from conan import tools | ||||
| import os | ||||
|  | ||||
|  | ||||
|  | ||||
| class loggingRecipe(ConanFile): | ||||
|     name = "logging" | ||||
|     version = "0.1.1" | ||||
|     license = "MIT" | ||||
|     author = "321640253@qq.com" | ||||
|     url = "https://github.com/WangZhongDian/logging.git" | ||||
|     description = "一个纯C的简单易用的日志库" | ||||
|     topics = ("logging", "C", "simple", "easy-to-use", "log","Logging") | ||||
|  | ||||
|     settings = "os", "compiler", "build_type", "arch" | ||||
|     options = {"shared": [True, False], "fPIC": [True, False]} | ||||
|     default_options = {"shared": False, "fPIC": True} | ||||
|  | ||||
|  | ||||
|     exports_sources = "include/*", "CMakeLists.txt", "src/*" | ||||
|  | ||||
|     def config_options(self): | ||||
|         if self.settings.os == "Windows": | ||||
|             del self.options.fPIC | ||||
|      | ||||
|     def configure(self): | ||||
|         if self.options.shared: | ||||
|             self.options.rm_safe("fPIC") | ||||
|  | ||||
|  | ||||
|      | ||||
|     def layout(self): | ||||
|         cmake_layout(self) | ||||
|  | ||||
|     def generate(self): | ||||
|         deps = CMakeDeps(self) | ||||
|         deps.generate() | ||||
|         tc = CMakeToolchain(self) | ||||
|         tc.variables["SKIPTEST"]=True | ||||
|         if self.options.shared: | ||||
|             tc.variables["SHARED"] = True | ||||
|         else: | ||||
|             tc.variables["SHARED"] = False | ||||
|         tc.generate() | ||||
|  | ||||
|     def build(self): | ||||
|         cmake = CMake(self) | ||||
|         cmake.configure() | ||||
|         cmake.build(target="Logging") | ||||
|  | ||||
|  | ||||
|     def package(self): | ||||
|         copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) | ||||
|         copy(self, pattern="*.h", src=os.path.join(self.source_folder, "include"), dst=os.path.join(self.package_folder, "include")) | ||||
|         copy(self, pattern="*.a", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"), keep_path=False) | ||||
|         copy(self, pattern="*.so", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"), keep_path=False) | ||||
|         copy(self, pattern="*.lib", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"), keep_path=False) | ||||
|         copy(self, pattern="*.dll", src=self.build_folder, dst=os.path.join(self.package_folder, "bin"), keep_path=False) | ||||
|         copy(self, pattern="*.dylib", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"), keep_path=False) | ||||
|  | ||||
|     def package_info(self): | ||||
|         self.cpp_info.libs = ["Logging"] | ||||
							
								
								
									
										
											BIN
										
									
								
								docs/img/.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/img/.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 63 KiB | 
							
								
								
									
										
											BIN
										
									
								
								docs/img/2024-08-13-22-21-37.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/img/2024-08-13-22-21-37.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 43 KiB | 
| @@ -7,8 +7,10 @@ | ||||
| #include <stdarg.h> | ||||
| #include <string.h> | ||||
| #include <time.h> | ||||
| #include <stdbool.h> | ||||
|  | ||||
| typedef enum { | ||||
|     LOG_FATAL, | ||||
|     LOG_ERROR, | ||||
|     LOG_WARNING, | ||||
|     LOG_INFO, | ||||
| @@ -20,21 +22,40 @@ typedef enum { | ||||
|     L_OK, | ||||
| } log_status; | ||||
|  | ||||
| typedef struct Handler { | ||||
|     FILE* file; | ||||
|     log_level level; | ||||
| typedef struct log_Handler { | ||||
|     void* stream; | ||||
|     bool apply_color; | ||||
|     void (*_free)(struct log_Handler* handler);//释放资源 | ||||
|     void (*output)(struct log_Handler* handler,const char* message); | ||||
| } log_Handler; | ||||
|  | ||||
|  | ||||
| typedef struct log_Interceptor { | ||||
|     log_level level;                                        //拦截级别 | ||||
|     log_Handler* handler;                                   //拦截目标处理器 | ||||
|     bool (*_dispose)(char* level,const char *message, ...); //拦截触发器 | ||||
|     void (*_free)(struct log_Interceptor* Interceptor);     //释放资源 | ||||
|  | ||||
| }  log_Interceptor; | ||||
|  | ||||
|  | ||||
| //日志操作器 | ||||
| typedef struct Logger | ||||
| { | ||||
|     log_level level; | ||||
|     log_Handler* handler; | ||||
|     log_Interceptor* interceptor; | ||||
|     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, ...); | ||||
|  | ||||
|     void (*addHandler)(log_Handler* handler); | ||||
|     // void (*addFormat)(const char* format); | ||||
|     // void (*addFilter)(const char* filter); | ||||
|     void (*addInterceptor)(log_Interceptor* Interceptor); | ||||
| } Logger; | ||||
|  | ||||
|  | ||||
| @@ -42,16 +63,25 @@ typedef struct Logger | ||||
| typedef struct Logging { | ||||
|     Logger* (*getLogger)(const char* name, log_level level); | ||||
|     log_status (*setLevel)(Logger* logger, log_level level); | ||||
|     // void (*addFormat)(const char* format); | ||||
|     // void (*addFilter)(const char* filter); | ||||
|     void (*addHandler)(log_Handler* handler); | ||||
| } Logging; | ||||
|  | ||||
|  | ||||
|  | ||||
| Logging* createLogging(); | ||||
| Logging* createLogging();                         | ||||
| log_status destroyLogging(Logging* logging); | ||||
| Logger* getCurrentLogger(void); | ||||
|  | ||||
|  | ||||
| log_Handler* fileHandler(const char* name,log_level level); | ||||
| /** | ||||
|  * @def 创建日志处理器 | ||||
|  * @file logging-handler.c | ||||
| */ | ||||
| log_Handler* fileHandler(const char* name);      | ||||
| log_Handler* consoleHandler(const char* name); | ||||
|  | ||||
|  | ||||
|  | ||||
| log_Interceptor* substringInterceptor(char *keywords[], int count, log_level level, log_Handler* handler); | ||||
|  | ||||
|  | ||||
| #endif // __LOGGING_H | ||||
							
								
								
									
										14
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								main.c
									
									
									
									
									
								
							| @@ -1,14 +0,0 @@ | ||||
| #include "logging.h" | ||||
|  | ||||
|  | ||||
| int main() { | ||||
|     // Your code goes here | ||||
|     Logging *log = createLogging(); | ||||
|     Logger *logger = log->getLogger("testLogger",LOG_INFO); | ||||
|     logger->info("This is an info message"); | ||||
|     logger->error("This is an error message"); | ||||
|     logger->debug("This is a debug message"); | ||||
|     logger->warning("This is a warning message"); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
| @@ -1,16 +1,62 @@ | ||||
|  | ||||
| /******************************************** | ||||
| * @Date: 2024 08 12 | ||||
| * @Description: 日志处理器 | ||||
| ********************************************/ | ||||
| #include "logging.h" | ||||
|  | ||||
|  | ||||
| /** | ||||
| * @description :释放文件日志处理器相关资源 | ||||
| * @param  | ||||
| * @return  | ||||
| */ | ||||
| static void __freeFileHandler(log_Handler* handler){ | ||||
|     fclose(handler->stream); | ||||
|     free(handler); | ||||
| } | ||||
|  | ||||
| static void outputFileHandler(log_Handler *handler, const char * message){ | ||||
|     fputs(message,handler->stream); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| log_Handler* fileHandler(const char* name,log_level level){ | ||||
|     FILE* fp = fopen(name, "w"); | ||||
| /** | ||||
| * @description :文件日志处理器 | ||||
| * @param  | ||||
| * @return  | ||||
| */ | ||||
| log_Handler* fileHandler(const char* name){ | ||||
|     char new_file_name[100]; | ||||
|     sprintf(new_file_name, "%s.log", name); | ||||
|     FILE* fp = fopen(new_file_name, "at"); | ||||
|     log_Handler* handler = (log_Handler*)malloc(sizeof(log_Handler)); | ||||
|     handler->file = fp; | ||||
|     handler->level = level; | ||||
|      | ||||
|     handler->stream = fp; | ||||
|     handler->apply_color = false; | ||||
|     handler->_free = __freeFileHandler; | ||||
|     handler->output = outputFileHandler; | ||||
|     return handler; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| static void __freeConsoleHandler(log_Handler* handler){ | ||||
|     free(handler); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void outputConsoleHandler(log_Handler* handler,const char * message){ | ||||
|     fputs(message,handler->stream); | ||||
| } | ||||
|  | ||||
| /** | ||||
| * @description :控制台日志处理器 | ||||
| * @param  | ||||
| * @return  | ||||
| */ | ||||
| log_Handler* consoleHandler(const char* name){ | ||||
|     log_Handler* handler = (log_Handler*)malloc(sizeof(log_Handler)); | ||||
|     handler->stream = stdout; | ||||
|     handler->apply_color = true; | ||||
|     handler->_free = __freeConsoleHandler; | ||||
|     handler->output = outputConsoleHandler; | ||||
|     return handler; | ||||
| } | ||||
							
								
								
									
										119
									
								
								src/logging-interceptor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								src/logging-interceptor.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | ||||
| /******************************************** | ||||
| * @Date: 2024 08 12 | ||||
| * @Description: 日志拦截器 | ||||
| *********************************************/   | ||||
|  | ||||
| #include "logging.h" | ||||
|  | ||||
| static log_Interceptor* G_interceptor = NULL; | ||||
|  | ||||
| static char **G_keywords = NULL; | ||||
|  | ||||
| static void get_next(char *str, int *next) { | ||||
|     next[1] = 0; | ||||
|     int i=1; | ||||
|     int j=0; | ||||
|     while (i < strlen(str)) { | ||||
|         if (j==0|| str[i] == str[j]) { | ||||
|             next[++i] = ++j; | ||||
|         } | ||||
|         else { | ||||
|             j = next[j]; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| static bool kmp_search(char *substr, char *master) { | ||||
|     int i = 0; | ||||
|     int j = 0; | ||||
|     int substrlen = strlen(substr); | ||||
|     int masterlen = strlen(master); | ||||
|     int *next = (int *)malloc(sizeof(int) * substrlen + 1); | ||||
|     get_next(substr, next); | ||||
|  | ||||
|     while (i < masterlen && j < substrlen) { | ||||
|         if (master[i] == substr[j]) { | ||||
|             i++; | ||||
|             j++; | ||||
|         } else { | ||||
|             if(j == 0) { | ||||
|                 i++; | ||||
|             } else { | ||||
|                 j = next[j]; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     free(next); | ||||
|     if (j == substrlen)return true; | ||||
|     else return false; | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
| * @description 处理 | ||||
| * @param  | ||||
| * @return  | ||||
| */ | ||||
| static bool _disposeSubstring(char* level,const char *message, ...){ | ||||
|     int count = 0; | ||||
|  | ||||
|     if (G_keywords == NULL) { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     while (G_keywords[count] != NULL) | ||||
|     { | ||||
|         if (kmp_search(G_keywords[count],(char*)message)) { | ||||
|             return true; | ||||
|         } | ||||
|         count++; | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| /** | ||||
| * @description : 完成拦截器自我释放内存 | ||||
| */ | ||||
| static void _freeSubstring(log_Interceptor* interceptor) { | ||||
|     int sum = 0; | ||||
|     while (G_keywords[sum] != NULL) { | ||||
|         free(G_keywords[sum]); | ||||
|         sum++; | ||||
|     } | ||||
|     free(G_keywords); | ||||
|     G_keywords = NULL; | ||||
|  | ||||
|     if(interceptor->handler != NULL){ | ||||
|         interceptor->handler->_free(interceptor->handler); | ||||
|     } | ||||
|  | ||||
|     free(interceptor); | ||||
| } | ||||
|  | ||||
| /** | ||||
| * @description : 子字符串拦截器 | ||||
| */ | ||||
| log_Interceptor* substringInterceptor(char *keywords[], int count, log_level level, log_Handler* handler) { | ||||
|     log_Interceptor* interceptor = (log_Interceptor*)malloc(sizeof(log_Interceptor)); | ||||
|     interceptor->_dispose = _disposeSubstring; | ||||
|     interceptor->handler = handler; | ||||
|     interceptor->level = level; | ||||
|     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]); | ||||
|     } | ||||
|     G_keywords[count] = NULL; | ||||
|  | ||||
|     G_interceptor = interceptor; | ||||
|     return G_interceptor; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										175
									
								
								src/logging.c
									
									
									
									
									
								
							
							
						
						
									
										175
									
								
								src/logging.c
									
									
									
									
									
								
							| @@ -1,7 +1,10 @@ | ||||
| /******************************************** | ||||
| * @Date: 2024 08 12 | ||||
| * @Description: 日志模块 | ||||
| ********************************************/ | ||||
|  | ||||
| #include "logging.h" | ||||
|  | ||||
|  | ||||
|  | ||||
| Logger* G_LOGGER = NULL; | ||||
|  | ||||
| #define RED "\033[0;31m" | ||||
| @@ -14,57 +17,134 @@ Logger* G_LOGGER = NULL; | ||||
| #define WHITE "\033[0;37m" | ||||
| #define BLACK "\033[0;30m" | ||||
|  | ||||
| #define LOG_BUFFER_SIZE 1024 | ||||
|  | ||||
|  | ||||
| static void getTimeStr(char * timeStr){ | ||||
|     time_t t = time(NULL); | ||||
|     struct tm* p = localtime(&t); | ||||
|     char _timeStr[18]; | ||||
|     char  _timeStr[20]; | ||||
|     strftime(_timeStr, sizeof(_timeStr), "%Y-%m-%d %H:%M:%S", p); | ||||
|     strcpy(timeStr, _timeStr); | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
| * @description : 添加日志处理器 | ||||
| */ | ||||
| static void addHandler(log_Handler* handler){ | ||||
|     if (G_LOGGER == NULL){ | ||||
|         return; | ||||
|     } | ||||
|     if (G_LOGGER->handler == NULL){ | ||||
|         G_LOGGER->handler = handler; | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     G_LOGGER->handler->_free(G_LOGGER->handler); | ||||
|      | ||||
|     G_LOGGER->handler = handler; | ||||
| } | ||||
|  | ||||
| void addInterceptor(log_Interceptor* Interceptor){ | ||||
|     if (G_LOGGER == NULL){ | ||||
|         return; | ||||
|     } | ||||
|     if (G_LOGGER->interceptor == NULL){ | ||||
|         G_LOGGER->interceptor = Interceptor; | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     G_LOGGER->interceptor->_free(G_LOGGER->interceptor); | ||||
|  | ||||
|     G_LOGGER->interceptor = Interceptor; | ||||
| } | ||||
|  | ||||
| /** | ||||
| * @description : 内置日志记录函数 | ||||
| */ | ||||
| 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]; | ||||
|     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\n", timeStr, color,level,RESET, message); | ||||
|     else sprintf(logStr, "%s %s %s\n", timeStr, level, message); | ||||
|  | ||||
|     handler->output(handler,logStr); | ||||
| } | ||||
|  | ||||
|  | ||||
| //*************************记录日志******************************* */ | ||||
| static void error(const char* format, ...){ | ||||
| static void fatal(const char* message, ...){ | ||||
|     if (G_LOGGER->level >= LOG_ERROR){ | ||||
|         char timeStr[18]; | ||||
|         getTimeStr(timeStr); | ||||
|         printf("%sError%s   %s %s\n",RED,RESET, timeStr, format); | ||||
|         char logStr[LOG_BUFFER_SIZE]; | ||||
|         va_list args; | ||||
|         va_start(args, message); | ||||
|         vsprintf(logStr, message, args); | ||||
|         va_end(args); | ||||
|         _builtin_log("Fatal",RED, logStr, args); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| static void warning(const char* format, ...){ | ||||
| static void error(const char* message, ...){ | ||||
|     if (G_LOGGER->level >= LOG_ERROR){ | ||||
|         char logStr[LOG_BUFFER_SIZE]; | ||||
|         va_list args; | ||||
|         va_start(args, message); | ||||
|         vsprintf(logStr, message, args); | ||||
|         va_end(args); | ||||
|         _builtin_log("Error",RED, logStr, args); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void warning(const char* message, ...){ | ||||
|     if (G_LOGGER->level >= LOG_WARNING){ | ||||
|         char timeStr[18]; | ||||
|         getTimeStr(timeStr); | ||||
|         printf("%sWarning%s %s %s\n",YELLOW,RESET, timeStr, format); | ||||
|         char logStr[LOG_BUFFER_SIZE]; | ||||
|         va_list args; | ||||
|         va_start(args, message); | ||||
|         vsprintf(logStr, message, args); | ||||
|         va_end(args); | ||||
|         _builtin_log("Warning",YELLOW, logStr, args); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| static void info(const char* format, ...){ | ||||
| static void info(const char* message, ...){ | ||||
|     if (G_LOGGER->level >= LOG_INFO){ | ||||
|         char timeStr[18]; | ||||
|         getTimeStr(timeStr); | ||||
|         printf("%sInfo%s    %s %s\n",GREEN,RESET, timeStr, format); | ||||
|         char logStr[LOG_BUFFER_SIZE]; | ||||
|         va_list args; | ||||
|         va_start(args, message); | ||||
|         vsprintf(logStr, message, args); | ||||
|         va_end(args); | ||||
|         _builtin_log("Info",GREEN, logStr, args); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void debug(const char* format, ...){ | ||||
| static void debug(const char* message, ...){ | ||||
|     if (G_LOGGER->level >= LOG_DEBUG){ | ||||
|         char timeStr[18]; | ||||
|         getTimeStr(timeStr); | ||||
|         printf("%sDebug%s   %s %s\n",CYAN,RESET, timeStr, format); | ||||
|         char logStr[LOG_BUFFER_SIZE]; | ||||
|         va_list args; | ||||
|         va_start(args, message); | ||||
|         vsprintf(logStr, message, args); | ||||
|         va_end(args); | ||||
|         _builtin_log("Debug",CYAN, logStr, args); | ||||
|     } | ||||
| } | ||||
| //*************************记录日志******************************* */ | ||||
| @@ -76,19 +156,30 @@ static void debug(const char* format, ...){ | ||||
| * @return  | ||||
| */ | ||||
| static Logger* getLogger(const char* name, log_level level){ | ||||
|     if (G_LOGGER != NULL){ | ||||
|         return G_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->addInterceptor = addInterceptor; | ||||
|  | ||||
|     logger->level = level; | ||||
|     logger->handler = NULL; | ||||
|     logger->name = name; | ||||
|     logger->interceptor = NULL; | ||||
|  | ||||
|     G_LOGGER = logger; | ||||
|     return G_LOGGER; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /** | ||||
| * @description :创建一个日志对象 | ||||
| * @return :Logging* 返回一个日志对象 | ||||
| @@ -96,6 +187,42 @@ static Logger* getLogger(const char* name, log_level level){ | ||||
| Logging* createLogging(){ | ||||
|     Logging* logging = (Logging*)malloc(sizeof(Logging)); | ||||
|     logging->getLogger = getLogger; | ||||
|     logging->addHandler = addHandler; | ||||
|     return logging; | ||||
| } | ||||
| } | ||||
|  | ||||
| /** | ||||
| * @description :销毁日志对象 | ||||
| */ | ||||
| log_status destroyLogging(Logging* logging){ | ||||
|     if (logging == NULL){ | ||||
|         return L_ERROR; | ||||
|     } | ||||
|     if (G_LOGGER != NULL){ | ||||
|         if (G_LOGGER->handler != NULL){ | ||||
|             G_LOGGER->handler->_free(G_LOGGER->handler); | ||||
|         } | ||||
|  | ||||
|         if (G_LOGGER->interceptor != NULL){ | ||||
|             G_LOGGER->interceptor->_free(G_LOGGER->interceptor); | ||||
|         } | ||||
|  | ||||
|         free(G_LOGGER); | ||||
|         G_LOGGER = NULL; | ||||
|     } | ||||
|     free(logging); | ||||
|     return L_OK; | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
| * @description :获取当前日志操作对象 | ||||
| * @return 当前唯一的日志操作对象 | ||||
| */ | ||||
| Logger* getCurrentLogger(void){ | ||||
|     if (G_LOGGER == NULL){ | ||||
|         return NULL; | ||||
|     } | ||||
|     return G_LOGGER; | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										29
									
								
								test_package/test_interceptor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								test_package/test_interceptor.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| #include "logging.h" | ||||
|  | ||||
| int main() { | ||||
|     Logging *log = createLogging(); | ||||
|     Logger *logger = log->getLogger("testLogger",LOG_DEBUG); | ||||
|     logger->addHandler(consoleHandler("test")); | ||||
|  | ||||
|     logger->info("This is an info message"); | ||||
|     logger->error("你好,这是一个错误消息%s", "123"); | ||||
|     logger->fatal("This is an fatal message"); | ||||
|     logger->debug("This is a debug message"); | ||||
|     logger->warning("This is a warning message%s", "123"); | ||||
|  | ||||
|     char *test1[] = {"123", "你好"};//要拦截的字符串 | ||||
|     //添加拦截器,将拦截到的日志重定向到拦截器的专属处理器中 | ||||
|     log_Interceptor * tint = substringInterceptor(test1,2,LOG_DEBUG,fileHandler("被拦截"));  | ||||
|     logger->addInterceptor(tint); | ||||
|     printf("Interceptor added\n"); | ||||
|  | ||||
|     logger->info("This is an info message"); | ||||
|     logger->error("你好,这是一个错误消息%s", "123"); | ||||
|     logger->fatal("This is an fatal message"); | ||||
|  | ||||
|     logger->debug("This is a debug message"); | ||||
|     logger->warning("This is a warning message%s", "123"); | ||||
|  | ||||
|     destroyLogging(log); | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										17
									
								
								test_package/test_simple.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								test_package/test_simple.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| #include "logging.h" | ||||
|  | ||||
|  | ||||
| int main() { | ||||
|     Logging *log = createLogging(); | ||||
|     Logger *logger = log->getLogger("testLogger",LOG_DEBUG); | ||||
|     logger->addHandler(consoleHandler("test")); | ||||
|  | ||||
|     logger->info("This is an info message"); | ||||
|     logger->error("你好,这是一个错误消息%s", "123"); | ||||
|     logger->fatal("This is an fatal message"); | ||||
|     logger->debug("This is a debug message"); | ||||
|     logger->warning("This is a warning message%s", "123"); | ||||
|  | ||||
|     destroyLogging(log); | ||||
|     return 0; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user