若要 mongoose.c 里的打印输出则需要在 main 函数里显式调用 mg_log_set(level),参数是打印等级,如:
mg_log_set(MG_LL_INFO);
这样设置之后,程序执行起来就可以实现打印输出了,但这个输出着实让人看得不太明白,其输出如下图:
其前 2 列表示什么一看是看不出来的,需要看代码,后几列无非就是文件名、行号、 函数名以及实际用户要输出的内容。看代码后才知道,第 1 列表示时间(单位是毫秒),第 2 列是打印等级,其定义如下:
enum { MG_LL_NONE, MG_LL_ERROR, MG_LL_INFO, MG_LL_DEBUG, MG_LL_VERBOSE };
于是就有了这篇文章,改造它这个打印输出格式。改造后最终的效果如下图所示一目了然:
首先看它的打印函数,其实就是宏定义,如下:
#if MG_ENABLE_LOG
#define MG_LOG(level, args) \
do { \
if (mg_log_prefix((level), __FILE__, __LINE__, __func__)) mg_log args; \
} while (0)
#else
#define MG_LOG(level, args) \
do { \
if (0) mg_log args; \
} while (0)
#endif
#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
#define MG_INFO(args) MG_LOG(MG_LL_INFO, args)
#define MG_DEBUG(args) MG_LOG(MG_LL_DEBUG, args)
#define MG_VERBOSE(args) MG_LOG(MG_LL_VERBOSE, args)
可以看到宏 MG_LOG(level, args) 是分为两段的,第一段前缀相当于是固定的,第二段是用户实际要输出的内容,我们只看第一段就可以了。原来的输出格式中的第一列是时间,函数 mg_millis()获取,第二列就是输出打印等级 level 如:
改造的时候添加一个获取时间字符串的函数 getTimeStamp(),其实现如下:
static void getTimeStamp(char *outBuf, size_t len)
{
time_t now;
struct timeval tv;
gettimeofday(&tv, NULL);
now = tv.tv_sec;
struct tm localTime;
localtime_r(&now, &localTime);
char timeBuf[128] = {0};
strftime((char *)timeBuf, sizeof(timeBuf), "%Y/%m/%d %H:%M:%S", &localTime);
snprintf(outBuf, len, "%s %06lu", timeBuf, tv.tv_usec % 1000000);
}
同时添加了打印等级对应的字符串,可读性更高一点,如:
static char *s_level_str[] = {
"None",
"Error",
"Info",
"Debug",
"Verbose"
};
所以最终改造的打印前缀的函数就是这样子:
bool mg_log_prefix(int level, const char *file, int line, const char *fname) {
if (level <= s_level) {
const char *p = strrchr(file, '/');
char buf[64];
char timeBuf[128] = {0};
size_t n;
getTimeStamp(timeBuf, sizeof(timeBuf));
if (p == NULL) p = strrchr(file, '\\');
n = mg_snprintf(buf, sizeof(buf), "[%s %s] %s:%d:%s", timeBuf, s_level_str[level],
p == NULL ? file : p + 1, line, fname);
if (n > sizeof(buf) - 2) n = sizeof(buf) - 2;
int i = 0;
while (n < sizeof(buf)) {
buf[n++] = ' '; /*这里是填充空格*/
if(i++ > 5) break; /*最多填充5个空格*/
}
logs(buf, n - 1);
return true;
} else {
return false;
}
}
while 循环那里就是填充空格,我这里最多只填充5个空格,太多也不好看,注意上面的 buf 的长度是64 字节,如果有函数名特别长那输出可能就被截断了。设置成 debug 等级,输出如下: