通过在启动的时候对一些常用目录的扫描,NLog会尝试使用找到的配置信息进行自动的自我配置。
单独的客户端,NLog将在以下目录搜索配置信息:
在ASP.NET项目中搜索的目录包括:
.NET Compact Framework不支持程序配置文件(*.exe.config)和环境变量,因此NLog将只会扫描这些地方:
从上面来看,不管哪个我们把配置文件命名为NLog.config,放在应用程序的目录下,肯定都可以扫描到,哈哈。
第一种就是我们熟悉的常规配置,使用configSections
<configuration> <configSections> <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/> </configSections> <nlog> </nlog> </configuration>
如果是第二种,是一个单独的Xml文件的话,需要按如下配置:
<nlog xmlns=http://www.nlog-project.org/schemas/NLog.xsd
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance > </nlog>
需要说明的是,根节点是<nlong></nlong>,两个命名空间是可选的,但是为了智能感应,你还是把它写上吧。
需要说明的是前两个元素,也就是targets和rules是必需配置的,其余是可选的,应该用于更复杂的配置上,我个人没用过还。
第一篇文章已经介绍过,应该不用再解释,具体输出到那个目标的详细配置,参见文档:https://github.com/nlog/NLog/wiki/Targets
<rules />区域定义了日志的路由规则。每一个路由表项就是一个<logger />元素。<logger />有以下属性:
如:
NLog最强大的功能之一就是使用布局(layouts)的能力。语法为:“${属性}”为标记所包围的文本所组成。这个标记也就是所谓的“布局生成器(layout renderers),我们可以用它来把一些上下文相关的信息插入到日志信息中。布局可以应用在许多地方,比如可以被用在控制输出到屏幕或写入文件信息的格式,也可以用在控制文件名。
假设我们希望每个输出到控制台的信息都包含一些这些信息:
利用Layout来实现很简单:,前面已经提到过:
<target name="c" xsi:type="Console" layout="${longdate} ${callsite} ${level} ${message}"/>
使用Layout控制输出的文件名:
<target name="f" xsi:type="File" fileName="${logger}.txt"/>
使用日期来区分日志文件。如果使用${shortdate}布局生成器:
<target name="f" xsi:type="File" fileName="${shortdate}.txt"/>
更多的布局生成器参考官方文档:
https://github.com/nlog/NLog/wiki/Layout%20Renderers
我们有这样的需求,不想让NLog.cofige文件太大,太多,读起来太累,我们可以把它分割下。如何分割成若干小的config呢?使用include简单完成。
<nlog> ... <include file="${basedir}/${machinename}.config"/> ... </nlog>
制定了要包含的config小文件位置就行。
配置文件中也可以定义变量,直接上例子,很明了:
<variable name="var" value="xxx" /> <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>
听起来确实挺不好理解的。但是确实也没什么。换句简单的话来说,当我们一旦启动程序,这时候NLog.config文件被读取后,知道程序再启动都不会再读取配置文件了。假如我们不想停掉程序,比如说服务器哪能说停就停哈。这就用上这个配置了,这个配置功能是,一旦你对配置文件修改,程序将会重新读取配置文件,也就是自动再配置。直接上代码:
<nlog autoReload="true"> ... </nlog>
程序没问题了,日志却出了问题。这个该怎么办,到底是哪里不正确了?假如日志本身除了bug该如何解决?这就需要日志排错。把日志的错误信息写入日志。
设置throwExceptions属性为“true”可以让NLog不再阻挡这类异常,而是把它们抛给调用者。在部署是这样做可以帮我们快速定位问题。一旦应用程序已经正确配置了,我们建议把throwExceptions的值设为“false”,这样由于日志引发的问题不至于导致应用程序的崩溃。
原理也不多说,直接上代码,使其具备异步处理能力。
<nlog> <targets async="true"> <!-- all targets in this section will automatically be asynchronous --> </targets> </nlog>
我们希望用同一种封装来处理所有的目标,比如说增加缓冲和/或自动重试功能。
NLog为此提供了专门的语法:<default-wrapper />。你只要把这个元素放在<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>
上面的例子里我们定义了两个缓冲文件目标和三个异步以及自动重试网络目标。
其实缺省就是把分散的统一在一个区域来定义,仅仅是个语法糖问题,缺省参数自然是把参数相同的抽象出来放到一个区域,统一定义罢了。下面代码是等价的。
<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>
<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>