日志打印注意事项:
1. 日志输出是有代价的,特别是在嵌入式系统,或者对执行时序要求较高的应用场景。因此
a) 只有在需要的地方加入,不能滥用
b) 一定要有一个全局的开关,在不需要或者产品发布的时候,关闭输出,或者降低日志输出的频率
2. 日志输出需要有优先级控制,例如:发生错误时的日志优先级最高,一般都要输出;一些重要的提示,优先级中等,可能会在debug版的软件中打开;一些不重要的提示,可能只会在需要的时候(例如跟踪bug)打开
3. 不要直接使用printk(或者printf)。日志输出的目标是多样的,例如通过printf输出到屏幕、通过串口输出到串口调试助手、通过文件操作写入到文件等等。要通过重定义的方式,将所有的日志输出指令定义到合适的输出路径,当需要修改输出路径的时候,只要修改重定义的部分即可。否则需要在整个代码中修改,就麻烦了。
4. 最好为每个软件模块提供单独的日志输出开关,以增加调试的灵活性
5. 很多时候,日志输出语句,可以部分代替代码注释的功能
实例代码:
#ifndef __EIM_DEBUG_H__
#define __EIM_DEBUG_H__
/*
* debug level,
* if is DEBUG_LEVEL_DISABLE, no log is allowed output,
* if is DEBUG_LEVEL_ERR, only ERR is allowed output,
* if is DEBUG_LEVEL_INFO, ERR and INFO are allowed output,
* if is DEBUG_LEVEL_DEBUG, all log are allowed output,
*/
enum debug_level
{
DEBUG_LEVEL_DISABLE = 0,
DEBUG_LEVEL_ERR,
DEBUG_LEVEL_INFO,
DEBUG_LEVEL_DEBUG,
};
/*
* the macro to set debug level, you should call it
* once in the files you need use debug system
*/
#define DEBUG_SET_LEVEL(x) static int debug = x
#define CONFIG_ENABLE_EIM_DEBUG
#ifdef CONFIG_ENABLE_EIM_DEBUG
/* it can be change to others, such as file operations */
#define PRINT printk
#define EIM_ASSERT() \
do { \
PRINT("ASSERT: %s %s %d", \
__FILE__, __FUNCTION__, __LINE__); \
while (1); \
} while (0)
#define EIM_ERR(...) \
do { \
if (debug >= DEBUG_LEVEL_ERR) { \
PRINT(__VA_ARGS__); \
} \
} while (0)
#define EIM_INFO(...) \
do { \
if (debug >= DEBUG_LEVEL_INFO) { \
PRINT(__VA_ARGS__); \
} \
} while (0)
#define EIM_DEBUG(...) \
do { \
if (debug >= DEBUG_LEVEL_DEBUG) { \
PRINT(__VA_ARGS__); \
} \
} while (0)
#else /* CONFIG_ENABLE_EIM_DEBUG */
#define DEBUG_SET_LEVEL(x)
#define EIM_ASSERT()
#define EIM_ERR(...)
#define EIM_INFO(...)
#define EIM_DEBUG(...)
#endif /* CONFIG_ENABLE_DEBUG */
#endif /* __EIM_DEBUG_H__ */