#include "dtl.h" #include #include 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]; }