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