Log4Net:使用滚动日期在RollingFileAppender上设置最大备份文件


69

我具有以下配置,但无法找到有关如何设置日期滚动样式的最大备份文件的任何文档。我知道您可以通过使用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>

+1正是我要寻找的内容
Magnus Lindhe 2009年

Answers:


50

你不能

log4net SDK参考
RollingFileAppender类

警告

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


3
更新是suppoerted与maxSizeRollBackups:logging.apache.org/log4net/release/sdk/...
schoetbi

@schoetbi,它仍然无法正常工作。我正在为此制作一些原型,尽管maxSizeRollBackups设置为3,但备份了4个以上的文件。
manu 2014年

5
这不是maxSizeRollBackups所做的,如果某个日期的文件被锁定或太大,则会为该日期创建一个备份。这限制了那些文件,而不是保存多少“天”文件,而是限制了一天中的多个文件。
埃里克·布朗-

1
已将文档链接固定为:logging.apache.org/log4net/release/sdk/html/…不再提及“警告”
Myster

2
和谨慎仍处于RollingFileAppender进行类文档:logging.apache.org/log4net/release/sdk/html/...
格雷戈尔Ažbe

41

即使它不受支持,这也是我处理这种情况的方法:

这是我的配置:

    <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>

在应用程序启动时,我这样做:

 XmlConfigurator.Configure();
 var date = DateTime.Now.AddDays(-10);
 var task = new LogFileCleanupTask();
 task.CleanUp(date);

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

using log4net;
using log4net.Appender;
using log4net.Config;

    public class LogFileCleanupTask
    {
        #region - Constructor -
        public LogFileCleanupTask()
        {
        }
        #endregion

        #region - Methods -
        /// <summary>
        /// Cleans up. Auto configures the cleanup based on the log4net configuration
        /// </summary>
        /// <param name="date">Anything prior will not be kept.</param>
        public void CleanUp(DateTime date)
        {
            string directory = string.Empty;
            string filePrefix = string.Empty;

            var repo = LogManager.GetAllRepositories().FirstOrDefault(); ;
            if (repo == null)
                throw new NotSupportedException("Log4Net has not been configured yet.");

            var app = repo.GetAppenders().Where(x => x.GetType() == typeof(RollingFileAppender)).FirstOrDefault();
            if (app != null)
            {
                var appender = app as RollingFileAppender;

                directory = Path.GetDirectoryName(appender.File);
                filePrefix = Path.GetFileName(appender.File);

                CleanUp(directory, filePrefix, date);
            }
        }

        /// <summary>
        /// Cleans up.
        /// </summary>
        /// <param name="logDirectory">The log directory.</param>
        /// <param name="logPrefix">The log prefix. Example: logfile dont include the file extension.</param>
        /// <param name="date">Anything prior will not be kept.</param>
        public void CleanUp(string logDirectory, string logPrefix, DateTime date)
        {
            if (string.IsNullOrEmpty(logDirectory))
                throw new ArgumentException("logDirectory is missing");

            if (string.IsNullOrEmpty(logPrefix))
                throw new ArgumentException("logPrefix is missing");

            var dirInfo = new DirectoryInfo(logDirectory);
            if (!dirInfo.Exists)
                return;

            var fileInfos = dirInfo.GetFiles("{0}*.*".Sub(logPrefix));
            if (fileInfos.Length == 0)
                return;

            foreach (var info in fileInfos)
            {
                if (info.CreationTime < date)
                {
                    info.Delete();
                }
            }

        }
        #endregion
    }

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);
    }
}

3
这是值得意识到的是,“创建日期”可能不是这个可靠因- stackoverflow.com/questions/2109152/...
伊恩

1
同样值得注意的是,此类必须满足以下两个条件才能正常运行:1) StaticLogFileName设置为true。2)preserveLogFileNameExtension设置为false
琼斯先生2014年

11

几个月前,我花了一些时间研究这个问题。v1.2.10不支持根据日期滚动删除较旧的日志文件。在下一个版本的任务列表中。我获取了源代码,并亲自添加了功能,如果有兴趣,可以将其发布给其他人。可以在https://issues.apache.org/jira/browse/LOG4NET-27上找到该问题和补丁。


如何使用它?您是否必须下载log4net源代码,添加它,然后重新编译并获取新的程序集文件?
n00b

据我所知,是的
Mafu Josh

9

要限制日志数量,请不要在日期模式中包含年份或月份,例如datePattern value =“ _ dd'.log'”

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


1
这听起来像是一个非常简单且有趣的想法,但我看到了以下问题-每次重启应用都会覆盖当天的现有文件。或者,如果您将其配置为不覆盖文件,而是附加-文件将无限增长。您如何精确配置?
卢卡斯K

@LukasK如果设置rollingStyle为CompositemaximumFileSizemaxSizeRollbackups,则可以限制每个文件的大小。但是,如果一个月的第6天有3次转换,而下个月只有2次,则可能会造成混淆。前一个月的“ _06.3”过渡将与当月混合。
mdisibio '19

2

不确定您到底需要什么。以下是我的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>

1
不知道为什么要投反对票。它被认为是解释为什么这样做的好形式,以便我们大家都能学习。
wcm

5
确实错过了问题的重点。maxSizeRollBackups不允许您删除超过10天的文件。我认为这是OP想要实现的目标。
Graham Griffiths 2014年

1
我认为您是对的,这是OP想要的。对于他当时想要完成的工作,我还不清楚。我的答案很简单,尝试向他展示我的代码。我仍然会以同样的方式回答问题,以期有所帮助,但我可以通过否决票看清您的来历。
wcm 2014年

2

最近,当我尝试根据传递到我的服务中的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);
        }
    }
}

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


1

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


1
你能给我礼物吗?我找不到如何在其WIKI
洋剑

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.