TraceListener creates huge log files

If you've used the .Net trace listeners, you'll know that they just keep appending to the file specified in the App.Config file, this can lead to some massive log files! Here's a simple TraceListener that logs to a new file for every day.

using System;
using System.Text;
using System.IO;
using System.Diagnostics;

namespace myNamespace
{
    public class DailyTraceListener : TraceListener
    {
        private string _LogFileLocation = "";
        private DateTime _CurrentDate;
        StreamWriter _TraceWriter;

        public DailyTraceListener(string FileName)
        {
            _LogFileLocation = FileName;
            _TraceWriter = new StreamWriter(GenerateFileName(), true);
        }

        public override void Write(string message)
        {
            CheckRollover();
            _TraceWriter.Write(message);
        }

        public override void Write(string message, string category)
        {
            CheckRollover();
            _TraceWriter.Write(category + " " + message);
        }


        public override void WriteLine(string message)
        {
            CheckRollover();
            StringBuilder sb = new StringBuilder();
            sb.Append(DateTime.Now);
            sb.Append("##");
            sb.Append(Process.GetCurrentProcess().Id);
            sb.Append("##");
            sb.Append(AppDomain.GetCurrentThreadId());
            sb.Append("##");
            sb.Append(message);
            _TraceWriter.WriteLine(sb.ToString());
        }

        public override void WriteLine(string message, string category)
        {
            CheckRollover();
            StringBuilder sb = new StringBuilder();
            sb.Append(DateTime.Now);
            sb.Append("##");
            sb.Append(Process.GetCurrentProcess().Id);
            sb.Append("##");
            sb.Append(AppDomain.GetCurrentThreadId());
            sb.Append("##");
            sb.Append(category);
            sb.Append("##");
            sb.Append(message);
            _TraceWriter.WriteLine(sb.ToString());
        }

        private string GenerateFileName()
        {
            _CurrentDate = DateTime.Today;
            return Path.Combine(Path.GetDirectoryName(_LogFileLocation), Path.GetFileNameWithoutExtension(_LogFileLocation) + "_" + _CurrentDate.ToString("yyyyMMdd") + Path.GetExtension(_LogFileLocation));
        }

        private void CheckRollover()
        {
            if (_CurrentDate.CompareTo(DateTime.Today) != 0)
            {
                _TraceWriter.Close();
                _TraceWriter = new StreamWriter(GenerateFileName(),true);
            }
        }

        public override void Flush()
        {
            lock(this)
            {
                if (_TraceWriter != null)
                {
                    _TraceWriter.Flush();
                }
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _TraceWriter.Close();
            }
        }
    }
}

You can configure this by amending the App.Config file:

<system.diagnostics>
    <trace autoflush="true" indentsize="4">
        <listeners>
           <add name="myListener"  type="myNamespace.DailyTraceListener" initializeData="e:\logfiles\mylogfile.log" />
        </listeners>
    </trace>
</system.diagnostics>

So on the day of this submission this would create a file in e:\logfiles called mylogfile_20060726.log.

Author Lee Keable

Comments

splitDiff said:

' Here is a VB.Net version of your Daily Trace Listener.

' Thanks -- splitDiff

Imports System

Imports System.Text

Imports System.Threading

Imports System.IO

Imports System.Diagnostics

Public Class DailyTraceListener

    Inherits TraceListener
    Dim _LogFileLocation As String = ""
    Dim _CurrentDate As DateTime
    Dim _TraceWriter As StreamWriter


    Public Sub DailyTraceListener(ByVal FileName As String)
        _LogFileLocation = FileName
        _TraceWriter = New StreamWriter(GenerateFileName(), True)
    End Sub


    Public Overrides Sub Write(ByVal message As String)
        CheckRollover()
        _TraceWriter.Write(message)
    End Sub


    Public Overrides Sub Write(ByVal message As String, ByVal category As String)
        CheckRollover()
        _TraceWriter.Write(category + " " + message)
    End Sub


    Public Overrides Sub WriteLine(ByVal message As String)
        CheckRollover()
        Dim sb As StringBuilder = New StringBuilder()
        sb.Append(DateTime.Now)
        sb.Append("##")
        sb.Append(Process.GetCurrentProcess().Id)
        sb.Append("##")
        sb.Append(Thread.CurrentThread.ManagedThreadId().ToString())
        sb.Append("##")
        sb.Append(message)
        _TraceWriter.WriteLine(sb.ToString())
    End Sub


    Public Overrides Sub WriteLine(ByVal message As String, ByVal category As String)
        CheckRollover()
        Dim sb As StringBuilder = New StringBuilder()
        sb.Append(DateTime.Now)
        sb.Append("##")
        sb.Append(Process.GetCurrentProcess().Id)
        sb.Append("##")
        sb.Append(AppDomain.GetCurrentThreadId())
        sb.Append("##")
        sb.Append(category)
        sb.Append("##")
        sb.Append(message)
        _TraceWriter.WriteLine(sb.ToString())
    End Sub


    Private Function GenerateFileName() As String
        Dim _CurrentDate As Date = DateTime.Today
        Return Path.Combine(Path.GetDirectoryName(_LogFileLocation), Path.GetFileNameWithoutExtension(_LogFileLocation) + "_" + _CurrentDate.ToString("yyyyMMdd") + Path.GetExtension(_LogFileLocation))
    End Function


    Private Sub CheckRollover()
        If (_CurrentDate.CompareTo(DateTime.Today) <> 0) Then
            _TraceWriter.Close()
            _TraceWriter = New StreamWriter(GenerateFileName(), True)
        End If
    End Sub


    Public Overrides Sub Flush()
        SyncLock (Me)
            If Not (_TraceWriter Is Nothing) Then
                _TraceWriter.Flush()
            End If
        End SyncLock
    End Sub


    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        If (disposing) Then
            _TraceWriter.Close()
        End If
    End Sub

End Class

28/Sep/2007 23:56 PM

Dev1 said:

I get the following error:

"Couldn't find type for class namespace.DailyTraceListener."

22/Feb/2013 08:00 AM

Add Comment

Name
Comment
 

Your comment has been received and will be shown once it passes moderation.