Wednesday, June 17, 2009

Custom DbTraceListener w/ Custom Exception Handler

This blog discusses how to have a database tracelistener which can log other information other than those which are provided by Enterprise Library's FormattedDatabaseTraceListener in conjuction with handling exceptions. Here are the steps:



1. Create a custom Log Entry:

public class CustomLogEntry: LogEntry

{

public string ContextId //this is the extra information i want to log

{

get;

set;

}

}



2. Create a custom exception handler which you can do either by implementing the IExceptionHandler interface or having your custom handler derive from the LoggingExceptionHandler as well.

[ConfigurationElementType(typeof(CustomHandlerData))]

public class MyLoggingExceptionHandler : LoggingExceptionHandler, IExceptionHandler

{

public override void WriteToLog(string logMessage, IDictionary data)

{

CustomLogEntry log = new CustomLogEntry(); // I created a CustomLogEntry

instead of a LogEntry



log.ContextId = Thread.CurrentContext.ContextID;

log.Message = logMessage;

log.Categories.Add(configAttributes["LogCategory"]);

log.Severity = System.Diagnostics.TraceEventType.Error;

foreach (DictionaryEntry dataEntry in exceptionData)

{

if (dataEntry.Key is string)

{

log.ExtendedProperties.Add(dataEntry.Key as string,

dataEntry.Value);

}

}

Logger.Write(log);

}

}



3. Create the custom database tracelistener which would log the LogEntry informations as well as those extra information available in a CustomLogEntry object.



4. Override the TraceData method of the CustomTraceListener. Check if the data parameter is an instance of a CustomLogEntry. If it is, call the Write(object o) method.



5. Override the Write(object o) method. This will be the place where you would create your DbCommand object and its parameters based on a CustomLogEntry object.



[ConfigurationElementType(typeof(CustomTraceListenerData))]

public class MyDatabaseTraceListener : CustomTraceListener

{

public override void TraceData(System.Diagnostics.TraceEventCache eventCache, string source, System.Diagnostics.TraceEventType eventType, int id, object data)

{

if (data is CustomLogEntry)

{

Write(data);

}

else

{

base.TraceData(eventCache, source, eventType, id, data);

}

}



public override void Write(object o)

{

CustomLogEntry myLog = o as CustomLogEntry;

Database db = DatabaseFactory.CreateDatabase();

DbCommand dbCommand = db.GetStoredProcCommand(

this.Attributes["WriteLogSp"]);

db.AddInParameter(dbCommand, "contextId", System.Data.DbType.Int32, (int)

myLog .Severity);

//add other parameters

db.ExecuteNonQuery(dbCommand);

}

}





That's it. If you want the full working example, you can mail me at pinkstarfish.305@gmail.com. I did hardcode some of the values but remember you can opt to include them in the Attributes collection property of the custom exceptionhandler and customtracelistener.

1 comment:

  1. Hi,

    A good post on Extending Enterprise Library. We are VA4World a virtual assistant firm who provide admin support service for SME’s all over the world. We would like to hear your feedback.

    Thanks,
    Sridhar – VA4World for viral marketing, SEO and admin support

    ReplyDelete