redirect std::cout to a custom writer

前端 未结 5 1203
生来不讨喜
生来不讨喜 2020-12-08 18:14

I want to use this snippet from Mr-Edd\'s iostreams article to print std::clog somewhere.

#include 
#include 
#include 

        
5条回答
  •  甜味超标
    2020-12-08 18:22

    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"<

提交回复
热议问题