RE: [boost] Re: Re: Logging Library -- Formal Review Request

From: John Torjo [mailto:john.lists@torjo.com] I really don't understand why you'd want this. And more to the point, I'm really curious how you could implement this in C++:
// show what you want above. BOOST_LOG(app) << "result of f() " << f();
And finally, I don't know why you'd want the above. What if f() then calls g(), and so on, all this functions doing some logging. Would you actually prefer:
a.cpp:14: result of f() [100 lines of other logged messages] a.cpp:14: 1234
To:
[100 lines of other logged messages] a.cpp:14: result of f(): 1234
Best, John
I'd like to add use case. I think that log messages should be written as soon as possible. Use case: program crash only on specific machine that you can't debug on. If logs messages will not be written immediately they will be lost. In this case this logger is pretty useless. I think that if someone prefer to see
a.cpp:14: result of f() [100 lines of other logged messages] a.cpp:14: 1234
he should wrote "log viewer" that will handle this. Roman

I'd like to add use case. I think that log messages should be written as soon as possible. Use case: program crash only on specific machine that you can't debug on. If logs messages will not be written immediately they will be lost. In this case this logger is pretty useless.
Yep. That's another very importance point against any kind of cashing. Gennadiy

On 5/4/05, Roman Yakovenko <roman.yakovenko@actimize.com> wrote:
Would you actually prefer:
a.cpp:14: result of f() [100 lines of other logged messages] a.cpp:14: 1234
To:
[100 lines of other logged messages] a.cpp:14: result of f(): 1234
I'd like to add use case. I think that log messages should be written as soon as possible. Use case: program crash only on specific machine that you can't debug on. If logs messages will not be written immediately they will be lost. In this case this logger is pretty useless.
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". If you instead choose to use the ts_appender, messages will be collected over some configurable time interval (default 100 milliseconds) and written to the output file all at once. In this case you face the possibility of losing any messages which were logged during that interval. The choice of which method to use is entirely up to the user. Aside: write_to_file opens the target file for appending on *every* write call. I think this implementation should be changed. Perhaps by using a shared_ptr<ostream>? FWIW, I have seen a number of posts regarding the proposed Logging library from folks that don't seem to have actually tried out John's implementation. I'd suggest that you actually read the docs and try out the code before suggesting features that are already implemented.
I think that if someone prefer to see
a.cpp:14: result of f() [100 lines of other logged messages] a.cpp:14: 1234
he should wrote "log viewer" that will handle this.
I don't see how implementing this would even be possible. -- Caleb Epstein caleb dot epstein at gmail dot com

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. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

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() :-) 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 * 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. * Not that this is a ringing endorsement, but you'd do no better with printf ("The operation-which-might crash returned: %d\n", crashme()); I really think that some level of buffering is unavoidable. -- Caleb Epstein caleb dot epstein at gmail dot com

On 5/4/05, Caleb Epstein <caleb.epstein@gmail.com> wrote:
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.
Actually, a way just occurred to me immediately after sending this. The proxy object that holds the stream ref that is the target of op<< could hold a lock as well. Still, I don't like this idea. I prefer the current design with its incremental formatting of individual BOOST_LOG messages in a stringstream with flushing to the appenders when the message is complete. -- Caleb Epstein caleb dot epstein at gmail dot com

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;

On 5/5/05, Rob Stewart <stewart@sig.com> wrote:
In the general case, one might really need to write
if (logging this level, subsystem, etc.) { do various things including logging messages }
I think you can just use the safe bool conversion in the current loggers for this: if (debug) { do_whatever (); BOOST_LOG(debug) << "Did whatever"; } -- Caleb Epstein caleb dot epstein at gmail dot com

From: Caleb Epstein <caleb.epstein@gmail.com>
On 5/5/05, Rob Stewart <stewart@sig.com> wrote:
In the general case, one might really need to write
if (logging this level, subsystem, etc.) { do various things including logging messages }
I think you can just use the safe bool conversion in the current loggers for this:
if (debug) { do_whatever (); BOOST_LOG(debug) << "Did whatever"; }
Right, but with levels and such coming, it probably won't be quite that simple. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;
participants (4)
-
Caleb Epstein
-
Gennadiy Rozental
-
Rob Stewart
-
Roman Yakovenko