Rolling File Trace Listener Extension for Enterprise Library 2.0

Rolling File Trace Listener


Erwyn van der Meer, LogicaCMG
Based on Rolling File Sink by Hisham Baz, Avanade

Download v0.5.2.0 source code + documentation. The source code and documentation are provided "AS-IS". Feel free to change and/or extend them. Please contact me or leave a comment if you find an issue.


Last updated: April 18, 2006


Overview


This article describes the RollingFileTraceListener extension of the Logging block of version 2.0 of the Microsoft Enterprise Library.  This is a custom trace listener that can be plugged into the Enterprise Library Logging block like the standard trace listeners that are included. The FlatFileTraceListener shipped with EntLib 2.0 may not be adequate for enterprise systems since log files by default will continue to grow unchecked.  This new trace listener provides support for rolling over log files based on age of the log file or file size.


Usage


The ZIP file contains a Visual Studio 2005 solution and projects with C# sources that are fully documented with XML comments. Extract the ZIP file, open the EnterpriseLibraryExtensions.sln solution in Visual Studio 2005 and build the solution. This will create the assemblies for the RollingFileTraceListener and a test application.


In Windows the maximum path + filename length for a file is 260 characters. Please ensure you extract the ZIP file into a directory with a path that is less than 82 characters in length. Otherwise you will get a compilation error because during compilation Visual Studio will create an intermediate file with a really long name for which the path exceeds the limit of 260 characters.


In order to use the new trace listener from the Enterprise Library Configuration tool, you must copy the assemblies into the same directory as the configuration tool. There are two files that need to be copied - LogicaCMG.EnterpriseLibraryExtensions.Logging.dll and LogicaCMG.EnterpriseLibraryExtensions.Logging.Configuration.Design.dll.  When these files are in the same directory, they will be registered during the startup of the tool. This will allow you to add a new Rolling File Trace Listener from the right-click context menu on the Trace Listeners collection node.


Screenshot of how you can add a RollingFileTraceListener to an application configuration file using the Enterprise Library Configuration Console.


Configuration


The trace listener creates a new log file when the current file exceeds defined thresholds.  The RollingFileTraceListener provides file age and file size thresholds that can be configured using the Enterprise Library Configuration tool like any other trace listener.


Screenshot of the configuration properties that can be set for a RollingFileTraceListener.


 The RollingFileTraceListener has the following properties



  • Filename – filename with optional relative or full path
  • Header – string (optional)
  • Footer – string (optional)
  • MaximumLogFilesBeforePurge – integer
  • Timestamp Format – string, e.g., yyyy-MM-dd [HH:mm:ss]  (optional)
  • Age Threshold - integer
  • Age Unit – None, Minutes, Hours, Days, Weeks, Months
  • Size Threshold – integer
  • Size Unit – None, KB, MB, GB

Design


The RollingFileTraceListener uses a database-style log roll-over process.  All new log entries are written to the file defined in the FileName property.  Before a log entry is written, the trace listener checks to see if the file has grown too big or the age limit has expired.  If the current log file exceeds the size or age threshold, then the log file is renamed with the current timestamp or an incremental counter.  The new file is created with the same name defined in FileName. So the current log file always has the same name.


Age Threshold


The age threshold allows you to limit the growth of your log files according to age.  The threshold is compared by evaluating the current date/time against the log file creation date/time.  For example, if the log file was created on 1/1/2006 at 3PM and the age threshold was set to 2 days, a new log file will be created for the first log entry written after 1/3/2006 at 3PM.


There are two properties that control the age threshold behavior – AgeThreshold and AgeUnit.  Select the appropriate unit size first – None, Minutes, Hours, Days, Weeks or Months - by setting the AgeUnit property.  Set the AgeThreshold property to 0 or the AgeUnit to None to disable the age threshold check.


Size Threshold


In addition to age threshold, you can limit log file growth based on file size


There are two properties that control the age threshold behavior – SizeThreshold and SizeUnit.  Select the appropriate unit size first – None, Kilobytes, Megabytes or Gigabytes - by setting the SizeUnit property.  Set the SizeThreshold property to 0 or the SizeUnit to None to disable the file size threshold check. 


Combination Thresholds


Both the age and size thresholds can be applied at the same time.  For example, logs can be configured to roll-over every week or earlier if the file grows over 10MB. To accomplish this, set the AgeUnit to Weeks, AgeThreshold to 1, SizeUnit to Megabytes and SizeThreshold to 10.


Filename Formatting


When log file exceeds the defined thresholds, it is given a new unique name.


The TimestampFormat property can be used to define a date-time format string used for generating new file names.  This allows overgrown or overaged log files to be renamed and stamped with the current timestamp. The timestamp is appended to the end of the new filename, before the extension.  For example, if TimestampFormat is set to yyyy-MM-dd and FileName is set to app.log, then when rolling over on February 15, 2006 the current log file is renamed to app2006-02-15.log.


If the new filename already exists, then an incremental counter is added until a unique combination is found.  If the TimestampFormat property is left blank, the counter will always be appended to the end of the FileName.  The counter is formatted to 7 digits (e.g., app[0000123].log) and counting begins from 1.


Purging


Log files can be automatically deleted after a certain maximum number of log files are present by setting the MaximumLogFilesBeforePurge property.  Set this property to 0 to disable automatic purging.  Purging occurs before the current log file is renamed. The log files are deleted in reverse order of their last modification time.



Change log


Version 0.5.2.0 – Fixed a bug that occurred when the application configuration file is changed while an application using the RollingFileTraceListener is running. In that case a GUID was prepended to the filename of the log file, because the log file was still locked by another RollingFileTraceListener instance.


Version 0.5.1.0 – Fixed a bug that prevented the formatter name from being saved correctly when using the Enterprise Library Configuration tool.


Version 0.5.0.0 – First public release.



Known problems


A GUID might be prepended to the filename of the log file


A RollingFileTraceListener instance "owns" the log file it is writing to and locks it for exclusive write access when it writes the first log entry. It keeps the file locked until the instance is disposed. If another RollingFileTraceListener  instance is created that points to the same file, before the first instance is disposed, the second instance cannot open this file for writing and will write to a new file with a GUID prepended to its name.


The RollingFileTraceListener indirectly derives from System.Diagnostics.TextWriterTraceListener. This class changes the filename to include a GUID when the file with the specified filename cannot be written to. This is because RollingFileTraceListener indirectly calls the EnsureWriter method on its base class TextWriterTraceListener. .NET Reflector shows this code for System.Diagnostics.TextWriterTraceListener.EnsureWriter() in System.dll (slightly rewritten to improve clarity):


    try
    {
        this.writer = new StreamWriter(fileNameWithPath, true, encoding1, 0x1000);
        break;
    }
    catch (IOException)
    {
        Guid guid1 = Guid.NewGuid();
        fileName = guid1.ToString() + fileName;
        fileNameWithPath = Path.Combine(folderPath, fileName );
    }

One thought on “Rolling File Trace Listener Extension for Enterprise Library 2.0

  1. Randy

    The GUID prepended to the filename of the log file will cause the log files to not overwrite themselves as intended (e.g. when using timeStampPattern="dd"), which can cause the number of log files to grow unchecked. A solution is to create a new file using an underscore and count instead of a GUID, if the log file is in use by another process. See the NoGuid version:
    http://www.codeplex.com/entlibcontrib/SourceControl/PatchList.aspx
    This solution has been proposed for the Enterprise Library Contrib:
    http://www.codeplex.com/entlibcontrib/WorkItem/View.aspx?WorkItemId=7472

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *