NLog文章系列——入门教程(中)

 

作者:Jarosław Kowalski <jaak@jkowalski.net>

翻译:Dflying Chen:http://dflying.cnblogs.com/

原文:http://www.nlog-project.org/tutorial.html

本文为《NLog文章系列》的第三篇,将继续描述演示用NLog书写日志的方法。本想今天就能搞定整个入门教程,无奈时间实在来不及了……只能再分一篇了……匆忙而为,言语多有不顺,还请各位见谅……

 

日志配置

下面我们来看一下NLog的配置原理。于其他工具不同,NLog将在程序启动时尝试进行自动配置,换句话说,NLog将自动在某些默认位置中搜索其配置文件。当NLog和标准的exe文件配合使用时,将自动按照顺序搜索下列路径,以得到配置文件:

  1. 应用程序的标准配置文件(通常为applicationname.exe.config)
  2. 应用程序所在目录中的applicationname.exe.nlog文件
  3. 应用程序所在目录中的NLog.config文件
  4. NLog.dll所在目录中的NLog.dll.nlog文件
  5. 环境变量NLOG_GLOBAL_CONFIG_FILE所指向的文件

对于ASP.NET应用程序,NLog将自动按照顺序搜索下列路径:

  1. Web应用程序的标准配置文件——web.config
  2. web.config所在目录中的web.nlog文件
  3. 应用程序所在目录中的NLog.config文件
  4. NLog.dll所在目录中的NLog.dll.nlog文件
  5. 环境变量NLOG_GLOBAL_CONFIG_FILE所指向的文件

.NET Compact Framework并不支持应用程序配置文件(*.exe.config)以及环境变量,因此NLog将自动按照顺序搜索下列路径:

  1. 应用程序所在目录中的applicationname.exe.nlog文件
  2. 应用程序所在目录中的NLog.config文件
  3. NLog.dll所在目录中的NLog.dll.nlog文件

 

配置文件形式

NLog支持两种形式的配置文件:

  1. 嵌入到*.exe.config或web.config等标准配置文件中
  2. 单独的配置文件

对于第一种形式,我们使用了标准化的configSection机制。这样配置文件将类似如下所示:

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

而对于第二种形式,XML配置文件将以<nlog />作为其根节点。XML的命名空间是可选的,但如果按照如下所示指定了命名空间,将会得到Visual Studio的智能感知支持。

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

若不指定XML命名空间,则NLog的配置文件对大小写不敏感。若指定了XML命名空间,则将变为对大小写敏感。智能感知将只能在指定了XML的命名空间时正常工作。

 

配置文件元素

在配置文件的<nlog />根元素中,我们可以指定如下的子元素。其中前两个是必须设定的,其余三个为可选设定。

  1. <targets /> - 定义日志的输出目标
  2. <rules /> - 定义对日志信息进行路由的规则
  3. <extensions /> - 定义从其他dll文件中加载的NLog扩展模块
  4. <include /> - 引入外部的配置文件
  5. <variable /> - 定义配置文件中用到的变量

 

输出目标(Target)

<targets />配置节用来定义日志信息的输出位置。每一个输出位置都用一个<target />元素表示。<target />元素有两个必须设置的属性:

  1. name - 输出目标的名称
  2. type - 输出目标的类型,例如“File”、“DataBase”、“Mail”等。若我们为配置文件指定了命名空间,则该属性名为xsi:type

除了上述两个必须设置的属性之外,<target />元素还支持一些其他的属性,同样可以影响记录诊断信息的方式。我们可以为每一个输出目标设定不同的属性参数,这些属性均在NLog的主页上有详细描述,且Visual Studio也都为其提供了智能感知功能支持。

例如:“File”输出目标接受一个名为fileName的参数,用来指定输出文件的名称;而“Console”输出目标则接受一个名为error的参数,表示是否用标准错误输出(stderr)代替标准输出(stdout)。

NLog提供了很多与定义的输出目标,这些均在NLog的主页上有详细介绍。若你觉得不够用,并希望能够编写自定义的输出目标,那么也同样非常简单——15-20行代码就够了,请参考Nlog的文档(documentation)。

 

路由规则(Rule)

路由规则将定义在配置文件的<rules />节中。这部分内容就是一个简单的路由表,用来定义不同的日志源(Logger的名称)以及记录等级的日志信息将被发送至哪个输出目标中。路由规则将从列表中的第一项开始执行,如果符合当前的路由规则,则该条日志信息将被发送至指定的输出目标中,若路由表中任意一项都不满足,则该条日志信息将不会被处理。

