I would like to write a convinient interface to my very simple logging library. Take two following pieces of code. The first one is what I do now, the second one is my idea for an intuitive interface:
std::ostringstream stream;
stream<<"Some text "<<and_variables<<" formated using standard string stream"
logger.log(stream.str()); //then passed to the logger
And
logger.convinient_log()<<"Same text "<<with_variables<<" but passed directly";
My thought-design process behind that idea is to return some kind of temporary stringstream-like object from logger.convinient_log()
function. That object on destruction (I hope it happens at the end of the line or in a similar, convinient place) would collect string from itself and call an actual logger.log()
. The point is I want to process it whole, not term-by-term, so that log() can add eg. prefix and sufix to whole line of text.
I'm very well avare that it might be straight impossible or impossible without some heavy magic. If that's the case, what would be an almost-as-convinient way to do that and how to implement it? I bet on passing some special variable that would force collect-call-logger.log()
operation.
If you don't know an exact answer, resources on the topic (eg. extending stringstream) would be also welcome.
Here's a class I've togeather a while ago. It sounds like what you're looking for is this. I was able to achieve it without any daunting inheriting of ostreams, stream_buf or anything else. You can write to files, console, sockets, or whatever you want whenever a flush is caught.
It doesn't work with ostream_iterators but handles all of the io_manip functions well.
Usage:
Implementation
This is how Boost.Log works, for example. The basic idea is simple:
std::uncaught_exceptions()
is used to avoid logging an incomplete message if an exception is thrown in the middle.Create a custom class derived from
std::basic_streambuf
to write to your logger, eg:And then you can instantiate a
std::basic_ostream
object giving it a pointer to aLoggerBuf
object, eg:Alternatively, derive a custom class from
std::basic_ostream
to wrap yourLoggerBuf
class, eg: