假设我们有以下代码:
LOG_INFO("rkipc_ini_path_ is %s, rkipc_iq_file_path_ is %s, rkipc_log_level is %d\n",rkipc_ini_path_, rkipc_iq_file_path_, rkipc_log_level);
1. LOG_INFO 宏定义
根据之前的 LOG_INFO
宏定义:
#define LOG_INFO(format, ...) \do { \if (rkipc_log_level < LOG_LEVEL_INFO) \break; \if (enable_minilog) \minilog_info("[%s][%s]:" format, LOG_TAG, __FUNCTION__, ##__VA_ARGS__); \else \fprintf(stderr, "[%s][%s]:" format, LOG_TAG, __FUNCTION__, ##__VA_ARGS__); \} while (0)
format
是你传递的日志格式字符串:"rkipc_ini_path_ is %s, rkipc_iq_file_path_ is %s, rkipc_log_level is %d\n"
。__VA_ARGS__
是可变参数,传递给宏的具体参数:rkipc_ini_path_
,rkipc_iq_file_path_
,rkipc_log_level
。
2. 宏展开
当你调用 LOG_INFO
时,宏会展开为下面的代码:
do {if (rkipc_log_level < LOG_LEVEL_INFO) break;if (enable_minilog) minilog_info("[%s][%s]:" format, LOG_TAG, __FUNCTION__, ##__VA_ARGS__);else fprintf(stderr, "[%s][%s]:" format, LOG_TAG, __FUNCTION__, ##__VA_ARGS__);
} while (0)
- 宏首先检查
rkipc_log_level
是否大于等于LOG_LEVEL_INFO
,如果小于则跳过日志输出。 - 然后,检查
enable_minilog
是否为true
。如果为true
,调用minilog_info
;否则,使用fprintf
输出日志信息。
3. 日志格式化
format
参数为:
"rkipc_ini_path_ is %s, rkipc_iq_file_path_ is %s, rkipc_log_level is %d\n"
__VA_ARGS__
参数分别为:
rkipc_ini_path_
rkipc_iq_file_path_
rkipc_log_level
假设它们的值分别是:
rkipc_ini_path_ = "/path/to/config.ini";
rkipc_iq_file_path_ = "/path/to/iq_file";
rkipc_log_level = 3;
在这种情况下,LOG_INFO
调用将会被展开为:
if (rkipc_log_level < LOG_LEVEL_INFO)break;
if (enable_minilog)minilog_info("[%s][%s]: rkipc_ini_path_ is %s, rkipc_iq_file_path_ is %s, rkipc_log_level is %d\n",LOG_TAG, __FUNCTION__,rkipc_ini_path_, rkipc_iq_file_path_, rkipc_log_level);
elsefprintf(stderr, "[%s][%s]: rkipc_ini_path_ is %s, rkipc_iq_file_path_ is %s, rkipc_log_level is %d\n",LOG_TAG, __FUNCTION__,rkipc_ini_path_, rkipc_iq_file_path_, rkipc_log_level);
LOG_TAG
会被替换为"rkipc_server"
,这是日志标记。__FUNCTION__
会被替换为当前函数的名称,例如"main"
,表示调用LOG_INFO
的函数。%s
和%d
会分别被rkipc_ini_path_
,rkipc_iq_file_path_
,rkipc_log_level
的值替换。
4. 最终输出
如果 enable_minilog = 1
(启用了 minilog
),则输出:
minilog_info("[rkipc_server][main]: rkipc_ini_path_ is /path/to/config.ini, rkipc_iq_file_path_ is /path/to/iq_file, rkipc_log_level is 3");
如果 enable_minilog = 0
(禁用了 minilog
),则输出到标准错误:
fprintf(stderr, "[rkipc_server][main]: rkipc_ini_path_ is /path/to/config.ini, rkipc_iq_file_path_ is /path/to/iq_file, rkipc_log_level is 3");