log4net (转)

1 实现目的  

一个好的应用系统离不开log文件的支持,所以log文件的处理在应用系统的开发过程中是占很大比重的。log文件的处理方法有很多种,采用一种功能强大且方法简单的处理方法,不但能保证log文件的输出质量,更能大大缩短系统开发和维护的周期。本文介绍的.net环境下log文件处理解决方案,采用的是开源日志框架log4net。本文介绍的log4net基于log4net-1.2.0版本。 

2  log4net概述  

log4net是一个辅助应用系统输出多种样式log信息的日志框架,它是著名的log4j框架在.net环境下的实现,在实际应用中,可以采用和log4j类似的方法在.net环境下构建起一个功能强大的log处理系统。log4net和应用系统的结合不需要修改应用系统本身的代码,它们之间的绑定非常简单,并且log4net处理log信息是和应用系统同步的,其处理速度和输出的多样性也是其它任何log处理系统无法比拟的。log4net最有特色的地方是,它对log进行了分等级处理,这样应用系统可以在实际运行环境下很简单的输出不同级别的log信息,帮助系统开发维护人员在最快的时间里得到最有用的系统log信息。 

log4net处理log文件的方法是灵活多变的,它可以将log信息输出不同的样式和输出到不同的地方,如控制台(Console),文本文件,XML文件,以流的形式发送到其它地方(如数据库),发送到电子邮件中,根据天数或者文件大小产生新的文件等等。并且开发人员可以根据自己的喜好格式化log输出,如自由指定样式,可以包含log级别与log信息,包含log时间、线程、类别等信息的样式等等。 

本文以最常见的log输出形式:输出到文本文件和数据库作为范例来介绍log4net的使用方法

3  log4net 主要结构分析  

在使用log4net之前先了解log4net的结构是非常有必要的,下面简要分析log4net结构中重要的几个部分。 

3.1 Logger Logger是应用程序与log4net交互的主要模块,它也是log4net生成log的模块。Logger主要负责得到log信息,得到log信息之后接下来的显示log则是在Layout模块中处理。 

3.1.1 Logger的管理方式

 

Logger提供了多种方法用于记录任何类型的log信息,可以在应用程序中使用多个Logger实例,而把它们的维护工作交给log4net框架作为“命名实体(Named Entity)”进行维护。这就意味着,不再需要将应用程序中生成的Logger实例作为参数在应用程序中传递,以便应用程序中的其它模块能使用该实例。唯一需要做的就是通过Logger的命名来调用它。

目前,log4net使用类似.net命名空间的方式管理命名实体。例如,有两个Logger,分别定义为logger.First以及logger.First.One。那么这两个是不同的Logger,而且logger.Firstlogger.First.One的祖先,同时logger.First.One继承了logger.First的属性。位于命名空间最高层的Logger是默认Logger,也被称为根LoggerRoot Logger)。 

3.1.2 实现自己的Logger

 

如果要实现自己的Logger,那么log4net提供了接口ILog用于实现自己的LoggerILog的大致结构如下: 

public interface Ilog
 







void Debug(object message); 



void Info(object message);




 


void Warn(object message); 
 



void Error(object message);
 



void Fatal(object message);
 



void Debug(object message, Exception ex);  
 



bool isDebugEnabled;
 



bool isInfoEnabled; 



}  



Logger中,log4net提供了一个名为LogManager的类给我们用于获取或者创建一个LoggerLogManager提供了方法GetLogger(),该方法接收一个string类型的参数,用于指定Logger的名称: 



log4net.ILog log = log4net.LogManager.GetLogger(Logger_Name) ;
 


当指定名称的Logger不存在时,LogManager将自动创建一个。通常情况下,都是使用Logger所在类的名称来作为Logger的名称,即GetLogger方法的参数可以是typeof(ClassName)。也可以使用如下的方法来传递该参数: 

log4net.Ilog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 


尽管上面的代码比typeof(ClassName)要长的多,但是这样做可以在任何一个类中使用相同的方法传递参数,从而减少出错的机率。 

 

3.2  Logger Levellog级别  

从上面的ILog的接口可以看出,log4net5种不同的记录方式。为什么需要有这5种记录方式呢?其实,这5种记录方式存在不同的优先级别。这些级别定义在log4net.spi.level中。可以根据需要在应用中使用任意一个方法,但是,为了在使用了这些方法之后,在回收时不至于浪费太多的CPU周期。因此,log4net提供了7个等级以及它们各自的布尔属性来节省CPU周期,如下: 

