ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring5.2.x-02-日志体系

2022-01-08 20:00:24  阅读:156  来源: 互联网

标签:02 log Spring5.2 slf4j SLF4J jcl 日志 log4j


现象

  1. Spring体系中, 如果log是由spring-jcl搞出来的, 那么log4j的配置会覆盖logback;即使有logback与slf4j的绑定器, 也会优先使用log4j; 而其他, 如mybatis里的日志, 还是用自己的独立的log组件来打印
  2. Spring-boot 默认使用logback, 日志技术是统一的, 所有的是用一致的log组件

问题

  1. Spring的日志体系为什么与mybatis不互通
  2. Spring-boot为什么可以让日志技术统一

java日志分类

实现类框架

  1. JUL: java自带log框架
  2. Log4j/Log4j2/LogBack: 第三方日志记录框架

门面框架

  1. JCL: 面向Log接口编程, 缺点是不更新、无法解决历史硬编码的log、log组件的选择范围是硬编码于代码中
  2. Slf4j: 通过 Adapter 和 Bridge, 解决了历史硬编码的log不统一; 通过绑定器, 解决log组件的范围自行配置

Spring-JCL

spring4.x用的是apache的jcl, 5.x之后用的是自己module的spring-jcl, 因为原来的jcl没有继续维护, spring-jcl自行维护了

spring-jcl只要看到log4j2, 就会启用, 详见以下代码片段

	private static final String LOG4J_SPI = "org.apache.logging.log4j.spi.ExtendedLogger";

	private static final String LOG4J_SLF4J_PROVIDER = "org.apache.logging.slf4j.SLF4JProvider";

	private static final String SLF4J_SPI = "org.slf4j.spi.LocationAwareLogger";

	private static final String SLF4J_API = "org.slf4j.Logger";
		// 只要有 log4j
		if (isPresent(LOG4J_SPI)) {
			// 有桥接器 && 有slf4j, 才启用 slf4j
			if (isPresent(LOG4J_SLF4J_PROVIDER) && isPresent(SLF4J_SPI)) {
				// log4j-to-slf4j bridge -> we'll rather go with the SLF4J SPI;
				// however, we still prefer Log4j over the plain SLF4J API since
				// the latter does not have location awareness support.
				logApi = LogApi.SLF4J_LAL;
			}
			else {
				// Use Log4j 2.x directly, including location awareness support
				logApi = LogApi.LOG4J;
			}
		}
		else if (isPresent(SLF4J_SPI)) {
			// Full SLF4J SPI including location awareness support
			logApi = LogApi.SLF4J_LAL;
		}
		else if (isPresent(SLF4J_API)) {
			// Minimal SLF4J API without location awareness support
			logApi = LogApi.SLF4J;
		}
		else {
			// java.util.logging as default
			logApi = LogApi.JUL;
		}

基本原理, 就是看能不能用反射找到对应的类, 找不到说明没有运行环境没有这个类, catch住为false即可

导致spring内部的log和外部其他的log不一定统一, 可能会出现Spring里面是log4j2, Tomcat又是 jul, 不能统一配置

因此要加一个log4j-to-slf4j的桥接器(Spring-boot-web默认配置了桥接器, 日志能统一为logback)

从日志框架转向SLF4J 桥接器

桥接器的包结构和需要桥接的日志框架是一样的, 类也是一样的, 这样编译就不会报错

应该用了代理, 不知道细节是怎么实现的...

  1. jul-to-slf4j:jdk-logging到slf4j的桥梁
  2. log4j-over-slf4j:log4j1到slf4j的桥梁
  3. jcl-over-slf4j:commons-logging到slf4j的桥梁

从SLF4J转向具体的日志框架 绑定器

  1. slf4j-jdk14:slf4j到jdk-logging的桥梁
  2. slf4j-log4j12:slf4j到log4j1的桥梁
  3. log4j-slf4j-impl:slf4j到log4j2的桥梁
  4. logback-classic:slf4j到logback的桥梁
  5. slf4j-jcl:slf4j到commons-logging的桥梁

标签:02,log,Spring5.2,slf4j,SLF4J,jcl,日志,log4j
来源: https://www.cnblogs.com/richardwlee/p/15773452.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有