Threadsafe日志记录

时间:2009-12-09 10:03:20

标签: c++ logging streambuf

我想实现一个简单的类来记录来自多个线程。这样的想法是,每个想要记录东西的对象都会收到一个ostream-object,它可以使用通常的操作符来写消息。所需的行为是,在刷新流时将消息添加到日志中。这样,消息不会被来自其他线程的消息中断。我想避免使用临时字符串流来存储消息,因为这会使大多数消息至少是twoliners。正如我所看到的,实现这一目标的标准方法是实现我自己的streambuffer,但这看起来非常麻烦且容易出错。有更简单的方法吗?如果没有,你知道关于自定义streambufs的好文章/指南/指南吗?

提前致谢,

Space_C0wbo0y

更新

因为它似乎有用,所以我添加了自己的答案。

4 个答案:

答案 0 :(得分:5)

看看log4cpp;他们有多线程支持。它可以节省你的时间。

答案 1 :(得分:1)

所以,我看了一下Boost.IOstreams,这就是我想出的:

class TestSink : public boost::iostreams::sink {
public:
    std::streamsize write( const char * s, std::streamsize n ) {
        std::string message( s, n );
            /* This would add a message to the log instead of cout.
               The log implementation is threadsafe. */
        std::cout << message << std::endl;
        return n;
    }
};

TestSink可用于创建流缓冲区(请参阅stream_buffer-template)。每个线程都会收到它自己的TestSink实例,但所有TestSinks都会写入同一个日志。 TestSink的用法如下:

TestSink sink;
boost::iostreams::stream_buffer< TestSink > testbuf( sink, 50000 );
std::ostream out( &testbuf );

for ( int i = 0; i < 10000; i++ )
    out << "test" << i;

out << std::endl;

这里的重要事实是,TestSink.write仅在流刷新(std::endlstd::flush)时调用,或者在stream_buffer实例的内部缓冲区时调用已满(默认缓冲区大小不能容纳40000个字符,因此我将其初始化为50000)。在此程序中,TestSink.write只调用一次(输出太长,无法在此处发布)。这样我就可以使用普通格式化的流-IO编写logmessage而不需要任何临时变量,并确保在刷新流时将消息一起发布到日志中。

如果有不同的建议/问题,我会在另一天开启这个问题。

答案 2 :(得分:1)

你认为log4cpp太重了,你可以转而使用Boost.IOStreams吗?咦?

您可以考虑logog。它对POSIX,Win32和Win64是线程安全的。

答案 3 :(得分:0)

重新。你自己的回应。如果您正在使用它进行错误记录,并且在刷新流之前编程崩溃,那么您的日志记录有点无用,不是吗?