前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >log4j解析(包含源码)

log4j解析(包含源码)

作者头像
Dylan Liu
发布2019-07-01 11:30:06
7920
发布2019-07-01 11:30:06
举报
文章被收录于专栏:dylanliudylanliudylanliu

读前问题:

1:log4j的日志流程是怎么样的?

2:log4j的配置文件各项都是什么含义?特别是有些配置里面有包名到底有什么用?

3:log4j的输出都是什么含义?具体见log4j conversion pattern各格式含义

一。log4j全局说明

log4j采用logger,appender模式,其中logger含有层级信息,顶级logger为rootLogger,其他logger在在解析时会以.(英文点号)为分隔符

划分层级,在获取logger时名字决定了要获取的logger实例

二。log4j配置文件解析

解析流程:

解析全局配置 => 解析log4j.rootLogger  => 解析log4j.appender.* =>解析logFactory => 解析log4j.logger.* => 解析renderers

2.1:解析全局配置

全局配置包含:

log4j.debug=true : Defining this value makes log4j print log4j-internal debug statements to System.out.

log4j.reset=true : If property set to true, then hierarchy will be reset before configuration

log4j.threshold=INFO #全局级别设定,不超过这个级别的一律不输出

2.2:解析log4j.rootLogger

格式:log4j.rootLogger=priority,appenderName1,appenderName2

说明:priority是日志级别,包含由低到高DEBUG,INFO,WARN,ERROR,FATAL五个级别

appenderName是自己定义的名称,只要与后面的一致就可以了,标示了在这个logger下面的输出器

ps:根logger必须有,是所有其余logger的顶级parent,他自身parent为null

rootLogger的名称为root,默认的

2.3:解析log4j.appender.* 格式:

log4j.appender.appenderName=appenderClass
log4j.appender.appenderName.threshold=priority
log4j.appender.appenderName.layout=layoutClass
log4j.appender.appenderName.layout.ConversionPattern=conversionPattern
log4j.appender.appenderName.filter.filterName=filterClass
log4j.appender.appenderName.errorhandler=errorhandlerClass
log4j.appender.appenderName.errorhandler.root-ref=[true|false]
log4j.appender.appenderName.errorhandler.logger-ref=loggerName

说明:上面只是列出了一部分,像filter跟errorhandler平常我们基本不会用到,其实只要记住log4j.appender.appenderName后面的配置都是appender的属性就可以了

譬如自己继承了AppenderSkeleton这个类,里面有一个attr的属性 可以用log4j.appender.appenderName.attr=anyValue

appender自身也有级别过滤日志是否输出,可以用log4j.appender.appenderName.threshold=ERROR 这样就设定这个appender只输出ERROR级别的日志

2.4:解析logFactory

格式:log4j.loggerFactory=loggerFactoryClass

就是讲log4j默认的日志工厂替换为自定义的,基本没有必要这么做

2.5:解析log4j.logger.*

格式:log4j.logger.loggerName=priority,appenderName1,appenderName2

说明:这个logger的解析流程与rootLogger的基本一致,不同点在于logger是有层级的

假设我们有这几个配置:log4j.logger.com.oschina.net=DEBUG,appenderName

log4j.logger.com.oschina.net.web.action=INFO,appenderName

log4j.logger.com=ERROR,appenderName

log4j解析规则为:

解析loggerName = log4j.logger.后面的内容,譬如loggerName为com.oschina.net.web.action

解析上下级关系:com.oschina.net.web.action的有效parent为com.oschina.net,

com.oschina.net的有效parent为com

com的有效parent为root

ps:这里所说为有效parent,实际上com.oschina.net的直接parent为com.oschina,再上级的parent才是com,这里log4j做了一个处理,将com.oschina这一级

设定为一个占位符ProvisionNode,没有任何的appender

2.6:解析renderers

格式:log4j.renderer.renderedClass=renderingClass #定制对象显示 使用renderingClass来render renderedClass

说明:renderer就是为了解决我们在直接打印对象的时候如何输出值的问题,而不是直接调用toString方法

三:log4j的日志打印规则

通常我们都是这样来获取一个logger实例:

Logger logger = LoggerFactory.getLogger(ObjectClass.class);

这里面的获取逻辑为:

假设ObjectClass.class的全限定路径为com.oschina.net.web.action.controller,那么LoggerFactory会生成一个名称为com.oschina.net.web.action.controller的logger(会缓存起来,下次直接使用),并初始化他的parent,此时logger的层级关系为:

日志打印时会自底向上用各自的appender输出日志内容,贴一下代码:

        for (Category c = this; c != null; c = c.parent) {
            // Protected against simultaneous call to addAppender, removeAppender,...
            synchronized (c) {
                if (c.aai != null) {
                    writes += c.aai.appendLoopOnAppenders(event);
                }
                if (!c.additive) {
                    break;
                }
            }
        }

不过这里有一点需要说明,因为在日志打印的时候需要判断logger的threshold,但是生成的最下面的com.oschina.net.web.action.controller这个loggerthreshold为null,

log4j会自底向上找到第一个不为null的logger来判定是否可以输出当前日志,因此在logger级别设定的时候就需要注意parent的级别需要比child的级别低,不然很容易导致

日志文件中输出了2条或以上的日志信息

四。appender类图

由于Logger相关类只有两个(另一个是Category类),configure相关类和filter类继承相关都很简单,这里只贴一个自己做的appender相关的类图

在看到DailyRollingFileAppender时,看到里面判断时间使用的System.currentTimeMillis(),在高并发下场景下是很耗时的一个操作,因此自己写了一个

加缓存的DailyRollingFileAppenderWithCache实现,具体可见github

五。总结

总的来说已经熟悉了log4j的流程,对曾经的疑问也已经有了解答,欢迎大家留言交流。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
日志服务
日志服务(Cloud Log Service,CLS)是腾讯云提供的一站式日志服务平台,提供了从日志采集、日志存储到日志检索,图表分析、监控告警、日志投递等多项服务,协助用户通过日志来解决业务运维、服务监控、日志审计等场景问题。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档