NLog文章系列——如何优化日志性能
作者:Jarosław Kowalski <jaak@jkowalski.net>
翻译:CrazyCoder(由衷感谢他的热心!!)
原文:http://www.nlog-project.org/howto_optimize_performance.html
更多关于NLog的中文文章,请参考《NLog文章系列》。
概述
日志的记录有时也要化为颇为可观的时间。本文的目的就是揭开日志记录的内部机理并提供一些有用的技巧帮助使用者优化日志记录的性能。
日志记录过程分析
每条日志信息的记录都需要经过一系列的步骤才能完成,其中包括诸如检查消息是否需要被记录以及输出到哪里等。每一条日志的记录都包括以下这些操作:
- 准备日志参数。这是由(.NET/Mono)的公共语言运行时完成的,通常由于一些内部的装箱和数组的操作会导致一些性能上的损失。
- 日志参数准备好以后就可以调用相应的日志方法(
Debug(), Info(), Warn(), Error(), Fatal()
orLog()
)。 - 日志方法以极快的速度检查该日志在该级别的输出是否已经被允许。由于使用了合适的数据结构,这一操作的速度很快。
- 即使成功通过上一步的检查,日志消息还是有可能不会被记录 – 过滤器的检查不通过的话消息就会被拒绝记录。注意,这一步可能很耗时。
- 经过上述几个操作,日志消息被允许记录了 – 这是要根据消息和传递给日志记录方法的参数对消息进行格式化。由于
String.Format
并不快,这一操作可能会很慢。 - 最后一步就是把日志发送给一个或多个需要写入的输出目标。这通常是最慢的一个操作,主要是因为写入的目标通常是一些持久性的存储(文件,数据库)设备,向这些设备写入数据很花时间。
“太糟糕了…”,这可能是你现在的想法吧。不过幸运的是NLog提供了许多编程方面的机制来给日志记录提速。
性能优化技巧
缓存日志记录者
一旦通过调用LogManager.GetLogger()
方法得到了需要的日志记录者,最好的做法是能够把它保存在什么地方,这样就可以重复使用同一个实例而不需要再次调用LogManager.GetLogger()
。给类声明一个静态的成员是个不错的办法,下面就是一个例子:
using NLog;
class MyClass {
// storing logger reference in a static variable is clean and fast
static Logger logger = LogManager.GetLogger("MyClass");
static void Main()
{
logger.Debug("This is a debugging message");
// it is not recommended to get the logger and store it in a local variable
Logger logger2 = LogManager.GetLogger("MyClass");
logger2.Debug("This is a debugging message");
}
}
TODO: add more tips here
为什么要编写自定义过滤器?
过滤器的作用就是减少向日志目标输出不需要的日志信息。NLog提供一些预定义的过滤器,这些过滤器支持大多数常用的字符串运算符。如果这些预定义的过滤器不符合你的需求,那就自己动手吧。
怎样编写?
写一个过滤器并不复杂。写一个继承了NLog.Filter
的类并重写其中的Check()
方法就可以了。Check()
方法的返回值包括:
- FilterResult.Neutral – 该过滤器不想决定这个消息是否应被记录。其它的过滤器(如果有的话)可以进一步检查。
- FilterResult.Ignore – 这个消息不应该被记录。
- FilterResult.Log – 这个消息应该被记录。也不需要其它过滤器的进一步检查。
通常即使一个消息符合过滤条件,也应该让用户来决定这个消息是否应当被过滤。这种情况下如果符合过滤条件滤器都应当返回Result
。如果过滤器要支持用户自定义配置那么应该返回Result
或者FilterResult.Neutral
。
例子
这个例子里介于两个特定时间之间记录的日志信息会被过滤。
csc.exe /t:library /out:MyAssembly.dll /r:NLog.dll MyFirstFilter.cs
using System;
using System.Text;
using NLog;
namespace MyNamespace
{
[Filter("hourRange")]
public sealed class HourRangeFilter: Filter
{
private int _fromHour = 0;
private int _toHour = -1;
public int FromHour
{
get { return _fromHour; }
set { _fromHour = value; }
}
public int ToHour
{
get { return _toHour; }
set { _toHour = value; }
}
protected override FilterResult Check(LogEventInfo ev)
{
if (ev.TimeStamp.Hour >= FromHour && ev.TimeStamp.Hour <= ToHour)
return Result;
else
return FilterResult.Neutral;
}
}
}
如何使用自定义过滤器
只要把自定义过滤器所在的动态链接库引用到配置文件的<extensions />区域即可,具体做法请参考这里。
配置文件的例子
这个配置文件设置过滤在10:00和12:59之间记录的日志。很简单吧。
<nlog>
<extensions>
<add assembly="MyAssembly"/>
</extensions>
<targets>
<target name="console" type="Console"/>
</targets>
<rules>
<logger name="*" minLevel="Info" appendTo="console">
<filters>
<hourRange fromHour="10" toHour="12" action="Ignore"/>
</filters>
</logger>
</rules>
</nlog>
怎样将配置参数传递给过滤器
看一下上面的例子,“FromHour”和“ToHour”这个两个属性就是两个配置参数。只需在类中声明公有属性来保存配置参数就可以了。过滤器配置中的每一个参数都会被传递给正确的公有属性。NLog支持integer,string,datetime和boolean类型的参数并会对类型进行自动转换。参数都是大小写敏感的。
<filters> ... <hourRange fromHour="10" toHour="12" action="Ignore" /> ... </filters>
这里在配置过滤器的时候FromHour的值被设为10,ToHour的值被设为12。可以使用更多的参数来传递更多的属性:
<filters> ... <hourRange p1="" p2="" p3="" p4="" pN="" action="Ignore" /> ... </filters>
需要一个专门的动态链接库吗?
完全不必。可以调用FilterFactory.AddFilter()来通过程序注册过滤器。不过必须保证注册完成之前不能记录任何日志信息。在<extensions />区域参照EXE可执行文件是允许的。
static void Main(string[] args)
{
FilterFactory.AddFilter("MyFirst", typeof(MyNamespace.MyFirstFilter));
// start logging here
}
NLog文章系列——如何配置NLog
作者:Jarosław Kowalski <jaak@jkowalski.net>
翻译:CrazyCoder(由衷感谢他的热心!!)
原文:http://www.nlog-project.org/config.html
更多关于NLog的中文文章,请参考《NLog文章系列》。
NLog支持以多种不同方式配置,目前同时支持直接编程和使用配置文件两种方法。本文将对目前支持的各种配置方式作详细描述。
日志配置
通过在启动的时候对一些常用目录的扫描,NLog会尝试使用找到的配置信息进行自动的自我配置。当你运行一个独立的*.exe客户端可执行程序时,NLog将在以下目录搜索配置信息:
- 标准的程序配置文件(通常为 程序名.exe.config)
- 程序目录下的程序名.exe.nlog文件
- 程序目录下的NLog.config文件
- NLog.dll所在目录下的NLog.dll.nlog文件
- 如果定义了NLOG_GLOBAL_CONFIG_FILE环境变量,则该变量所指向的文件
如果是一个ASP.NET程序,被搜索的目录包括:
- 标准的web程序配置文件web.config
- 和web.config在同一目录下的web.nlog文件
- 程序目录下的NLog.config文件
- NLog.dll所在目录下的NLog.dll.nlog文件
- 如果定义了NLOG_GLOBAL_CONFIG_FILE环境变量,则该变量所指向的文件
由于.NET Compact Framework不支持程序配置文件(*.exe.config)和环境变量,因此NLog将只会扫描这些地方:
- 程序目录下的NLog.config文件
- NLog.dll所在目录下的NLog.dll.nlog文件
- 如果定义了NLOG_GLOBAL_CONFIG_FILE环境变量,则该变量所指向的文件
配置文件格式
NLog支持两种配置文件格式
- 配置信息嵌入在.NET应用程序标准的*.exe.config或者web.config文件里
- 保存在独立文件里,也叫单一格式
如果你选择了第一种方式,使用的是标准的configSections这种机制,那么你的配置文件看起来差不多是这个样子:
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<nlog>
</nlog>
</configuration>
单一格式的配置文件就是一个以<nlog />为根节点的纯XMl文件。命名空间并不强制使用,如果使用的话我们就可以利用Visual Studio的智能感应。
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
</nlog>
需要注意的是NLog的配置文件总是大小写敏感的,不管是在使用的时候,或者即使你没有使用名字空间。当然只有你的大小写符合要求,智能感应才能正常工作。
配置元素
下面这些元素可以作为<nlog />的字节点。列表中的前两个元素在所有的NLog配置文件中都必须提供,其余的则可以选择使用,通常用于一些复杂场景。
- <targets /> - 定义日志的目标/输出
- <rules /> - 定义日志的路由规则
- <extensions /> - 从*.dll加载NLog扩展
- <include /> - 导入外部配置文件
- <variable /> - 为配置变量赋值
输出目标
<target />区域定义了日志的目标或者说输出。每一个<target />元素代表一个目标。我们需要为每一个目标设置两个属性:
- name - 目标的名称
- type - 目标的类型 - 比如“File”,“Database”,“Mail”。如果你使用了名字空间,这个属性会被命名为 xsi:type.
除了这两个属性,通常来说给目标添加一些其它参数,这些属性将会影响你在程序中如何使用诊断跟踪语句(diagnostic traces)。每一个目标都可以有一组不同的参数集合,并且参数都是上下文相关的,你可以在本项目的主页上找到更多关于参数的详细说明。Visual Studio的智能感应对这些参数同样有用。
举个例子 - “File”目标可以使用“fileName”作为参数来定义输出文件名,而“Console”目标可以借助“error”参数的值来判断是否应该把当前进程的diagnostic traces结果输出到标准错误(stderr)还是标准输出(stdout)控制台。
下面这个例子演示了在<targets />区域同时定义多个目标:两个files目标,一个network目标和一个OutputDebugString目标:
<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提供了许多已经预先定义好的目标。关于这些目标的详细说明请参考本项目的主页。实际上,你也可以很容易的为自己创建目标 - 全部只需大约15-20行代码即可,更多信息请参考项目文档。
路由规则
<rules />区域定义了日志的路由规则。实际上它是一个简单的路由表,对每一个日志源/记录者的名称和记录等级的组合,定义了一个日志写入目标列表。 表中的规则是被顺序处理的。每当遇到匹配的规则时,日志信息就会被送到规则中定义的一个或多个目标去。如果一个规则被标识为最后一个,那么其后的规则都不会被执行。
每一个路由表项就是一个<logger />元素,它的可以接受的属性有:
- name - 日志源/记录者的名字 (允许使用通配符*)
- minlevel - 该规则所匹配日志范围的最低级别
- maxlevel - 该规则所匹配日志范围的最高级别
- level - 该规则所匹配的单一日志级别
- levels - 该规则所匹配的一系列日志级别,由逗号分隔。
- writeTo - 规则匹配时日志应该被写入的一系列目标,由逗号分隔。
- final - 标记当前规则为最后一个规则。其后的规则即时匹配也不会被运行。
一些例子:
- <logger name="Name.Space.Class1" minlevel="Debug" writeTo="f1" /> - 名字空间Name.Space下的Class1这个类的所有级别等于或者高于Debug的日志信息都写入到“f1”这个目标里。
- <logger name="Name.Space.Class1" levels="Debug,Error" writeTo="f1" /> -名字空间Name.Space下的Class1这个类的所有级别等于Debug或Error的日志信息都写入到“f1”这个目标里。
- <logger name="Name.Space.*" writeTo="f3,f4" /> -名字空间Name.Space下所有类的所有级别的日志信息都写入到“f3”和“f4”这两个目标里。
- <logger name="Name.Space.*" minlevel="Debug" maxlevel="Error" final="true" /> - 名字空间Name.Space下所有类的、级别在Debug和Error之间的(包括Debug,Info,Warn,Error) 日志信息都不会被记录(因为这条规则没有定义writeTo),同时其它后续规则也都会被忽略(因为这里设置了final="true")。
最简单的情况下,整个日志的配置信息可以只由一个<target />元素和一个<logger />规则构成,就可以吧一定级别的日志信息路由到期望的目标去。随着程序不断的变大,增加新的目标和规则也很简单。
上下文信息
NLog最棒的功能之一就是使用布局(layouts)的能力。布局由被一个美元符号$加左大括弧“${”和一个右大括弧“}”为标记所包围的文本所组成。这个标记也就是所谓的“布局生成器(layout renderers),我们可以用它来把一些上下文相关的信息插入到日志信息中。布局可以应用在许多地方,比如可以被用在控制输出到屏幕或写入文件信息的格式,也可以用在控制文件名。接下来我们会更多的了解布局的强大。
假设我们希望每个输出到控制台的信息都包含一些这些信息:
· 当前的日期和时间
· 产生日志信息的类和方法的名字
· 日志等级
· 日志内容
利用Layout来实现很简单:
<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"/>
这样我们就能够给每一个职员生成一个日志文件了:
- Administrator.txt
- MaryManager.txt
- EdwardEmployee.txt
- ...
更复杂的场景也能做到。下面这个例子说明了如何为每个人每天生成一个日志文件。每天的日志文件存放在不同的文件夹里:
<target name="f" xsi:type="File"
fileName="${shortdate}/${windows-identity:domain=false}.txt"/>
这将创建如下文件:
- 2006-01-01/Administrator.txt
- 2006-01-01/MaryManager.txt
- 2006-01-01/EdwardEmployee.txt
- 2006-01-02/Administrator.txt
- 2006-01-02/MaryManager.txt
- 2006-01-02/EdwardEmployee.txt
- ...
NLog提供了许多预先定义好的布局生成器。关于它们的说明都在这个页面:http://www.nlog-project.org/layoutrenderers.html。建立你自己的布局生成器也很容易,大概只需要15-20行的代码而已。详细做法请参考项目文档。
包含文件
有时我们希望把配置文件分割为一些比较小的文件。NLog提供了包含文件这一机制来支持这种需求。要包含一个外部文件,你需要做的只是设置fileName这个属性。同时,和其它大多数NLog配置文件的属性一样,fileName也支持用大家都很熟悉的${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>
自动再配置
配置文件在程序启动时会被自动读取。然而在一些长时间运行的程序中(比如Windows服务或者ASP.NET程序),有时我们希望能够在不中断程序的前提下临时提高日志的级别。NLog可以一直监视日志配置文件的状态,并在它们被修改后重新读取。要激活这一机制,你只需在你的配置文件中设置<nlog autoReload="true" />。注意自动再配置支持引入文件,所以每次如果一个引入文件被修改了,会引起整个配置信息被重新载入。
日志排错
有时候即使你觉得你已经把日志配置的没有任何问题了,你的程序就是不输出任何日志信息。原因可能有很多,最常见的是权限问题,尤其在ASP.NET程序里,aspnet_wp.exe或者w3wp.exe进程可能没有足够的权限访问存放日志文件的目录。NLog被设计为吃掉任何由于记录日志而带来的运行时异常。而下面这些设置可以改变这种行为并/或者重定向这些信息。
· <nlog throwExceptions="true" />- 设置throwExceptions属性为“true”可以让NLog不再阻挡这类异常,而是把它们抛给调用者。在部署是这样做可以帮我们快速定位问题。一旦应用程序已经正确配置了,我们建议把throwExceptions的值设为“false”,这样由于日志引发的问题不至于导致应用程序的崩溃。
· <nlog internalLogFile="file.txt" />- 设置internalLogFile属性可以让NLog把内部的调试和异常信息都写入指定文件里。
· <nlog internalLogLevel="Trace|Debug|Info|Warn|Error|Fatal" /> - 决定内部日志的级别,级别越高,输出的日志信息越简洁。
· <nlog internalLogToConsole="false|true" /> - 是否把内部日志输出到标准控制台。
· <nlog internalLogToConsoleError="false|true" /> - 是否把内部日志输出到标准错误控制台 (stderr)。
异步处理,封装和复合目标
NLog提供的封装和复合目标可以修改其它目标的行为,这可以增加一些功能如:
· 异步处理 (被封装的目标在另一个线程上运行)
· 自动重试 (retry-on-error)
· 负载平衡 (round-robin targets)
· 缓冲 (buffering)
· 过滤 (filtering)
· 备份目标 (灾难恢复failover)
· 更多请参考http://www.nlog-project.org/targets.html
定义一个封装或者复合目标,你只需在一个目标节点里嵌套另一个目标节点即可。你甚至可以封装一个封装目标。嵌套的层数没有任何限制。比如,要给你的配置文件加上异步日志记录的功能,同时异步日志记录可以自动重试,你可以这样做:
<targets>
<target name="n" xsi:type="AsyncWrapper">
<target xsi:type="RetryingWrapper">
<target xsi:type="File" fileName="${file}.txt"/>
</target>
</target>
</targets>
因为异步处理使用的非常普遍,NLog专门为异步处理设计了一个简化符号,这样所有需要异步处理的目标都不需要显式的定义封装了。你只要设置<targets async="true" />然后你所有的目标就都具备了异步处理的能力了。
缺省封装
有时我们希望用同一种封装来处理所有的目标,比如说增加缓冲和/或自动重试功能。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 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也提供了<default-target-parameters />来让你为目标参数设置缺省值。比如,如果你不希望日志文件总是被打开,你既可以通过给每一个目标增加 keepFileOpen=”false”属性来达到这个目的:
<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 />区域里所有的目标。缺省参数时依据不同的类型定义的,并且在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>
NLog文章系列——与Visual Studio集成
作者:Jarosław Kowalski <jaak@jkowalski.net>
翻译:CrazyCoder(由衷感谢他的热心!!)
原文:http://www.nlog-project.org/visualstudio.html
更多关于NLog的中文文章,请参考《NLog文章系列》。
NLog可以完全支持与Visual Studio 2005集成(包括支持Visual C#和Visual Basic.NET的Express版)。与Visual Studio .NET 2002和2003也可以集成,不过有一部分功能将不可用。下面关于这些集成特性的说明:
- 代码智能感知- Intellisense(TM)
- 集成到添加参照的对话框 - Integration with Add/Reference dialog
- 配置模板 - New Item Templates
- 代码片断 - Code Snippets
代码智能感知 - Intellisense(TM)
无论编辑App.config还是独立的配置文件,NLog支持在编辑XML配置文件的时候使用代码智能感知功能。只需把两个命名空间的声明加到<nlog />标签里:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- configuration goes here -->
</nlog>
接下来需要把<target type="TypeName" /> 修改为 <target xsi:type="TypeName" />。现在,Visual Studio就能很好的为你的配置文件提供智能感知和检查功能了。这里有一个演示视频(小心!这是一个22MB的Flash)。
把NLog的动态链接库集成到添加参照对话框
NLog的安装程序会把NLog的动态链接库信息注册到Visual Studio的相关注册表项目中,这样在Visual Studio的添加参照的对话框中我们就能够找到NLog的几个动态链接库。Visual Studio的所有版本都可以使用这一功能。
配置模板
NLog内置了3个模板配置文件,你可以通过“添加新项”对话框添加并把它们快速应用到你的工程里。这3个模板是:
· 定义了一个文件目标的配置文件(最常用)
· 定义了一个控制台目标的配置文件
· 一个空配置文件
请注意:一定要把NLog.config文件的属性“Copy to Output Directory”设为“Copy always”。
配置模板只支持Visual Studio 2005的各个版本。
代码片断
NLog会向Visual Studio 2005安装一个“nlogger”的代码片断,用这个代码片断可以很快地向程序里添加一个日志记录者。其生成的代码如下:
private static Logger logger = LogManager.GetCurrentClassLogger();
Last updated: 2006-07-10 11:32:55
NLog文章系列——入门教程(上)
作者:Jarosław Kowalski <jaak@jkowalski.net>
翻译:Dflying Chen:http://dflying.cnblogs.com/
原文:http://www.nlog-project.org/tutorial.html
本文为《NLog文章系列》的第二篇,将用实例程序演示用NLog书写日志的方法。
应用程序跟踪介绍
很久以前,在那个没有调试器,软件也大都是基于控制台的年代里,开发者习惯于使用printf()语句输出跟踪调试信息。而现在,世界发生了翻天覆地般的变化——printf()被Console.WriteLine()代替了……
我们都曾经书写过类似如下的代码:
static void Main()
{
Console.WriteLine("SuperApp started.");
DoSomething();
Console.WriteLine("SuperApp finished.");
}
上面这段代码中的Console.WriteLine() 就是所谓的“跟踪”语句,因为这个语句除了输出当前程序的执行状态之外,并没有什么其他用处。由Console.WriteLine() 的输出也叫做应用程序跟踪。在上面的例子中,这两条跟踪语句就用来告诉我们DoSomething()方法是否执行完毕。
在开发以及测试完成之后,我们可能会想要删除这些跟踪代码,以提高序执行效率(因为跟踪调试语句执行效率很低)。通常我们将这些跟踪语句注释掉,以便今后需要的时候可以方便地再次启用。可是不幸的是,将跟踪语句注释掉之后,我们还需要重新编译一遍程序。
或许有一天,在经历过第N次将无数的调试语句注释和取消注释之后,你会依稀感觉到这样并不是一个好的解决方案,并期待着这样的功能:
- 能够通过简单的方法控制显示哪些等级的跟踪信息(例如只显示警告和错误级别的跟踪信息,或是显示所有级别的跟踪信息等)。
- 将控制跟踪信息的显示与否的逻辑与应用程序的视线代码分开,跟踪信息的显示与否并不需要重新编译应用程序。
- 将跟踪信息写至文件、系统日志、消息队列……
- 能够将一些极为重要的信息通过Email发送给指定收信人,或是存放在数据库中。
- 更多你能想到的……
有些朋友可能觉得,在图形化调试器大行其道的当今软件开发环境中,这种书写日志的跟踪调试方式似乎用处非常有限。不过,当你的程序每一秒都被成千上万人同时访问,哪怕是停机一分钟都不能接受的时候,你就会知道这些调试信息对定位Bug来说意味着什么了(即所谓的“Live Site Debugging”)。
NLog是什么?
NLog((http://www.nlog-project.org)是一个基于.NET平台编写的类库,我们可以使用NLog在应用程序中添加极为完善的跟踪调试代码。NLog完全实现了我们上面的期望目标,并且还远远不止这些……
NLog允许我们自定义从跟踪消息的来源(source)到记录跟踪信息的目标(target)的规则(rules)。记录跟踪信息的目标(target)可以为如下几种形式:
- 文件
- 文本控制台
- 数据库
- 网络中的其它计算机(通过TCP或UDP)
- 基于MSMQ的消息队列
- Windows系统日志
- 其他形式,请参考http://www.nlog-project.org/targets.html
除此之外,每一条跟踪消息都可以自动带有上下文信息(contextual information),并将其发送给记录跟踪信息的目标。这些上下文信息可以包含如下内容:
- 当前的日期和时间(多种格式)
- 记录等级
- 来源名称
- 输出跟踪消息的方法的堆栈信息
- 环境变量的值
- 异常的详细信息
- 计算机、进程和线程名称
- 其他,请参考:http://www.nlog-project.org/layoutrenderers.html
每条跟踪信息都包含一个记录等级(log level)信息,用来描述该条信息的重要性。NLog支持如下几种记录等级:
- Trace - 最常见的记录信息,一般用于普通输出
- Debug - 同样是记录信息,不过出现的频率要比Trace少一些,一般用来调试程序
- Info - 信息类型的消息
- Warn - 警告信息,一般用于比较重要的场合
- Error - 错误信息
- Fatal - 致命异常信息。一般来讲,发生致命异常之后程序将无法继续执行。
NLog是一个免费的、基于BSD license发布的开源类库。即使将其应用于商业使用中,也基本上不会有任何的限制。NLog的二进制可执行文件以及原文件均可在http://www.nlog-project.org/download.html页面中下载。我们同时还为NLog提供了图形界面的安装程序,您可以选择NLog的安装路径,并可在安装过程中添加如下内容到Visual Studio集成开发环境中(同样支持Express版本):
- 配置文件模板
- NLog配置文件智能感知支持
- 代码片断(code snippet)
- 集成至“Add Reference...”对话框
我们的第一个NLog应用程序
接下来让我们用Visual Studio 2005创建第一个使用NLog的应用程序。该示例程序将从把日志输出到控制台开始,并不断添加新的功能,以演示在NLog中对日志进行配置的方法。
首先在Visual Studio 2005中创建一个新项目(本示例程序将使用C#演示),然后在“Add New Item...”对话框中为该程序添加一个NLog配置文件。这里我们选择“Empty NLog Configuration File”,并命名为“NLog.config"”:
注意到NLog.dll的引用被自动添加到了我们的项目中。刚刚添加的NLog.config文件的内容如下,这也正是我们在本示例程序中将要配置的:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
</targets>
<rules>
</rules>
</nlog>
接下来需要一个额外的步骤:设置该配置文件的“Copy To Output Directory”选项为“Copy always”。这样该配置文件将自动被部署到*.exe所在的目录下。这样以后,无需任何设置,NLog即可自动搜寻到并加载该配置文件。
接下来让我们配置一下日志的输出,在<targets />节中,添加一个新条目让日志输出到控制台中,并添加必要的输出布局(layout):
<targets>
<target name="console" xsi:type="Console"
layout="${longdate}|${level}|${message}"/>
</targets>
在输入上述代码时,可以看到Visual Studio的智能感知功能发挥了作用:输入xsi:之后,将得到当前可用的输出目标列表:
然后,我们要在<rules />节中添加必要的规则,将所有记录等级等于或高于Debug的信息输出至控制台。这段XML配置文件字解释能力足够强,无需多言:
<rules>
<logger name="*" minlevel="Debug" writeTo="console"/>
</rules>
若希望生成并输出诊断信息,我们还需要添加一个Logger对象。Logger对象的方法名和记录等级的名称一样(Debug()、Info()、Fatal()……)。Logger对象是通过LogManager对象创建的。建议Logger对象的名称和程序的类名保持一致。调用LogManager的GetCurrentClassLogger()方法即可自动为当前类创建一个Logger对象。
接下来开始修改Visual Studio自动生成的这个C#文件。首先在文件头部添加“using NLog”语句,引入NLog程序集的命名空间。然后添加创建Logger对象的代码,注意在这里我们可以使用随NLog的安装而添加的Visual Studio的代码片断:输入“nlogger”,然后按两次Tab键即可。
using System;
using System.Collections.Generic;
using System.Text;
using NLog;
namespace NLogExample
{
class Program
{
private static Logger logger = LogManager.GetCurrentClassLogger();
static void Main(string[] args)
{
logger.Debug("Hello World!");
}
}
}
运行该程序,将看到一条日志信息输出到了控制台,该信息包含当前的时间,记录等级,以及“Hello World”消息。
最后,让我们总结一下实现该功能的步骤:
- 用LogManager.GetCurrentClassLogger(); 创建了一个Logger对象。该Logger对象代表与当前类相关联的日志消息的来源。
- 通过调用Logger对象的Debug()方法,发出一条Debug记录等级的诊断信息。
- 因为记录等级和消息来源符合配置文件中的<rules />声明,所以该消息将以指定的布局(layout)格式化后输出到控制台中。
稍微复杂一些的场景
接下来让我们将这些日志信息,包括其中的一些上下文信息(例如堆栈信息等),输出到文件和命令行两个地方。要实现这个需求,我们只要修改NLog的配置文件,并添加一个类型为“File”的目标即可。
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="console" xsi:type="ColoredConsole"
layout="${date:format=HH\:mm\:ss}|${level}|${stacktrace}|${message}"/>
<target name="file" xsi:type="File" fileName="${basedir}/file.txt"
layout="${stacktrace} ${message}"/>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="console,file"/>
</rules>
</nlog>
接下来这段C#代码生成了更多的日志信息,还使用了NLog提供的一些其他方法用来输出堆栈信息。
static void C()
{
logger.Info("Info CCC");
}
static void B()
{
logger.Trace("Trace BBB");
logger.Debug("Debug BBB");
logger.Info("Info BBB");
C();
logger.Warn("Warn BBB");
logger.Error("Error BBB");
logger.Fatal("Fatal BBB");
}
static void A()
{
logger.Trace("Trace AAA");
logger.Debug("Debug AAA");
logger.Info("Info AAA");
B();
logger.Warn("Warn AAA");
logger.Error("Error AAA");
logger.Fatal("Fatal AAA");
}
static void Main(string[] args)
{
logger.Trace("This is a Trace message");
logger.Debug("This is a Debug message");
logger.Info("This is an Info message");
A();
logger.Warn("This is a Warn message");
logger.Error("This is an Error message");
logger.Fatal("This is a Fatal error message");
}
运行该程序,如下日志信息将被写入应用程序所在目录中的“file.txt”文件中。
Program.Main This is a Trace message
Program.Main This is a Debug message
Program.Main This is an Info message
Program.Main => Program.A Trace AAA
Program.Main => Program.A Debug AAA
Program.Main => Program.A Info AAA
Program.Main => Program.A => Program.B Trace BBB
Program.Main => Program.A => Program.B Debug BBB
Program.Main => Program.A => Program.B Info BBB
Program.A => Program.B => Program.C Info CCC
Program.Main => Program.A => Program.B Warn BBB
Program.Main => Program.A => Program.B Error BBB
Program.Main => Program.A => Program.B Fatal BBB
Program.Main => Program.A Warn AAA
Program.Main => Program.A Error AAA
Program.Main => Program.A Fatal AAA
Program.Main This is a Warn message
Program.Main This is an Error message
Program.Main This is a Fatal error message
同时,控制台中也输出了如下漂亮的日志信息。
再来修改一下配置文件——开发中一个很常见的需求就是让不同记录等级的日志输出到不同的目标中。例如,让记录等级等于或高于Info的信息输出至控制台,同时将任意记录等级的信息都存放在文件中保存。在NLog中,实现这个需求只要修改配置文件的<rules />节即可,无需修改应用程序。
<rules>
<logger name="*" minlevel="Info" writeTo="console"/>
<logger name="*" minlevel="Trace" writeTo="file"/>
</rules>
再次运行程序,可以看到Trace和Debug等级的信息只出现在了文件中,而并不显示在控制台中。
(待续……)
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文件配合使用时,将自动按照顺序搜索下列路径,以得到配置文件:
- 应用程序的标准配置文件(通常为applicationname.exe.config)
- 应用程序所在目录中的applicationname.exe.nlog文件
- 应用程序所在目录中的NLog.config文件
- NLog.dll所在目录中的NLog.dll.nlog文件
- 环境变量NLOG_GLOBAL_CONFIG_FILE所指向的文件
对于ASP.NET应用程序,NLog将自动按照顺序搜索下列路径:
- Web应用程序的标准配置文件——web.config
- web.config所在目录中的web.nlog文件
- 应用程序所在目录中的NLog.config文件
- NLog.dll所在目录中的NLog.dll.nlog文件
- 环境变量NLOG_GLOBAL_CONFIG_FILE所指向的文件
.NET Compact Framework并不支持应用程序配置文件(*.exe.config)以及环境变量,因此NLog将自动按照顺序搜索下列路径:
- 应用程序所在目录中的applicationname.exe.nlog文件
- 应用程序所在目录中的NLog.config文件
- NLog.dll所在目录中的NLog.dll.nlog文件
配置文件形式
NLog支持两种形式的配置文件:
- 嵌入到*.exe.config或web.config等标准配置文件中
- 单独的配置文件
对于第一种形式,我们使用了标准化的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 />根元素中,我们可以指定如下的子元素。其中前两个是必须设定的,其余三个为可选设定。
- <targets /> - 定义日志的输出目标
- <rules /> - 定义对日志信息进行路由的规则
- <extensions /> - 定义从其他dll文件中加载的NLog扩展模块
- <include /> - 引入外部的配置文件
- <variable /> - 定义配置文件中用到的变量
输出目标(Target)
<targets />配置节用来定义日志信息的输出位置。每一个输出位置都用一个<target />元素表示。<target />元素有两个必须设置的属性:
- name - 输出目标的名称
- 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 />元素支持如下几个属性:
- name - 日志源(Logger的名称),可以使用*通配符
- minlevel - 匹配该规则需要的最低记录等级
- maxlevel - 匹配该规则需要的最高记录等级
- level - 匹配该规则需要的单一的记录等级
- levels - 匹配该规则需要的记录等级列表,记录等级之间用逗号隔开
- writeTo - 匹配该规则的日志信息将被发送至的输出目标列表,输出目标之间用逗号隔开
- 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)”,即随当前日志插入一段上下文信息。我们可以在很多地方使用布局,例如控制日志信息写入到屏幕以及文件中的格式,甚至还可以控制日志输出文件的名称。这个特性功能非常强大,接下来我们就来看看:
假设我们需要为输出到控制台的每一条信息添加如下附加信息:
- 当前的时间日期
- 发送该消息的类名和方法名
- 日志等级
- 日志内容
实现起来非常简单:
<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将根据每个员工的登陆信息将日志输出到单独的文件中:
- Administrator.txt
- MaryManager.txt
- EdwardEmployee.txt
- ...
当然还有更加复杂的情况。下面这个配置文件就为每个人每天生成一个单独的日志文件,并存放至用时间区分的目录中:
<target name="f" xsi:type="File"
filename="${shortdate}/${windows-identity:domain=false}.txt"/>
这条配置信息将生成类似如下的一些日志文件:
- 2006-01-01/Administrator.txt
- 2006-01-01/MaryManager.txt
- 2006-01-01/EdwardEmployee.txt
- 2006-01-02/Administrator.txt
- 2006-01-02/MaryManager.txt
- 2006-01-02/EdwardEmployee.txt
- ...
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>
NLog文章系列——入门教程(下)
作者:Jarosław Kowalski <jaak@jkowalski.net>
翻译:Dflying Chen:http://dflying.cnblogs.com/
原文:http://www.nlog-project.org/tutorial.html
本文为《NLog文章系列》的第四篇,即入门教程的最后一篇。将继续描述演示用NLog书写日志的方法。
自动重新配置
NLog的配置文件将在程序启动之后自动加载。对于某些将长时间运行的进程(例如Windows服务或ASP.NET应用程)来说,往往需要在程序运行当中临时性地提高记录等级,而这时我们却并不希望重新启动该应用程序。NLog可以自动跟踪其配置文件的变化,一旦配置文件被修改,NLog将立即自动重新加载。我们可以通过在配置文件中设置<nlog autoReload="true" />来实现该需求。这种自动重新配置功能也会应用到被包含的文件上,也就是说若包含文件发生了变化,NLog同样将自动重新加载整个的配置文件。
日志功能排错
虽然已经配置好了NLog,可是有些时候应用程序仍旧会出现一些难以理解的问题,例如没有任何日志输出。其中最常见的原因就是ASP.NET的权限——ASP.NET的aspnet_wp.exe或w3wp.exe可能没有对NLog配置文件中指定目录的写入权限。NLog对于其自身运行中发生的异常有着很强的监测能力。如下设定可以将这些监测结果输出至指定位置,或是对这些异常进行相应的处理(默认设定将忽略自身异常):
· <nlog throwExceptions="true" />- 当NLog自身掷出异常时,该选项可以将异常掷回日志的调用者。在开发过程中,这个设定将变得非常有用,能够迅速帮助我们定位异常的位置以及原因。而当程序开发结束并部署到应用环境时,应该尽快设定throwExceptions为false,免得NLog自身的异常导致整个应用程序的崩溃。
· <nlog internalLogFile="file.txt" />- 让NLog将自身运行过程中的日志信息(包括可能出现的异常)写入到文件中。
· <nlog internalLogLevel="Trace|Debug|Info|Warn|Error|Fatal" /> - 选择写入内部日志的记录等级。该等级设定的越高,相应的输出日志文件将越小。
· <nlog internalLogToConsole="false|true" /> - 将内部日志信息发送至控制台。
· <nlog internalLogToConsoleError="false|true" /> - 将内部日志信息发送至标准异常输出(stderr)。
异步处理、包装器(Warpper)以及复合输出目标
NLog的包装器和复合输出目标特性让我们能够修改输出目标的默认行为,这种修改体现在如下几个方面:
· 异步处理(向目标输出将用单独的线程处理)
· 异常时自动重试
· 负载平衡
· 缓存
· 过滤
· 备用输出目标(主输出目标失败时启用备用输出目标)
· 其他,请参考http://www.nlog-project.org/targets.html
只要在配置文件中将若干个target节点嵌套起来,即可完成对包装器或复合输出目标的定义。嵌套深度没有任何限制。例如为某个输出目标添加异步处理以及异常自动重试功能,只要按照如下代码配置NLog即可:
<targets>
<target name="n" xsi:type="AsyncWrapper">
<target xsi:type="RetryingWrapper">
<target xsi:type="File" fileName="${file}.txt"/>
</target>
</target>
</targets>
异步处理特性极为常用,因此NLog提供了一种简写方式——即<targets async="true" />,这样该输出目标将自动应用AsyncWrapper包装器。
以编程方式进行配置
某些情况下我们可能不愿用配置文件来配置NLog,而是选择使用NLog的配置API进行。对这些API的详细介绍已经超过了本文的范围,所以我们这里仅仅简单介绍一些。若希望以编程的方式对NLog进行配置,我们需要:
- 创建一个LoggingConfiguration对象,用来保存配置信息
- 至少创建一个输出目标对象
- 设置该输出目标对象的属性
- 设置LoggingRule对象,并将其添加到LoggingConfiguration对象的LoggingRules集合中
- 启用该LoggingConfiguration对象(将LogManager.Configuration设定为该LoggingConfiguration对象即可)
下面的代码片段以编程方式创建了两个输出目标对象——支持颜色的控制台和文件,并将记录等级等于或高于Debug的日志信息发送至这两个输出目标:
using NLog;
using NLog.Targets;
using NLog.Config;
using NLog.Win32.Targets;
class Example
{
static void Main(string[] args)
{
// Step 1. Create configuration object
LoggingConfiguration config = new LoggingConfiguration();
// Step 2. Create targets and add them to the configuration
ColoredConsoleTarget consoleTarget = new ColoredConsoleTarget();
config.AddTarget("console", consoleTarget);
FileTarget fileTarget = new FileTarget();
config.AddTarget("file", fileTarget);
// Step 3. Set target properties
consoleTarget.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}";
fileTarget.FileName = "${basedir}/file.txt";
fileTarget.Layout = "${message}";
// Step 4. Define rules
LoggingRule rule1 = new LoggingRule("*", LogLevel.Debug, consoleTarget);
config.LoggingRules.Add(rule1);
LoggingRule rule2 = new LoggingRule("*", LogLevel.Debug, fileTarget);
config.LoggingRules.Add(rule2);
// Step 5. Activate the configuration
LogManager.Configuration = config;
// Example usage
Logger logger = LogManager.GetLogger("Example");
logger.Trace("trace log message");
logger.Debug("debug log message");
logger.Info("info log message");
logger.Warn("warn log message");
logger.Error("error log message");
logger.Fatal("fatal log message");
}
}
NLog还能干点儿啥?
NLog supports some more logging scenarios, which couldn't be fully described here. See the links below for more information:
除此之外,NLog还支持一些更加复杂的需要日志记录的场景。限于篇幅,这里无法一一列出,若你对其感兴趣,可以参考如下链接:
· 异常日志记录 - http://sourceforge.net/mailarchive/forum.php?thread_id=6766833&forum_id=41984
· 条件表达式语言 - http://www.nlog-project.org/conditions.html
· NLogViewer - 实时的日志记录查看器(当前还在pre-alpha阶段)- http://viewer.nlog-project.org/
Last updated: 2006-07-10 11:32:55
译注and后记
CrazyCoder朋友将加入到NLog文档的翻译过程中,他目前已经完成了对NLog配置文件这一节的翻译,不日即将发布。我非常感谢CrazyCoder的无私奉献精神!
由于某些原因,这一段时间我又会忙起来了…………可能不会如这一个月一样这样频繁地更新这个Blog,当然对于留言,我仍会尽量及时答复的。十分感谢朋友们一贯的支持!
虽然很不情愿,但是很有可能这个《NLog文章系列》也没办法继续写下去了……我真的非常希望有热心的朋友可以参与进来,既可以帮助开源社区的发展,也可以学习到新的知识,与朋友们进行交流,更能够顺便提高自己的英文能力。
如果你愿意奉献出自己的一点点时间,参与《NLog文章系列》的翻译,烦请你和我联系。参与翻译之后,如果你有能力且愿意的话,我也十分愿意尽自己微薄之力,帮你和出版社联系并翻译出版真正的图书。
NLog使用方法
2012-04-16 15:06:08| 分类: C# | 标签:nlog、日志 |字号大小 订阅
一、软件
网站:http://www.nlog-project.org/
说明:如果是.Net 2.0使用, 请下载nlog-1.0-net-2.0.zip
里面的bin目录下有多个,c# 使用nlog.dll
文件:nlog.dll
大小:248K
版本:1.0.0.505
二、 WinForm下使用
添加nlog.dll的引用,然后在nlog.dll的文件夹下创建nlog.dll.nlog
内容如下:
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<targets>
<target name="console" xsi:type="ColoredConsole"
layout="${date:format=HH\:mm\:ss}|${level}|${stacktrace}|${message}"/>
<target name="file" xsi:type="File" fileName="${basedir}/log.txt"
layout="[${date:format=yyyy-MM-dd HH\:mm\:ss}][${level}] ${message} ${exception}"/>
</targets>
<rules>
<logger name="*" minlevel="debug" writeTo="console"></logger>
<logger name="*" minlevel="debug" writeTo="file"></logger>
</rules>
</nlog>
在你要写日志的类中如下使用:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace nlogDemo
{
public partial class Form1 : Form
{
NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
log.Info("hi");
}
}
}
三、WebForm,Asp.net下的使用方法
同样添加nlog.dll,不过这次的配置文件放到web.config中
如下:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<appSettings/>
<connectionStrings/>
<system.web>
<compilation debug="false">
</compilation>
<authentication mode="Windows"/>
</system.web>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="file" xsi:type="File" fileName="${basedir}/App_Data/log.txt"
layout="[${date:format=yyyy-MM-dd HH\:mm\:ss}][${level}] ${message} ${exception}" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="file" />
</rules>
</nlog>
</configuration>
注意:我把日志文件放到了App_Data下面了。这里的话不能下载的。
使用方法如下,default.aspx.cs
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using DevExpress.XtraCharts;
public partial class _Default : System.Web.UI.Page
{
NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();
protected void Page_Load(object sender, EventArgs e)
{
log.Info("hi");
}
}
更加详细的使用可以参考:
NLog Doc http://www.nlog-project.org/
NLog文章系列 http://www.cnblogs.com/dflying/archive/2006/12/15/593158.html
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/greenerycn/archive/2008/10/25/3142806.aspx
2008-10-25 12:55 1822人阅读 评论(1) 收藏 举报
NLog 在winform和webform下使用快速攻略
Greenerycn 2008-10-25
一、软件
网站:http://www.nlog-project.org/
下载:http://sourceforge.net/project/showfiles.php?group_id=116456
说明:如果是.Net 2.0使用, 请下载nlog-1.0-net-2.0.zip
里面的bin目录下有多个,c# 使用nlog.dll
文件:nlog.dll
大小:248K
版本:1.0.0.505
二、 WinForm下使用
添加nlog.dll的引用,然后在nlog.dll的文件夹下创建nlog.dll.nlog
内容如下:
- <?xml version="1.0" encoding="utf-8" ?>
- <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
- <targets>
- <target name="console" xsi:type="ColoredConsole"
- layout="${date:format=HH/:mm/:ss}|${level}|${stacktrace}|${message}"/>
- <target name="file" xsi:type="File" fileName="${basedir}/log.txt"
- layout="[${date:format=yyyy-MM-dd HH/:mm/:ss}][${level}] ${message} ${exception}"/>
- </targets>
- <rules>
- <logger name="*" minlevel="debug" writeTo="console"></logger>
- <logger name="*" minlevel="debug" writeTo="file"></logger>
- </rules>
- </nlog>
在你要写日志的类中如下使用:
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Text;
- using System.Windows.Forms;
- namespace nlogDemo
- {
- public partial class Form1 : Form
- {
- NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();
- public Form1()
- {
- InitializeComponent();
- }
- private void button1_Click(object sender, EventArgs e)
- {
- log.Info("hi");
- }
- }
- }
三、WebForm,Asp.net下的使用方法
同样添加nlog.dll,不过这次的配置文件放到web.config中
如下:
- <?xml version="1.0"?>
- <configuration>
- <configSections>
- <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
- </configSections>
- <appSettings/>
- <connectionStrings/>
- <system.web>
- <compilation debug="false">
- </compilation>
- <authentication mode="Windows"/>
- </system.web>
- <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <targets>
- <target name="file" xsi:type="File" fileName="${basedir}/App_Data/log.txt"
- layout="[${date:format=yyyy-MM-dd HH/:mm/:ss}][${level}] ${message} ${exception}" />
- </targets>
- <rules>
- <logger name="*" minlevel="Debug" writeTo="file" />
- </rules>
- </nlog>
- </configuration>
注意:我把日志文件放到了App_Data下面了。这里的话不能下载的。
使用方法如下,default.aspx.cs
- using System;
- using System.Collections.Generic;
- using System.Web;
- using System.Web.UI;
- using System.Web.UI.WebControls;
- using DevExpress.XtraCharts;
- public partial class _Default : System.Web.UI.Page
- {
- NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();
- protected void Page_Load(object sender, EventArgs e)
- {
- log.Info("hi");
- }
- }
更加详细的使用可以参考: