I want to use this snippet from Mr-Edd\'s iostreams article to print std::clog somewhere.
#include
#include
#include
I needed to grab outputs to std::cout and std::cerr from third party libraries and log them using log4cxx, and still retaining the original outputs.
This is what I came up with. It's pretty straight-forward:
I replace the old buffer of an ostream (like std::cout) with my own class so that I get access to what ever is written to it.
I also create a new std::ostream object with the old buffer so that I can continue to get the output to my console, besides sending it to my logger. Which I find kind of handy.
Code:
class intercept_stream : public std::streambuf{
public:
intercept_stream(std::ostream& stream, char const* logger):
_logger(log4cxx::Logger::getLogger(logger)),
_orgstream(stream),
_newstream(NULL)
{
//Swap the the old buffer in ostream with this buffer.
_orgbuf=_orgstream.rdbuf(this);
//Create a new ostream that we set the old buffer in
boost::scoped_ptr os(new std::ostream(_orgbuf));
_newstream.swap(os);
}
~intercept_stream(){
_orgstream.rdbuf(_orgbuf);//Restore old buffer
}
protected:
virtual streamsize xsputn(const char *msg, streamsize count){
//Output to new stream with old buffer (to e.g. screen [std::cout])
_newstream->write(msg, count);
//Output to log4cxx logger
std::string s(msg,count);
if (_logger->isInfoEnabled()) {
_logger->forcedLog(::log4cxx::Level::getInfo(), s, LOG4CXX_LOCATION);
}
return count;
}
private:
log4cxx::LoggerPtr _logger;
std::streambuf* _orgbuf;
std::ostream& _orgstream;
boost::scoped_ptr _newstream;
};
Then to use it:
std::cout << "This will just go to my console"<