I’ve seen several homemade logging mechanism used in various applications, and they all do their job, but every one of them seems to be very tightly coupled, and the source that does the logging must to changed to add a new logging destination. I’d like to share a method that my team uses in our code. When we wanted to get the information to another destination, the code doing the logging doesn’t have to know about it. First, we need an object to hold our logging information. I’ll call it TraceEntry:
using System;
using System.Collections;
using System.Diagnostics;
using System.Text;
namespace ConsoleTestHarness
{
public class TraceEntry
{
protected string m_message = string.Empty;
protected DateTime m_createdOn = DateTime.Now;
protected TraceLevel m_entryLevel = TraceLevel.Info;
protected Type m_caller;
public string Message{
get { return m_message; }
}
public DateTime CreatedOn{
get { return m_createdOn; }
}
public TraceLevel EntryLevel{
get { return m_entryLevel; }
}
public TraceEntry(string message, TraceLevel entryLevel, Type caller){
m_message = message;
m_entryLevel = entryLevel;
m_caller = caller;
Trace.Write(this);
}
// For the default trace listeners, this method will be called implicitly.
public override string ToString() {
StringBuilder builder = new StringBuilder();
builder.Append(m_createdOn.ToString().PadRight(22));
builder.Append(m_caller.Name.PadRight(15));
builder.Append(m_entryLevel.ToString().PadRight(9));
builder.Append(m_message);
return builder.ToString();
}
}
}
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using Dell.Titans.Framework.Diagnostics;
namespace ConsoleTestHarness
{
class TestHarness
{
[STAThread]
static void Main(string[] args)
{
Trace.Listeners.Add(new CustomTraceListener());
new TraceEntry(“This is a message”, TraceLevel.Verbose, typeof(TestHarness));
Console.ReadLine();
}
}
}
using System;
using System.Diagnostics;
namespace ConsoleTestHarness
{
public class CustomTraceListener : TraceListener
{
public override void Write(object o) {
// If we know what this object is, we can work with it.
if(o is TraceEntry){
TraceEntry entry = o as TraceEntry;
// Pull out the pieces of the object and log them where you wish.
Console.WriteLine(entry);
}
}
public override void WriteLine(object o) {this.Write(o);}
public override void Write(object o, string category) {this.Write(o);}
public override void WriteLine(object o, string category) {this.Write(o);}
// abstract method implementations.
public override void Write(string message) {}
public override void WriteLine(string message) {}
}
}