如何修改C语言decode_log函数,将调试打印内容写入本地文件
日志写入文件实现方案
下面提供两种可直接落地的实现方案,第一种改动最小,不需要调整原有日志解析逻辑。
方案1:修改DEBUG_Print宏实现终端+文件双输出(推荐,改动最小)
不需要修改decode_log函数的任何代码,只需要调整打印宏和增加文件初始化/销毁逻辑即可。
实现步骤
- 引入必要头文件,定义全局文件指针和文件操作函数
#include <stdio.h> #include <stdint.h> // 若原有代码未引入该头文件需补上,用于uint8_t等类型定义 static FILE *g_log_file = NULL; // 初始化日志文件,传入要保存的文件路径,返回0成功,返回-1失败 int log_file_init(const char *file_path) { // 用"a"为追加写入,每次运行日志累加;要每次覆盖旧日志就换成"w" g_log_file = fopen(file_path, "a"); if(g_log_file == NULL) { printf("打开日志文件失败!\n"); return -1; } return 0; } // 程序退出前调用,关闭日志文件 void log_file_deinit(void) { if(g_log_file != NULL) { fclose(g_log_file); g_log_file = NULL; } }
- 修改
DEBUG_Print宏,增加写入文件的逻辑
#define DEBUG_Print(...) do{ \ printf(__VA_ARGS__); \ fflush(stdout); \ if(g_log_file != NULL) { \ fprintf(g_log_file, __VA_ARGS__); \ fflush(g_log_file); // 实时写入磁盘,避免程序异常退出丢失日志 } \ }while(0)
- 调用逻辑
- 在程序启动后、第一次调用
decode_log之前,先执行初始化:
// 示例:在main函数开头调用,文件保存路径可自定义 log_file_init("./device_usage.log");
- 程序正常退出前调用销毁函数关闭文件:
log_file_deinit();
方案2:不修改原有DEBUG_Print,单独写入文件
如果不想影响其他地方的调试打印输出,可以单独给decode_log增加文件写入逻辑:
- 先实现方案1中的
log_file_init、log_file_deinit和全局文件指针 - 在每个
DEBUG_Print调用的位置,对应增加fprintf调用即可,示例:
// 原有终端打印逻辑 DEBUG_Print("\n=== USAGE_LOG ===\n" "Power cycles: %u\n" "Unpause events: %u\n" "Power-on time: %us\n" "Unpaused time: %us\n", get_uint32(data+0), get_uint32(data+4), get_uint32(data+8), get_uint32(data+12)); // 新增写入文件逻辑 if(g_log_file != NULL) { fprintf(g_log_file, "\n=== USAGE_LOG ===\n" "Power cycles: %u\n" "Unpause events: %u\n" "Power-on time: %us\n" "Unpaused time: %us\n", get_uint32(data+0), get_uint32(data+4), get_uint32(data+8), get_uint32(data+12)); }
所有打印位置都按上述方式新增写入逻辑即可,也可以单独封装一个专门写文件的宏简化代码。
注意事项
- 多线程场景下需要加锁保护文件写入操作,避免日志内容错乱
- 嵌入式环境如果没有标准文件系统,需要适配自身的存储写入逻辑替换fopen/fprintf等函数
- 如果日志量很大,可以增加定时滚动日志文件的逻辑,避免单个文件体积过大
内容的提问来源于stack exchange,提问作者user12800116
相关产品推荐
相关产品推荐

