
From: Caleb Epstein <caleb.epstein@gmail.com>
On 5/4/05, Rob Stewart <stewart@sig.com> wrote:
From: Caleb Epstein <caleb.epstein@gmail.com>
If one uses the supplied write_to_file appender, the messages will be written to the output file as soon as they are complete. So for example,
BOOST_LOG(debug) << "Wrote " << len << " bytes to socket fd " << fd;
would write a single message like "Wrote 56 bytes to socket 3" or nothing at all (e.g. if the application crashed sometime in the middle of formatting the message). I think this is eminently reasonable and hardly "useless".
The point is not so clear if the expression following BOOST_LOG() includes side effects that cause the application to crash, for example.
If the stream provided by BOOST_LOG() were unbuffered, then output would be flushed as soon as it was formatted, so you'd get output up until the point of the crash. Any buffering means that the buffered output is lost when the app crashes.
Without some sort of buffer between message formatting and message output, how do you allow multiple threads to write to a log without intermingling their messages? Locking on every op<< isn't good enough. Are you really that concerned about losing a single log message in a crash scenario? Perhaps if its something like "The reason I'm crashing is " << e.what() :-)
I was raising a flag as to a problem scenario and suggesting that there are multiple forces to be balanced to reach an optimum solution. Furthermore, I was suggesting that calling code with side effects *in* the log expression is fraught with peril. In the general case, one might really need to write if (logging this level, subsystem, etc.) { do various things including logging messages }
Bear in mind:
* If you are really concerned that the operations you're invoking are fragile, you can split them across multiple calls to BOOST_LOG
That needs to be highlighted.
* John has agreed to add exception guards to the logging macro(s). Perhaps something like the Boost.Test execution monitor that catches SIGSEGV etc could be optionally put in place as well.
Interesting.
* Not that this is a ringing endorsement, but you'd do no better with printf ("The operation-which-might crash returned: %d\n", crashme());
Right.
I really think that some level of buffering is unavoidable.
As do I. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;