Search code examples
c#wcfloggingenterprise-librarytrace-listener

Enterprise Library Logging: Custom trace listener which sends messages to arbitrary WCF endpoint


I'm trying to write a custom trace listener for Enterprise Library Logging which sends all log messages to an arbitrary WCF endpoint. The idea behind this is that I can set up a simple console app, etc at the other end which prints out all log messages in real time.

My question is in two parts:

  1. Is there a mechanism to do this already? I already looked at the MSMQ listener and I'm not interested in using that because I may have a need to use a different protocol/binding at some point.
  2. The way I have it implemented below - is it efficient enough or is there a better way? My concern is that every time a message comes through from the Logger (which may be frequent) I'm opening a new channel and then slamming it shut. Will this cause performance issues?

In my sample RemoteClient derives from ClientBase<T>.

[ConfigurationElementType(typeof(CustomTraceListenerData))]
public class RemoteTraceListener : CustomTraceListener
{
    public override void Write(string message)
    {
        RemoteClient client = new RemoteClient();
        client.Open();
        client.Write(message);
        client.Close();
    }

    public override void WriteLine(string message)
    {
        RemoteClient client = new RemoteClient();
        client.Open();
        client.WriteLine(message);
        client.Close();
    }

    public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data)
    {
        if (data is LogEntry && this.Formatter != null)
        {
            WriteLine(this.Formatter.Format(data as LogEntry));
        }
        else
        {
            WriteLine(data.ToString());
        }
    }
}

Solution

  • I found an open-source project called 'CLog' which does exactly what I'm looking for: http://clog.codeplex.com/.

    A brief glance at the source code shows that he's using a singleton object to keep track of all the open channels that will receive log messages, and he's going with ChannelFactory<TChannel> as opposed to ClientBase<T> to instantiate each channel proxy. There are some threading implications that need to be addressed but I still think this is the way to fly.

    It shouldn't be too hard to use this as a starting point for the implementation of my own custom trace listener which logs to WCF endpoints.