Log4j简介
Log4J最核心的也就5个类:
Logger用于对日志记录行为的抽象,提供记录不同级别日志的接口
Level对日志级别的抽象
Appender是对记录日志形式的抽象
Layout是对日志行格式的抽象
LoggingEvent是对一次日志记录过程中所能取到信息的抽象
它们之间的关系如下:
而,它们工作的序列图如下:
即获取Logger实例->判断Logger实例对应的日志记录级别是否要比请求的级别低->若是调用forceLog记录日志->创建LoggingEvent实例->将LoggingEvent实例传递给Appender->Appender调用Layout实例格式化日志消息->Appender将格式化后的日志信息写入该Appender对应的日志输出中。
Logger层次与继承
Logger遵循类似包的层次。如
Logger rootLog = Logger.getRootLogger(); Logger logA = Logger.getLogger("AClass"); Logger logB = Logger.getLogger("AClass.BClass"); Logger logC = Logger.getLogger("AClass.BClass.CClass");
那么rootLog是logA的父Logger,logA是logB的父Logger,logC是logB的Logger。Logger象Java中的类继承一样,子记录器可以继承父Logger的设置信息,也可以覆写相应的信息。
Logger层次的继承有什么用处?
假设程序中的每个包都会输出一些公共的日志信息,而每个包的不同子包又有一些特殊的日志信息要输出,这种情况就可以象处理Java中的类一样,运用Logger中的层次关系来达到目的。假设有个名为A的包,有名为A,B的两个子包。现在需要将A包下的所有类都要把日志信息输出到控制台中;A.B包除了输出到控制台外还要输出到文件中;A.C包除了输出到控制台中还要输出到HTML文档中。
如何使用记录器层次的继承?
通过Logger.getLogger(XXX.Class.getName())来取得Logger对象。现在我们假设A.B的包下有一个类CClass,那么当调用Logger.getLogger(CClass.class.getName())时,最理想的情况是返回名为A.B.CClass的Logger对象。但是如果不存在名为A.B.CClass的Logger时它会怎样呢?其实通过Logger类的getLogger方法取得记录器时存在下面两种情况:
1.如果存在与所要找的名字完全相同的Logger,则返回相应的Logger对象。
2.但如果找不到,它会尝试返回记录器层次中与所要找的Logger最接近的祖先Logger对象。
Appender层次与继承
同Logger的层次继承类似,Appender也有类似的继承关系。继承层次底层的Logger可以使用其祖先的Appender。不用每个Logger都设置Appender,底层Logger没有设置Appender的情况下,可以一次性从祖先Logger中直接将更换Logger的Appender。实现方法:从自己开始向祖先方法访问各Logger的Appenders。如果继承属性(additive)为false,则在调用了自己所有的Appender后,就直接跳出循环。
###参考:
http://logging.apache.org/log4j/1.2/manual.html
http://blog.csdn.net/shrekmu/article/details/271777
(完)
本文作者 : cyningsun
本文地址 : https://www.cyningsun.com/07-04-2014/inside-log4j.html
版权声明 :本博客所有文章除特别声明外,均采用 CC BY-NC-ND 3.0 CN 许可协议。转载请注明出处!