使用std :: cout添加时间戳

Sig*_*ont 5 c++ logging iostream

我有以下代码将我的std::cout输出重定向到日志文件.

std::ofstream out("out.txt");
std::streambuf *coutbuf = std::cout.rdbuf(); //save old buf
std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt!
Run Code Online (Sandbox Code Playgroud)

现在我想要的是,每当发生换行时,当前时间戳将被写入文件.

我知道我可以用以下方法实现:

std::cout << getTime() << "printing data" << std::endl;
Run Code Online (Sandbox Code Playgroud)

但我想要的是以std::cout某种方式自动处理它.那可能吗?

cpp*_*ger 10

我假设,如果下一行的第一个字符出现在输出中,则需要打印TimeStamp.获取一个新类并从std :: streambuf继承它,并以与使用filebuf相同的方式连接它.如果出现换行符,则将此事件存储在对象中.出现另一个字符将时间戳添加到流中.

我写了一个使用RAII习语连接streambuf的例子.

class AddTimeStamp : public std::streambuf
{
public:
    AddTimeStamp( std::basic_ios< char >& out )
        : out_( out )
        , sink_()
        , newline_( true )
    {
        sink_ = out_.rdbuf( this );
        assert( sink_ );
    }
    ~AddTimeStamp()
    {
        out_.rdbuf( sink_ );
    }
protected:
    int_type overflow( int_type m = traits_type::eof() )
    {
        if( traits_type::eq_int_type( m, traits_type::eof() ) )
            return sink_->pubsync() == -1 ? m: traits_type::not_eof(m);
        if( newline_ )
        {   // --   add timestamp here
            std::ostream str( sink_ );
            if( !(str << getTime()) ) // add perhaps a seperator " "
                return traits_type::eof(); // Error
        }
        newline_ = traits_type::to_char_type( m ) == '\n';
        return sink_->sputc( m );
    }
private:
    AddTimeStamp( const AddTimeStamp& );
    AddTimeStamp& operator=( const AddTimeStamp& ); // not copyable
    // --   Members
    std::basic_ios< char >& out_;
    std::streambuf* sink_;
    bool newline_;
};
Run Code Online (Sandbox Code Playgroud)

以下列方式调用此类的对象:

// some initialisation ..
{
    AddTimeStamp ats( cout ); // timestamp is active
    // every output to 'cout' will start with a 'getTime()' now
    // ...
} // restore the old streambuf in the destructor of AddTimeStamp
Run Code Online (Sandbox Code Playgroud)