.net Log4Net:在具有滚动日期的滚动FileAppender上设置最大备份文件数

.net Log4Net:在具有滚动日期的滚动FileAppender上设置最大备份文件数,.net,log4net,.net,Log4net,我有以下配置,但是我还没有找到关于如何设置日期滚动样式的最大备份文件数的任何文档。我知道您可以通过使用maxSizeRollBackups使用大小滚动样式来实现这一点 <appender name="AppLogFileAppender" type="log4net.Appender.RollingFileAppender"> <file value="mylog.log" /> <appendToFile value="true" />

我有以下配置,但是我还没有找到关于如何设置日期滚动样式的最大备份文件数的任何文档。我知道您可以通过使用maxSizeRollBackups使用大小滚动样式来实现这一点

<appender name="AppLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="mylog.log" />
    <appendToFile value="true" />
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <rollingStyle value="Date" />
    <datePattern value=".yyMMdd.'log'" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%d %-5p %c - %m%n"  />
    </layout>
</appender>

不确定您需要什么。下面是我的一个lo4net.config文件的摘录:

  <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
    <param name="File" value="App_Data\log"/>
    <param name="DatePattern" value=".yyyy-MM-dd-tt&quot;.log&quot;"/>
    <param name="AppendToFile" value="true"/>
    <param name="RollingStyle" value="Date"/>
    <param name="StaticLogFileName" value="false"/>
    <param name="maxSizeRollBackups" value="60" />
    <layout type="log4net.Layout.PatternLayout">
      <param name="ConversionPattern" value="%r %d [%t] %-5p %c - %m%n"/>
    </layout>
  </appender>

你不能

小心

不支持按日期/时间边界滚动时备份文件的最大数量


几个月前我花了一些时间研究这个问题。v1.2.10不支持根据滚动日期删除旧的日志文件。它位于下一版本的任务列表中。我自己获取了源代码并添加了功能,如果其他人感兴趣,我会发布给他们。该问题和修补程序可在上找到。

即使它不受支持,以下是我如何处理这种情况的:

这是我的配置:

    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
        <file value="C:\logs\LoggingTest\logfile.txt" />
        <appendToFile value="true" />
        <rollingStyle value="Composite" />
        <datePattern value="yyyyMMdd" />
        <maxSizeRollBackups value="10" />
        <maximumFileSize value="1MB" />
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date  - %message%newline" />
        </layout>
    </appender>

使用系统;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
使用系统文本;
使用log4net;
使用log4net.Appender;
使用log4net.Config;
公共类LogFileCleanupTask
{
#区域构造函数-
公共日志文件清理任务()
{
}
#端区
#区域-方法-
/// 
///清理。根据log4net配置自动配置清理
/// 
///之前的任何内容都不会保留。
公共空间清理(日期时间日期)
{
string directory=string.Empty;
string filePrefix=string.Empty;
var repo=LogManager.GetAllRepositories().FirstOrDefault();
if(repo==null)
抛出新的NotSupportedException(“尚未配置Log4Net”);
var app=repo.GetAppenders()。其中(x=>x.GetType()==typeof(RollingFileAppender)).FirstOrDefault();
如果(应用程序!=null)
{
var appender=app作为RollingFileAppender;
directory=Path.GetDirectoryName(appender.File);
filePrefix=Path.GetFileName(appender.File);
清理(目录、文件前缀、日期);
}
}
/// 
///打扫卫生。
/// 
///日志目录。
///日志前缀。示例:日志文件不包括文件扩展名。
///之前的任何内容都不会保留。
公共无效清除(字符串日志目录、字符串日志前缀、日期时间日期)
{
if(string.IsNullOrEmpty(logDirectory))
抛出新ArgumentException(“缺少logDirectory”);
if(string.IsNullOrEmpty(logPrefix))
抛出新ArgumentException(“缺少logPrefix”);
var dirInfo=新目录信息(logDirectory);
如果(!dirInfo.Exists)
返回;
var fileInfos=dirInfo.GetFiles(“{0}*.*”.Sub(logPrefix));
如果(fileInfos.Length==0)
返回;
foreach(fileInfos中的var info)
{
如果(信息创建时间<日期)
{
info.Delete();
}
}
}
#端区
}
Sub方法是一个扩展方法,它基本上包装string.format,如下所示:

/// <summary>
/// Extension helper methods for strings
/// </summary>
[DebuggerStepThrough, DebuggerNonUserCode]
public static class StringExtensions
{
    /// <summary>
    /// Formats a string using the <paramref name="format"/> and <paramref name="args"/>.
    /// </summary>
    /// <param name="format">The format.</param>
    /// <param name="args">The args.</param>
    /// <returns>A string with the format placeholders replaced by the args.</returns>
    public static string Sub(this string format, params object[] args)
    {
        return string.Format(format, args);
    }
}
//
///字符串的扩展助手方法
/// 
[DebuggerStepThrough,DebuggerNonUserCode]
公共静态类扩展
{
/// 
///使用and设置字符串格式。
/// 
///格式。
///args。
///格式占位符替换为args的字符串。
公共静态字符串子(此字符串格式,参数对象[]args)
{
返回string.Format(格式,args);
}
}

