Introduction
This is a trace listener that can be used over a network. I.e., if you have trace messages being written in your application and want to listen to them over the network, you can add a DLL in the bin directory of the app, add a few lines in the config file, and you are ready to listen remotely.
Background
I searched for some similar articles and the above one was close, but needed inclusion into the project being developed. I wanted to be able to have a pristine production service running without anything attached to it in the way of debugging and then, if needed, drop in a DLL and a few config entries and be able to listen to it.
Because of this, I'm not terribly worried about performance. That being said, I used OneWay WCF attributes so it doesn't wait for a response when writing each trace, it just dumps the message and continues.
Using the code
The good news is that in order to use it, you only need code similar to the below in your config file:
<system.diagnostics>
<trace autoflush="true" indentsize="4">
<listeners>
<add name="NetworkTraceListener"
type="NetworkTraceListener.TraceClient, NetworkTraceListener"/>
</listeners>
</trace>
</system.diagnostics>
<system.serviceModel>
<client>
<endpoint
address="net.tcp://localhost:8001/NetworkTraceListenerViewer/service"
binding="netTcpBinding" contract="ITraceServer" />
</client>
</system.serviceModel>
Points of interest
You'll need NUnit 4.0 to compile the solution - or remove the test project. To use, launch the WPF app which is the viewer and server, and then include the above and the compiled NetworkTraceListener.dll in the project you want to listen to. You should see the messages in the viewer application.
I used a static Start
and Stop
method on TraceServer
rather than an instance. This was for convenience to get this thing going quickly. If I used an instance class, I would need some way of getting the events from the WCF instance to the separate instance used to start/stop. I didn't foresee needing multiple viewers in the same process, so it seemed the simple way to go.
The TraceClient
does something unusual, in that it eats all exceptions. I didn't ever want a communication failure, listener being closed, etc. to cause an app to fail when all I wanted to do was listen to the trace messages. I didn't bother logging those issues because I'm not interested in them and because trying to do additional writing in a Trace listener has caused me some problems in the past.
WCF was very easy to use - I was very happy with how simple it was to setup network functionality without too much wrangling with ports and sockets and what not.
Here is the unit test which confirms that a server can be instantiated, a client can write a couple messages, and they are received:
[Test]
public void TestSingleStartStopWithSendOk()
{
int MessageCount = 0;
try
{
AutoResetEvent ServerStartWait = new AutoResetEvent(false);
TraceServer.ServiceListening +=
new TraceServer.ServiceListeningType(delegate(object o, EventArgs e) {
ServerStartWait.Set();
});
TraceServer.Start();
TraceServer.MessageReceived +=
new TraceServer.MessageReceivedType(delegate (string Message) {
MessageCount++;
});
ServerStartWait.WaitOne(20000, true);
TraceClient client = new TraceClient();
client.WriteLine("test1");
client.WriteLine("test2");
client.Flush();
Thread.Sleep(1000);
client.Close();
}
finally
{
TraceServer.Stop();
}
Assert.AreEqual(2, MessageCount);
}
ToDo
Add a "gratuitous animation" checkbox which enables Star Wars style scrolling trace messages as received. Possible "gratuitous audio" checkbox with theme music.
History
- 17-Feb-2008 - Initial version.