So, I took a look at Boost.IOstreams and this is what I came up with:
class TestSink : public boost::iostreams::sink { public: std::streamsize write( const char * s, std::streamsize n ) { std::string message( s, n ); std::cout << message << std::endl; return n; } };
TestSink can be used to create a stream buffer (see stream_buffer-template ). Each thread will receive its own instance of TestSink , but all TestSinks will be written to the same log. TestSink used as follows:
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;
The important fact here is that TestSink.write is called only when the stream stream ( std::endl or std::flush ) or when the internal buffer of the stream_buffer instance stream_buffer full (the default buffer size cannot hold 40,000 characters, so I initialize it to 50,000 ) In this program, TestSink.write is called exactly once (the output is too long to publish here). This way I can write logmessage using standard formatted I / O stream without any temporary variables and make sure that the message is sent to the log in one fragment when I clear the stream.
I will leave the question open one more day if there are different suggestions / problems that I have not considered.
Bjรถrn pollex
source share