从log4net appender继承并添加(比如)您自己的重写方法来执行文件清理非常容易。我重写了OpenFile来执行此操作。下面是一个定制log4net appender的示例,让您开始使用:

我最近在尝试根据传递到我的服务中的maxAgeInDays配置值清理日志时遇到了这种需要。。。和我之前的许多人一样,我接触到了NTFS的“功能”隧道,这使得使用FileInfo.CreationDate成了问题(尽管我后来也解决了这个问题)

因为我有一个模式去关闭,我决定只推出我自己的清理方法。。。我的记录器是以编程方式配置的,因此我仅在记录器安装完成后调用以下命令

    //.........................
    //Log Config Stuff Above...

    log4net.Config.BasicConfigurator.Configure(fileAppender);
    if(logConfig.DaysToKeep > 0)
       CleanupLogs(logConfig.LogFilePath, logConfig.DaysToKeep);
}

static void CleanupLogs(string logPath, int maxAgeInDays)
{
    if (File.Exists(logPath))
    {
        var datePattern = "yyyy.MM.dd";
        List<string> logPatternsToKeep = new List<string>();
        for (var i = 0; i <= maxAgeInDays; i++)
        {
            logPatternsToKeep.Add(DateTime.Now.AddDays(-i).ToString(datePattern));
        }

        FileInfo fi = new FileInfo(logPath);

        var logFiles = fi.Directory.GetFiles(fi.Name + "*")
            .Where(x => logPatternsToKeep.All(y => !x.Name.Contains(y) && x.Name != fi.Name));

        foreach (var log in logFiles)
        {
            if (File.Exists(log.FullName)) File.Delete(log.FullName);
        }
    }
}
/。。。。。。。。。。。。。。。。。。。。。。。。。
//上面的日志配置内容。。。
log4net.Config.BasicConfigurator.Configure(fileAppender);
如果(logConfig.DaysToKeep>0)
CleanupLogs(logConfig.LogFilePath,logConfig.DaysToKeep);
}
静态void CleanupLogs(字符串日志路径,int maxAgeInDays)
{
if(File.Exists(logPath))
{
var datePattern=“yyyy.MM.dd”;
List LOGPATTERNSTOKEP=新列表();
对于(变量i=0;i logpatternstokep.All(y=>!x.Name.Contains(y)&&x.Name!=fi.Name));
foreach(日志文件中的var日志)
{
如果(File.Exists(log.FullName))File.Delete(log.FullName);
}
}
}

可能不是最漂亮的方法,但对我们来说效果很好…

为了限制日志数量,在datepattern中不包括年份或月份,例如datepattern value=“\u dd'.log'”


这将每天创建一个新日志,并将在下个月被覆盖。

,其设置方式与Log4Net几乎相同(&被积极维护-甚至支持.NET Core),支持基于日期的滚动日志。

+1正是我想要的。值得注意的是,由于此原因,“创建日期”可能不可靠-还值得注意的是,该类只有在以下情况下才能正常运行
/// <summary>
/// Extension helper methods for strings
/// </summary>
[DebuggerStepThrough, DebuggerNonUserCode]
public static class StringExtensions
{
    /// <summary>
    /// Formats a string using the <paramref name="format"/> and <paramref name="args"/>.
    /// </summary>
    /// <param name="format">The format.</param>
    /// <param name="args">The args.</param>
    /// <returns>A string with the format placeholders replaced by the args.</returns>
    public static string Sub(this string format, params object[] args)
    {
        return string.Format(format, args);
    }
}
    //.........................
    //Log Config Stuff Above...

    log4net.Config.BasicConfigurator.Configure(fileAppender);
    if(logConfig.DaysToKeep > 0)
       CleanupLogs(logConfig.LogFilePath, logConfig.DaysToKeep);
}

static void CleanupLogs(string logPath, int maxAgeInDays)
{
    if (File.Exists(logPath))
    {
        var datePattern = "yyyy.MM.dd";
        List<string> logPatternsToKeep = new List<string>();
        for (var i = 0; i <= maxAgeInDays; i++)
        {
            logPatternsToKeep.Add(DateTime.Now.AddDays(-i).ToString(datePattern));
        }

        FileInfo fi = new FileInfo(logPath);

        var logFiles = fi.Directory.GetFiles(fi.Name + "*")
            .Where(x => logPatternsToKeep.All(y => !x.Name.Contains(y) && x.Name != fi.Name));

        foreach (var log in logFiles)
        {
            if (File.Exists(log.FullName)) File.Delete(log.FullName);
        }
    }
}