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...”对话框
下面是一个配置文件模版,关于插件下载可以直接NUGET。
<?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"> <!-- See https://github.com/nlog/nlog/wiki/Configuration-file for information on customizing logging rules and outputs. --> <!-- 使用说明 1.一般控制台调式日志(打印到控制台) logger.Trace("GetHotelBrand 操作数据库异常 sqlText : " + sqlText); 2. 一般文本日志,如记录接口,响应值等 请求参数等(记录文本,支持异步), logger.Info("GetHotelBrand 操作数据库异常 sqlText : " + sqlText); 3.错误日志 一般影响到业务流程的正常使用 (记录到DB) logger.ErrorException("GetHotelBrand 操作数据库异常 sqlText : " + sqlText, ex); 4.致命性错误 如金额数据,订单数据操作失败 (发送邮件通知) logger.FatalException("GetHotelBrand 操作数据库异常 sqlText : " + sqlText, ex); --> <!-- add your targets here --> <targets> <!--调式打印控制台日志--> <target name="console" xsi:type="ColoredConsole" layout="[${date:format=yyyy-MM-dd HH\:mm\:ss}][${level}] ${message} ${exception}"/> <!-- 记录一般INFO文本日志(启用异步) --> <!--<target name="file" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard"> <target xsi:type="File" fileName="${basedir}/logs/logs/${shortdate}/${level}.log" layout="${longdate} ${uppercase:${level}} ${message}" maxArchiveFiles="100" archiveFileName="${basedir}/logs/logs/${shortdate}/${level}/${shortdate}_log.{#####}.txt" archiveAboveSize="10240" archiveNumbering="Sequence" concurrentWrites="true" /> </target>--> <!-- 普通文本日志记录 --> <target name="file" xsi:type="File" layout="${longdate} ${logger} ${message}" fileName="${basedir}/logs/${shortdate}/[${date:format=yyyy-MM-dd HH\:00\:00}].txt" <!-- 按小时记录--> archiveFileName="${basedir}/logs/archives/${shortdate}/log.{#####}.txt" archiveAboveSize="10240000" archiveNumbering="Sequence" concurrentWrites="true" keepFileOpen="false" /> <!-- 发生错误异常记录数据库日志 --> <target name="database" xsi:type="Database" useTransactions="true" connectionString="Data Source=XX;Initial Catalog=XXX;Persist Security Info=True;User ID=XX;Password=XX" commandText="insert into NLogExceptionInterFaceLog([CreateTime],[Origin],[LogLevel], [Message], [Exception],[StackTrace]) values (getdate(), @origin, @logLevel, @message,@exception, @stackTrace);"> <!--日志来源--> <parameter name="@origin" layout="${callsite}"/> <!--日志等级--> <parameter name="@logLevel" layout="${level}"/> <!--日志消息--> <parameter name="@message" layout="${message}"/> <!--异常信息--> <parameter name="@exception" layout="${exception}" /> <!--堆栈信息--> <parameter name="@stackTrace" layout="${stacktrace}"/> </target> <!-- 发生致命错误发送邮件日志 --> <target name="email" xsi:type="Mail" header="-----header------" footer="-----footer-----" layout="${longdate} ${level} ${callsite} ${message} ${exception:format=Message, Type, ShortType, ToString, Method, StackTrace}" html="false" encoding="UTF-8" addNewLines="true" subject="${message}" to="xxxxx@qq.com" from="xxxxx@163.com" body="${longdate} ${level} ${callsite} ${message} ${exception:format=Message, Type, ShortType, ToString, Method, StackTrace}" smtpUserName="xxxxx@163.com" enableSsl="false" smtpPassword="***********************" smtpAuthentication="Basic" smtpServer="smtp.163.com" smtpPort="25"> </target> </targets> <!-- add your logging rules here --> <rules> <!-- add your logging rules here --> <logger name="*" minlevel="Trace" writeTo="console" /> <logger name="*" minlevel="Info" writeTo="file" /> <logger name="*" minlevel="Fatal" writeTo="email" /> <logger name="*" level="Error" writeTo="database"></logger> </rules> </nlog>
一般性用法:
private readonly static NLog.Logger loger = NLog.LogManager.GetCurrentClassLogger();
string context = "Nlog日志"; loger.Info(context);
搬运自:http://www.cnblogs.com/dflying/archive/2006/12/05/583071.html

浙公网安备 33010602011771号