Rolling over TextWriterTraceListner logs
Do you utilize the Trace and Debug classes from the
System.Diagnostics namespace? Do you use a TextWriterTraceListener to log
your messages? Have you ever wondered why the TextWriterTraceListener
doesn't have the ability to roll over its logs at certain intervals?
I've developed a number of server-based applications
in which we employed the abilities of the System.Diagnostics classes to trace
certain application events. Whether its for debugging purposes or to
report unexpected events. Its easy enough to utilize the
TextWriterTraceListener to capture these messages and easily view them when
needed. Depending on what types of events your tracing and at what levels
your tracing at (see TraceSwitch), the trace log can get quite large
for a server-based application. I would find it very beneficial if
the TextWriterTraceListener would roll over its logfile at certain intervals,
say on a weekly, daily, or hourly basis. One of my mottos is: If it
doesn't exist, build it!
Here is a simple wrapper for the
TextWriterTraceListener that rolls over each day. I'm a little reluctant
in posting source code on a blog because I know there are some people who will
look at it and say, "Why on earth did you do it that way, you idiot!". But
that's allright. I can take the criticism. As a matter of fact,
that's why I'm posting this. For one, I want to share this with whomever
finds it useful and I also want someone to pick it apart and start a dialogue to
discuss if there's a better solution.
There is one question I hope the blog community
can help me come to a conclusion on. What happens when the log file rolls
over and another process is trying to write a trace message during the
rollover? Does that message get lost? Can I solve it through thread
synchronization? Is this even an issue?
Anyhow... here's the code for the
RollOverTextWriter:
using
System;
using System.Diagnostics;
using System.IO;
namespace
Corgan
{
public class RollOverTextWriter:
System.Diagnostics.TraceListener
{
string _fileName;
System.DateTime _currentDate;
System.IO.StreamWriter _traceWriter;
public
RollOverTextWriter(string
fileName)
{
// Pass in the path of the logfile (ie.
C:\Logs\MyAppLog.log)
// The logfile will actually
be created with a yyyymmdd format appended to the
filename
_fileName =
fileName;
_traceWriter =
new
StreamWriter(generateFilename(), true);
}
public override void Write(string value)
{
checkRollover();
_traceWriter.Write(value);
}
public override void WriteLine(string value)
{
checkRollover();
_traceWriter.WriteLine(value);
}
private string
generateFilename()
{
_currentDate =
System.DateTime.Today;
return
Path.Combine(Path.GetDirectoryName(_fileName),
Path.GetFileNameWithoutExtension(_fileName) + "_"
+
_currentDate.ToString("yyyymmdd") + Path.GetExtension(_fileName));
}
private void
checkRollover()
{
// If the date has changed, close the current stream and create a new
file for today's date
if
(_currentDate.CompareTo(System.DateTime.Today) !=
0)
{
_traceWriter.Close();
_traceWriter = new
StreamWriter(generateFilename(), true);
}
}
protected override void Dispose( bool disposing )
{
if( disposing
)
{
_traceWriter.Close();
}
}
}
}