Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

log4net - Remove old files rolling by date

Tags:

log4net

INTENT:

a) I want my logs to be rolled by date in following file format yyyy-MM-dd.txt.

b) Additionally to this I want to remove old files which are out of maxSizeRollBackups range.

CAUTION A maximum number of backup files when rolling on date/time 
  boundaries is not supported. [RollingFileAppender spec][1]

SOLUTION

for a) is enough to do the configuration

<appender name="FileAppender" type="log4net.Appender.RollingFileAppender">
  <file value="logs\" />
  <appendToFile value="true" />
  <rollingStyle value="Date" />
  <maxSizeRollBackups value="30" />
  <datePattern value="yyyy-MM-dd'.txt'" />
  <staticLogFileName value="false" />
  <layout type="log4net.Layout.XmlLayoutSchemaLog4j"/>
  <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
</appender>

for b) Is the inheritance from RollingFileAppender + delete stuff the only way to achieve this ?

like image 468
ruslander Avatar asked Feb 18 '10 17:02

ruslander


3 Answers

I spent some time looking into this a few months ago. v1.2.10 doesn't support deleting older log files based on rolling by date. It is on the task list for the next release. I took the source code and added the functionality myself, and posted it for others if they are interested. The issue and the patch can be found at https://issues.apache.org/jira/browse/LOG4NET-27 .

like image 100
Mafu Josh Avatar answered Nov 07 '22 15:11

Mafu Josh


Considering that more than a decade went by and it's still not supported, I opted for the following solution of overriding RollingFileAppender with the required functionality:

public class RollingDateAppender : RollingFileAppender {
  public TimeSpan MaxAgeRollBackups { get; set; }

  public RollingDateAppender()
    : base() {
    PreserveLogFileNameExtension = true;
    StaticLogFileName = false;
  }

  protected override void AdjustFileBeforeAppend() {
    base.AdjustFileBeforeAppend();

    string LogFolder = Path.GetDirectoryName(File);
    var CheckTime = DateTime.Now.Subtract(MaxAgeRollBackups);
    foreach (string file in Directory.GetFiles(LogFolder, "*.log")) {
      if (System.IO.File.GetLastWriteTime(file) < CheckTime)
        DeleteFile(file);
    }
  }

}

Configuration is just as simple as with the original class:

roller = new RollingDateAppender {
  AppendToFile = true,
  File = ...;
  MaxAgeRollBackups = TimeSpan.FromDays(7),
  RollingStyle = RollingFileAppender.RollingMode.Date,
  ...
};
roller.ActivateOptions();
BasicConfigurator.Configure(roller);

Note that looking for *.log files in the log directory only makes sense if PreserveLogFileNameExtension is used or the DatePattern is used to include the extension at the end of the filename. If you need a different naming scheme, modify these in sync.

(I used version 2.0.8 of log4net, earlier versions might not allow the necessary function to be overridden.)

like image 25
Gábor Avatar answered Nov 07 '22 16:11

Gábor


It seems that patch version 4 of RollingFileAppenderer provided here https://issues.apache.org/jira/secure/attachment/12565940/RollingFileAppender.zip works fine with a minor change: in line 1286 replace ".*" with "*".

For this you can use the following configuration:

<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
  <file type="log4net.Util.PatternString" value="MyProduct.log" />
  <param name="DatePattern" value="'_'yyyy-MM-dd"/>
  <param name="AppendToFile" value="true"/>
  <param name="RollingStyle" value="Date"/>
  <param name="StaticLogFileName" value="false"/>
  <param name="MaxDateRollBackups" value="3" />
  <param name="preserveLogFileNameExtension" value="true" />
  <layout type="log4net.Layout.PatternLayout">
    <param name="ConversionPattern" value="%r %d [%t] %-5p %c - %m%n"/>
  </layout>
</appender>
like image 23
Pavel Calin Avatar answered Nov 07 '22 15:11

Pavel Calin