Logger的不同等级: 

Level 

 

Allow Method

 

 

Boolean Property

 

Value

 

 

 

OFF

 

 

 

 

 

 

 

 

 

Highest

 

 

 

FATAL

 

 

 

void Fatal(...);

 

 

 

bool IsFatalEnabled;

 

 

 

 

 

 

ERROR

 

 

 

void Error(...);

 

 

 

bool IsErrorEnabled;

 

 

 

 

 

 

WARN

 

 

 

void Warn(...);

 

 

 

bool IsWarnEnabled;

 

 

 

 

 

 

INFO

 

 

 

void Info(...);

 

 

 

bool IsInfoEnabled;

 

 

 

 

 

 

DEBUG

 

 

 

void Debug(...);

 

 

 

bool IsDebugEnabled;

 

 

 

 

 

 

ALL

log4net中,每一个Logger会通过配置文件中的配置信息给予一个优先级别,如果没有指定的优先级别,那么它将尝试从它的父类中继承一个优先级别。同样,Logger的每一个方法都有一个预定义的级别,如上表中列出的,Info()方法有着INFO的级别。当运行时,log4net会检查方法的级别以及配置文件赋予Logger的级别,然后执行不同的操作。例如,假设某个Logger具有INFO的级别,那么当执行如下操作时: 

Logger.Info(“message”);
 



Logger.Debug(“message”);
 



Logger.Warn(“message”);
 


将会有如下的情况:

1、 方法Info的级别等于LoggerINFO级别,那么Info方法将执行; 

2、 方法Debug的级别低于LoggerINFO级别,那么Debug方法将不执行或抛出异常; 

3、方法Warn的级别高于LoggerINFO级别,那么Warn方法将被执行。 

由此可以看出,当方法的级别大于或等于Logger的级别时,方法将得以执行。 

在上表中还定义了两个特殊的级别:ALLOFFALL意味着任何方法都可以执行,OFF则相反。为了明确那些操作能够执行,可以用上表中的属性进行判断: 

if (logger.IsDebugEnabled){
 



  Logger.Debug("message");
 



}
 


3.3  Appenderlog目的地  

每个Logger都可以拥有一个或者多个appender,每个appender表示一个log的输出目的地,比如console、某个文件、数据库甚至电子邮件。可以使用Logger.addAppender(Appender app)logger增加一个appender;也可以使用Logger.removeAppender(Appender app)logger移除一个appender 

默认情况下,Loggeradditive标志被设置为true,表示子Logger将继承父Logger的所有appenders。该选项可以被重置,表示子Logger将不再继承父Loggerappenders 

Root Logger拥有目标为System.consoleconsoleAppender,故默认情况下,所有的Logger都将继承该appender 

3.4  Layoutlog格式化器  

每个appender都和一个layout相联系;layout的任务是格式化用户的logging requestLayout使log的输出样式多样,比如可以在输出的log信息中包含log级别、log时间、线程、异常信息等。 

appender的任务是把layout格式化好的输出内容送往指定的目的地。 

3.5  Configuration:配置信息  

log4net环境的配置就是对Root Logger的配置,包括把Root Logger设置为哪个级别(level);为它增加哪些appender,等等。这些可以通过设置系统属性的方法来隐式地完成,也可以在程序里调用XXXConfigurator.configure()方法来显式地完成。以上介绍的几部分是log4net中最主要的几部分,在使用log4net之前了解这几部分的主要结构和作用非常有助于更好的使用log4net。下面介绍log4net.net应用程序中的使用方法。

4 Log4net的使用方法  

.net应用程序中使用log4net非常简单,完全不需要改变.net应用程序的结构,只需要为项目添加log4net引用,配置config文件,实例化一个Logger实例,在需要输出log的地方调用Logger的方法即可。使用log4net最重要的地方是config文件的配置。 

 

4.1  config文件配置 

Application项目中,log4net默认读取配置信息的文件是App.config,在Web项目中默认读取配置信息的文件是Web.config。但是config文件的配置方法在这两种情况下都是相同的,所以可以很简单的将一个config文件从Application项目移植到Web项目中。前面介绍过的将log输出到文本文件、数据库、XML文件等多种输出形式,以及log输出的多种样式等,在应用程序中只需要配置config文件即可实现,完全不用改动程序。下面介绍将log输出到文本文件和数据库的config文件配置方法。 

4.1.1 输出log到文本文件的config文件配置  

