日志在工作中起到关键作用,我们经常使用它来打印关键信息,方便分析,或者是输出错误信息,用于bug排查,spring中同样使用了日志进行信息的输出,但是spring4和spring5之间的日志又有些不同,接下来我们就进行一些分析。

1. 各种日志技术简述:  

    log4j,jul,jcl,log4j2,slf4j

    我们先把他们展示出来,以免引用错误。

  1.1 log4j

   使用log4j需要引入log4j的配置文件log4j.properties,内容简配一下:

log4j.rootLogger = info,stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

  pom文件中只引入log4j所需要的jar包

  

  程序也写的简单一点,输出日志就行:

  

  结果:

  

  日志是输出的。

 1.2JUL

  JUL 是jdk自带的,所以pom文件中不需要引入任何包,直接撸代码:

  

  结果:

  

  日志输出格式我们不再做改变,记住log4j和jul的日志输出格式,后面有用到。

 1.3:JCL

  pom中引入所需要的包:

  撸代码:

  

  结果:

  

  呜呼,这个日志输出是不是很眼熟呀,长得很像上面JUL打印出来的日志,难道他们之间有什么不可描述的事情?所以最帅的我准备打开JCL的源码一探究竟。

  从上面代码中的LogFactory的getLog方法下手,进去:

  

  木得意思,就一行代码,那就再深一点,进入getInstance()中,

  

  第一行代码看着像是拿到了log,不过老哥我已经帮大家踩过坑了,debug走了一遍,第一行代码执行后,Log 依然是null,所以我们继续往下走,进入到

this.newInstance()方法中,有点长,就酱紫:

protected Log newInstance(String name) throws LogConfigurationException {
Log instance = null; try {
Object[] params;
if (this.logConstructor == null) {
instance = this.discoverLogImplementation(name);
} else {
params = new Object[]{name};
instance = (Log)this.logConstructor.newInstance(params);
} if (this.logMethod != null) {
params = new Object[]{this};
this.logMethod.invoke(instance, params);
} return instance;
} catch (LogConfigurationException var5) {
throw var5;
} catch (InvocationTargetException var6) {
Throwable c = var6.getTargetException();
if (c != null) {
throw new LogConfigurationException(c);
} else {
throw new LogConfigurationException(var6);
}
} catch (Throwable var7) {
throw new LogConfigurationException(var7);
}
}

  这段代码差一点就比我的长处还长呢,所以我又帮大家debug了一遍,在第一个if判断 之后执行的这个方法 this.discoverLogImplementation(name);就是我们要找的,再深入,在

discoverLogImplementation()这个方法中,我找到了这段代码:

  

  result属性就是我们需要返回的Log,循环条件中有一个classesToDiscover,并且还把他的值传给了this.createLogFromClass()方法,点击看看他是什么,

String[] classesToDiscover = new String[]{"org.apache.commons.logging.impl.Log4JLogger", 
                          "org.apache.commons.logging.impl.Jdk14Logger",
                          "org.apache.commons.logging.impl.Jdk13LumberjackLogger",
                          "org.apache.commons.logging.impl.SimpleLog"};

  这个数组里面找到了 org.apache.commons.logging.impl.Jdk14Logger,这不就是我们的JUL 吗?再想到刚刚的for循环,我们很容易理解,JCL就是循环这个数组,一次获取Log,知道Log 不为null为止,为了验证我们的猜想,

我们可以引入log4j的jar包和配置文件,其他代码不做修改,这样按照数组顺序,应该打印出来log4j的日志。

果然,在有log4j的情况下,JCL按照刚刚那个数组,顺序加载log,知道Log不为null。

  由此可以看出,JCL起到的是一个中间商赚差价的作用,在有log4j的时候使用log4j,否则使用JUL

2 Sring4 的日志体系

  上面说了那么多,只是介绍了一部分日志技术,接下来我们开始分别分析spring4和spring5的日志体系。

 2.1 构建spring4项目

  采用java+注解的方式快速构建,pom中只引入spring-context包

  

  运行下面的代码,可以看到有日志输出

  

  

  找到打印日志的地方,debug模式下,查看输出日志的Log是什么log

  

  可以看出是jdk14Logger,这个在JCL中说过,这个指的是JUL,也就是说在默认spring日志体系下,采用的是JUL,

  接下来,我们按照之前的方法引入log4j,debug运行上面的程序,再次查看日志类型

  

  额,这次在增加log4j jar包和配置文件的情况下,spring4有使用了log4j,这么像JCL呢,木错,让我们在idea中打开spring4的日志依赖结构:

  

  common-logging 这不就是JCL使用到的包吗,可以看出,Spring4使用的是原生的JCL,所以在有log4j的时候使用log4j打印日志,没有的时候使用JUL打印日志。

3.Spring5日志体系

  线上依赖结构图:

  

  答题结构没变,只是原来common-logging ,换成了spring-jcl,看名字就知道是spring自造的包,jcl,更是标注了,它使用的是JCL日志体系。

  所以还是看源码吧。

  按照之前的经验,我们只用debug找到spring内部一个Log,看看他的产生方式和类型。这次我给大家找了AbstractApplicationContext里面找到产生Log的地方

  

  进入这个方法的getLog()中,一直深入,不要怜惜spring,找到LogAdapter中的createLog()方法

  

  可以看出来spring5中对日志的生产,不在像原生JCL中那样使用一个数组,然后进行循环产生,这里用到的是Switch case,这个关键字段LogApi又是在哪一部分赋值的呢?看图

  

  Duang ,没错是在静态代码块中赋的值,为了验证,我们准备用其中提到的log4j2验证(注意:log4j不行,因为这里的switch没有log4j选项),首先我们准备log4j2的配置文件

  

