Exception Handling: Log and Notify Correlation

Topics: Exception Handling Application Block, Logging Application Block
Aug 15, 2007 at 4:35 PM
I'm using exception handling block in our app
in Data Access Layer ,I use "Data Access Layer" Policy to log ,catch and wrap the exception so a {handlingInstanceID} will generate by
App block.
In Business layer I Log and propagate Exception with App Block using "Business Layer" Policy so another {handlingInstanceID} will generate.
In business Facade I Log And Replace so again another {handlingInstanceID}.
As you see there are 3 times log if an exception raise from data access layer.
I can get rid of these redundant loging , because all exception that throw from Data Access Layer wrap in exception of type DataAccessException
or drived one,and same strategy for business layer.
So I can add DataAccessException type to "Business Layer" and "Business Facade" policy and do not include logging handler for it.
But when "Business Facade" policy Handle exception that raised from Data Access Layer , It will generate new{handlingInstanceID} for new exception (replaced exception) , And I will notify my user with wrong {handlingInstanceID} that there is no trace of it in my first log (in Data Access Policy).
I hope you can get that what do I mean of {innerExceptionHandlingInstanceID}.
so , has any one have any solution to get rid of multiple redundant log?

Thanks in advance

Aug 16, 2007 at 1:02 PM
Hi,

Is this a problem about redundant logging or traceability? I don't think the handlingInstanceID is meant to be used for traceability among different exception handling chains, so you'll need to use a different mechanism for this, like the the Tracer class...

Regards,
Fernando
Aug 16, 2007 at 1:46 PM
Hi Fernando,
Thanks for reply. As I see in Enterprise Library document and quick start sample , it seams that I should use {handlingInstanceID} when I notify my user about an exception, So the support staff will be able to trace the log with that.
So the problem raise when I use ExceptionPolicy.HandleException to handle Exception In DataAccess Layer (with "Data Access Layer" Policy that Log and throw new wraped exception), Also I use ExceptionPolicy.HandleException to handle exception in business Facad layer too, that will Replace the exception for security reason.
As you konw every HandleException will generate new {handlingInstanceID} , so if I want to keep relation between generated {handlingInstanceID} in Replace Exception policy in business Facade with one, that I loged in "Data Access Layer" Policy I have too log the exeption in "Business Facade" Policy again with its previous {handlingInstanceID} (included in its message) , And if I dont do this , user will see a {handlingInstanceID} that dose not exist in any log.

Regards,
Mohsen
Aug 16, 2007 at 2:15 PM
Hi,

I think you may have misinterpreted the documentation. The handling instance id is used to correlate the actions of the handlers on a single handling chain (i.e. a single invocation to the EHAB); this token of information does not bubble up outside of the EHAB, or even for different invocations of the EHAB.

As I mentioned before, the way to correlate different log entries is to use a Tracer. I'm aware this is a logging specific feature, but you should still be able to access the current activity id from your handlers or your end user UI.

Regards,
Fernando
Aug 18, 2007 at 11:34 AM
Edited Aug 18, 2007 at 4:04 PM
Hi Fernando,
Thank you again. My problem is not to correlate diffrent log, because I don't want to have redundant log for an exception.
but it is some kind of correlation. I use Tracer in following example. But I'am looking for a more clear way.


My code is something like this.

//Data Access Layer

DAL.A()
{
  • try
  • {
    • // Do something
  • }
  • catch(Exception ex)
  • {
    • if (ExceptionPolicy.HandleException(ex, "Data Access Layer")) // this policy will log and throw new wraped execption
      • throw; //of type DataAccessException or drived one
  • }
}


//Business Facade

BF.A()
{
  • try
  • {
    • new DAL().A();
  • }
  • catch(Exception ex)
  • {
    • if (ExceptionPolicy.HandleException(ex, "Business Facade")) // this policy will replace execption and do not log exceptions
      • throw; // of Type DataAccessException (redundant log)
  • }
}

you mean I should use something like this


//Data Access Layer

DAL.A()
{
  • try
  • {
    • // Do something
  • }
  • catch(Exception ex)
  • {
    • ex.Data["CurrentActivityID"]=Trace.CorrelationManager.ActivityId; //I do this because I want ActivityID appear in log
    • if (ExceptionPolicy.HandleException(ex, "Data Access Layer")) // this policy will log and throw new wraped the execption
      • throw;
  • }
}


//Business Facade

BF.A()
{
  • using (new Tracer("General"))
  • {
    • try
    • {
      • new DAL().A();
    • }
    • catch(Exception ex)
    • {
      • ex.Data["CurrentActivityID"]=Trace.CorrelationManager.ActivityId;
      • Exception replacedException;
      • if (ExceptionPolicy.HandleException(ex, "Bisuness Facade",out replacedException)) // this policy will replace execption and do not log exceptions
      • { // of Type DataAccessException (redundant log)
        • replacedException.Data["CurrentActivityID"]=Trace.CorrelationManager.ActivityId; // for using in UI to inform user
        • throw replacedException;
      • }
    • }
  • }
}

I didn't see any way to log ActivityID automaticaly, It seems that I need a token like {CurrentActivityID} in Formater.Template.
Or I have to write a custom handler or formater?

Best Regards,
Mohsen
Aug 18, 2007 at 2:43 PM
Hi,
I find a token {activity} in TextFormater, but I think it's missed in configuration utility text formater template's tokens list.
I have checked it and it worked.
So I can ommit ex.Data[CurrentActivityID]=Trace.CorrelationManager.ActivityId; lines
from above list.
Any idea to make above code more clear?

Regards,
Mohsen