【问题标题】:Nlog fixed file name per app session每个应用会话的 Nlog 固定文件名
【发布时间】:2011-09-11 17:04:36
【问题描述】:

我正在使用 Nlog 从我的 c# 应用程序中记录日志。以下是我的 Nlog.config 中的 <targets> 部分:

<targets>
    <target name="logfile" xsi:type="File" fileName="..\logs\${date:format=yyyyMMdd_HHmmss}_trg.log"
    layout="${counter} | ${date:format=yyyy-MM-dd HH\:mm\:ss.ffff} | ${machinename} | ${level:uppercase=true} | ${logger:shortName=true} | ${stacktrace} | ${message:exceptionSeparator=EXCEPTION:withException=true}" 
    keepFileOpen="true"/>
</targets>

对于filename,我使用${date:format=yyyyMMdd_HHmmss}_trg.log 根据创建时间来命名日志。但是,当我的应用程序运行时,记录器每秒都会创建一个新的日志文件。如何强制 Nlog 修复文件名并在每个会话中只创建一个日志?

【问题讨论】:

标签: c# logging filenames nlog


【解决方案1】:

显然有一个${cached} 布局渲染器,它将渲染布局一次并重用它。 https://github.com/nlog/nlog/wiki/Cached-Layout-Renderer

不过,感谢@wageoghe 的意见。您使用 GlobalDiagnosticContext 的解决方案让我开始考虑将其他值传递给 NLog.config。

【讨论】:

【解决方案2】:

使用 ${cached} 包装器 (https://github.com/nlog/NLog/wiki/Cached-Layout-Renderer) 创建每个应用程序会话日志文件的示例:

<target 
    name="logfile" 
    xsi:type="File" 
    fileName="log-${date:cached=True:format=yyyy-MM-dd HH-mm-ss-fff}.txt"
/>

【讨论】:

    【解决方案3】:

    我认为通过更改 Main 函数中或程序开头的 NLog 配置文件中指定的日志文件来实现这种方式。这是目标“日志文件”作为示例配置文件中的文件目标。

    FileTarget target = LogManager.Configuration.FindTargetByName("logfile") as FileTarget;
    String logfile = "..\logs\" +  DateTime.Now.ToString("yyyyMMdd_HHmmss") + "_trg.log";
    target.FileName = logfile; 
    

    【讨论】:

      【解决方案4】:

      我不确定,但我的猜测是 NLog 根据文件名属性检查日志文件是否存在(这是动态的,因为您使用的是日期布局渲染器)。因此,由于文件名正在改变(即每次检索文件名值时它都不同(或可能不同)),NLog 会创建一个新文件。

      尝试使用这样的短日期布局渲染器:

      <targets>     
        <target name="logfile" xsi:type="File"    
                fileName="..\logs\${shortdate}_trg.log"     
                layout="${counter} | ${date:format=yyyy-MM-dd HH\:mm\:ss.ffff} | ${machinename} | ${level:uppercase=true} | ${logger:shortName=true} | ${stacktrace} | ${message:exceptionSeparator=EXCEPTION:withException=true}"      
                keepFileOpen="true"/> 
      </targets> 
      

      我想你会看到你的文件名不会改变(直到午夜)。

      关键是 NLog 将始终检查文件是否存在(根据文件名的值在写入日志消息时),如果存在则创建文件还不存在。

      或者,如果您想用更精确的文件名命名您的日志文件(即它是在某个日期的某个时间创建的),那么您可以将该时间存储在 GlobalDiagnosticContext 并使用 gdc 布局渲染器来帮助命名文件。像这样的:

      //Early in your program do something like this:
      NLog.GlobalDiagnosticContext["StartTime"] = DateTime.Now.ToString("yyyyMMdd_HHmmss");
      

      在您的 NLog.config 文件中,执行以下操作:

      <targets>     
        <target name="logfile" xsi:type="File"    
                fileName="..\logs\${gdc:item=StartTime}_trg.log"     
                layout="${counter} | ${date:format=yyyy-MM-dd HH\:mm\:ss.ffff} | ${machinename} | ${level:uppercase=true} | ${logger:shortName=true} | ${stacktrace} | ${message:exceptionSeparator=EXCEPTION:withException=true}"      
                keepFileOpen="true"/> 
      </targets> 
      

      最后,您可以编写一个自定义 LayoutRenderer 来填充日期/时间。它会获取一次时间,然后每次返回相同的值。

      看起来像这样:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Runtime.CompilerServices;
      
      using System.Globalization;
      
      using NLog;
      using NLog.Config;
      using NLog.LayoutRenderers;
      
      namespace MyNLogExtensions
      {
        [LayoutRenderer("StartTime")]
        class StartTimeLayoutRenderer : LayoutRenderer
        {
          private DateTime start = DateTime.Now;
      
          public StartTimeLayoutRenderer()
          {
            this.Format = "G";
            this.Culture = CultureInfo.InvariantCulture;
          }
      
          //
          // In NLog 1.x, LayoutRenderer defines a Culture property.
          // In NLog 2.0, LayoutRenderer does not define a Culture property.
          //
          public CultureInfo Culture { get; set; }
      
          [DefaultParameter]
          public string Format { get; set; }
      
          protected override void Append(StringBuilder builder, LogEventInfo logEvent)
          {
            builder.Append(start.ToString(this.Format, this.Culture));
          }
      
          protected override int GetEstimatedBufferSize(LogEventInfo logEvent)
          {
            return 10;
          }
        }
      }
      

      在你的 NLog.config 文件中,你需要这样的东西来告诉你的扩展在哪里:

        <extensions>
          <add assembly="MyAssembly.dll"
        </extensions>
      

      然后您的目标配置将如下所示:

      <targets>     
        <target name="logfile" xsi:type="File"    
                fileName="..\logs\${StartTime:format=yyyyMMdd_HHmmss}_trg.log"     
                layout="${counter} | ${date:format=yyyy-MM-dd HH\:mm\:ss.ffff} | ${machinename} | ${level:uppercase=true} | ${logger:shortName=true} | ${stacktrace} | ${message:exceptionSeparator=EXCEPTION:withException=true}"      
                keepFileOpen="true"/> 
      </targets>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-06-30
        • 2011-02-22
        • 1970-01-01
        • 1970-01-01
        • 2012-09-06
        • 1970-01-01
        • 2011-01-25
        相关资源
        最近更新 更多