日志记录的结果如下所示:
------------ 2024_06_23_15_12_48.txt ------------
[2024-06-23 15:12:48][0.258337] web server root path: /home/buda/code/buda/vue/dist
[2024-06-23 15:12:48][0.91629] web server listen port: 8888
[2024-06-23 15:12:48][0.55383] create server listen socket succeed
[2024-06-23 15:12:48][0.27657] bind server listen socket to port 8888 succeed
[2024-06-23 15:12:48][0.30240] server socket starts listening ...
其中[0.258337]表示距离上一条Log的间隔时间是0秒+258337纳秒。
下面是实现上面日志记录的两个函数,一个函数创建日志文件,另一个函数往日志文件里写一条日志。
static const char *log_dir = "../../../log/"; // ~/code/log
static FILE* log_file = NULL;
static struct timespec last_log_time = {0, 0};
#define BudaWriteStep2(c, len, remain) c += len; remain -= len;
int log_start()
{
clock_gettime(CLOCK_MONOTONIC, &last_log_time);
char relative_path[PATH_MAX], real_path[PATH_MAX], *c=relative_path; int remain=PATH_MAX_1, len;
len = snprintf(c, remain, "%s", log_dir); BudaWriteStep2(c, len, remain);
*c=0; c = realpath(relative_path, real_path); if(c!=real_path) { printf("get log dir real path error: %s\n", relative_path); goto fail; }
c=real_path; remain=PATH_MAX_1; len=strlen(c); BudaWriteStep2(c, len, remain);
len = snprintf(c, remain, "/"); BudaWriteStep2(c, len, remain);
len = time_text_filename(c, remain); BudaWriteStep2(c, len, remain);
len = snprintf(c, remain, ".txt"); BudaWriteStep2(c, len, remain);
*c=0; log_file = fopen(real_path, "ab"); if (log_file == NULL) { printf("Failed to open file: %s\n", real_path); goto fail; }
printf("created log file: %s\n", real_path);
succeed: return 0;
fail: return -1;
}
void log(const char *format, ...)
{
char buf[TIME_BUF_SIZE]; long len, sep_sec, sep_nsec;
len = time_text(buf, TIME_BUF_SIZE1); buf[len]=0; struct timespec log_time; clock_gettime(CLOCK_REALTIME, &log_time);
sep_sec=log_time.tv_sec-last_log_time.tv_sec; sep_nsec=log_time.tv_nsec-last_log_time.tv_nsec; if(sep_nsec<0) { sep_nsec+=1000000000; sep_sec--; }
last_log_time = log_time;
fprintf(log_file, "[%s][%ld.%ld] ", buf, sep_sec, sep_nsec);
va_list args; va_start(args, format); vfprintf(log_file, format, args); va_end(args); fflush(log_file);
va_start(args, format); vprintf(format, args); va_end(args);
fprintf(log_file, "\n"); printf("\n");
succeed: return;
fail: printf("log failed\n"); return;
}
int time_text(char *r, int max_len)
{
time_t now; time(&now); struct tm parts, *p = &parts; localtime_r(&now, p);
int len = (int)strftime(r, max_len, "%Y-%m-%d %H:%M:%S", p); r[len]=0; return len;
}
int time_text_filename(char *r, int max_len)
{
time_t now; time(&now); struct tm parts, *p = &parts; localtime_r(&now, p);
int len = (int)strftime(r, max_len, "%Y_%m_%d_%H_%M_%S", p); r[len]=0; return len;
}
作者寄语
以上如有错漏之处,敬请大家指正。我是主修C/C++、Vue3开发的程序员,我的联系方式:
微信:TobeBuda
Email/Paypal: jinmin.si@outlook.com
邀请您加入「社区资讯服务」创业微信群,共同探讨打造社区资讯服务的美好未来。
参考资料
chatgpt
gemini