使用NLog作为翻转文件记录器

Kav*_*ian 19 .net c# nlog

如何 - 如果可能 - 我可以使用NLog作为翻转文件记录器吗?仿佛:

我希望31天内最多可以有31个文件,当新的一天开始时,如果有一个旧日志文件##.log,那么它应该被删除但是在那一天所有的日志都被附加并且至少会在那里为期27天.

Kav*_*ian 27

最后,我已经确定了基于大小的文件存档.我用了一招一个月就在一天后,命名该文件,我需要基于尺寸的文件档案,因为它确实有助于当你开始日志增长超过几百兆字节.它有助于制作 - 例如 - 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>
Run Code Online (Sandbox Code Playgroud)

此配置为每月的每一天生成1 MB日志文件,并在My Documents\MyApp\Log文件夹中保留最多10个已归档的1 MB日志块; 像29.log,30.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>
Run Code Online (Sandbox Code Playgroud)

在每个我想要日志记录功能的类中,我把它放在:

static readonly Logger SlotClassLogger = LogManager.GetCurrentClassLogger();
static Logger ClassLogger { get { return SlotClassLogger; } }
Run Code Online (Sandbox Code Playgroud)

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

public static Logger DataLog { get; private set; }
public static Logger AppEventLog { get; private set; }
Run Code Online (Sandbox Code Playgroud)

它们应该在app start初始化:

DataLog = LogManager.GetLogger("Data");
AppEventLog = LogManager.GetLogger("Event");
Run Code Online (Sandbox Code Playgroud)

注意:有时在您的应用程序退出时,您会收到NLog生成的异常.这是因为未初始化的东西无法处理!您只需在应用开始时在记录器中写入一个空条目,例如:

DataLog.Info(string.Empty);
Run Code Online (Sandbox Code Playgroud)

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


Jon*_*eet 11

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

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

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

debug-2010-06-08.log
Run Code Online (Sandbox Code Playgroud)

考虑到文档中示例,使用NLog应该很容易实现这一部分.

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

事实上,看看NLog文档,看起来"基于时间的文件存档"目标可能完全符合您的要求......但即使它没有,正常的"每天一个日志文件"方法和滚动你自己的清理应该很容易.