目录
1.1 log4net的简要说明,在具体项目中扮演的功能角色。
1.2 Log4net 组成结构说明
1.3 Log4net配置文件解析
1.4 举一个实际的例子,阐述Log4net的完整的实现流程
1.1 log4net的简要说明,在具体项目中扮演的功能角色。
Log4net 是一个第三方开源组件,它设计的主要目的是组合,生成日志信息,同时将配置保存到各种存储介质或者展现平台中,在实际项目中,Log4net 可以保存系统运行情况,可以在系统出现异常时,根据保存的日志信息,查看当时系统的状态。
1.2 Log4net 组成结构说明
主要的接口和类的UML图
ILog
定义日志的基本操作(添加各种告警日志)。
LogImpl
继承了ILog接口,实现log基本的功能的类
在LogImpl 类中包含了一个或者多个继承了AppenderSkeleton基类的类
AppenderSkeleton
定义输出源结构,提供保存日志信息的方式(这里,输出源可以是数据库,文件,系统日志,控制台程序,等等)
LogManager
负责根据LoggerName或者Type 等参数接口来生成并返回对应的ILog
IFilter
过滤器,负责筛选需要保存的日志。
ILayout
负责日志信息生成的格式
上面说明了Log4net组件中的主要的类之间的关系。看了后,我们对一个Logger 是怎么组成的还是不怎么了解。下面我们着重的说明他们的组合关系
|
Logger的结构图
注: 此处参考了(http://www.cnblogs.com/dragon/archive/2005/03/24/124254.aspx)
1.3 Log4net配置文件解析
Log4net 的配置文件中配置项结构和log4net 设计类的结构相吻合的。
我把配置文件分成了三块
1.3.1 <Root>块设置
<root>
<level value="WARN" />
<appender-ref ref="LogFileAppender" />
<appender-ref ref="ConsoleAppender" />
</root>
在Log4net 设计中logger都继承于root,定义了一个基本日志对象的配置,在<root>中设置的配置信息可以被自定义的Logger继承并覆盖。当然了自定义Logger本身也是可以继承的。
在<root>中我们可以配置保存配置文件的级别<level>,级别可以分为OFF FATAL RROR WARN INFO DEBUG ALL 这几种。
和对应的输出源<appender-ref> 输出源需要配置 在其后定义的输出源配置名称。
1.3.2 <Logger>块设置
<logger name="testApp.Logging">
<level value="DEBUG"/>
<appender-ref ref="ConsoleAppender" />
</logger>
<logger> 元素预定义了一个具体日志对象的设置。其定义的规则和<root>是一样的,在这里面要补充的是可以通过调用LogManager.GetLogger(“LoggerName”)的函数来调用已经配置的日志对象。
1.3.3 <Appender>块设置
<appender name="RootAppender" type="log4net.Appender.RollingFileAppender">
<file value=" E:\work\Leather Machine Business flat\Data Source\Web\Web\Log\lmbf.log" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<datePattern value="yyyyMMdd" />
<param name="MaxSizeRollBackups" value="-1" />
<param name="MaximumFileSize" value="10MB" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout" >
<conversionPattern value="%date [%c]-[%p] %m%n" />
</layout>
</appender>
对于整个配置文件来讲 <appender>部分是最复杂的,以为log4net 支持的输出源是多样的,且每一种输出源的需要配置的信息也是不同的,上面的例子是配置的一个FileAppender
<file value> :文件的路径
<appendToFile>: 是否追加文件
< rollingStyle >: 滚动类型?
< datePattern >:日期方式
MaximumFileSize :日志文件最大容量
< lockingModel >:日志文件锁方式
< layout > : 呈现方式
log4net.Layout.PatternLayout中的转换模式(ConversionPattern)
%m(message):输出的日志消息,如ILog.Debug(…)输出的一条消息
%n(new line):换行
%d(datetime):输出当前语句运行的时刻
%r(run time):输出程序从运行到执行到当前语句时消耗的毫秒数
%t(thread id):当前语句所在的线程ID
%p(priority): 日志的当前优先级别,即DEBUG、INFO、WARN…等
%c(class):当前日志对象的名称
其他输出源配置请参照(http://logging.apache.org/log4net/release/config-examples.html)这里面包含了全部的appender类型配置说明。
1.4 举一个实际的例子,阐述Log4net的完整的实现流程
场景:在系统中一个组件负责处理日志信息,日志信息是保存到日志文件中的,配置文件和日志文件的路径和运行系统的主目录直接挂钩。(系统研发的过程中,日志组件在调试,测试下运行的环境不一致,尤其是B/s 测试时根本不知道Web配置文件的存在)
在此类中组件分两个类Logger 类 和ConfigFileCreate 类
Logger 负责提供日志的主入口,供系统的其它部分来调用日志的功能。
ConfigFileCreate 负责动态生成配置文件。
下面是两个类的源代码
/**//// <summary>
/// The class
/// which 's Main function is Init Log Config file(in the Catalogue of Assembly)
///
/// </summary>
internal class ConfigFileCreate
{
public const string Log4Config = "UtilityConfig.xml";
/**//// <summary>
///
/// </summary>
/// <returns></returns>
internal string GetConfigFile()
{
string _AssemblyCatalogue =GetAssemblyCatalogue();
FileInfo _fileinfo = new FileInfo(_AssemblyCatalogue + @"/" + Log4Config);
//find where the file is contained
if (!_fileinfo.Exists)
{
CreateXMLConfig(_fileinfo);
}
return _fileinfo.FullName;
}
/**//// <summary>
///
/// </summary>
/// <returns></returns>
private string GetAssemblyCatalogue()
{
return AppDomain.CurrentDomain.BaseDirectory;
}
private void CreateXMLConfig(FileInfo fileInfo)
{
using (StreamWriter sw = File.CreateText(fileInfo.FullName))
{
sw.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
sw.WriteLine("<configuration>");
sw.WriteLine(" <log4net><!-- contain the Log2net component 's configuration information -->");
sw.WriteLine("<root>");
sw.WriteLine("<!-- base configuration-->");
sw.WriteLine("<level value=\"Debug\"></level>");
sw.WriteLine("<appender-ref ref=\"RootAppender\" />");
sw.WriteLine("</root>");
sw.WriteLine("<appender name=\"RootAppender\" type=\"log4net.Appender.RollingFileAppender\">");
sw.WriteLine("<file value=\" " + fileInfo.DirectoryName+ "\\Log\\lmbf.log\" />");
sw.WriteLine("<appendToFile value=\"true\" />");
sw.WriteLine(" <rollingStyle value=\"Composite\" />");
sw.WriteLine("<datePattern value=\"yyyyMMdd\" />");
sw.WriteLine("<param name=\"MaxSizeRollBackups\" value=\"-1\" />");
sw.WriteLine("<param name=\"MaximumFileSize\" value=\"10MB\" />");
sw.WriteLine("<lockingModel type=\"log4net.Appender.FileAppender+MinimalLock\" />");
sw.WriteLine("<layout type=\"log4net.Layout.PatternLayout\" >");
sw.WriteLine("<conversionPattern value=\"%date [%c]-[%p] %m%n\" />");
sw.WriteLine("</layout>");
sw.WriteLine("</appender>");
sw.WriteLine("<logger name=\"Test\">");
sw.WriteLine("<level value=\"Debug\"/> ");
sw.WriteLine("<appender-ref ref=\"RootAppender\" />");
sw.WriteLine("</logger>");
sw.WriteLine("</log4net>");
sw.WriteLine("</configuration>");
sw.Close();
}
}
}
/**//// <summary>
/// 日志类
///
/// 功能 :
/// 负责生成系统日志
/// </summary>
public class Logger
{
private ILog _log = null;
private static Logger _logger=null;
/**//// <summary>
/// the contruct of Logger
/// </summary>
private Logger()
{
//load the configeration file ,and init the Component of log4net
FileInfo _configFile = new FileInfo(new ConfigFileCreate().GetConfigFile());
XmlConfigurator.ConfigureAndWatch(_configFile);
_log = LogManager.GetLogger("Test");
}
/**//// <summary>
/// Logger 's Only Instance
/// </summary>
public static Logger Instance
{
get {
if (_logger == null)
_logger = new Logger();
return _logger;
}
}
//actives about the Logger
public void Fatal(string message)
{
_log.Fatal(message);
}
public void Fatal(String message, System.Exception exception)
{
_log.Fatal(message, exception);
}
public void Warn(String message)
{
_log.Warn(message);
}
public void Warn(String message, System.Exception exception)
{
_log.Warn(message, exception);
}
public void Error(String message)
{
_log.Error(message);
}
public void Error(String message, System.Exception exception)
{
_log.Error(message, exception);
}
public void Debug(String message)
{
_log.Debug(message);
}
public void Info(String message)
{
_log.Info(message);
}
}