I used the logstream class throughout my code, liking that I could use
it like cout.

My preference is to see one of the following:
1) If the implementation of logstream were changed from
basic_ostringstream to a MessageBuffer, would that make logstream work
more satisfactorily?  (I don't remember at the moment what the issues
were.)

2) Perhaps the new logging macros, or something similar, could be
wrapped in a class that works like the logstream class.

3) Leaving logstream deprecated would certainly help me, since I won't
have time to re-work any of the logging framework for a while, but I'd
like to use the newly released version when I do.

4) If not 1) or 2) above, then I'd appreciate advice on how I could wrap
the internals of the new logging macros in my own logstream-like class.

Thank you,
-David


-----Original Message-----
From: Curt Arnold [mailto:[EMAIL PROTECTED] 
Sent: Tuesday, September 25, 2007 3:03 AM
To: Log4CXX Dev
Subject: Restoring operator<< in LOG4CXX_INFO et al

I've committed changes that should restore the ability to use the <<  
operator in the message fragment of LOGCXX_INFO and similar macros.   
It had been removed 3 years ago when the ability to have both char* and
wchar_t* messages processed in the same log4cxx build since the log4cxx
0.9.7 macro definition wasn't compatible with wchar_t based messages.

The log4cxx 0.9.7 definition was:

#define LOG4CXX_INFO(logger, message) { \
        if (logger->isInfoEnabled()) {\
        ::log4cxx::StringBuffer oss; \
        oss << message; \
        logger->forcedLog(::log4cxx::Level::INFO, oss.str(), __FILE__,
__LINE__); }}

where ::log4cxx::StringBuffer is effectively std::ostringstream.

The current SVN HEAD definition is:

#define LOG4CXX_INFO(logger, message) { \
         if (logger->isInfoEnabled()) {\
            ::log4cxx::helpers::MessageBuffer buf; \
            logger->forcedLog(::log4cxx::Level::getInfo(), buf.str (buf
<< message), LOG4CXX_LOCATION); }}

The MessageBuffer class was designed specifically for this usage pattern
and hopefully the class and macro combine so that:

1.  log requests using the << operator that worked in 0.9.7 still work
2.  log requests that have a simple message (char*, std::string,
wchar_t*, std::wstring) work but avoid the overhead of
std::ostringstream construction (which can be surprisingly expensive) 3.
log requests that are simply concatenation of strings using operator<<
also avoid std::ostringstream construction.
4. log requests that contain a ((char*) 0) or ((wchar_t*) 0) will be
converted to "null" when std::ostringstream construction is avoided.
5. log requests where the first part of the expression is wchar_t based
will use std::basic_ostringstream<wchar_t>.

So all the following should work as expected:

//
//   no std::ostringstream construction
//
LOG4CXX_INFO(logger, "Hello");
LOG4CXX_INFO(logger, L"Hello");
LOG4CXX_INFO(logger, "Hello" << ", World"); LOG4CXX_INFO(logger,
L"Hello" << L", World"); LOG4CXX_INFO(logger, "null:" << ((char*) 0)");
//
//   uses std::ostringstream
//
LOG4CXX_INFO(logger, "Iteration " << i); LOG4CXX_INFO(logger,
std::scientific << "pi=" << 3.1415926); // //  uses
std::basic_ostringstream<wchar_t> // LOG4CXX_INFO(logger, L"Iteration "
<< i);


I haven't tried a Windows build yet which will have to wait till
tomorrow.  I'd appreciate any feedback, particularly with any code base
that made extensive use of operator<< in messages.

If this works effectively, then we should remove LogStream from SVN HEAD
as it was never particularly satisfying.  If somebody really wants it to
stay, we could leave it in and mark it deprecated.

Reply via email to