c# - 每个应用程序 session 的 Nlog 固定文件名

标签 c# logging filenames nlog

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

<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 修复文件名并在每个 session 中只创建一个日志?

最佳答案

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

尝试像这样使用 shortdate 布局渲染器:

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

关于c# - 每个应用程序 session 的 Nlog 固定文件名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6293386/

相关文章:

c# - 将按位比较从 C++ 转换为 C#

python - python 警告的日志堆栈跟踪

.net - 如何使用 ILogger 和应用程序洞察关联相关的自定义日志?

logging - 奇怪的 openssh-server 登录/var/log/auth.log

php - 删除文件名中除文件扩展名前的点之外的所有点

c# - 大型客户端/服务器项目布局和 Ivy 设置的建议

c# - 如何阻止所有键盘和鼠标输入到我的 WinForms 应用程序?

bash - 理解(多重和自动)文件名引用

c# - 连接池管理

c# - ASP C# : Special characters: #, $,+ 无法通过 URL 参数