Log4j vs. Logback 性能比较Inside

看过源码有段时间了,对logback中对判定是否记录一条日志记录的优化印象比较深刻,整理如下,希望对你有所帮助。
 
Java的logger框架有一个重要的层级(hierarchy)的概念,按约定,是通过小数点来区别父子关系的,也就是名字为“x.y”的logger是“x.y.z”logger的parent。
Hierachy的命名规则:
Named Hierarchy
A logger is said to be an ancestor of another logger if its name followed by a dot is a prefix of the descendant logger name. A logger is said to be a parent of a child logger if there are no ancestors between itself and the descendant logger.
这样做的好处是我们可以灵活的指定不同logger的log level和Appender targets。
Logger
Name
Assigned
Level
Inherited
Level
Added
Appenders
Additivity
Flag
Output Targets Comment
root warn
warn
A1 not applicable A1 The root logger is anonymous but can be accessed with the Logger.getRootLogger() method.
There is no default appender attached to root.
x info
info
A-x true A1, A-x Appenders of "x" and root.
x.y none
info
A-xy false A1, A-x, A-xy Appenders in "x.y" , and its parents "x" and root. Log level is info which is inherited from "x"
x.y.z
debug
debug
A-xyz true A-xyz Appenders of "x.y.z". becuase its parent "x.y" addivitity is false, so no more appenders will be added
 
因为这个hierachy的关系,在做日志输出时,logger不仅要check自己是不是满足输出条件,还要遍历其所有的Additivity为非false的parent,看parents们能不能输出日志。
 
下图是一个Filter和Handler在Logger Hierarchy中运作的示意图,其运行逻辑是:

When a message is passed to a Logger, the message is passed through the Logger's Filter, if the Loggerhas a Filter set. The Filter can either accept or reject the message. If the message is accepted, the message is forwarded to the Handler's set on the Logger. If no Filter is set, the message is always accepted.

If a message is accepted by the Filter, the message is also forwarded to the Handler's of the parentLogger's. However, when a message is passed up the hierarchy, the message is not passed through theFilter's of the parent Logger's. The Filter's are only asked to accept the message when the message is passed directly to the Logger, not when the message comes from a child Logger.

 Log4j vs. Logback 性能比较Inside

更多详细请参考http://tutorials.jenkov.com/java-logging/logger-hierarchy.html
 
log4j中是怎样处理这个hierachy的呢?
Log4j vs. Logback 性能比较Inside
 
上面的实现有两个比较损耗性能的地方:
1)当日志不需要输出时,new LoggingEvent()纯属是做无用功。
2)当logger的日志自身不满足输出条件是,遍历parents也是在做无用功。
 
logback中是怎样做优化的呢?
Log4j vs. Logback 性能比较Inside
 
logback还有一个比较明显的优化点(贤亮补充)

在log4j中,当某个logger调用关联的appenders进行输出前会先通过synchronized加锁,如下代码所示:

Log4j vs. Logback 性能比较Inside

但是在logback中,只会在某个appender要输出日志时,使用ReentrantLock来进行加锁,如下代码所示:

Log4j vs. Logback 性能比较Inside

这两者的主要区别不在于ReentrantLock和synchronized,因为最新的JVM中,这两个性能不会相差太多,主要区别在于加锁粒度上,当大并发的情况下,logback会有明显的优势,这个原理和ConcurrentHashMap的分段锁类似。

对于其他的优化点,可以考虑自己做一些性能测试+阅读源码,体会会更深一些。
 
参考:
上一篇:企业应用架构实践(复杂性应对之道)


下一篇:UML 类图关系汇总