日志在工作中起到关键作用,我们经常使用它来打印关键信息,方便分析,或者是输出错误信息,用于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. 【Java例题】4.5异常处理

    5. 对于输入的数,如果出现小数,则作为异常处理,并舍去小数,显示结果:如果输入的数据类型不对也作为异常处理,显示结果0. package chapter4; import java.util.*; ...

  2. TI MSP430工程配置及2019年电赛A题编程示例(使用430 F5529)

    配置 第一步:右击工程,选择Options 第二步:在General Options的Target选项卡里选择对应的器件Device,这里是MSP430G2231 第三步:在Debugger里选择FE ...

  3. 前端插件之Datatables使用--下篇

    工欲善其事,必先利其器 本系列文章介绍我在运维系统开发过程中用到的那些顺手的前端插件,上一篇文章介绍了Datatables插件的基本使用,这一篇文章作为上一篇的延续,会介绍Databases的一些高级 ...

  4. java中String,StringBuffer,StringBuilder的区别

    String: 1,是字符串常量,一旦创建就不能修改.对于已经存在了的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去. 2,String也是final类,不能被继承. 3,而且S ...

  5. 服务注册组件——Eureka高可用集群搭建

    服务注册组件--Eureka高可用集群搭建 什么是Eureka? 服务注册组件:将微服务注册到Eureka中. 为什么需要服务注册? 微服务开发重点在一个"微"字,大型应用拆分成微 ...

  6. QMS 的趨勢概述

    自泰勒Taylor提出的科学管理被奉行后,制造业的分工已然成形,而产品不再是由工匠单独负责完成.为确保产品的质量,产品在完工后的检验为确保瑕疵品不外流出给客户的必要关卡.然而当产品依靠检验结果并无法减 ...

  7. centos7.x 安装系统/配置网络/设置主机名

    1.安装系统     系统的安装就不多说了,自行查找百度,如:https://www.cnblogs.com/wcwen1990/p/7630545.html   2.配置网络(局域网上网) 修改配置 ...

  8. Sqlserver2012 评估期已过问题

    sql server 2012提示评估期已过的解决方法: 第一步:进入SQL2012配置工具中的安装中心. 第二步:再进入左侧维护选项界面,然后选择选择版本升级. 第三步:进入输入产品密钥界面,输入相 ...

  9. Pyinstaller打包多个.py文件

    https://blog.csdn.net/CholenMine/article/details/80964272

  10. SpringMVC源码分析6:SpringMVC的视图解析原理

    title: SpringMVC源码分析6:SpringMVC的视图解析原理 date: 2018-06-07 11:03:19 tags: - SpringMVC categories: - 后端 ...