ADD: ./program/c_cpp/coding-style.md ./linux/command -> timeshift FIX: ./linux/arch/auto.sh ./linux/config/.bashrc
168 lines
4.8 KiB
C
168 lines
4.8 KiB
C
#include "log.h"
|
|
|
|
#ifdef NDEBUG
|
|
#define POINT_STR(str)
|
|
#define PERROR(str)
|
|
#else
|
|
#define POINT_STR(str) for(int i = 0; i < strlen(str); i++) { \
|
|
printf("%c --- %d\n", (char)str[i], (int)str[i]);}
|
|
#define PERROR(str) printf(str);return
|
|
#endif
|
|
|
|
static int low_show_level = LOG_INFO;
|
|
static int log_number = 1;
|
|
static FILE *log_out_fp = NULL;
|
|
static char log_head_format[LOG_HEAD_MAX_FORMAT] = "[%y-%m-%d-%n]";
|
|
static char log_head[LOG_HEAD_MAX_FORMAT << 3];
|
|
|
|
|
|
static int
|
|
get_loghead(void);
|
|
// 根据 log_head_format 生成日志头 log_head
|
|
// 有无法识别的符号返回 -1 成功返回0
|
|
|
|
static void
|
|
int_to_str(int num, char *restrict str);
|
|
// 将int 型数据转换成str
|
|
// 需要注意 str 要大于 int 的位数,否则将溢出
|
|
|
|
|
|
void
|
|
log_setoutfile(const char *restrict filename) {
|
|
if((log_out_fp = fopen(filename, "w")) == NULL)
|
|
PERROR("LOG: log_setoutfile open file fail !\n");
|
|
return;
|
|
}
|
|
|
|
void
|
|
log_setlevel(int level) {
|
|
if(level < LOG_INFO || level > LOG_FATAL) { // 检测最低日志等级
|
|
low_show_level = LOG_INFO;
|
|
PERROR("LOG: log_setlevel level is > LOG_FATAL or < LOG_INFO\n");
|
|
}
|
|
low_show_level = level;
|
|
return;
|
|
}
|
|
|
|
void
|
|
log_sethead(const char *restrict head) {
|
|
if(strlen(head) >= LOG_HEAD_MAX_FORMAT)
|
|
PERROR("LOG: log_sethead head so long!\n");
|
|
strncpy(log_head_format, head, LOG_HEAD_MAX_FORMAT);
|
|
if(get_loghead())
|
|
PERROR("LOG: log_sethead have fail char !\n");
|
|
return;
|
|
}
|
|
|
|
void
|
|
log_print(int level, const char *restrict message) {
|
|
if(log_out_fp == NULL) // 未设置输出文件
|
|
log_out_fp = stdout;
|
|
if(level < LOG_INFO || level > LOG_FATAL) // 日志等级不在范围内
|
|
PERROR("LOG: log_print level out of range !\n");
|
|
if(level < low_show_level) // 低于最低等级的log不进行打印
|
|
return;
|
|
|
|
if(get_loghead() != 0) // 生成日志头
|
|
PERROR("LOG: log_print get_loghead error\n");
|
|
if(!fputs(log_head, log_out_fp)) // 打印日志头
|
|
PERROR("LOG: log_print fputs_head error\n");
|
|
|
|
switch(level) { // 打印错误等级
|
|
case LOG_INFO:
|
|
if(fputs("INFO:", log_out_fp))
|
|
break;
|
|
case LOG_WARNING:
|
|
if(fputs("WARNING:", log_out_fp))
|
|
break;
|
|
case LOG_ERROR:
|
|
if(fputs("ERROR:", log_out_fp))
|
|
break;
|
|
case LOG_FATAL:
|
|
if(fputs("FATAL:", log_out_fp))
|
|
break;
|
|
default:
|
|
PERROR("LOG: log_print out level is untrue !\n");
|
|
}
|
|
|
|
if(!fputs(message, log_out_fp)) // 打印message
|
|
PERROR("LOG: log_head fputs fail !\n");
|
|
fputc('\n', log_out_fp);
|
|
log_number++; // 日志计数++
|
|
return;
|
|
}
|
|
|
|
int
|
|
get_loghead(void) {
|
|
char buf[64];
|
|
time_t now_time = time(NULL);
|
|
clock_t core_time = clock() / CLOCKS_PER_SEC; // 以 s 为单位的 cpu 时间
|
|
struct tm *tm_time = localtime(&now_time);
|
|
int temp;
|
|
|
|
memset(log_head, '\0', sizeof(log_head)); // 重置日志头
|
|
|
|
for(int i = 0; i < strlen(log_head_format); i++) {
|
|
if(log_head_format[i] != '%') { // 非特殊字符则按正常复制
|
|
log_head[strlen(log_head)] = log_head_format[i];
|
|
continue;
|
|
}
|
|
|
|
i++;
|
|
switch(log_head_format[i]) { // 特殊字符转换
|
|
case 'y' :
|
|
strftime(buf, 64, "%Y", tm_time);
|
|
break;
|
|
case 'm' :
|
|
strftime(buf, 64, "%m", tm_time);
|
|
break;
|
|
case 'd' :
|
|
strftime(buf, 64, "%d", tm_time);
|
|
break;
|
|
case 'h' :
|
|
strftime(buf, 64, "%H", tm_time);
|
|
break;
|
|
case 'M' :
|
|
strftime(buf, 64, "%M", tm_time);
|
|
break;
|
|
case 's' :
|
|
strftime(buf, 64, "%S", tm_time);
|
|
break;
|
|
case 'n' :
|
|
int_to_str(log_number, buf);
|
|
break;
|
|
case 'c' :
|
|
int_to_str(core_time, buf);
|
|
break;
|
|
default:
|
|
return -1;
|
|
}
|
|
strcat(log_head, buf);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
int_to_str(int num, char *restrict str) {
|
|
if(num < 0)
|
|
return; // 日志编号不可能小于 0
|
|
|
|
// 逐位提取数字(反向存储)
|
|
int start = 0;
|
|
do {
|
|
str[start++] = num % 10 + '0';
|
|
num /= 10;
|
|
} while (num > 0);
|
|
str[start] = '\0';
|
|
|
|
// 反转数字部分
|
|
char buf[16];
|
|
strncpy(buf, str, 16);
|
|
for(int i = 0; i < strlen(buf); i++)
|
|
str[--start] = buf[i];
|
|
return;
|
|
}
|
|
|
|
#undef POINT_STR
|
|
#undef PERROR
|