汇总一些嵌入式打log的一些规则

在我们嵌入式开发中,打印日志是最常用的一种调试手段。合理地打印日志,可以帮助我们快速地分析问题。
本篇文章我们来汇总一些嵌入式打log的一些规则。
1、什么操作下加日志?
(1)错误处理
对于不能恢复的严重错误,日志内容应详细到足以帮助定位问题,但同时不应该包含敏感信息。比如申请内存失败时使用错误(error)级别加上日志信息。
(2)一些关键性的操作
一些很关键地处理,无论是正常情况或者异常情况都要打印日志。比如wifi打开时要有对应的日志信息。
(3)系统的打开、关闭
记录系统启动和关闭过程中的关键步骤有助于分析系统初始化是否正确,或者系统是否正常关闭。
(4)性能监控
日志可以记录系统运行的关键性能指标,如cpu和内存使用率、io操作等,以便进行系统性能分析和优化。
(5)关键数据
一些关键数据需要打印,很多功能上的问题大多直接与数据进行挂钩。
(6)通信日志
对于需要与外部设备或网络通信的嵌入式系统,记录通信日志可以帮助分析和调试通信协议或数据交换的问题。
(7)记录用户行为
在需要分析用户如何与嵌入式设备交互的情况下,记录用户行为的日志会非常有帮助。
(8)if、switch
分支判断中,各执行分支需要加上对应的日志信息,可以帮助我们准确地知道程序执行的走向。
(9)程序崩溃时的信息
比如,linxu下应用进程崩溃时的调用堆栈信息。
#include #include #include #include void func0(void){    printf(this is func0);    int *p = null;    *p = 1234;}void func1(void){    printf(this is func1);    func0();}void func2(void){    printf(this is func2);    func1();}void dump(int signo){    void *array[100];    size_t size;    char **strings;    size = backtrace(array, 100);    strings = backtrace_symbols(array, size);    printf(obtained %zd stacks., size);    for(int i = 0; i < size; i++)    {        printf(%s, strings[i]);    }            free(strings);    exit(0);}int main(int argc, char **argv){    printf(==================segmentation fault test5==================);    signal(sigsegv, &dump);    func2();    return 0;}  
2、功能模块标签
项目中肯定会划分有多个模块,可以给各个模块标记一个模块标签字符串,包含在日志条目里。这样我们就可以在日志文件里通过模块标签来筛选某个模块的日志,提高我们定位问题的效率。
比如:
// app_wifi.c#define log_tag    [wifi_module]#define log_d(fmt, arg...) log_d_tag(log_tag, fmt, ##arg)log_d(hello wifi module);  
输出:
[wifi_module]hello wifi module  
3、模块日志开关
设置模块日志开关,可以方便我们调试、分析问题时,缩小分析范围。当我们的函数设计有多个功能函数模块的时候,当某个模块出现问题时,这个时候我们只是关心此模块,那么可以先把其他模块的日志功能关闭掉,只是打开关心模块的日志。
如:
// module1.c#include module1.h#if module1_log_switch#define log_module1(fmt, args...)   dbg_printf(fmt, ##args)  #else#define log_module1(fmt, args...) #endif// module2.c#include module2.h#if module2_log_switch#define log_module2(fmt, args...)   dbg_printf(fmt, ##args)  #else#define log_module2(fmt, args...) #endif// config.h#define  module1_log_switch  0#define  module2_log_switch  1  
4、时间戳
日志应包含时间戳,可以方便地查看某段代码的执行时间、确定问题发生的具体时间。时间戳最好能精确到微秒/毫秒。
5、日志级别
使用不同的日志级别可以帮助筛选和控制输出的信息量。
常见的日志级别包括:
错误(error):程序无法运行或严重问题。
警告(warning):可能的问题,程序可以继续运行。
信息(info):程序运行状态信息。
调试(debug):详细的调试信息,包括变量值和程序流程。
详细(verbose):非常详细的信息,用于深入调试。
6、格式统一
为了使日志易于阅读,所有日志应保持一致的格式。
日志里常包含的固定信息有:
文件名
行号
时间日期/时间戳
函数名
模块名称
进程id
线程id
可根据需要进行组合。如:
[2024-01-14 11:12:30.666][wifi_module][func:wifi_init]  
7、过滤控制
使用日志动态过滤控制功能可以动态地调整日志地输出,但前提是项目使用地日志组件具备这样的能力。比如easylogger(https://github.com/armink/easylogger)。
8、release/debug开关
由于日志打印可能占用不少系统资源,应当注意其对性能的影响。在release版本中,可能需要减少日志输出或者去掉一些不必要的日志,需要一个开关来进行切换。
9、封装日志接口
嵌入式中,日志的输出大多数情况下会输出到串口终端。但也有一些场景,需要把日志输出到屏幕、网络设备、定制化的上位机等场景。需要留出对应接口,方便灵活切换。


suaoki推出一款便携式储能移动电源,支持车充充电,并能够使用太阳能供电
中国航空公司正式启动了LEAP发动机培训项目
最新黑科技:人体内运输细胞的微型机器人
没有大算力的ChatGPT,不是好AIGC
77英寸索尼A1正式开售:14999元仅次于LG OLED77W7P
汇总一些嵌入式打log的一些规则
华为正式宣布推出openEuler 20.3 LTS操作系统 可免费获取LTS版本并商业化
国内工业机器人产业需求旺盛 销量迅速增长
四大能量收集技术助力突破物联网设备供电困境
与特朗普分道扬镳后,马斯克深受中国的“宠爱”
360n5s最新消息:360N5s手机正式发布,双摄+6G运存=1699元!上手初晒!
韩国进口日本隔膜受限,中国企业机遇几何
气密性防水检测设备在医疗阀门气密性测试中的应用
光合有效传感器简介
工业级ADSL有线路由器/远程视频监控专用路由器
香农芯创:与华为没有业务往来,与SK海力士合作关系正常
如何选择一款“极耐寒”的非易失性内存
基于255 W ATX电源参考设计符合多种待机能耗标准的要求
嵌入式处理器是什么以及它的作用
国网发布关于《国家电网智能化规划》两大子规划