也许这是一个微不足道的问题,很多/大多数/所有优秀的框架都能做到,但我正在寻找一个记录器类/框架(尽可能简单)使其变得简单有一个嵌套的日志输出,如
[time] A::doSomething start
[time] doing this
[time] doing that
[time] calling B
[time] B::somethingElse start
[time] do
[time] re
[time] mi
[time] c::foo start
[time] ...
[time] c::foo end
[time] B::somethingElse end
[time] A::doSomething end
我在搜索互联网时最接近的是nested diagnostic contexts in log4j。但是a)这是针对java和b)我不确定这是否提供了我正在寻找的东西......
在文档中有这个“当离开上下文时,调用NDC.pop”。如果可能的话,我想拥有更多基于堆栈的魔法。
那里有没有可以做我正在寻找的项目?
TIA
答案 0 :(得分:0)
我不知道有任何日志记录框架,但我玩过足够漂亮的打印机,我知道这并不困难。
假设存在支持push
和pop
操作的Logger类:
class LogNester: private boost::noncopyable {
public:
LogNester(Logger& l): logger(l) { logger.push(); }
~LogNester() { logger.pop(); }
private:
Logger& logger;
};
用法:
void foo() {
LogNester _(GlobalLogger);
// do something
}
一个重点:您需要命名变量,LogNester(GlobalLogger)
将仅为此语句推送和弹出(oups),而命名变量将活到范围的最后。
如果你厌倦了每次都想出新名字(我能理解),你可以随时使用一个宏:
#define NESTLOG() LogNester BOOST_PP_CAT(log, __LINE__)(GlobalLogger);
但是,它并不完全是......自动化的,因为您需要在每个方法输入时定义LogNester
对象。从理论上讲,只要你不介意有点慢下来,你应该能够神奇地获得深度:使用堆栈调用信息。 gcc
使用backtrace
实用程序
#include <execinfo.h> // GNU/Linux specific header
inline unsigned depth() {
void* Stack[64];
return backtrace(Stack, sizeof(Stack));
}
然后,增强您的日志记录宏:
#define LOG(Message_) \
do { \
GlobalLogger.log(__FILE__, __LINE__, __FUNCTION__, depth(), Message_); \
} while(0)
当然,这在很大程度上取决于是否内联电话。
我个人认为__FILE__
,__LINE__
和__FUNCTION__
足以满足我的需求。