用C++写Logger,常见的有这几种方法:
- 写一个Logger类,封装诸如Info(format, …)、Warn(format, …)之类的方法,然后用个实例化一个全局对象,处处皆可输出log,不仅到屏幕,而且可以到文件甚至是网络。
- 在c99之前,宏定义中的可变参数…是不能直接在宏中展开的,必须在函数中使用va_list这样的方式来处理,所以如果不使用c99标准,简易的Logger可以使用
- 在c99标准及以后,已经支持可变参数在宏定义中直接展开了,所以LOG_INFO可以这样来定义:
#define LOG_INFO(msg) printf msg
这样的方式来定义一个宏,然后用以下方式来使用
LOG_INFO((“hello, %s!\n”, “world”));
不过,这种方法的弊端在于,LOG_INFO宏在代码中的表现看起来不太符合常理,它应该像个函数,参数周围只用一对括号才好。为什么要用两对括号呢?因为只用一对括号,每个用’,’分隔的参数都会被传进对应的宏,而宏本身并不支持多态,所以只用一对括号,在c99以前的标准下,根本没法做到。并且如果我希望在每条log前都输出标识”[INFO] “的话,只能在每个使用了LOG_INFO的format参数中增加”[INFO] “,目的虽然能达到,但是灵活性不够,一旦需要修改,处处都得改。
#define LOG_INFO(…) fprintf(stderr, “[INFO] “__VA_ARGS__)
这样,我既可以选择将log输出到stdout,或是stderr, 或是某个文件指针(暂不讨论输出到文件,因为我暂时没这需求)。并且还可以随意地在format字串里加上前缀,甚至是文件(__FILE__)或函数(__FUNC__)信息,并且使用时就像正常的函数一样使用:
LOG_INFO(“hello, %d!”, “world”);
如果使用gcc 4.0以上的版本,总是会有警告”warning: anonymous variadic macros were introduced in C99”出现,编译时加上参数”-Wno-variadic-macros”就清静了。