i want to prepare log message and store it in something.
then pass this something to function ,which apply << to this something putting it into BOOst_LOG macro.
i need this because i put this log to several backends using several loggers .
i read about formatting_ostream but all examples show overloading of << ,during this it takes lvalue reference to formatting_ostream. i wonder where is formatting_ostream created??.
can i do this:
boost::log::formatting_ostream os << "Request #" << this->GetId() << " for " << mUrl << " has been cancelled by the user at start of execute coroutine." << std::endl;
boost_log_function(mHTTPRequest_LoggingInstance_shared_pointer);
then :
BOOST_LOG(*loggerChannel_cancelExecute.get()) << os;
First, you don't need to output a log record in multiple loggers in order to have it processed in multiple sink backends. As long as the record is not rejected by filters, every log record is processed in all sinks, regardless of which logger was used to produce it. If you purposely arrange filters and attributes in loggers so that records from one logger are only processed in one sink (e.g. by using channels), you could also arrange them in a way that allows records from other loggers not associated with particular sinks to be processed in all sinks. This is much more efficient than generating multiple records in different loggers because it avoids overhead of creating extra log records and applying filters to them.
Now, to directly answer your question, the formatting_ostream
object that is passed to various functions is created by Boost.Log. Exactly where it is created depends on the function in question. For example, the stream that is passed to formatters is created as part of the sink frontend implementation.
You can create formatting_ostream
, but you need to remember the following:
formatting_ostream
constructor. That string must stay alive for the whole lifetime of the stream object.std::string str;
boost::log::formatting_ostream strm(str);
strm << "Request #" << this->GetId() << " for " << mUrl
<< " has been cancelled by the user at start of execute coroutine.";
strm.flush();
BOOST_LOG(*loggerChannel_cancelExecute.get()) << str;
However, you are not required to use formatting_ostream
in the first place. You can compose the string in any way you want, including std::ostringstream
, Boost.Format or even std::snprintf
.
You should know though that pre-composing the message string like this may be bad for performance. If a log record is discarded by filters, the streaming expression is not evaluated at all. But your code that pre-composes the message is always evaluated, even if the log record is discarded afterwards.