Log4j-设计原理

Log4j有三个主要的组件:Logger、Appender和Layout。这三个组件相互配合使得我们可以获得非常强大的日志记录的能力。

Logger

Logger的名称是区分大小写的,依据名称可以确定其层次结构(即父子关系),规则如下:

  • 如果Logger A的名称后跟一个点(.)是Logger B的名称的前缀就认为Logger A是LoggerB的祖先。
  • 如果在Logger A和Logger B之间,Logger B没有任何其它的祖先就认为Logger A是LoggerB的父亲。

在Logger的层次结构的最顶层是root logger,它会永远存在,而且不能通过名字取到。

上面文字的描述可能不好的理解,为此我们给出了一张图,Logger的层次结构图,从中可以非常直观的看出三种主要组件的关系和各自所起的作用。

图示 1. Logger的层次结构图

 Log4j的设计原理和使用方法

Loger x.y是Logger x.y.z的祖先,因为x.y.是x.y.z的前缀,这符合规则的前一条。另外在Loggerx.y和Logger x.y.z之间,Logger x.y.z没有其它的祖先,因此Logger x.y是Loggerx.y.z的父亲,这符合规则的后一条。这样我们依据上面的规则就可以构造出如图1所示的Logger的层次结构。

从图1中我们还可以看到每一个Logger都有一个Level,根据该Level的值Logger决定是否处理对应的日志请求。如果Level没有被设置,就象图1中的Loggerx.y一样,又该怎么办呢?答案是可以从祖先那里继承。

如果Logger C没有被设置Level,那么它将沿着它的层次结构向上查找,如果找到就继承并结束,否则会一直查找到rootlogger结束。因为log4j在设计时保证rootlogger会被设置一个默认的Level,所以任何logger都可以继承到Level。

图1中的Logger x.y没有被设置Level,但是根据上面的继承规则,Logger x.y继承了rootlogger的Level。

我们在来看看Logger选择日志记录请求(log request)的规则:

假设Logger M具有q级的Level,这个Level可能是设置的也可能是继承到的。

如果向LoggerM发出一个Level为p的日志记录请求,那么只有满足p>=q时这个日志记录请求才会被处理。

org.apache.log4j.Logger中的不同方法发出不同Level的日志记录请求,如下:

  • public void debug(Object message),发出Level为DEBUG的日志记录请求
  • public void info(Object message),发出Level为INFO的日志记录请求
  • public void warn(Object message),发出Level为WARN的日志记录请求
  • public void error(Object message),发出Level为ERROR日志记录请求
  • public void fatal(Object message),发出Level为FATAL的日志请求
  • public void log(Level l, Object message),发出指定Level的日志记录请求

其中的静态常量DEBUG、INFO、WARN、ERROR、FATAL是在org.apache.log4j.Level中定义的,除了使用这些预定义的Level之外,Log4j还支持自定义Level。

注:org.apache.log4j.Level中还预定义了一些其它的Level。

Appender

在Log4j中,Appender指的是日志记录输出的目的地。当前支持的Appender(目的地)有文件(file)、控制台(console)、java.io.OutputStream、java.io.Writer、远程服务器、远程UnixSyslog守护者、远程JMS监听者、NTEventLog或者发送e-mail。如果您在上面没有找到适合的Appender,那就需要考虑实现自己的自定义Appender了。

每个Logger可以有多个Appender,但是相同的Appender只会被添加一次。

Appender的附加性意味着Logger C会将日志记录发给它的和它祖先的所有Appender。在图1中Loggera会将日志记录发给它自己的JDBCAppender和它的祖先rootlogger的ConsoleAppender和FileAppender。Loggerx.y.z自己没有Appender,它将把日志记录发给它的祖先rootlogger的ConsoleAppender和FileAppender,如果Loggerx.y也含有Appender,那么它们也会包括在内。

Appender的附加性是可以被中断的。假设Logger C的一个祖先为Logger P,如果LoggerP的附加性标志(additivity flag)设置为假,那么Logger C会将日志记录只发给它的和在它和LoggerP之间的祖先(包括Logger P)的Appender,而不会发给LoggerP的祖先的Appender。Logger的附加性标志(additivity flag)默认值为ture。

在图1中如果没有设置Logger a的附加性标志(additivity flag),而是使用默认值true,那么Loggera会将日志记录发给它自己的JDBCAppender和它祖先rootlogger的ConsoleAppender和FileAppender,这和上面的描述相同。如果设置Loggera的附加性标志(additivity flag)的值false,那么Loggera会将日志记录发给它自己的JDBCAppender而不会在发给它祖先rootlogger的ConsoleAppender和FileAppender了。

Layout

Appender定制了输出目的地,通常我们还需要定制日志记录的输出格式,在Log4j中是通过将Layout和Appender关联到一起来实现的。Layout依据用户的要求来格式化日志记录。PatternLayout(标准Log4j组件)让用户依据类似于C语言printf函数的转换模式来指定输出格式。

例如,转换模式(conversion pattern)为"%r [%t] %-5p %c -%m%n"的PatternLayout将生成类似于以下内容的输出:

176 [main] INFO  org.foo.Bar - Located nearest gas station.   

在上面的输出中:

  • 第一个字段表示自程序开始到发出日志记录请求时所消耗的毫秒数
  • 第二个字段表示发出日志记录请求的线程
  • 第三个字段表示日志记录请求的Level
  • 第四个字段表示发出日志记录请求的Logger的名称
  • 第五个字段(-后的文本)表示日志记录请求的消息

Log4j中还提到了一些其它的Layout,包括HTMLLayout、SimpleLayout、XMLLayout、TTCCLayout和DateLayout。如果这些不能满足您的要求,还可以自定义自己的Layout。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值