2

我的 C++ 程序中有以下(简化的)代码:

std::string DataRequest::toString() const {
LOG4CPLUS_TRACE(logger,
        LOG4CPLUS_TEXT("symbol=" << m_contract.symbol));

std::ostringstream oss;
oss << "id=" << reqId
    << ",symbol=" << m_contract.symbol;
return oss.str();
}

int DataService::requestData(
    DataRequest request) {

LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("requestData: " << request.toString()));
}

然后,此代码会生成日志消息:

TRACE symbol=AAA
INFO  symbol=AAArequestData: id=1,symbol=AAA

但是我期待

TRACE symbol=AAA
INFO  requestData: id=1,symbol=AAA

由于在 log4cplus 消息中生成了一条 log4cplus 消息,因此它似乎将两条消息连接成一条消息。这是正常行为吗?是否有强制每条消息独立生成的解决方案?

4

1 回答 1

2

这是错误的代码

LOG4CPLUS_TRACE(logger,
        LOG4CPLUS_TEXT("symbol=" << m_contract.symbol));

它应该读

LOG4CPLUS_TRACE(logger,
        LOG4CPLUS_TEXT("symbol=") << m_contract.symbol);

反而。

至于连接的消息,您使用的是什么输出布局?如果是模式布局,那么您应该%n在格式字符串的最后添加格式化程序。

编辑:

不幸的是,我仍然遇到日志消息被连接的问题。我认为这与日志消息本身中的调用 request.toString() 也有对日志消息的调用有关,但由于某种原因,即使在代码修复之后,这两条消息也会一起打印。:(

啊,我最初误解了这个问题。因此,您在首先准备时正在记录第二个事件。问题是格式化是针对 thread-local 完成的ostringstream。线程本地ostringstream用作性能增强。(ostringstream不必在每条记录的消息上构造和销毁。)

为了立即解决,您有两个选择。首先,您停止此嵌套日志记录。其次,您“修复”LOG4CPLUS_*()宏以不使用线程本地ostringstream或滚动您自己的日志记录宏。两者都不应该那么难。

从长远来看,我可以为日志记录宏添加一个特殊情况,使它们ostringstream每次都使用新鲜,以允许您的用例。

编辑2:

我已经填写了一个错误报告并附加了一个实现解决方法的补丁。请参阅https://sourceforge.net/p/log4cplus/bugs/153/

于 2012-12-31T07:27:32.700 回答