在项目开发中,日志记录是任何时候都少不了的,在本文中,将简单介绍一下如下几种日志记录工具,以及推荐一些学习的资源:
1.Log4net
2.Logging Application Block
3.NLog
一.Log4net
Log4net是从java平台下非常优秀的日志记录框架log4j上移植到.NET下的,它是apache基金资助的项目的一部分。Log4net可以帮助我们把日志信息输出到各种不同目标(文本文件、数据库、控制台等)的.net类库,它可以容易的加载到开发项目中,实现程序调试和运行的时候的日志信息输出,提供了比.net自己提供的debug类和trace类的功能更多,使用起来也是非常的简单。在Log4net 主要有四种重要的组件,分别是Logge, Repository, Appender以及 Layout,Log4net支持两种不同的配置方式:配置文件和代码配置,一般情况下推荐使用配置文件,一个完整的配置示例如下:
已经能够完全满足我们日常开发的日志记录功能,但是它容易为人所诟病的一点是没有可视化的配置工具支持,需要手工编写配置文件。如果你还在担心这一点,不妨看看这篇《Log4net GUI configuration tool》文章,文中作者为我们提供了一种Log4net的可视化配置工具,界面如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler,
log4net-net-1.0" />
</configSections>
<log4net>
<root>
<level value="WARN" />
<appender-ref ref="AdoNetAppender" />
<appender-ref ref="ConsoleAppender" />
</root>
<logger name="testApp.Logging">
<level value="DEBUG"/>
</logger>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="100" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionString value="data source=[database server];initial catalog=[database name];integrated security=false;persist security info=True;User ID=[user];Password=[password]" />
<commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" />
<parameter>
<parameterName value="@log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="@thread" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread" />
</layout>
</parameter>
<parameter>
<parameterName value="@log_level" />
<dbType value="String" />
<size value="50" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level" />
</layout>
</parameter>
<parameter>
<parameterName value="@logger" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger" />
</layout>
</parameter>
<parameter>
<parameterName value="@message" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
<parameter>
<parameterName value="@exception" />
<dbType value="String" />
<size value="2000" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter>
</appender>
<appender name="ConsoleAppender"
type="log4net.Appender.ConsoleAppender" >
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern"
value="%d [%t] %-5p %c [%x] - %m%n"
/>
</layout>
</appender>
</log4net>
</configuration>
<configuration>
<configSections>
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler,
log4net-net-1.0" />
</configSections>
<log4net>
<root>
<level value="WARN" />
<appender-ref ref="AdoNetAppender" />
<appender-ref ref="ConsoleAppender" />
</root>
<logger name="testApp.Logging">
<level value="DEBUG"/>
</logger>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="100" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionString value="data source=[database server];initial catalog=[database name];integrated security=false;persist security info=True;User ID=[user];Password=[password]" />
<commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" />
<parameter>
<parameterName value="@log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="@thread" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread" />
</layout>
</parameter>
<parameter>
<parameterName value="@log_level" />
<dbType value="String" />
<size value="50" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level" />
</layout>
</parameter>
<parameter>
<parameterName value="@logger" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger" />
</layout>
</parameter>
<parameter>
<parameterName value="@message" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
<parameter>
<parameterName value="@exception" />
<dbType value="String" />
<size value="2000" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter>
</appender>
<appender name="ConsoleAppender"
type="log4net.Appender.ConsoleAppender" >
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern"
value="%d [%t] %-5p %c [%x] - %m%n"
/>
</layout>
</appender>
</log4net>
</configuration>
在该示例中,配置了两种目标的输出,分别为数据库和控制台方式,在代码中使用示例:
Log4net.ILog log = Log4net.LogManager.GetLogger("MyLogger");
if (log.IsDebugEnabled)
log.Debug("message");
if (log.IsInfoEnabled)
log.Info("message");
if (log.IsDebugEnabled)
log.Debug("message");
if (log.IsInfoEnabled)
log.Info("message");
Log4net
学习资料
1.Log4net的官方文档
2.Sema翻译的Log4net使用指南 (个人认为,如果你从没有接触过Log4net,看这篇就足够使用它了)
3.菩提树的Log4net五步走也很值得推荐。
二.Logging Application Block
Logging Application Block是微软Enterprise Library其中的一个应用程序块,可以使开发人员可以在其应用程序中集成标准的日志和监测功能,应用程序可以使用日志和监测块在多个位置记录事件,记录的位置包括:事件日志(Event Log)、电子邮件(Email)、数据库(DataBase)、文本文件(TextFile)、消息队列(MSMQ)、WMI、用户自定义位置。并且使用Enterprise Library Configuration工具进行完全可视化配置,并且可以设置输出日志信息的格式。如图所示:
配置完成后,所有的配置都放在了应用程序配置文件里面(针对EL2.0):
<configuration>
<configSections>
<section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging" />
</configSections>
<loggingConfiguration tracingEnabled="true" defaultCategory="General">
<logFilters>
<add
name="Category"
type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.CategoryFilter, Microsoft.Practices.EnterpriseLibrary.Logging"
categoryFilterMode="AllowAllExceptDenied">
<categoryFilters>
<add name="UI Events" />
</categoryFilters>
</add>
<add
name="Priority"
type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.PriorityFilter, Microsoft.Practices.EnterpriseLibrary.Logging"
minimumPriority="2"
/>
<add name="LogEnabled Filter"
type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.LogEnabledFilter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
enabled="true"
/>
</logFilters>
</loggingConfiguration>
</configuration>
<configSections>
<section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging" />
</configSections>
<loggingConfiguration tracingEnabled="true" defaultCategory="General">
<logFilters>
<add
name="Category"
type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.CategoryFilter, Microsoft.Practices.EnterpriseLibrary.Logging"
categoryFilterMode="AllowAllExceptDenied">
<categoryFilters>
<add name="UI Events" />
</categoryFilters>
</add>
<add
name="Priority"
type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.PriorityFilter, Microsoft.Practices.EnterpriseLibrary.Logging"
minimumPriority="2"
/>
<add name="LogEnabled Filter"
type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.LogEnabledFilter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
enabled="true"
/>
</logFilters>
</loggingConfiguration>
</configuration>
在代码中使用时非常简单,如下代码片断所示:
LogEntry logEntry = new LogEntry();
logEntry.EventId = 100;
logEntry.Priority = 2;
logEntry.Message = "Informational message";
//设置多个Category
logEntry.Categories.Add("Trace");
logEntry.Categories.Add("UI Events");
Logger.Write(logEntry);
logEntry.EventId = 100;
logEntry.Priority = 2;
logEntry.Message = "Informational message";
//设置多个Category
logEntry.Categories.Add("Trace");
logEntry.Categories.Add("UI Events");
Logger.Write(logEntry);
很多朋友使用Logging Application Block,有一个担心的地方就是Enterprise Library 2.0中把所有的配置信息都放在了应用程序配置文件里面,这样由配置工具生成的配置代码和我们手工添加的一些配置代码混合在一起,会显得非常混乱,如果你有这样的疑问,想把每一个应用程序块的配置信息单独放在外部文件中,不妨看看这篇文章《Enterprise Library 2.0 技巧(1):如何使用外部配置文件》
关于Logging Application Block还应该提一下它的可扩展性,除了系统中默认的输出目标之外,用户可以自行扩展自己的目标,比如说控制台等;除此之外,用户也可以扩展自己的日志输出格式,比如说XML格式等。
学习资源
三.NLog
NLog是C#编写的开源日志类库,它的设计思想是使其简单而灵活。NLog让你处理诊断的日志消息,用相关信息扩充消息,依照你的选择格式化日志消息和把日志消息输出到一个或多个目的地,基本上类似于Log4net。同样,NLog也提供了很多的扩展,可以自定义日志输出目标,日志格式,过滤器等。看一个简单的配置示例:NLog虽然没有提供可视化的配置工具,但是安装后,我们会在VS2005的New Item里面看到有关本NLog的配置文件这么一项,是用该配置文件是支持自动补全功能的。
<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>
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>
在代码中使用如下所示:
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");
}
{
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");
}
学习资源
没有发现目前有好的中文学习资源,大家可以参考官方文档,希望有时间可以写几篇NLog的使用教程,弥补一下当前中文文档的空缺。
总结
以上简单的介绍了.NET下的几种开源日志记录框架,如果你的系统整体架构都使用了Enterprise Library,那么使用Logging Application Block更适合你;否则,如果使用了NHiberante或者Castle等数据持久框架,那么选用Log4net将会更适合,因为在NH中本身就是用Log4net作为日志记录工具的;在没有使用任何其他框架的情况下,可以在以上几种工具中自行选用,个人认为它们都很优秀!
本文出自 “TerryLee技术专栏” 博客,请务必保留此出处http://terrylee.blog.51cto.com/342737/67594