.NET 中使用 NLog 的配置文件通常是 NLog.config,这是一个 XML 文件,用于配置日志记录的各种参数。本文主要介绍NLog配置文件中配置说明以及使用说明。

配置文件存放位置

在启动时,NLog在各种文件中搜索其配置,如下所述。它加载找到的第一个nlog配置。搜索在找到第一个nlog配置时结束。如果未找到配置,则NLog失败。
对于独立的*.exe应用程序,搜索文件如下:

  • 标准应用程序配置文件(通常是applicationname.exe.config
  • applicationname.exe.nlog在应用程序的目录中
  • 应用程序目录中的NLog.config
  • NLog.dll.nlog位于NLog.dll所在的目录中(仅当GAC中未安装NLog时)

对于ASP.NET应用程序,将按如下方式搜索文件:

  • 标准Web应用程序文件web.config
  • web.nlog与web.config位于同一目录中
  • 应用程序目录中的NLog.config
  • NLog.dll.nlog位于NLog.dll所在的目录中(仅当GAC中未安装NLog时)

对于.NET Compact Framework(无法识别应用程序配置文件(* .exe.config)或环境变量),将按如下方式搜索文件:

  • applicationname.exe.nlog在应用程序的目录中
  • 应用程序目录中的NLog.config
  • NLog.dll.nlog位于NLog.dll所在的目录中(仅当GAC中未安装NLog时)

对于Xamarin Android,支持assets文件夹。资产文件夹中的“NLog.config”将自动加载。如果文件名不同,则使用:

LogManager.Configuration = new XmlLoggingConfiguration("assets/someothername.config");

配置文件布局

NLog配置格式为XML,可嵌入Visual Studio项目配置文件(app.config或web.config)中,也可以是独立的XML文件。
要嵌入项目配置文件,请在其sectionconfigSections添加nlog section 元素并添加nlog元素。例如:

<configuration>
  <configSections>
    <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
  </configSections>
  ...
  <nlog>
  ...
  </nlog>
</configuration>

作为独立文件,根元素是nlog。例如:

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

...

</nlog>

使用XML命名空间是可选的,但在Visual Studio中启用了Intellisense。
NLog config在不使用命名空间时,不区分大小写,在使用命名空间时,区分大小写。

Top-level(顶级)元素

您可以使用以下元素作为子项nlog。targets并且rules在任何配置中都是必需的。其他配置是可选的,在高级方案中非常有用。

  • targets - 定义日志目标/输出
  • rules - 定义日志路由规则
  • extensions - 从* .dll文件加载NLog扩展
  • include- 包括外部配置文件
  • variable - 设置配置变量的值

最简单的配置包含一个target和一个规则(logger),用于将消息路由到目标。

Targets

该targets部分定义了日志Targets。每个target由一个target元素表示。每个target需要两个属性:

  • name - target名称
  • type - target类型 - 例如,"File", "Database", "Mail"。使用名称空间时,此属性已命名xsi:type

除了这些属性之外,targets通常还接受其他参数,这些参数会影响诊断跟踪的编写方式。每个target都有一组不同的参数,它们在项目主页上有详细描述,并且它们是上下文相关的。Intellisense也可以在Visual Studio中使用。
例如,File目标接受fileName定义输出文件名的参数,Console目标具有error确定诊断,跟踪是否写入标准错误(stderr),而不是过程的标准输出(stdout)的参数。

此示例演示了一个targets定义多个targets的部分:两个文件,一个网络target和OutputDebugString target

<targets>
  <target name="f1" xsi:type="File" fileName="file1.txt"/>
  <target name="f2" xsi:type="File" fileName="file2.txt"/>  
  <target name="n1" xsi:type="Network" address="tcp://localhost:4001"/>
  <target name="ds" xsi:type="OutputDebugString"/>
</targets>

NLog提供了许多预定义的Targets。实际上创建自己的target非常容易 - 请参阅如何编写自定义target。

规则配置

该rules部分将记录器映射到目标和日志级别。
规则是logger具有以下属性的元素:

  • name - 记录器名称模式 - 可能包含通配符(*)
  • minlevel - 记录的最低级别
  • maxlevel - 记录的最高级别
  • level - 单级记录
  • levels - 逗号分隔的记录级别列表
  • writeTo - 逗号分隔的要写入的目标列表
  • final - 最终规则匹配后不处理任何规则
  • enabled- 设置为false禁用规则而不删除它

注意:虽然规则命名为logger,但它没有定义logger。它引用一个或多个记录器。

通过将规则name模式与logger名称匹配,将规则映射到logger。规则name属性可以包括通配符(*),以通过通配符匹配来匹配logger名称。
规则按顺序处理。多个规则可以用于一个logger。使用final在找到匹配项后停止处理规则。
规则定义记录哪些日志条目级别。其他级别的条目将被忽略。常用的说明符是minLevel。其他说明符允许更高级的配置。
如果一个规则包含一个以上的声明级别属性(levellevelsminLevelmaxLevel)只有第一级别声明属性或设置使用,其余被忽略。
级别声明属性按以下顺序处理:

  1. level
  2. levels
  3. minlevel和maxlevel(这些具有相同的优先权)
  4. none(记录所有级别)

[需要澄清:是否使用了顺序的第一级相关属性?或者说是第一处理中使用?例如,给出“minLevel=Warn level=Info”,使用哪个?]
如果规则被标记为final,并包含任何级别声明属性,则该final属性仅适用于指定的级别。
示例规则

<logger name="Name.Space.Class1" minlevel="Debug" writeTo="f1" />

将具有级别Debug和更高级别的名为 "Name.Space.Class1"  logger的消息配置为写入"f1" target。
logger可以有任何名称,但在这种情况下,它是由类 "Class1" 创建的,它位于名称空间 "Name.Space" 中。见

LogManager.GetCurrentClassLogger()
<logger name="Name.Space.Class1" levels="Debug,Error" writeTo="f1" />

使用级别配置来自名为 "Name.Space.Class1" 的logger的消息,Debug或者Error将其写入"f1" target。

<logger name="Name.Space.*" writeTo="f3,f4" />

将来自 "Name.Space" 命名空间中任何类的消息配置为写入"f3" 和 "f4" targets,而不管级别如何。

<logger name="Name.Space.*" minlevel="Debug" maxlevel="Error" final="true" />
<logger name="*" writeTo="f1" />

配置以忽略来自任何类的消息Name.Space与之间水平的命名空间Debug和Error(其是Debug,Info,Warn,Error)。第一个规则选择logger,但由于没有writeTo,因此不记录这些消息。并且,由于此规则包含'final = true',因此最后一条规则不适用于与第一条规则匹配的logger。

Include files

NLog提供包含文件功能,以便配置可以存储在多个文件中。

<include file="nlog-common.config" />

与NLog配置中的大多数属性一样,file属性可以引用变量。以下示例包含一个名称与运行nlog的计算机相同的文件。

<include file="${machinename}.config"/>

如果无法加载包含文件,则将属性设置ignoreErrors  true以防止启动失败 - 找不到文件,无效的XML,....使用“ 故障排除日志记录”部分记录错误。此属性是可选的,默认为false

从NLog 4.4.2开始,允许使用通配符 (*)。例如,

<include file="nlog-*.config"/>

这里可以找到一个更大的例子:XML config <include /> example

配置中的变量

变量允许您通过访问环境信息来增强配置,并通过减少重复的文本来简化配置。NLog定义了可以在配置中使用的变量。此外,您还可以定义和使用自定义变量。

定义自定义变量,如下所示:

<variable name="varname" value="xxx" />

可以通过${varname}语法将变量的值插入到属性值中。变量值甚至可以用于定义另一个变量的值。以下示例显示使用预定义变量shortdate并定义和使用自定义变量logDirectory

<nlog>
  <variable name="logDirectory" value="logs/${shortdate}"/>
  <targets>
    <target name="file1" xsi:type="File" fileName="${logDirectory}/file1.txt"/>
    <target name="file2" xsi:type="File" fileName="${logDirectory}/file2.txt"/>
  </targets>
</nlog>

使用此语法,必须在使用前定义变量。否则配置初始化将失败。

NLog 4.1引入了使用变量值的新语法。请参见Variable layout renderer

${var:varname}

与旧语法相比,此语法具有以下优点:

  • 可以从API更改,删除和创建变量
  • 可以为变量配置默认值,例如 ${var:password:default=unknown}
  • 默认情况下,重新加载配置时会重置变量。为了从当前配置中获取变量,添加keepVariablesOnReload="true"到nlog元素(在NLog 4.4中引入)。

Layouts 和 layout renderers

NLog最强大的资产之一是使用布局的能力。在最简单的形式中,布局是带有由${和分隔的嵌入标签的文本}。标签称为Layout Renderers,可用于将多条上下文信息插入到文本中。

布局可以在很多地方使用,例如,它们可以控制写在屏幕上或发送到文件的信息格式,也可以控制文件名本身。这是非常强大的,我们马上就会看到。

让我们假设,我们想要注释写入控制台的每条消息:

  • 当前日期和时间
  • 发出日志消息的类和方法的名称
  • 日志级别
  • 消息文本

这很容易:

<target name="c" xsi:type="Console"  layout="${longdate} ${callsite} ${level} ${message}"/>

我们可以使每个logger的每条消息都转到一个单独的文件,如下例所示:

<target name="f" xsi:type="File" fileName="${logger}.txt"/>

如您所见,${logger} layout rendererfileName属性中使用,这会导致每条日志消息都写入其名称包含logger名称的文件。上面的示例将创建以下文件:

  • Name.Space.Class1.txt
  • Name.Space.Class2.txt
  • Name.Space.Class3.txt
  • Other.Name.Space.Class1.txt
  • Other.Name.Space.Class2.txt
  • Other.Name.Space.Class3.txt

日志级别

每个日志条目都有一个级别。并且每个logger都配置为包含或忽略某些级别。常见配置是指定包含该级别和更高级别的最低级别。例如,如果最低级别为Info,则会记录Info,Warn,Error和Fatal,但会忽略Debug和Trace。

日志级别按降序排列如下:

Level(级别)

典型用途

Fatal

很糟糕的情况下;应用程序停止

Error

一些情况失败了; 应用可能会也可能不会继续

Warn

出乎意料的情况; 应用程序能继续

Info

正常行为,如邮件发送,用户更新配置文件等

Debug

用于调试; 执行查询,用户通过身份验证,会话已过期

Trace

用于跟踪调试; 开始方法X,结束方法X.

还有一个级别,Off。由于它是最高值而不用于条目,因此在用作最小日志级别时,会禁用日志记录。

自动重新配置

程序启动时会自动读取配置文件。在长时间运行的进程(例如Windows服务或ASP.NET应用程序)中,有时需要暂时提高日志级别而不停止应用程序。NLog可以监视日志记录配置文件,并在每次修改时重新读取它们。要启用此机制,只需将autoReload="true"参数添加到配置文件即可。

<nlog autoReload="true">
   ...
</nlog>

请注意,自动重新配置支持包含文件,因此每次更改其中一个包含的文件时,都会重新加载整个配置。
只是为了明确,自动重新加载不会停止/回收IIS应用程序池。

故障诊断日志记录

有时我们的应用程序不会向日志文件写入任何内容,即使我们已经正确配置了日志记录。没有写入日志的原因可能有很多。最常见的问题是权限问题,通常在ASP.NET进程中,aspnet_wp.exe或者w3wp.exe进程可能没有对我们要存储日志的目录的写访问权。

NLog旨在吞噬可能由日志记录导致的运行时异常。以下设置可以更改此行为和/或重定向这些消息。

  • <nlog throwExceptions="true" />- throwExceptions在配置文件中添加属性会导致NLog停止屏蔽异常并将其传递给调用应用程序。此属性在部署时非常有用,可以快速找到任何问题。我们推荐设置throwExceptions,以"false"尽快申请被正确配置来运行,因此,任何意外的日志记录问题不会导致应用程序崩溃。
  • <nlog throwConfigExceptions="true" /> - 与throwExceptions配置异常相同。如果未设置(或null),则此值与throwExceptions。在NLog 4.3中引入。默认值null(因此值相同throwExceptions)
  • <nlog internalLogFile="file.txt" />- 添加internalLogFile导致NLog将其内部调试消息写入指定文件。这包括在日志记录期间可能抛出的任何异常。
  • <nlog internalLogLevel="Trace|Debug|Info|Warn|Error|Fatal" /> - 确定内部日志级别。级别越高,内部日志输出的详细程度就越低。
  • <nlog internalLogToConsole="false|true" /> - 确定是否将内部日志记录消息发送到控制台。
  • <nlog internalLogToConsoleError="false|true" /> - 确定是否将内部日志记录消息发送到控制台错误输出(stderr)。
  • <nlog internalLogToTrace="false|true" />- 确定是否将内部日志记录消息发送到System.Diagnostics.Trace,可以在Visual Studio中轻松查看。

异步处理和包装器(wrapper)targets

NLog提供包装器(wrapper)和复合target,通过添加以下功能来修改其他target的行为:

  • 异步处理(包装目标在单独的线程中运行)
  • 出错重试
  • 负载均衡
  • 缓冲
  • 过虑
  • 故障转移(故障转移)

要在配置文件中定义包装器(wrapper),只需将target节点嵌套在另一个target节点中。你甚至可以包装一个包装器target - 深度没有限制。例如,要添加具有重试错误功能的异步日志记录,请将其添加到配置文件中:

<targets>
  <target name="n" xsi:type="AsyncWrapper">
    <target xsi:type="RetryingWrapper">
      <target xsi:type="File" fileName="${file}.txt" />
    </target>
  </target>
</targets>

由于异步处理是一种常见方案,因此NLog支持简写表示法,以便为所有目标启用它,而无需指定显式包装器(wrapper)。您只需设置 async="true" targets元素,该元素中的所有目标都将包含在AsyncWrapper target中。

<nlog>
  <targets async="true">
    <!-- all targets in this section will automatically be asynchronous -->
  </targets>
</nlog>

默认包装器(wrappers)

有时我们要求以相同的方式包装所有targets,例如添加缓冲和/或重试。NLog <default-wrapper />为此提供语法。您只需将此元素放在该<targets />部分中,所有targets将自动用指定的包装器包装。请注意,<default-wrapper />仅适用于单个<targets />部分,您可以拥有多个部分,以便您可以定义以类似方式包装的targets组。

<nlog>  
  <targets>  
    <default-wrapper xsi:type="BufferingWrapper" bufferSize="100"/>  
    <target name="f1" xsi:type="File" fileName="f1.txt"/>  
    <target name="f2" xsi:type="File" fileName="f2.txt"/>  
  </targets>  
  <targets>  
    <default-wrapper xsi:type="AsyncWrapper">  
      <wrapper-target xsi:type="RetryingWrapper"/>  
    </default-wrapper>  
    <target name="n1" xsi:type="Network" address="tcp://localhost:4001"/>  
    <target name="n2" xsi:type="Network" address="tcp://localhost:4002"/>  
    <target name="n3" xsi:type="Network" address="tcp://localhost:4003"/>  
  </targets>  
</nlog>

在上面的例子中,我们定义了两个缓冲的File targets 和三个异步和重试的Network targets。

默认 target 参数

与默认包装器(wrappers)类似,NLog提供了<default-target-parameters />允许您指定targets参数的默认值的方法。例如,如果您不希望文件保持打开状态,则可以添加keepFileOpen="false"到每个target,如下例所示:

<nlog>
  <targets>
    <target name="f1" xsi:type="File" fileName="f1.txt" keepFileOpen="false"/>
    <target name="f2" xsi:type="File" fileName="f2.txt" keepFileOpen="false"/>
    <target name="f3" xsi:type="File" fileName="f3.txt" keepFileOpen="false"/>
   </targets>
</nlog>

或者,您可以指定<default-target-parameters />适用于该<targets />部分中所有targets的单个。默认参数是基于每个类型定义的,并且在XML文件中定义的实际属性之前应用:

<nlog>
  <targets>
    <default-target-parameters xsi:type="File" keepFileOpen="false"/>
    <target name="f1" xsi:type="File" fileName="f1.txt"/>
    <target name="f2" xsi:type="File" fileName="f2.txt"/>
    <target name="f3" xsi:type="File" fileName="f3.txt"/>
  </targets>
</nlog>

内容转义(escaping)

在配置文件中,需要转义一些字符。因为它是XML文件,所以<>括号应该用<和转义>。这也适用于属性值,如条件。
在布局中我们需要转义}括号,冒号:应该被转义,因为:

  • : 是值分隔符
  • } 是布局的结束

嵌套布局渲染器不需要转义。反斜杠也不需要逃避。

例子:

  • ${appdomain:format={1\}{0\}} (escape of })
  • ${rot13:inner=${ndc:topFrames=3:separator=x}} (no escaping needed)
  • ${when:when=1 == 1:Inner=Test\: Hello} (escape of :)

扩展

扩展可以配置为包含其他NLog包或自定义包:
只需在配置中引用DLL,<extensions />如下所示。名称不应包括.dll

配置文件示例:

<nlog> 
  <extensions> 
    <add assembly="MyAssembly"/> 
  </extensions> 
  <targets> 
    <target name="a1" type="MyFirst" host="localhost"/> 
  </targets> 
  <rules> 
    <logger name="*" minLevel="Info" appendTo="a1"/> 
  </rules> 
</nlog>

从NLog 4.0程序集开始,名称为“NLog * .dll”,现在自动加载,如“NLog.CustomTarget.dll”。此程序集应与文件夹相同NLog.dll

推荐文档