使用C语言设计编写程序日志,实现时间戳、 日志级别、日志内容、 日志输出、 日志轮转功能,其中日志轮转功能具体指的是在文件内存超出一定限制后再新建一个日志文件,给出具体的.c,.h和测试文件代码,
时间: 2024-02-18 20:01:06 浏览: 92
用C语言实现高效日志功能(含源码)
5星 · 资源好评率100%
好的,以下是一个简单的C语言日志模块的实现,包括时间戳、日志级别、日志内容、日志输出和日志轮转功能。
首先是日志.h文件,定义了日志相关的结构体和函数声明:
```c
#ifndef LOG_H
#define LOG_H
#include <stdio.h>
#include <stdbool.h>
#define LOG_MAX_SIZE 1024 * 1024 // 日志文件最大尺寸为1MB
#define LOG_PATH "./log.txt" // 日志文件路径
typedef enum {
LOG_LEVEL_DEBUG,
LOG_LEVEL_INFO,
LOG_LEVEL_WARN,
LOG_LEVEL_ERROR,
LOG_LEVEL_FATAL,
} log_level_t;
typedef struct {
FILE* file;
bool rotate_enabled;
} log_t;
int log_init(log_t* log, bool rotate_enabled);
int log_printf(log_t* log, log_level_t level, const char* fmt, ...);
void log_destroy(log_t* log);
#endif
```
接下来是日志.c文件,实现了日志相关的函数:
```c
#include "log.h"
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
#include <sys/stat.h>
static const char* level_strings[] = {
"DEBUG",
"INFO",
"WARN",
"ERROR",
"FATAL",
};
static struct {
log_level_t level;
const char* color;
} level_colors[] = {
{ LOG_LEVEL_DEBUG, "\033[0m" },
{ LOG_LEVEL_INFO, "\033[32m" },
{ LOG_LEVEL_WARN, "\033[33m" },
{ LOG_LEVEL_ERROR, "\033[31m" },
{ LOG_LEVEL_FATAL, "\033[35m" },
};
static int log_rotate(log_t* log);
int log_init(log_t* log, bool rotate_enabled) {
log->file = fopen(LOG_PATH, "a");
if (!log->file) {
return -1;
}
log->rotate_enabled = rotate_enabled;
return 0;
}
int log_printf(log_t* log, log_level_t level, const char* fmt, ...) {
if (!log->file) {
return -1;
}
if (ftell(log->file) >= LOG_MAX_SIZE) {
if (log->rotate_enabled) {
log_rotate(log);
} else {
fclose(log->file);
log->file = fopen(LOG_PATH, "w");
}
}
time_t now = time(NULL);
struct tm* tm = localtime(&now);
char time_str[20];
strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", tm);
int color_index = -1;
for (int i = 0; i < sizeof(level_colors) / sizeof(level_colors[0]); i++) {
if (level_colors[i].level == level) {
color_index = i;
break;
}
}
fprintf(log->file, "[%s] %s%s[%s]%s %s\n", time_str, color_index >= 0 ? level_colors[color_index].color : "", level_strings[level], __FILE__, "\033[0m", fmt);
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
return 0;
}
void log_destroy(log_t* log) {
fclose(log->file);
}
static int log_rotate(log_t* log) {
fclose(log->file);
char old_path[1024];
snprintf(old_path, sizeof(old_path), "%s.old", LOG_PATH);
remove(old_path);
rename(LOG_PATH, old_path);
log->file = fopen(LOG_PATH, "w");
if (!log->file) {
return -1;
}
return 0;
}
```
最后是一个测试文件,main.c,演示了如何使用日志模块:
```c
#include "log.h"
int main() {
log_t log;
if (log_init(&log, true) != 0) {
return -1;
}
log_printf(&log, LOG_LEVEL_DEBUG, "debug message\n");
log_printf(&log, LOG_LEVEL_INFO, "info message\n");
log_printf(&log, LOG_LEVEL_WARN, "warn message\n");
log_printf(&log, LOG_LEVEL_ERROR, "error message\n");
log_printf(&log, LOG_LEVEL_FATAL, "fatal message\n");
log_destroy(&log);
return 0;
}
```
在这个测试文件中,我们首先调用了log_init函数初始化日志模块,指定日志轮转功能开启,然后依次调用log_printf函数记录日志,最后调用log_destroy函数销毁日志模块。
阅读全文