diff --git a/README.md b/README.md index e69de29..996b324 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,56 @@ +# 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); //获取日志控制器 + + log->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); + log->addHandler(fileHandler("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; +} +``` \ No newline at end of file diff --git a/include/logging.h b/include/logging.h index f067567..f134595 100644 --- a/include/logging.h +++ b/include/logging.h @@ -7,8 +7,10 @@ #include #include #include +#include typedef enum { + LOG_FATAL, LOG_ERROR, LOG_WARNING, LOG_INFO, @@ -21,8 +23,8 @@ typedef enum { } log_status; typedef struct Handler { - FILE* file; - log_level level; + void* out; + bool apply_color; } log_Handler; @@ -31,6 +33,8 @@ typedef struct Logger { log_level level; log_Handler* handler; + const char* name; + void (*fatal)(const char* format, ...); void (*error)(const char* format, ...); void (*warning)(const char* format, ...); void (*info)(const char* format, ...); @@ -50,8 +54,11 @@ typedef struct Logging { Logging* createLogging(); +log_status destroyLogging(Logging* logging); -log_Handler* fileHandler(const char* name,log_level level); +log_Handler* fileHandler(const char* name); //文件处理器 +log_Handler* consoleHandler(const char* name); //控制台处理器 + #endif // __LOGGING_H \ No newline at end of file diff --git a/main.c b/main.c index 5d5a325..3e21df2 100644 --- a/main.c +++ b/main.c @@ -4,11 +4,15 @@ int main() { // Your code goes here Logging *log = createLogging(); - Logger *logger = log->getLogger("testLogger",LOG_INFO); + Logger *logger = log->getLogger("testLogger",LOG_DEBUG); + // log->addHandler(consoleHandler("test")); + log->addHandler(fileHandler("test")); logger->info("This is an info message"); - logger->error("This is an error 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"); + logger->warning("This is a warning message%s", "123"); + destroyLogging(log); return 0; } \ No newline at end of file diff --git a/src/logging-handler.c b/src/logging-handler.c index d0e1edd..0bd7018 100644 --- a/src/logging-handler.c +++ b/src/logging-handler.c @@ -2,15 +2,30 @@ #include "logging.h" - - - - -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->out = fp; + handler->apply_color = false; + return handler; +} + + +/** +* @description :控制台日志处理器 +* @param +* @return +*/ +log_Handler* consoleHandler(const char* name){ + log_Handler* handler = (log_Handler*)malloc(sizeof(log_Handler)); + handler->out = stdout; + handler->apply_color = true; return handler; } \ No newline at end of file diff --git a/src/logging.c b/src/logging.c index 3f7446a..f507b10 100644 --- a/src/logging.c +++ b/src/logging.c @@ -1,7 +1,5 @@ #include "logging.h" - - Logger* G_LOGGER = NULL; #define RED "\033[0;31m" @@ -14,12 +12,13 @@ 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); } @@ -32,39 +31,75 @@ static void addHandler(log_Handler* handler){ G_LOGGER->handler = handler; } +static void _builtin_log(char* level, const char *color, const char* format, ...){ + if (G_LOGGER == NULL){ + return; + } + if (G_LOGGER->handler == NULL){ + return; + } + char timeStr[20]; + getTimeStr(timeStr); + char logStr[LOG_BUFFER_SIZE]; + if (G_LOGGER->handler->apply_color) sprintf(logStr, "%s %s%s%s %s\n", timeStr, color,level,RESET, format); + else sprintf(logStr, "%s %s %s\n", timeStr, level, format); + fputs(logStr, G_LOGGER->handler->out); +} + //*************************记录日志******************************* */ +static void fatal(const char* format, ...){ + if (G_LOGGER->level >= LOG_ERROR){ + char logStr[LOG_BUFFER_SIZE]; + va_list args; + va_start(args, format); + vsprintf(logStr, format, args); + va_end(args); + _builtin_log("Fatal",RED, logStr, args); + } +} + static void error(const char* format, ...){ 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, format); + vsprintf(logStr, format, args); + va_end(args); + _builtin_log("Error",RED, logStr, args); } - } static void warning(const char* format, ...){ 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, format); + vsprintf(logStr, format, args); + va_end(args); + _builtin_log("Warning",YELLOW, logStr, args); } - } static void info(const char* format, ...){ 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, format); + vsprintf(logStr, format, args); + va_end(args); + _builtin_log("Info",GREEN, logStr, args); } } static void debug(const char* format, ...){ 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, format); + vsprintf(logStr, format, args); + va_end(args); + _builtin_log("Debug",CYAN, logStr, args); } } //*************************记录日志******************************* */ @@ -76,7 +111,11 @@ 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; @@ -84,6 +123,7 @@ static Logger* getLogger(const char* name, log_level level){ logger->level = level; logger->handler = NULL; + logger->name = name; G_LOGGER = logger; return G_LOGGER; @@ -98,4 +138,21 @@ Logging* createLogging(){ logging->getLogger = getLogger; logging->addHandler = addHandler; return logging; -} \ No newline at end of file +} + + +log_status destroyLogging(Logging* logging){ + if (logging == NULL){ + return L_ERROR; + } + if (G_LOGGER != NULL){ + if (G_LOGGER->handler != NULL){ + fclose(G_LOGGER->handler->out); + free(G_LOGGER->handler); + } + free(G_LOGGER); + G_LOGGER = NULL; + } + free(logging); + return L_OK; +}