138 lines
3.9 KiB
C
138 lines
3.9 KiB
C
#include "dtl.h"
|
|
#include <time.h>
|
|
#include <string.h>
|
|
|
|
static enum LOG_LEVEL low_show_level = LOG_INFO;
|
|
static uint32_t 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];
|
|
|
|
|
|
/*
|
|
* 解析日志头
|
|
*
|
|
* Description:
|
|
* 解析log_head_format中的特殊符号
|
|
* ret 0 -> success
|
|
* ret !0 -> Unrecognized symbol
|
|
*/
|
|
static void
|
|
get_loghead(void);
|
|
|
|
static void
|
|
int_to_str(char *restrict dst, uint32_t num, size_t n);
|
|
|
|
|
|
/*-----------------------------------------------------------*/
|
|
/*-----------------------------------------------------------*/
|
|
|
|
|
|
void
|
|
log_setoutfile(const char *restrict filename)
|
|
{
|
|
if((log_out_fp = fopen(filename, "w")) == NULL)
|
|
perror("log-dtl.c:log_setoutfile: Failed to open file !\n");
|
|
}
|
|
|
|
|
|
void
|
|
log_setlevel(enum LOG_LEVEL level) {
|
|
if(level < LOG_INFO || level > LOG_FATAL)
|
|
low_show_level = LOG_INFO;
|
|
else
|
|
low_show_level = level;
|
|
}
|
|
|
|
|
|
void
|
|
log_sethead(const char *restrict head) {
|
|
if(strlen(head) >= LOG_HEAD_MAX_FORMAT)
|
|
return;
|
|
strncpy(log_head_format, head, LOG_HEAD_MAX_FORMAT);
|
|
}
|
|
|
|
|
|
void
|
|
log_print(enum LOG_LEVEL level, const char *restrict message) {
|
|
if(log_out_fp == NULL)
|
|
log_out_fp = stdout;
|
|
if(level < low_show_level)
|
|
return;
|
|
|
|
get_loghead();
|
|
fputs(log_head, log_out_fp);
|
|
|
|
switch(level) { // 打印错误等级
|
|
case LOG_INFO:
|
|
fputs("INFO:", log_out_fp);break;
|
|
case LOG_WARNING:
|
|
fputs("WARNING:", log_out_fp);break;
|
|
case LOG_ERROR:
|
|
fputs("ERROR:", log_out_fp);break;
|
|
case LOG_FATAL:
|
|
fputs("FATAL:", log_out_fp);break;
|
|
}
|
|
|
|
fputs(message, log_out_fp);
|
|
fputc('\n', log_out_fp);
|
|
log_number++; // 日志计数++
|
|
}
|
|
|
|
|
|
void
|
|
get_loghead(void) {
|
|
char buf[32];
|
|
time_t now_time = time(NULL);
|
|
clock_t core_time = clock() / CLOCKS_PER_SEC;
|
|
struct tm *tm_time = localtime(&now_time);
|
|
|
|
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, 32, "%Y", tm_time);break;
|
|
case 'M':
|
|
strftime(buf, 32, "%m", tm_time);break;
|
|
case 'd':
|
|
strftime(buf, 32, "%d", tm_time);break;
|
|
case 'h':
|
|
strftime(buf, 32, "%H", tm_time);break;
|
|
case 'm':
|
|
strftime(buf, 32, "%M", tm_time);break;
|
|
case 's':
|
|
strftime(buf, 32, "%S", tm_time);break;
|
|
case 'n':
|
|
int_to_str(buf, log_number, 32);break;
|
|
case 'c':
|
|
int_to_str(buf, core_time, 32);break;
|
|
default:
|
|
strcpy(buf, "!!");
|
|
}
|
|
strcat(log_head, buf);
|
|
}
|
|
}
|
|
|
|
void
|
|
int_to_str(char *restrict dst, uint32_t num, size_t n) {
|
|
// 逐位提取数字(反向存储)
|
|
int start = 0;
|
|
do {
|
|
dst[start++] = num % 10 + '0';
|
|
num /= 10;
|
|
} while (num > 0);
|
|
dst[start] = '\0';
|
|
|
|
// 反转数字部分
|
|
char buf[16];
|
|
strncpy(buf, dst, 15);
|
|
for(int i = 0; i < strlen(buf); i++)
|
|
dst[--start] = buf[i];
|
|
}
|