在项目开发中,日志记录是任何时候都少不了的,在本文中,将简单介绍一下如下几种日志记录工具,以及推荐一些学习的资源:
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
>
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
<
log4net
>
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
<
root
>
<
level
value
="WARN"
/>
<
appender-ref
ref
="AdoNetAppender"
/>
<
appender-ref
ref
="ConsoleAppender"
/>
</
root
>
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
<
logger
name
="testApp.Logging"
>
<
level
value
="DEBUG"
/>
</
logger
>
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
<
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
>
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
<
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
>
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
</
log4net
>
</
configuration
>
在该示例中,配置了两种目标的输出,分别为数据库和控制台方式,在代码中使用示例:
Log4net.ILog log
=
Log4net.LogManager.GetLogger(
"
MyLogger
"
);
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
if
(log.IsDebugEnabled)
log.Debug(
"
message
"
);
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
if
(log.IsInfoEnabled)
log.Info(
"
message
"
);
Log4net
![](https://i-blog.csdnimg.cn/blog_migrate/7eb6c1ca5e1407eb86c84605e5000173.gif)
官方主页:http://logging.apache.org/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工具进行完全可视化配置,并且可以设置输出日志信息的格式。如图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/5d939b8c978df35652d131a77456ab4a.gif)
配置完成后,所有的配置都放在了应用程序配置文件里面(针对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
>
在代码中使用时非常简单,如下代码片断所示:
LogEntry logEntry
=
new
LogEntry();
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
logEntry.EventId
=
100
;
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
logEntry.Priority
=
2
;
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
logEntry.Message
=
"
Informational message
"
;
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
//
设置多个Category
logEntry.Categories.Add(
"
Trace
"
);
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
logEntry.Categories.Add(
"
UI Events
"
);
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
Logger.Write(logEntry);
很多朋友使用Logging Application Block,有一个担心的地方就是Enterprise Library 2.0中把所有的配置信息都放在了应用程序配置文件里面,这样由配置工具生成的配置代码和我们手工添加的一些配置代码混合在一起,会显得非常混乱,如果你有这样的疑问,想把每一个应用程序块的配置信息单独放在外部文件中,不妨看看这篇文章《Enterprise Library 2.0 技巧(1):如何使用外部配置文件》
关于Logging Application Block还应该提一下它的可扩展性,除了系统中默认的输出目标之外,用户可以自行扩展自己的目标,比如说控制台等;除此之外,用户也可以扩展自己的日志输出格式,比如说XML格式等。
官方主页:http://msdn.microsoft.com/practices/
学习资源
1.Enterprise Library Step By Step系列(七):日志和监测应用程序块——入门篇
2.Enterprise Library Step By Step系列(八):日志和监测应用程序块——进阶篇
3.Enterprise Library 2.0(2):Logging Application Block学习
4.Enterprise Library 2.0 技巧(3):记录ASP.NET站点中未处理的异常
5.Enterprise Library 2.0 技巧(4):如何用编程的方法来配置Logging Application Block
6.Enterprise Library 2.0 Hands On Lab 翻译(4):日志应用程序块(一)
7.Enterprise Library 2.0 Hands On Lab 翻译(5):日志应用程序块(二)
8.Enterprise Library 2.0 Hands On Lab 翻译(6):日志应用程序块(三)
三.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
>
在代码中使用如下所示:
static
void
C()
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
{
logger.Info("Info CCC");
}
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
static
void
B()
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
{
logger.Trace("Trace BBB");
logger.Debug("Debug BBB");
logger.Info("Info BBB");
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
C();
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
logger.Warn("Warn BBB");
logger.Error("Error BBB");
logger.Fatal("Fatal BBB");
}
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
static
void
A()
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
{
logger.Trace("Trace AAA");
logger.Debug("Debug AAA");
logger.Info("Info AAA");
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
B();
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
logger.Warn("Warn AAA");
logger.Error("Error AAA");
logger.Fatal("Fatal AAA");
}
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
static
void
Main(
string
[] args)
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)