dtl/log-dtl.c
2025-06-01 21:17:47 +08:00

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];
}