输出log到文本文件,需要在config文件中指定log文件的存放路径,文件名称,log输出格式,文本文件达到多大时重新创建文件等等,如下: 

<configuration>
 



<configSections>
 



  <section name="log4net" type="System.Configuration.IgnoreSectionHandler"



/>



 </configSections>
 



 <log4net>
 



<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
 



 <param name="File" value="c:\LogData\log.txt" />
 



 <param name="AppendToFile" value="true" />
 



  <layout type="log4net.Layout.PatternLayout">
 



 <param name="Header" value="[Header]\r\n" />
 



 <param name="Footer" value="[Footer]\r\n" />
 



 <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] 



&lt;%X{auth}&gt; - %m%n" />



 </layout>
 



 </appender>
 



 <root>
 



 <level value="DEBUG" />
 



 <appender-ref ref="LogFileAppender" />
 



  </root>  
 



<logger name="OpenDB">
 



    <level value="INFO" />
 



</logger>
 



</log4net>
 



</configuration>  



下面分析config文件配置信息中主要部分代表的意义:




 


<configSections>
 



<section name="log4net" type="System.Configuration.IgnoreSectionHandler"/>
 



</configSections>



log4,log4net,Log4配置,log4net使用实例,.net中使用LOG4输出日志,LOG4纪录日志

Log4配置

一、常用输出格式

%c   列出logger名字空间的全称,如加上{<层数>}表示出从最内层算起的指定层数的名字空间
%X  按MDC(Mapped Diagnostic Context,线程映射表)输出日志。通常用于多个客户端连接同一台服务器,方便服务器区分是那个客户端访问留下来的日志。
%p  日志信息级别
%d   %d{<日期格式>}:日志信息产生时间,使用ISO8601定义的日期格式
%C   日志信息所在地(全限类名)
%m   产生的日志具体信息
%n    输出日志信息换行
%F 显示调用logger的源文件名
%l     输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数
%L    显示调用logger的代码行
%M   显示调用logger的方法名
%r     显示从程序启动时到记录该条日志时已经经过的毫秒数
%t     输出产生该日志事件的线程名
%% 显示一个
二、log4j.properties


#控制包中日志输出级别
log4j.logger.org.apache.struts = debug

# 应用于控制台
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %-4r [%t] %-5p %c %x - %m%n
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n

#应用于文件
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=file.log
log4j.appender.FILE.Append=false
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %-4r [%t] %-5p %c %x - %m%n
# Use this layout for LogFactor 5 analysis

# 应用于文件回滚
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLING_FILE.Threshold=ERROR
log4j.appender.ROLLING_FILE.File=rolling.log
log4j.appender.ROLLING_FILE.Append=true
log4j.appender.ROLLING_FILE.MaxFileSize=100KB
log4j.appender.ROLLING_FILE.MaxBackupIndex=10
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %-4r [%t] %-5p %c %x - %m%n


#应用于socket
log4j.appender.SOCKET=org.apache.log4j.net.SocketAppender
log4j.appender.SOCKET.RemoteHost=localhost
log4j.appender.SOCKET.Port=5001
log4j.appender.SOCKET.LocationInfo=true
# Set up for Log Facter 5
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n


# Log Factor 5 Appender
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000

# 发送日志给邮件
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.Threshold=FATAL
log4j.appender.MAIL.BufferSize=10
log4j.appender.MAIL.From=web@www.wuset.com
log4j.appender.MAIL.SMTPHost=www.wusetu.com
log4j.appender.MAIL.Subject=Log4J Message
log4j.appender.MAIL.To=web@www.wusetu.com
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %-4r [%t] %-5p %c %x - %m%n

# 用于数据库
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
log4j.appender.DATABASE.user=root
log4j.appender.DATABASE.password=
log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES (''[framework] %d - %-4r [%t] %-5p %c %x - %m%n'')
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %-4r [%t] %-5p %c %x - %m%n

#每日回滚日志文件
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=SampleMessages.log4j
log4j.appender.A1.DatePattern=yyyyMMdd-HH''.log4j''
log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout

#自定义Appender
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender
log4j.appender.im.host = mail.cybercorlin.net
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = corlin@cybercorlin.net
log4j.appender.im.layout=org.apache.log4j.PatternLayout
log4j.appender.im.layout.ConversionPattern =[framework] %d - %-4r [%t] %-5p %c %x - %m%n


posted on 2009-03-21 09:59  马德华  阅读(907)  评论(0编辑  收藏  举报