Build a Custom TraceListener Class for
Program Logging Activity
By Peter A. Bromberg, Ph.D.

Peter Bromberg

"People that are really very weird can get into sensitive positions and have a tremendous impact on history." -- Dan Quayle

How many times do you wish you had an easy way to capture logging, debugging and other messages, from your running application, and have a way to view and sort the report of messages by category or time?



Enter the handy TraceListener Class. TraceListener provides the abstract base class for the listeners who monitor trace and debug output. There are already some useful implementations, namely the DefaultTraceListener , TextWriterTraceListener and the EventLogTraceListener classes that you can use. Or, as I have chosen here, you can use one of these and customize it even further, if its base functionality already does what you want. Or, you can implement a brand new invention of your own that derives from the abstract base class.

Typically TraceListeners are configured in the app.config or web.config file. However, they do not have to be. In fact, in many situations it may be both easier and cleaner to create your own custom class with static methods that requires no configuration at all. And, that's what I've chosen to do here. First, let's take a look at the implementation, which is extremely simple. I create a Custom TextWriterTraceListener derived from the supplied "stock" TextWriterTraceListener class. I only do this because I want it to automatically do a couple of handy things by default: First, I want my log in .CSV format, with delimited log lines so that I can easily load it into Excel and sort the rows by either time or category. And second, I want each of my logged events to automatically have the time prepended as its first Excel column. Now here's the code:

using System;
using System.Diagnostics;

namespace PAB.Utils
{ 
 public class CustomTextWriterTraceListener :TextWriterTraceListener
 {
  private static object dork = new Object();
  public   CustomTextWriterTraceListener(string file):  base(file)
  {                 
  }

  public CustomTextWriterTraceListener(string file, string name):base(file,name)
  {
  }

  public override void Write(string message)
  {
   lock(dork)
   {
    message=DateTime.Now.ToLongTimeString() + "," +message;
    base.Write(message);
   }
  }

  public override void WriteLine(string message, string category)
  {
   lock(dork)
   {    
    message=DateTime.Now.ToLongTimeString() + "," +message + "," + category;
    base.WriteLine (message);
   }
  }

  public override void Write(string message, string category)
  {
   lock(dork)
   {
    message=DateTime.Now.ToLongTimeString() + "," +message + "," +category;
    base.Write (message);
   }
  }

  public override void WriteLine(string message)
  {
   lock(dork)
   { 
    message=DateTime.Now.ToLongTimeString() + "," +message;
   base.WriteLine(message);
   }
  }
 }

 public class TraceLog
 {
  public static CustomTextWriterTraceListener myWriter;
   static TraceLog()
  {        
  myWriter =new  CustomTextWriterTraceListener(Environment.CurrentDirectory+"\\log.csv");
  Trace.Listeners.Add(myWriter);
  }
 }
}

And this is what the UI of my test harness looks like:

Here is how we call the methods:


private void button1_Click(object sender, System.EventArgs e)
{
  TraceLog.myWriter.WriteLine(this.txtMessage.Text,this.cboCategory.SelectedItem.ToString());
}

-- Pretty easy, wouldn't you say? No Installation, no fuss, no muss. Just make a static call and your log info is written. Later, when you are done you can call the Flush and the Close methods. Now here is how the Log looks in Excel when you press the sample "View Log" Button above:

As can be seen, everthing is nicely delimited into the desired columns, which you can now sort by either time and or category. Enjoy!

Download the Visual Studio.NET 2003 Solution accompanying this article

 


Peter Bromberg is a C# MVP, MCP, and .NET consultant who has worked in the banking and financial industry for 20 years. He has architected and developed web - based corporate distributed application solutions since 1995, and focuses exclusively on the .NET Platform.
Article Discussion: