std.log available for viewing

Jose Armando Garcia jsancio at gmail.com
Tue May 31 11:10:20 PDT 2011


On Tue, May 31, 2011 at 2:34 PM, Steven Schveighoffer
<schveiguy at yahoo.com> wrote:
> On Tue, 31 May 2011 12:28:12 -0400, Jose Armando Garcia <jsancio at gmail.com>
> wrote:
>
>> On Tue, May 31, 2011 at 11:28 AM, Steven Schveighoffer
>> <schveiguy at yahoo.com> wrote:
>>>
>>> On Sun, 29 May 2011 16:57:52 -0400, Brad Roberts <braddr at puremagic.com>
>>> wrote:
>>>
>>>> On 5/29/2011 8:44 AM, Andrei Alexandrescu wrote:
>>>>>
>>>>> 1. The fatal log should never be stripped. This is because execution of
>>>>> code after using fatal depends on compile-time
>>>>> flags, which is unacceptable. Logging to fatal should terminate the
>>>>> application regardless of circumstances. Otherwise
>>>>> people would need to write things like:
>>>>>
>>>>> fatal("blah");
>>>>> assert(0, "Execution cannot continue even though logging is stripped");
>>>>>
>>>>> This is needless and bug-prone. Fatal is fatal.
>>>
>>> Fatal can be with context.  Let's say you have one thread that hits a
>>> fatal
>>> error, and another thread which is finishing out a DB transaction.  Since
>>> logging the fatal error will kill the whole application, I now would have
>>> to
>>> write some sync function that all threads have to periodically call to
>>> make
>>> sure I don't kill some perfectly valid process that's unrelated to the
>>> fatal
>>> error.  This seems like way more work to me than assert(0).
>>>
>> For some applications fatal makes sense for others critical is better
>> and for others error is better. Use the one that fits your application
>> or library. Having said that you can replace the assert(false) by
>> using a fatal handler the only requirement on this handler is that it
>> doesn't return or throw; otherwise std.log will assert(false).
>
> Again, this sounds way too complicated for what it's giving you (avoiding
> having to forcibly kill your application if that's what you desire).  If I
> had to choose from your options, I'd use neither critical nor fatal.  I'd
> probably just stick with the higher levels, and start putting my own levels
> in as strings to avoid what I'd consider to be "buggy" behavior...
>
> From my own experience, I almost never *never* use a forced kill.  A
> graceful shutdown works much better.  Remember that a 'fatal' error is not
> so much a "this program can't continue because it's not sane," but a "this
> program cannot continue because something is misconfigured, etc."  This does
> not warrant raw destruction.
>

That is probably because most programmers write web application in
which independent request/processing are all handle by the same
process. So by definition since requests are independent it is unfair
for one request to affect another request (by asserting) because they
share the same process.  Not everyone writes application using that
model. If your programming model is such (or architecture if you
prefer that word ;), then yes using fatal("") is not wise but maybe
critical("") and error("") is.

Let say instead you are writing a multi-process embedded system for
the mars-rover and your subsystem deals with propulsion then maybe you
do want to fatal("") or assert(false) instead of driving down a cliff
even though the camera sub-system wants to take a picture of a pretty
rock.

> A better option is to make the default "handler" assert(0), and let you
> override that when you set a new one.  This should not be too difficult
> (only need assert(0) in one place).
>
> Flexibility in this regard is way more valuable than consistency between
> applications.  I don't see the reasoning for the hard requirements.  Is it
> simply because it's this way in glog?
>

This is a matter of who makes the decision and has the domain
knowledge. I say that the decision if something should assert or throw
or just logs is up to the module coder. The coder that wrote fatal("")
for example. Not the person that configures the logger/writer which in
many systems knows nothing about the intricacies of the application or
modules.

>>>> At one time I used a log framework that included this behavior.  After a
>>>> couple years, I came to greatly regret it.
>>>> Fatalness down in libraries became overused, particularly in layers that
>>>> were libraries.  In some ways it was abuse of
>>>> fatal for things that shouldn't have been, but it's mere existence
>>>> encouraged it's use.
>>>>
>>>> I really don't think it's the log libraries job to implement app
>>>> termination behavior.
>>>
>>> Would it be possible to provide a "non-action" logger implementation?  It
>>> seems that the logger instantiation is customizable on the call to
>>> initializeLogging.  I'd say that should be the default as well (if you
>>> want
>>> certain actions, you can select the more proactive one).
>>>
>> This is not possible. Can you please motivate you requirement? The
>> intent is that some of the semantic of fatal, critical, error,
>> warning, info and verbose is set by the frontend to std.log and it
>> doesn't change when the user changes the backend. I want to give the
>> user some kind of guarantee on how the library behaves.
>
> Sure, the requirement is that the logger never ever alters my program's
> behavior without my permission.  I'm using the logger to log data, not to
> create code paths.  If I want a function that logs a message and then halts
> the application, I can write one of those (you can even include it as part
> of std.log!).  It's like having fopen halt your application if it can't open
> a file.
>

As a exercise, try to write such a function that gives you the same
flexibility of std.log. E.g. willLog, when(), compile time disabling,
etc. and I think you will end up with something similar to std.log!

> Essentially I think it is an egregious mistake to tie whole-application
> functionality to logging.  I don't care of the convenience, a logger is for
> logging, nothing else.  For sure, if std.log implements mandatory halting,
> my belief is another competitor log library will certainly get the lion's
> share of users, even if it's third party.
>

I would like to be flexible and meet your requirements but what is the
problem of not using fatal if you don't want to assert and not using
critical if you don't want to throw and instead use error if you just
want to log?

> -Steve
>


More information about the Digitalmars-d mailing list