How do I prevent log4cplus log messages within log messages?
Logging Framework for C++
Brought to you by:
wilx
From SO post http://stackoverflow.com/questions/14035870/how-do-i-prevent-log4cplus-log-messages-within-log-messages:
have the following (simplified) code in my C++ program:
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(); }
and
int DataService::requestData( DataRequest request) { LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("requestData: " << request.toString())); }
This code then produces the log message:
TRACE symbol=AAA INFO symbol=AAArequestData: id=1,symbol=AAA
however I was expecting
TRACE symbol=AAA INFO requestData: id=1,symbol=AAA
Since there is a log4cplus message being generated within a log4cplus message it appears to be concatenating the two messages into a single message. Is this normal behaviour? Is there a solution to force each message to be generated independently?
Please apply the attached patch and define
LOG4CPLUS_MACRO_DISABLE_TLS
in your application anywhere before including loggingmacros.h. This will disable use of thread-local storage that is at the root of this problem.Last edit: Václav Haisman 2013-01-02
Wouldn't another option be for new messages to check whether there is already a message in the ostringstream? If so, it create the second-message in a separate ostringstream? Perhaps even a (user-defined) handful of ostringstreams could be initialized for this purpose?
Doing this would complicate the logging macros further just to optimize an uncommon case, pessimizing the common case for, IMHO, little benefit.
What do you think the performance impact would be by using the temporary instances of ostringstream and snprintf_buf instead of the thread-local instances?
log4cplus 1.0.2 is ancient and it does not use thread-local storage for performance optimization, yet people have used it. I think that performance hit is acceptable, given uniqueness of your situation/code.
You can also disable the thread-local storage usage selectively, only in files where you really need it, to limit the performance hit only to some parts of your code.
Diff: