【问题标题】:Using NLog as a rollover file logger使用 NLog 作为翻转文件记录器
【发布时间】:2011-03-01 08:22:18
【问题描述】:

如果可能的话,我如何将 NLog 用作翻转文件记录器?好像:

我希望在 31 天内最多拥有 31 个文件,当新的一天开始时,如果有旧日日志文件 ##.log,则应将其删除,但在那一天,所有日志都将被追加,并将在那里至少 27 天。

【问题讨论】:

    标签: c# .net nlog


    【解决方案1】:

    我终于和size-based file archival 达成了一致。我使用一个技巧在一个月的某天之后命名文件,并且我需要基于大小的文件存档,因为当您的日志开始增长超过数百兆字节时,它真的很有帮助。它有助于制作 - 例如 - 20 MB 的日志块,因此可以使用 Notepad++ 等轻量级工具轻松快速查看。

    它已经工作了将近一年。这是我的NLog.config 文件的简化版本:

    <?xml version="1.0" encoding="utf-8" ?>
    <nlog autoReload="true" throwExceptions="true"
          xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <variable name="LogDir" value="${specialfolder:folder=MyDocuments}/MyApp/Log"/>
      <variable name="LogDay" value="${date:format=dd}"/>
      <targets>
        <target name="LogTarget1" xsi:type="File" fileName="${LogDir}/${LogDay}.log" encoding="utf-8"
            maxArchiveFiles="10" archiveNumbering="Sequence" archiveAboveSize="1048576" archiveFileName="${LogDir}/{#######}.a" />
      </targets>
      <rules>
        <logger name="AppLog" writeTo="LogTarget1" />
      </rules>
    </nlog>
    

    此配置为每月的每一天生成 1 MB 的日志文件,并在 My Documents\MyApp\Log 文件夹中最多保留 10 个归档的 1 MB 日志块;比如29.log30.log31.log

    编辑:我使用这个NLog.config 文件已经有一段时间了,它几乎涵盖了我需要的所有情况。我在不同的文件中有不同级别的日志记录,当它们变大时,它们会根据大小按小时归档:

    <?xml version="1.0" encoding="utf-8" ?>
    <nlog autoReload="true" throwExceptions="true" internalLogFile="nlog-internals.log"
          xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <variable name="LogHome" value="${basedir}/Log"/>
      <variable name="DailyDir" value="${LogHome}/${date:format=yyyy}/${date:format=MM}/${date:format=dd}"/>
      <variable name="HourlyArchive" value="${DailyDir}/${date:format=HH}-Archive/${level}-${logger}-{#######}-archived.a"/>
      <variable name="AppLogPath" value="${DailyDir}/${level}-${logger}.log"/>
      <variable name="DataLogPath" value="${DailyDir}/_data/inouts-${shortdate}.log"/>
      <variable name="EventSource" value="Application" />
      <targets>
        <target name="AppAsyncTarget" xsi:type="AsyncWrapper">
          <target xsi:type="RetryingWrapper" retryDelayMilliseconds="3000" retryCount="10">
            <target xsi:type="File" fileName="${AppLogPath}" encoding="utf-8"
                maxArchiveFiles="50" archiveNumbering="Sequence" archiveAboveSize="1048576" archiveFileName="${HourlyArchive}"
                layout="`${longdate}`${level}`${message}" />
          </target>
        </target>
        <target name="DataAsyncTarget" xsi:type="AsyncWrapper">
          <target xsi:type="RetryingWrapper" retryDelayMilliseconds="1500" retryCount="300">
            <target xsi:type="File" fileName="${DataLogPath}" encoding="utf-8"
                layout="`${longdate}`${message}" />
          </target>
        </target>
        <target name="EventLogAsyncTarget" xsi:type="AsyncWrapper">
          <target xsi:type="RetryingWrapper">
            <target xsi:type="EventLog" source="${EventSource}" machineName="." />
          </target>
        </target>
      </targets>
      <rules>
        <logger name="Data" writeTo="DataAsyncTarget" final="true" />
        <logger name="Event" writeTo="EventLogAsyncTarget" final="true" />
        <logger name="*" writeTo="AppAsyncTarget" />
      </rules>
    </nlog>
    

    在我想要记录功能的每个类中,我都写了这个:

    static readonly Logger SlotClassLogger = LogManager.GetCurrentClassLogger();
    static Logger ClassLogger { get { return SlotClassLogger; } }
    

    另外两个记录器用于每天堆积一些数据并写入 Windows 事件日志;哪些是应用范围的记录器:

    public static Logger DataLog { get; private set; }
    public static Logger AppEventLog { get; private set; }
    

    并且它们应该在应用启动时被初始化:

    DataLog = LogManager.GetLogger("Data");
    AppEventLog = LogManager.GetLogger("Event");
    

    注意:有时在您的应用退出时,您会收到由 NLog 产生的异常。这是因为没有初始化的东西不能被处理掉!您刚刚在应用程序启动时在记录器中写入了一个空条目,例如:

    DataLog.Info(string.Empty);
    

    我已添加此大小限制,因此可以在(例如)低端服务器上的记事本中查看日志文件,以便快速查看。您应该根据自己的需要修改它们。

    【讨论】:

      【解决方案2】:

      我建议你把问题分成两个不同的方面:

      • 每天滚动到一个新的文件名(记住时区;也许是 UTC 日?)
      • 删除旧的日志文件

      根据我的经验,将日期保留在日志文件名中是值得的,例如

      debug-2010-06-08.log
      

      考虑到examples in the docs,这部分应该很容易使用 NLog。

      现在第二部分可以很容易地在第二个线程中完成,甚至可以在完全不同的过程中完成——它只需要查看存在多少文件并在必要时删除最旧的文件。如果日期在文件名中,则查找“最旧的”应该很容易,即使您不想信任文件系统信息。

      事实上,查看 NLog 文档,看起来 "time-based file archival" 目标可能完全符合您的要求......但即使没有,正常的“每天一个日志文件”方法并滚动您的自己清理应该很容易。

      【讨论】:

        猜你喜欢
        • 2012-11-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        相关资源
        最近更新 更多