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.
更多详细请参考 http://tutorials.jenkov.com/java-logging/logger-hierarchy.html log4j中是怎样处理这个hierachy的呢? 上面的实现有两个比较损耗性能的地方: 1)当日志不需要输出时,new LoggingEvent()纯属是做无用功。 2)当logger的日志自身不满足输出条件是,遍历parents也是在做无用功。 logback中是怎样做优化的呢? logback 还有一个比较明显的优化点(贤亮补充)
在log4j中,当某个logger调用关联的appenders进行输出前会先通过synchronized加锁,如下代码所示:
但是在logback中,只会在某个appender要输出日志时,使用ReentrantLock来进行加锁,如下代码所示:
这两者的主要区别不在于ReentrantLock和synchronized,因为最新的JVM中,这两个性能不会相差太多,主要区别在于加锁粒度上,当大并发的情况下,logback会有明显的优势,这个原理和ConcurrentHashMap的分段锁类似。
对于其他的优化点,可以考虑自己做一些性能测试+阅读源码,体会会更深一些。 参考: https://logging.apache.org/log4j/1.2/manual.html http://logback.qos.ch/manual/ Logger Hierarchy: http://tutorials.jenkov.com/java-logging/logger-hierarchy.html