路由表中的每一个条目都由一个<logger />元素定义,<logger />元素支持如下几个属性:

  1. name - 日志源(Logger的名称),可以使用*通配符
  2. minlevel -  匹配该规则需要的最低记录等级
  3. maxlevel - 匹配该规则需要的最高记录等级
  4. level - 匹配该规则需要的单一的记录等级
  5. levels - 匹配该规则需要的记录等级列表,记录等级之间用逗号隔开
  6. writeTo - 匹配该规则的日志信息将被发送至的输出目标列表,输出目标之间用逗号隔开
  7. final - 让该规则成为日志信息的最后一个匹配条目。满足该条规则的日志信息被处理之后,将不会再继续尝试匹配下面定义的路由规则。

一些例子:

来自于命名空间Name.Space下Class1的、记录等级等于或高于Debug的日志信息将被发送至输出目标f1。

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

来自于命名空间Name.Space下Class1的、记录等级等于为Debug或Error的日志信息将被发送至输出目标f1。

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

来自于命名空间Name.Space下任意类的任意日志信息将被发送至输出目标f3和f4。

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

来自于命名空间Name.Space下任意类的、记录等级在Debug和Error之间(包括Debug、Info、Warn和Error)的日志信息将被忽略(没有writeTo属性),且也不会再被下面的路由规则处理(因为设置了final="true")。

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

在前面的示例程序中,配置文件只包含了一个<target />元素和一个<logger />元素。随着对程序的需求不断扩充,添加新的输出目标以及路由规则也将一样非常简单。

 

上下文信息

NLog最具优势的特性之一就是它的布局(layout)概念。“${}”符号用来表示“布局呈现器(layout renderer)”,即随当前日志插入一段上下文信息。我们可以在很多地方使用布局,例如控制日志信息写入到屏幕以及文件中的格式,甚至还可以控制日志输出文件的名称。这个特性功能非常强大,接下来我们就来看看:

假设我们需要为输出到控制台的每一条信息添加如下附加信息:

  1. 当前的时间日期
  2. 发送该消息的类名和方法名
  3. 日志等级
  4. 日志内容

实现起来非常简单:

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

还可以让来自不同类的日志信息输出到不同的文件中:

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

可以看到,上面我们在fileName属性中使用了${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
  • ...

一个非常常见的需求就是将每天的日志文件分开存放。使用${shortdate}布局呈现器,这个要求真是小菜一碟:

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

想要为每个员工生成不同的日志文件?${windows-identity}布局呈现器可以轻松搞定:

<target name="f" xsi:type="File" filename="${windows-identity:domain=false}.txt"/> 

这样,NLog将根据每个员工的登陆信息将日志输出到单独的文件中:

  1. Administrator.txt
  2. MaryManager.txt
  3. EdwardEmployee.txt
  4. ...

当然还有更加复杂的情况。下面这个配置文件就为每个人每天生成一个单独的日志文件,并存放至用时间区分的目录中:

<target name="f" xsi:type="File" 
        filename="${shortdate}/${windows-identity:domain=false}.txt"/> 

这条配置信息将生成类似如下的一些日志文件:

  1. 2006-01-01/Administrator.txt
  2. 2006-01-01/MaryManager.txt
  3. 2006-01-01/EdwardEmployee.txt
  4. 2006-01-02/Administrator.txt
  5. 2006-01-02/MaryManager.txt
  6. 2006-01-02/EdwardEmployee.txt
  7. ...

NLog提供了很多与定义的布局呈现器,在http://www.nlog-project.org/layoutrenderers.html 这个页面中有详细介绍。创建自己的布局呈现器也同样简单,依然是15-20行代码的事,请参考NLog的文档(documentation )。

 

包含文件

有时我们需要将NLog的配置文件分割成几个存放。NLog同样支持在某一配置文件中对其他的配置文件进行引用包含,然后在运行时一起处理。和NLog配置文件中其他部分一样,我们可以使用熟悉的${var}标记。这样就方便根据不同环境设置智能装载相应的配置文件,例如如下示例降加载基于计算机名的配置文件:

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

使用变量则可以方便地处理复杂的表达式,或者以统一的方式引用多次重复出现的表达式。我们可以使用<variable name="var" value="xxx" />表达式定义一个变量,定义之后该变量即可在各种布局呈现器中使用——同样是${var}语法。例如下面的示例:

<nlog> 
  <variable name="logDirectory" value="${basedir}/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> 
posted on 2006-12-06 18:15  Dflying Chen  阅读(13921)  评论(30编辑  收藏  举报