Exception Management Application Block Sample...
From an upcoming INETA article, this demonstrates how to create a custom publisher using MSMQ.... Keep in mind that EMAB has been superceded by the Enterprise Integration Framework (EIF), but EMAB is extreemly lightweight, easy to use, and can feed EIF....
The following example illustrates using MSMQ to publish exceptions using a custom Publisher component.
To implement a custom publisher, one must create a class that implements the IExceptionPublisher interface. This interface requires you to implement the Publish method, which accepts three parameters:
exception
|
The Exception object to be published.
|
additionalInfo |
The additional contextual information associated with the exception.
|
configSettings
|
A NameValueCollection object that contains the exception management settings from the application’s configuration file |
In our example, we define the Publisher method as follows:
public class MSMQPublisher: IExceptionPublisher
{
void IExceptionPublisher.Publish(Exception exception, NameValueCollection additionalInfo, NameValueCollection configSettings)
{
From there, it’s as simple as implementing our MSMQ logic. One caveat: what happens if there is an exception in our custom publisher code, preventing the publishing to MSMQ? For that, we turn to the ExceptionManager.PublishInternalException method, which will publish the exception to the default publisher, which is the Windows application event log.
Our sample code follows:
using System;
using Microsoft.ApplicationBlocks.ExceptionManagement;
using System.Xml;
using System.Text;
using System.Collections.Specialized;
using System.Messaging;
namespace EMABMSMQ
{
public class MSMQPublisher: IExceptionPublisher
{
void IExceptionPublisher.Publish(Exception exception, NameValueCollection additionalInfo, NameValueCollection configSettings)
{
string msmqpath="";
string subjectprefix="";
string subject="";
string body="";
//Get the configuration information
if (configSettings != null)
{
//get the msmq path
if (configSettings["msmqpath"]!=null&&configSettings["msmqpath"].Length>0)
msmqpath=configSettings["msmqpath"];
//get the subject line prefix
if (configSettings["subjectprefix"]!=null && configSettings["subjectprefix"].Length>0)
{
subjectprefix=configSettings["subjectprefix"];
}
else
{
subjectprefix="EX_MGMT_AP_BLOCK Exception:";
}
}
//Throw another exception if no valid config found
if (msmqpath=="")
{
//we do not have a queue name, so revert to application event log
ExceptionManager.PublishInternalException(exception, additionalInfo);
}
//build the subject and contents of the msmq message
subject = System.DateTime.Now.ToString() + " ";
subject += subjectprefix;
subject += " ";
subject += exception.Source;
body += "Exception: " + " at " + System.DateTime.Now.ToString() + System.Environment.NewLine ;
body += System.Environment.NewLine;
body += "Exception Information" + System.Environment.NewLine;
body += System.Environment.NewLine;
body += exception.Message.ToString() + System.Environment.NewLine;
body += "Additional Information" + System.Environment.NewLine;
foreach (string i in additionalInfo)
{
body+= additionalInfo.Get(i) + System.Environment.NewLine;
}
body += "Stack Trace" + System.Environment.NewLine;
body += exception.StackTrace.ToString();
body += System.Environment.NewLine;
try
{
string mqPath = @".\" + msmqpath;
if(!MessageQueue.Exists(mqPath))
{
MessageQueue.Create(mqPath);
}
MessageQueue mq = new MessageQueue(mqPath);
mq.Label = subject;
mq.Send(body,subject);
}
catch (System.Exception myex)
{
//if we get an exception with MSMQ, revert to our default publisher
ExceptionManager.PublishInternalException (exception,additionalInfo);
}
}
}
}
Now, of course, we need to get this sucker working!
To do this, we make use of our application configuration file. This XML file is either called WEB.CONFIG (if using ASP.NET), or APP.CONFIG, if developing a standard windows forms application.
This file specifies a configSettings block, which in turn references our custom publisher. The custom publisher information includes the assembly name and type, as well as any specific parameters our publisher might need to complete its work.
Here’s our app.config (note this is bare bones, yours might vary):
<configuration>
<configSections>
<section name="exceptionManagement"
type="Microsoft.ApplicationBlocks.ExceptionManagement.ExceptionManagerSectionHandler, Microsoft.ApplicationBlocks.ExceptionManagement" />
</configSections>
<exceptionManagement>
<!-- Configure our publisher here -->
<publisher mode="on" assembly="Microsoft.ApplicationBlocks.ExceptionManagement" type="EMABMSMQ.MSMQPublisher"
<!-- specify the prefix for messages -->
subjectprefix = "MSMQ"
<!-- specify the msmq path here -->
msmqpath="private$\myexceptions"/>
</exceptionManagement>
</configuration>
In this example, we have two custom settings that our publisher needs, the subjectprefix, and the msmqpath.
In order to test our publisher, I’ve built a really simple Windows Forms application. The form has two buttons, one to test the MSMQ functionality (can we write to our MSMQ queue), and the other to cause an exception.
To run this example, make sure you’ve create an MSMQ queue on your system. Typically, this would be a private queue. In our case, we are using a private queue with the name myexceptions .
Here is the code to test MSMQ from the button event:
private void TestMSMQ_Click(object sender, System.EventArgs e)
{
string mqPath = @".\private$\myexceptions";
if(!MessageQueue.Exists(mqPath))
{
MessageQueue.Create(mqPath);
}
MessageQueue mq = new MessageQueue(mqPath);
mq.Label = "adam1";
mq.Send("we created this!","my subject");
}
And here’s the code to generate the exception:
private void GenerateException_Click(object sender, System.EventArgs e)
{
//assumes you don’t have a file called
//msmqdsfoo.xml in the root of drive C
System.Data.DataSet myds = new System.Data.DataSet();
try
{
myds.ReadXml(@"c:\msmqdsfoo.xml");
}
catch (System.Exception ex)
{
ExceptionManager.Publish(ex);
}
}
As you can see, creating a custom publisher allows you to log exceptions where you want them, and is very lightweight. You can even use a custom publisher in conjunction with the default publisher (the application event log), or hook it into the EIF to bubble exceptions up to the enterprise level. In fact, you can chain as many publishers as you want together!
Deploying the exception management assemblies can be done for each application individually, or to the Global Assembly Cache for shared use. See the documentation that comes with EMAB to determine any specific steps for each scenario.
Comments
- Anonymous
October 14, 2006
PingBack from http://www.jasonhyland.com/?p=61 - Anonymous
June 15, 2009
PingBack from http://unemploymentofficeresource.info/story.php?id=14669