logback初入

最近想推动项目组在新产品/新项目上使用logback,于是打算了解下logback
1.官方手册 http://logback.qos.ch/manual/,介绍的非常详细。
2.基本上只需要引入如下三个jar,就可以满足与log4j类似的日志特性了。
logback-classic-1.1.8.jar
logback-core-1.1.8.jar
slf4j-api-1.7.22.jar

3.翻阅了下源码进行了初步梳理

4.下一步打算通过阅读官方手册+阅读源码,整理一份配置文件的sample
//TODO

5.logback与log4j callAppender方法的差异分析

    a.log4j的callAppender方法对for循环中获取的logger使用synchronize关键字进行修饰;   logback中没有使用sychronized
    b.log4j和logback的addAppender/removeAppender方法都有sychronized关键字进行修饰;logback的detachAppender没有使用synchronized关键字修饰
    c.log4j使用Vector存放appender;logback使用CopyOnWriteArrayList存放appender
    d.log4j在callAppender方法中如果不使用synchronized,则并发情况下会持续其他线程调用addAppender/removeAppender等方法,改变Vector中存放的appener。由于遍历appender使用的是for(int i...),会导致出现越界(数组变小)或者未能访问后续增加的appender
    e.log4j由于对Logger使用了synchronized修饰,当多个线程并发访问同一个logger时,会出现等待锁的情况,存在性能风险
    f.logback因为使用CopyOnWriteArrayList存放appender,且遍历appender使用的是foreach,可以避免出现越界(数组变小)和未能方位后续追加成果的appender。
    g.CopyOnWriteArrayList的iterator返回的是COWIterator对象,每次的hasNext都是使用构造时传入的数组对象(addIfAbsent和remove执行成果后会改变这个数组)的length跟cursor进行判断,故可以避免越界风险,也可以避免没有及时访问到新追加成功的元素(appender)

ps:

       a.log4j在初始化时,通过LogManager创建了一个Hierarchy实例,所有的logger都存放在Hierarchy的HashTable中,并根据包路径层次关系构建父子关系
       b.logback通过StaticLoggerBinder初始化获取单实例,并通过其defaultLoggerContext属性来指向LoggerContext实例,所有的logger都存放在LoggerContext的ConcurrentHashMap中,并根据包路径层次关系构建父子关系

猜你喜欢

转载自yangbb.iteye.com/blog/2348563
今日推荐