<Configuration status="WARN">

<Appenders>

<Console name="Console" target="SYSTEM_OUT">

<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>

</Console>

</Appenders>

<Loggers>

<Root level="debug">

<AppenderRef ref="Console"/>

</Root>

</Loggers>

</Configuration>

  然后准备pom

  

   代码还是这一行,直接运行:

  结果有日志打印出来了

  

  所以,在spring5中,依然使用的是JCL,但是不是原生的,是经过改造的JCL,默认使用的是JUL,而原生JCL中默认使用的是log4j.

  好了,就酱紫,求轻拍,大家中秋快乐。

  

  

  

  

      

      

      

分析spring4和spring5日志中的不同的更多相关文章

  1. How To:分析ORACLE监听日志中的IP信息

    有时候需要分析出ORACLE日志监听中的IP信息,分享一个组合命令,Linux的shell下运行正常. grep "HOST=.*establish.*\* 0" listener ...

  2. 在linux中使用shell来分析统计日志中的信息

    在运维工作中,要经常分析后台系统的日志,通过抓取日志中的关键字信息,对抓取结果进行统计,从而为监控结果提供基础数据.下面的shell演示了如何从大量的日志中取得想要的统计结果.其中展示了各种有趣的命令 ...

  3. Mysql(Mariadb)慢查询日志中long_query_time 与log_queries_not_using_indexes与min_examined_row_limit 关系分析

    慢查询日志中long_query_time 与log_queries_not_using_indexes与min_examined_row_limit 关系分析   参数介绍: long_query_ ...

  4. Log4j 输出的日志中时间比系统时间少了8小时的解决方法,log4j日志文件重复输出

    1. 第一个问题:时间少了8小时 Log4j 输出的日志中,时间比系统时间少了8小时,但是 eclipse 控制台输出的日志的时间却是对的. log4j配置如下: #all logger output ...

  5. DBA_Oracle LogMiner分析重做和归档日志(案例)

    2014-08-19 Created By BaoXinjian

  6. mysqlsla 分析mysql慢查询日志

    发现有一个工具mysqlsla,分析查询日志比 mysqldumpslow分析的会更清晰明了! 安装mysqlsla: 下载mysqlsla-2.03.tar.gz [root@yoon export ...

  7. 关注LoadRunner脚本回放日志中的Warning信息-转载

    关注LoadRunner脚本回放日志中的Warning信息   最近在与大家的讨论中发现了LoadRunner的很多问题,出于解决问题的出发点,我也就相关自己不理解的问题在Google中搜索了一番,并 ...

  8. fluentd结合kibana、elasticsearch实时搜索分析hadoop集群日志<转>

    转自 http://blog.csdn.net/jiedushi/article/details/12003171 Fluentd是一个开源收集事件和日志系统,它目前提供150+扩展插件让你存储大数据 ...

  9. Nginx日志中的金矿 -- 好文收藏

    转:http://www.infoq.com/cn/articles/nignx-log-goldmine Nginx(读作Engine-X)是现在最流行的负载均衡和反向代理服务器之一.如果你是一名中 ...

随机推荐

  1. 完整原型链详细图解之JS构造函数、原型 原型链、实例化对象

    一.首先说一下什么是构造函数: 构造函数:用来在创建对象时初始化对象.特点:构造函数名一般为大写字母开头:与new运算符一起使用来实例化对象. 举例: function Person(){} //Pe ...

  2. C++基础之:扫雷破解

    版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...

  3. Netty基础系列(4) --堆外内存与零拷贝详解

    前言 到目前为止,我们知道Nio当中有三个最最核心的组件,分别是:Selelctor,Channel,Buffer.在Netty基础系列(3) --彻底理解NIO 这一篇文章中只是进行了大致的介绍. ...

  4. 时间格式的字符串在ios中的转换问题

    在移动端使用时间选择器的时候,选择了一个时间转换为时间戳,谷歌浏览器以及安卓手机使用  new Date( 选择的时间 ).getTime()  都能够拿到时间戳, 但是在ios手机上会出现出现NAN ...

  5. 从SpringBoot构建十万博文聊聊缓存穿透

    前言 在博客系统中,为了提升响应速度,加入了 Redis 缓存,把文章主键 ID 作为 key 值去缓存查询,如果不存在对应的 value,就去数据库中查找 .这个时候,如果请求的并发量很大,就会对后 ...

  6. echarts legend 限制规定显示个数,显示省略号,修改默认样式

    类似百度统计,有的时候legend的个数比较多,但是前端需要控制初始化显示的个数,以及最多显示的条数,先看效果图: 先给代码: <!DOCTYPE html> <html lang= ...

  7. java并发系列 - 第28天:实战篇,微服务日志的伤痛,一并帮你解决掉

    这是java高并发系列第28篇文章. 环境:jdk1.8. 本文内容 日志有什么用? 日志存在的痛点? 构建日志系统 日志有什么用? 系统出现故障的时候,可以通过日志信息快速定位问题,修复bug,恢复 ...

  8. Springboot源码分析之项目结构

    Springboot源码分析之项目结构 摘要: 无论是从IDEA还是其他的SDS开发工具亦或是https://start.spring.io/ 进行解压,我们都会得到同样的一个pom.xml文件 4. ...

  9. 终于,我感受到了IDEA的强大

    Java开发者千千万,开发者用的开发工具目前主流却只有2种:eclipse和IDEA,我入行以来一直用的eclipse,听过IDEA很好很强大,但是也只是处于听说的阶段,基本没用过,自然没怎么体会过. ...

  10. Django上线部署之IIS

    环境: 1.Windows Server 2016 Datacenter 64位 2.SQL Server 2016 Enterprise 64位 3.Python 3.6.0 64位 4.admin ...