Distributed applications almost always require a logging mechanism to log major events or errors to a logging service. These applications also require the logging solution to be highly available, reliable, and efficient.
In the following article a remote logging mechanism is discussed that uses .NET Queued Component framework for logging. .NET Queued Components provide an asynchronous, highly available, and guaranteed delivery functionality using COM+ queuing framework.
.NET Queued Components
A Queued Component is merely an object that runs asynchronously within COM+. The client of a queued component dynamically creates a proxy object for the deployed queued component. The proxy object works transparently as recorder and records all the methods invoked on the object. When released, this proxy object takes all method calls and builds a message that is sent to the server queue.
A COM+ listener at server side processes the messages in the server queue transparent to the client. It reads the message from the queue and invokes the method on the server object in the same order they were invoked at client side earlier. In case of errors during the method invocation, the method invocation is aborted and the message containing all the method calls is placed into a retry queue. If it fails on that retry, it is put into another retry queue. The intervals between retries are not configurable.
The message is placed into a special queue dead letter queue after five unsuccessful retries. Manual intervention of some type is required to successfully process or deal with such messages.
Proposed solution is based on a client and a server class. The sample code consists of a
LogServer class. A test application uses
LogClient to log messages in
LogServer class inherits from
ServicedComponent, which makes it run within
LogServer class also implements
ILogServer interface to enable queuing support.
public interface ILogServer
void LogEventMessage(string logString);
void LogExceptionMessage(string logString,byte arrBytes);
LogEventMessage() method logs a given message and
LogExceptionMessage() method logs a given caller name and an object of
ApplicationException as byte stream in log file.
LogServer Queued Component to log messages. The client's
LogExceptionMessage methods use a COM Moniker. A Moniker is a special name for a class that not only includes the class name, but also includes controlling information.
LogServer = (ILogServer)
The .NET Framework includes a special namespace
System.Runtime.InteropServices to deal with COM Interop, including COM Monikers. The
Marshal.BindToMoniker method comes from the
InteropServices namespace. It allows us to create an object from a COM Moniker.
MSMQ must be installed on the computer in workgroup mode in order to run the sample application. A batch file register.bat is included in the sample application package. Change this file according to your directory structure and run it to register the
LogServer queue. Start the LogServer from Component Services. Now run LogServerTest application to log messages.
Marshalling between client and server component is simpler for simple types like string, integers but complex types need to implement
IPersistStream interface for marshalling. I used byte stream to marshal an
ApplicationException object to server.
private byte ObjectToByteArray(Object obj)
if(obj == null)
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
At server side, un-marshalling is done by converting byte stream to an
private Object ByteArrayToObject(byte arrBytes)
MemoryStream memStream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(arrBytes, 0, arrBytes.Length);
Object obj = (Object) binForm.Deserialize(memStream);
Further details about .NET Queued Components can be found at MSDN. I hope this logging approach would be helpful.
- Source code last updated - 12/16/2002