Developer

Custom publishers for the Exception Management Application Block

A distributed application that stores its exception log on each individual machine is pretty worthless. Use the Exception Management Application Block and your SQL Server to create a centralized store for all exceptions in your application.


In a previous article, I discussed how Microsoft’s Exception Management Application Block (EMAB) made it easy to log exceptions using a single line of code. To review, important EMAB features include:
  • Single-line exception logging in your application
  • The ability to turn EMAB on and off without recompiling the application
  • The ability to log to any source, although this requires some extra effort
  • The ability to change some logging features without recompiling the application
  • Full access to the EMAB source code

One of the potential drawbacks to EMAB is that by default, it logs to the Application Log on the computer where the application is running. If you've got a distributed application running on a number of desktop machines, this means exceptions are recorded in the local application logs on those machines, which leaves the developers completely unaware there are any problems with the application.

Fortunately, EMAB is extensible, allowing you to create custom publishers. The EMAB document discusses logging to text files, but that doesn’t seem too exciting. Instead, it might make more sense to log to a centralized server such as a SQL Server database.

Creating the custom publisher
In order to create the custom publisher, you inherit either the IExceptionPublisher or IExceptionXmlPublisher. You get the interfaces as part of the EMAB projects you download (see previous article for more on downloading and building the EMAB projects).

To create a custom publisher, you start a new Class Library project in Visual Studio .NET. Add a reference to the Microsoft.ApplicationBlocks.ExceptionManagement.Interfaces DLL. This DLL contains the two interfaces mentioned above, one of which must be inherited by your component.

After adding the reference to the DLL, add the following line to the top of the file:
Imports Microsoft.ApplicationBlocks.ExceptionManagement

In order to work with the data that is returned from the ExceptionManager, you’ll also want to add the following line just after the previous one:
Imports System.Collections.Specialized

Other Imports will be used in this project, as you can see in the full code listing (Listing A).

Next, you will create a class. In my example, I call it myCustomPub. After declaring the class, you implement the interface with this line:
Implements IExceptionPublisher

You could also implement IExceptionXmlPublisher if you prefer to receive exception details in XML format.

As soon as you implement the interface, Visual Studio gives you the skeleton for the Publish method you must implement. Publish is the only method you need to worry about, thanks to the simplicity of the EMAB.

The Publish method accepts three parameters. The first parameter is of type System.Exception, which is the same exception you capture normally using the Try…Catch syntax. The second argument is AdditionalInfo and comes in the form of a NamedValueCollection; this is why you imported the SystemCollections.Specialized namespace. Finally, the last argument is ConfigSettings and allows you to modify the custom publisher from a configuration file.

In this simple example, you’ll also see an Imports statement for System.Data.SqlClient because the code will publish exception information to SQL Server. The ConnectionString is very simple; you’ll want to modify it based on your environment.

You’ll want to process the AdditionalInfo that is passed to you. The easiest way is to move through the collection and build a string with the information. This code loops through the collection and uses a StringBuilder in order to build a string with all the additional information:
If Not additionalInfo Is Nothing Then
    For Each i As String In additionalInfo
       sbAddInfo.AppendFormat("{0}: {1};", _
           i, additionalInfo.Get(i))
    Next
End If

At this point, you have an Exception that was passed in, and all the AdditionalInfo has been saved into a string. Because the Exception is a standard .NET Exception, you can use the properties to pull various pieces of information out of it. You can format this data in any way necessary. In this simple example, you have a SQL Server table created with the fields to hold the necessary information. The code for the SQL table looks like this:
CREATE TABLE [dbo].[ExceptionLog] (
       [ExcID] [int] IDENTITY (1, 1) NOT NULL ,
       [ExcMessage] [nvarchar] (255) NULL ,
       [ExcSource] [nvarchar] (255) NULL ,
       [ExcTargetSite] [nvarchar] (255) NULL ,
       [ExcAddInfo] [text] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

Note that there are three fields of 255 characters and one text field of “unlimited” length. These lengths might not be adequate for all applications.

After creating the table, your complete code to insert records can be seen in Listing A.

You have now created a custom publisher that publishes exception information to a centralized SQL Server. Now, you must hook this custom publisher up to your client application.

Configuring the client
The client application uses EMAB just as it did previously. You’ll want to add a reference to the Microsoft.ApplicationBlocks.ExceptionManagement namespace. Then, you’ll be able to use the Publish method in order to log exceptions. You’ll also need to reference the assembly holding the custom publisher. Assuming you compiled the code above into an assembly called myPublisher.dll, you’d reference that assembly in your client application. You then code the application as normal.

In order to use the custom publisher, you do not change anything in the application; instead, you simply modify the app.config file. The key is the exceptionManagement section. If your assembly is named myPublisher.dll, your exceptionManagement block should look like this:
<exceptionManagement>
    <publisher mode="on" assembly="myPublisher"
         type="myPublisher.myCustomPub" />
</exceptionManagement>

A word of caution: our column wrap in this article may make it look like two lines but the publisher attribute must all be on one line!

Now, you can run the application, and any exceptions will be logged into the database. Figure A shows you the result of an Overflow Exception being caught and recorded in the database.

Figure A
An overflow exception caught and recorded in the SQL Server database


Microsoft’s Exception Management Application Block is a tool for helping you automate and standardize the logging of exceptions from your .NET applications. With its support for creating custom publishers, you have the flexibility to send exceptions to a variety of places: event logs, e-mail clients, databases, just about anywhere you want.

Editor's Picks