Hi Mike,
 
Thanks for the response. You are right there are multiple requirements on the logging system but I don't quite see how two loggers can solve the problem. It is:
 
>> simply logs the error for your non-techie operator?
 
which is the real driver for needing context. Its the operators only hope to being able fix the problem. It's not good enough to leave the exception message and the stack trace because it does not give state information about the object instances e.g.
 
Executing Model A1
Executing Model B7
Executing Model C2
Exception : Malformed TimeZone
 
is more useful than:
 
Model::Execute
Model::Execute
Model::Execute
Model::PrepareConfig
Exception : Malformed TimeZone
 
The operator can then go and check their C2 configuration.
 
There are of course workarounds for this dodgy example e.g. logging "Preparing configuration" before doing something or better error handling for configuration validation but being able to take advantage of the ndc context would be the fail-safe when either of the others have been omitted - which has happened.
 
thanks,
Duncan
 
 


From: Mike Raath [mailto:[EMAIL PROTECTED]
Sent: 30 June 2006 14:37
To: Log4NET User
Subject: Re: When to log, when to throw - Help!

It sounds like you have 2 different logging requirements, so why not have 2 different loggers? Use the standard FileAppender or similar to log the exception and full stack trace (you don't need to do any more than log usingg the error method, and have another that simply logs the error for your non-techie operator?

Both of these can be designed using the standard formatting strings and the advantage is that you can then alert for different error priorities.

On 6/30/06, Duncan Woods <[EMAIL PROTECTED]> wrote:
Hi Ron,

Thanks for reply.

>> I usually catch exceptions at higher levels (my user interface
>> or business layer) and let lower levels such as my data level
>> simple bubble the exceptions up.

Precisely what I do but almost all the error messages are unhelpful
without context. The following example gives a bit more of a feel for
the hierarchical multi part operations that include external plug-ins
(which also use log4net):

try
{
  foreach (service in Services)
  {
    using(NDC.Push("Updating service " + service.Name))
    {
      foreach (model in service.models)
      {
        using(NDC.Push("Executing model " + model.Name))
        {
            foreach (input in model)
          {
            using(NDC.Push("Extracting input " + input.Name))
            {
               // db
            }
              using(NDC.Push("Calculate " + model.Name))
            {
               // external calc
            }
          }
        }
      }
    }
  }
}
catch (Exception e)
{
  log.Error("Unexpected error. Cause: " + ex.Message, ex);
}

This works great for successful logging where each log message is
qualified with its own context but every exception is fatal so there are
few catch handlers. A typical framework exception like "Key not found"
from a dictionary object is useless at the top level but with an NDC an
error could be logged with:

"Updating service Foo, Executing model Bar, Extracting Input Dingo".

which gives a chance to resolve the problem. If they are my own
exceptions (lots are) then I could do this:

catch (NdcException e)
{
  using(NDC.Push(e.Ndc))
  {
    log.Error("Unexpected error. Cause: " + ex.Message, ex);
  }
}

where e.Ndc is the state of the Ndc at the throw minus the ndc at the
catch. I'd still have to wrap and rethrow non NdcExceptions at every
level of the Ndc hierarchy. I suppose that when not using a logging
framework I expect to catch, wrap and rethrow exceptions to give them
context anyway but I'm not satisfied with that given that there is an
Ndc sat there.

Thoughts?

http://logging.apache.org/log4net/release/manual/contexts.html

I need a thread context stack so I believe ndc is the best bet since its
handled by tools like ChainSaw.

Thanks,
Duncan



-----Original Message-----
From: Ron Grabowski [mailto:[EMAIL PROTECTED]]
Sent: 30 June 2006 01:45
To: Log4NET User
Subject: Re: When to log, when to throw - Help!

A good rule of thumb about exceptions is that if you can't do something
with the exception (i.e. handle it gracefully or recover from it) then
you shouldn't be catching it. I usually catch exceptions at higher
levels (my user interface or business layer) and let lower levels such
as my data level simple bubble the exceptions up.

What items are are you pushing onto the NDC?

When you talk about the NDC and catch blocks, are you doing this:

using(NDC.Push("test1"))
{
try
{
  generateApplicationException("Oh no!");
}
catch (Exception ex)
{
  log.Error("Unexpected error. Cause: " + ex.Message, ex);
}
}

Are you loosing the NDC inside of the catch block? Are you aware of the
other context objects:

http://logging.apache.org/log4net/release/manual/contexts.html

If you want to keep the contents of the NDC seperate from the logging
message itself, have you thought about creating a simple XML layout
that does that (the log4j schema may or may not already do this):

<log>
  <message>Unexpected error. Cause: Oh no!</message>
  <exception>
   ... ApplicationException ...
  </exception>
  <ndc>
   <item level="0">test1</item>
  <ndc>
</log>

Does that help any?

--- Duncan Woods <[EMAIL PROTECTED]> wrote:

> Hi all,
>
> I don't think I have grasped something basic about using error
> handling
> as I am having trouble integrating exceptions with logging. The goal
> of
> my logging is at high levels to be comprehensible to a non software
> engineer and provide sufficient information to fix any problem that
> has
> occurred. Exceptions are the default error handling of .Net and
> almost
> every object can throw them in some situation. Catch handlers around
> every call is not realistic but the level of detail I add to the NDC
> is
> sufficient.
>
> The problem is that if I log an exception message at the catch
> handler,
> I have lost the context of the NDC and the resultant log message is
> unhelpful. What are the other options? What design guidelines do you
> set
> down?
>
> i) Log the exception's call stack
>
>     This does not give presentable messages
>
> ii) Log and throw at the same time
>
>     This can cause the same message to be logged repeatedly through
> the
> hierarchy as the error ripples up to the top level. Ugly and harms
> admin's ability to use log4net to trigger actions based on trace
> message
> contents.
>
> c) Append the NDC to an exception message
>
>     Suffers from both the previous problems - its not nice that the
> NDC
> becomes part of them message and rethrowing an exception will cause
> multiple copies of the NDC.
>
>
> Thanks in advance for your ideas,
>
> Duncan

Reply via email to