作为一名程序员,不可避免的要在开发中打印一些关键信息,以方便业务调试,整体业务代码的打印需要保持意义明确,有明确时间参考点,便于调试。
日志打印主要级别划分
严重等级排序: TRACE < DEBUG < INFO < WARN < ERROR
ERROR 表示应用系统出现异常或故障,需要预警并及时解决,否则该功能将无法正常运行并提供服务能力。
WARN 表示应用系统出现不符合预期的现象,但服务并未受损,可根据实际情况选择性预警,解决时效要求不高,但需要额外关注。
INFO 表示用于记录系统运行过程或重要信息点,主要为故障定位、过程追溯、数据分析等提供辅助能力。
DEBUG 表示用于在测试或本地的非生产环境中使用,主要为了方便开发调试程序,而在生产环境中禁止使用
TRACE 特别详细的服务调用流程各个节点信息。业务代码中,除非涉及到多级服务的调用,否则不要使用。
在自定义日志打印中,用...
可表示可变参数,用__VA_ARGS__来复制参数,在
__VA_ARGS__前面加上##可得到##
__VA_ARGS__的作用是当可变参数的个数为0时,这里的##可以把把前面多余的","去掉,否则会编译出错。举例如下
//...表示可变参数,__VA_ARGS__就是将...的值复制到这里 #define LOG1(...) printf(__VA_ARGS__)
#include <stdio.h> #define LOG3(fmt, ...) printf("<%s:%s>:"fmt"\r\n", __FILE__, __FUNCTION__, ##__VA_ARGS__) int main(int argc, char** argv) { char *str = "test __VA_ARGS__"; int num = 10086; LOG3("this is test __VA_ARGS__"); LOG3("this is test __VA_ARGS__:%s, %d", str, num); LOG3(); return 0; }
打印结果: <main.c:main>:this is test __VA_ARGS__ <main.c:main>:this is test __VA_ARGS__:test __VA_ARGS__, 10086 <main.c:main>:
接下来就是一个自定义日志打印范本。
#define LOG_COLOR_RESET "\033[0m" #define LOG_COLOR_BLACK "\033[0;30m" #define LOG_COLOR_RED "\033[0;31m" #define LOG_COLOR_GREEN "\033[0;32m" #define LOG_COLOR_YELLOW "\033[0;33m" #define LOG_COLOR_BLUE "\033[0;34m" #define LOG_COLOR_PURPLE "\033[0;35m" #define LOG_COLOR_CYAN "\033[0;36m" #define LOG_COLOR_WHITE "\033[0;37m"
#define RSSU_LOG_OUT_FUNC printf static inline void print_time() { struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); int ms = (int)(ts.tv_nsec / 1000000); RSSU_LOG_OUT_FUNC("%06d:%03d", (int)ts.tv_sec, ms); }
//__func__是预置在编译器中的宏,并不包含于任何头文件,可直接调用 //预处理阶段,__LINE__ 会被替换成自己所在行的行号 #define RSSU_LOG_WARPPER(module, level, color, format, ...) \ do { \ print_time(); \ RSSU_LOG_OUT_FUNC(" " level " %06x %s [%s:%d] " color, \ (uint32_t)k_current_get(), module, __func__, \ __LINE__); \ RSSU_LOG_OUT_FUNC(format LOG_COLOR_RESET "\n", ##__VA_ARGS__); \ } while (0);
#define RSSU_LOG_FATAL(module, format, ...) \ RSSU_LOG_WARPPER(module, "F", LOG_COLOR_PURPLE, format, ##__VA_ARGS__) #define RSSU_LOG_ERROR(module, format, ...) \ RSSU_LOG_WARPPER(module, "E", LOG_COLOR_RED, format, ##__VA_ARGS__) #define RSU_LOG_INFO(module, format, ...) \ RSSU_LOG_WARPPER(module, "I", LOG_COLOR_GREEN, format, ##__VA_ARGS__) #define RSU_LOG_WARN(module, format, ...) \ RSSU_LOG_WARPPER(module, "W", LOG_COLOR_YELLOW, format, ##__VA_ARGS__) #define RSU_LOG_DEBUG(module, format, ...) \ RSSU_LOG_WARPPER(module, "D", "", format, ##__VA_ARGS__) #define RSU_LOG_VERBOSE(module, format, ...) \ RSSU_LOG_WARPPER(module, "V", LOG_COLOR_BLUE, format, ##__VA_ARGS__)
#define SCHED_MODULE "RSSU_SCHED" #define SCHED_LOG_FATAL(format, ...) \ RSSU_LOG_FATAL(SCHED_MODULE, format, ##__VA_ARGS__) #define SCHED_LOG_ERROR(format, ...) \ RSSU_LOG_ERROR(SCHED_MODULE, format, ##__VA_ARGS__) #define SCHED_LOG_INFO(format, ...) \ RSSU_LOG_INFO(SCHED_MODULE, format, ##__VA_ARGS__) #define SCHED_LOG_WARN(format, ...) \ RSSU_LOG_WARN(SCHED_MODULE, format, ##__VA_ARGS__) #define SCHED_LOG_DEBUG(format, ...) \ RSSU_LOG_DEBUG(SCHED_MODULE, format, ##__VA_ARGS__) #define SCHED_LOG_VERBOSE(format, ...) \ RSSU_LOG_VERBOSE(SCHED_MODULE, format, ##__VA_ARGS__)