diff --git a/README.md b/README.md index e37816c..3e4f84a 100644 --- a/README.md +++ b/README.md @@ -70,15 +70,18 @@ int main() { Logger *logger = log->getLogger("testLogger", LOG_DEBUG); logger->info("This is an info message"); - logger->error("你好,这是一个错误消息%s", "123"); + logger->error("This is an error message%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 = - loggingSubStringInterceptor(test1, 2, LOG_DEBUG, loggingFileHandler("被拦截")); + char *test1[] = {"123", "tt"}; + + log_Interceptor *tint = loggingSubStringInterceptor( + test1, + 2, + LOG_DEBUG, + loggingFileHandler("test_interceptor", 1024 * 1024)); logger->addInterceptor(tint); @@ -87,7 +90,7 @@ int main() { printf("\n"); logger->info("This is an info message"); - logger->error("你好,这是一个错误消息%s", "123"); + logger->error("This is an error message%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"); diff --git a/include/logging.h b/include/logging.h index 387b071..c9c87de 100644 --- a/include/logging.h +++ b/include/logging.h @@ -8,6 +8,9 @@ #include "logging/logging-handler.h" #include "logging/logging-interceptor.h" +#ifdef __cplusplus +extern "C" { +#endif typedef struct Logger { log_level level; @@ -34,4 +37,8 @@ typedef struct Logging { Logging *newLogging(); +#ifdef __cplusplus +} +#endif + #endif // __LOGGING_H__ \ No newline at end of file diff --git a/include/logging/logging-core.h b/include/logging/logging-core.h index 25e8f6a..5418900 100644 --- a/include/logging/logging-core.h +++ b/include/logging/logging-core.h @@ -1,6 +1,10 @@ #ifndef __LOGGING_CORE_H__ #define __LOGGING_CORE_H__ +#ifdef __cplusplus +extern "C" { +#endif + typedef enum { LOG_FATAL, LOG_ERROR, @@ -14,4 +18,8 @@ typedef enum { L_OK, } log_status; +#ifdef __cplusplus +} +#endif + #endif // __LOGGING_CORE_H__ diff --git a/include/logging/logging-handler.h b/include/logging/logging-handler.h index 9254266..79f341f 100644 --- a/include/logging/logging-handler.h +++ b/include/logging/logging-handler.h @@ -3,6 +3,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + typedef struct log_Handler { void *stream; bool apply_color; @@ -10,7 +14,11 @@ typedef struct log_Handler { void (*output)(struct log_Handler *handler, const char *message); } log_Handler; -log_Handler *loggingFileHandler(const char *name); +log_Handler *loggingFileHandler(const char *name, unsigned int max_size); log_Handler *loggingConsoleHandler(); +#ifdef __cplusplus +} +#endif + #endif //__LOGGING_HANDLER_H__ \ No newline at end of file diff --git a/include/logging/logging-interceptor.h b/include/logging/logging-interceptor.h index 973fe48..d93e201 100644 --- a/include/logging/logging-interceptor.h +++ b/include/logging/logging-interceptor.h @@ -4,6 +4,10 @@ #include "logging-core.h" #include "logging-handler.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct log_Interceptor { log_level level; log_Handler *handler; @@ -23,4 +27,8 @@ log_Interceptor *loggingSubStringInterceptor(char *keywords[], log_level level, log_Handler *handler); +#ifdef __cplusplus +} +#endif + #endif // __LOGGING_INTERCEPTOR_H__ \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 93e3dd2..d01b49c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,6 +3,7 @@ project(logging) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SRC) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/handler SRC) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/interceptor SRC) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/utils SRC) if (SHARED) add_library(${PROJECT_NAME} SHARED ${SRC}) diff --git a/src/handler/logging-handler-file.c b/src/handler/logging-handler-file.c index b2bbc2a..f951800 100644 --- a/src/handler/logging-handler-file.c +++ b/src/handler/logging-handler-file.c @@ -1,28 +1,73 @@ #include "logging/logging-handler.h" #include #include +#include + +#define Handler_FILE_EX_PRT(fp) \ + ((log_Handler_file_ex_t *)(fp + sizeof(log_Handler))) + +typedef struct log_Handler_file_ex_s { + unsigned int file_size; + unsigned int file_size_max; + unsigned int suffix; + char *file_name; +} log_Handler_file_ex_t; + +static unsigned int getFileSize(FILE *fp) { + fseek(fp, 0L, SEEK_END); + return ftell(fp); +} static void __freeFileHandler(log_Handler *handler) { fclose(handler->stream); + free(Handler_FILE_EX_PRT(handler)->file_name); free(handler); } +static void changeFile(log_Handler *handler) { + log_Handler_file_ex_t *handler_ex = Handler_FILE_EX_PRT(handler); + fclose(handler->stream); + char new_file_name[30]; + sprintf(new_file_name, "%s_%d.log", handler_ex->file_name, ++handler_ex->suffix); + handler->stream = fopen(new_file_name, "at"); + handler_ex->file_size = getFileSize(handler->stream); +} + static void outputFileHandler(log_Handler *handler, const char *message) { fputs(message, handler->stream); + log_Handler_file_ex_t *handler_ex = Handler_FILE_EX_PRT(handler); + handler_ex->file_size += strlen(message); + if (handler_ex->file_size > handler_ex->file_size_max) + changeFile(handler); } -log_Handler *loggingFileHandler(const char *name) { - char new_file_name[100]; - sprintf(new_file_name, "%s.log", name); +log_Handler *loggingFileHandler(const char *name, unsigned int max_size) { + char new_file_name[30]; + int suffix = 0; + unsigned int file_size; + FILE *fp; - FILE *fp = fopen(new_file_name, "at"); + do { + sprintf(new_file_name, "%s_%d.log", name, suffix++); + fp = fopen(new_file_name, "at"); + file_size = getFileSize(fp); + } while (file_size > max_size); - log_Handler *handler = (log_Handler *)malloc(sizeof(log_Handler)); + /// 分配log_Handler与记录文件大小的空间 + log_Handler *handler = (log_Handler *)malloc(sizeof(log_Handler) + + sizeof(log_Handler_file_ex_t)); - handler->stream = fp; - handler->apply_color = false; - handler->_free = __freeFileHandler; - handler->output = outputFileHandler; + log_Handler_file_ex_t *handler_ex = Handler_FILE_EX_PRT(handler); + handler_ex->file_size_max = max_size; + handler_ex->file_size = file_size; + handler_ex->suffix = suffix; + handler_ex->file_name = malloc(strlen(new_file_name) + 1); + strcpy(handler_ex->file_name, name); + + handler->stream = fp; + handler->apply_color = false; + handler->_free = __freeFileHandler; + handler->output = outputFileHandler; return handler; } \ No newline at end of file diff --git a/src/logging.c b/src/logging.c index 6b7c455..e58324a 100644 --- a/src/logging.c +++ b/src/logging.c @@ -1,5 +1,6 @@ #include "logging.h" #include "logging/logging-handler.h" +#include "utils/logging-utils.h" #include #include #include @@ -17,14 +18,10 @@ Logger *G_LOGGER = NULL; -static void getTimeStr(char *timeStr) { - time_t t = time(NULL); - struct tm *p = localtime(&t); - char _timeStr[20]; - strftime(_timeStr, sizeof(_timeStr), "%Y-%m-%d %H:%M:%S", p); - strcpy(timeStr, _timeStr); -} - +/** + * @brief 为日志添加一个handler + * @param handler 处理器对象 + */ static void addHandler(log_Handler *handler) { if (G_LOGGER == NULL) { return; @@ -53,6 +50,14 @@ void addInterceptor(log_Interceptor *Interceptor) { G_LOGGER->interceptor = Interceptor; } +/** + * @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) { @@ -77,7 +82,7 @@ _builtin_log(char *level, const char *color, const char *message, ...) { if (handler->apply_color) sprintf(logStr, - "%s: %s %s%s%s %s\n", + "[%s]: %s %s%s%s %s\n", G_LOGGER->name, timeStr, color, @@ -86,7 +91,7 @@ _builtin_log(char *level, const char *color, const char *message, ...) { message); else sprintf( - logStr, "%s: %s %s %s\n", G_LOGGER->name, timeStr, level, message); + logStr, "[%s]: %s %s %s\n", G_LOGGER->name, timeStr, level, message); handler->output(handler, logStr); } diff --git a/src/utils/logging-utils.c b/src/utils/logging-utils.c new file mode 100644 index 0000000..e9480d2 --- /dev/null +++ b/src/utils/logging-utils.c @@ -0,0 +1,15 @@ +#include "logging-utils.h" +#include +#include + +/** +* @brief 获取当前时间字符串 +* @param timeStr 存储时间字符串缓冲区指针 +*/ +void getTimeStr(char *timeStr) { + time_t t = time(NULL); + struct tm *p = localtime(&t); + char _timeStr[20]; + strftime(_timeStr, sizeof(_timeStr), "%Y-%m-%d %H:%M:%S", p); + strcpy(timeStr, _timeStr); +} \ No newline at end of file diff --git a/src/utils/logging-utils.h b/src/utils/logging-utils.h new file mode 100644 index 0000000..e187bb6 --- /dev/null +++ b/src/utils/logging-utils.h @@ -0,0 +1,5 @@ +#ifndef __LOGGING_UTILS_H__ +#define __LOGGING_UTILS_H__ + +void getTimeStr(char *timeStr); +#endif // __LOGGING_UTILS_H__ \ No newline at end of file diff --git a/tests/test_interceptor.c b/tests/test_interceptor.c index 08889b3..5ccc97a 100644 --- a/tests/test_interceptor.c +++ b/tests/test_interceptor.c @@ -11,10 +11,13 @@ int main() { logger->debug("This is a debug message"); logger->warning("This is a warning message%s", "123"); - char *test1[] = {"123", "tt"}; + char *test1[] = {"123", "tt"}; - log_Interceptor *tint = - loggingSubStringInterceptor(test1, 2, LOG_DEBUG, loggingFileHandler("test_interceptor")); + log_Interceptor *tint = loggingSubStringInterceptor( + test1, + 2, + LOG_DEBUG, + loggingFileHandler("test_interceptor", 1024 * 1024)); logger->addInterceptor(tint);