一、类比 JDBC—数据库驱动的架构(门面设计模式)
1. 在我们开发应用的场景中,需要用到很多jar包,而这些包又有自己的日志框架
那么,如何实现便捷的切换日志记录框架?
解决:
首先,写了一个统一的接口层 SLF4J,作为日志门面(日志的一个抽象层),例如:logging-abstract.jar;
想用哪个日志框架(实现了日志门面接口),就给项目中导入具体的日志实现就行了;
上图 slf4j 有六种用法,一共五种角色,
application 不用说,就是我们的系统;
SLF4J API 就是日志接口层(门面);
蓝色和最下面灰色的就是具体日志实现(子系统);
而 Adaptation 就是适配层。
上图第二,第三种用法。
其中第二种就是 SpringBoot 的默认用法;
而为什么会出现第三种?
因为 Log4J 出现得比较早,它根本不知道后面会有 SLF4J 这东西。
Log4J 不能直接作为 SLF4J 的日志实现,所以中间就出现了适配层。第四种同理。
注意:
这里提醒下,每一个日志的实现框架都有自己的配置文件。使用 slf4j 以后,配置文件还是做成日志实现框架自己本身的配置文件。比如,Logback 就使用 logback.xml、Log4j 就使用 Log4j.xml 文件。
2. 如何让应用中所有的日志框架都统一使用 slf4j ?
我们自己的应用SpringBoot中启用了 Logback 这个日志框架;我们又整合了框架 Hibernate,Hibernate 中使用的日志框架为 jboss-logging:我们的应用SpringBoot又使用了 Spring ,Spring 中使用的日志框架为 commons-logging。
这就引出,如何统一日志记录,即使是别的框架和我一起统一使用slf4j进行输出?
解决办法:引入中间替换包
- 将系统中其他日志框架先排除出去;
- 用中间包来替换原有的日志框架;
- 我们导入slf4j其他的实现。
以log4j为例:
SpringBoot 引入中间替换包把其他的日志都替换成了 slf4j
3. 如何移除依赖jar包?
比如 Spring 使用的是 commons-logging 框架,我们可以这样移除:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
SpringBoot 能自动适配所有的日志,而且底层使用 slf4j+logback 的方式记录日志,引入其他框架的时候,只需要把这个框架依赖的日志框架排除掉即可。
二、SpringBoot 的 日志记录细节(官方)
Spring Boot使用Commons Logging日志框架进行所有内部日志记录,但是,使底层日志实现保持了开放状态。 提供了Java Util、Logging、Log4J2和Logback的默认配置。 在每种情况下,日志记录器都被预先配置为使用控制台输出,同时还提供可选文件输出。
默认情况下,如果使用Starters (启动器),则使用Logback日志框架进行日志记录。 还包括适当的Logback路由,以确保使用Java Util Logging,Commons Logging,Log4J或SLF4J的从属库都可以正常工作。
SpringBoot 底层默认选用的就是 SLF4j 和 Logback 来实现日志输出。
在创建Spring Boot工程时,我们引入了spring-boot-starter,
其中包含了spring-boot-starter-logging,该依赖内容就是Spring Boot默认的日志框架Logback。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
注意:
-
log4j2太厉害,但是太厉害 以至于 SpringBoot 都跟不上
-
SpringBoot的底层是Spring框架,Spring框架默认是用JCL日志门面,日志门面实现是Commons Logging
三、市面上的日志框架
日志门面 | 日志门面的具体实现 |
---|---|
JCL(Jakarta Commons Logging)、SLF4j(Simple Logging Facade for Java)、 jboss-logging | Log4j 、JUL(java.util.logging) 、Log4j2 、 Logback |
名词解释:
- 日志门面:一个统一的接口层(SLF4J)
- 日志门面的具体实现:接口层的具体逻辑实现(Logback)
四、SLF4j使用
在开发的时候,日志记录方法的调用,不应该来直接调用日志的实现类,而是调用日志抽象层里面的方法;给应用里面导入slf4j的jar和 logback的实现jar。
SpringBoot默认帮我们配置好了日志 slf4j + logback
官方案例:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
public static void main(String[] args) {
// HelloWorld.class 就是你要打印的指定类的日志,
// 如果你想在其它类中打印,那就把 HelloWorld.class 替换成目标类名.class 即可。
Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.info("Hello World");
}
}
日志输出格式:
%d表示日期时间,
%thread表示线程名,
%-5level:级别从左显示5个字符宽度
%logger{50} 表示logger名字最长50个字符,否则按照句点分割。
%msg:日志消息,
%n是换行符
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
SpringBoot修改日志的默认配置:
# 日志记录配置文件的位置,例如,logback的"classpath:logback.xml"。
logging.config=classpath:logback.xml
# 指定 类/包 的日志级别
logging.level.com.springboot.template=trace
# 日志文件名,名称可以是确切的位置,也可以是相对于当前目录的
logging.file.name=C:/spring/myapp.log
# 日志文件的位置,例如,"/var/log",使用 spring.log 作为默认文件名
logging.file.path=/var/log
# 在控制台输出的日志的格式
logging.pattern.console=%d{yyyy‐MM‐dd} [%thread] %‐5level %logger{50} ‐ %msg%n
# 指定文件中日志输出的格式
logging.pattern.file=%d{yyyy‐MM‐dd} === [%thread] === %‐5level === %logger{50} ==== %msg%n
# 最大日志文件大小,默认值10MB
logging.file.max-size=10MB
logging.file. name | logging.file. path | 例子 | 描述 |
---|---|---|---|
(none) | (none) | 只在控制台输出 | |
指定文件名 | (none) | my.log | 输出日志到my.log文件 |
(none) | 指定目录 | /var/log | 输出到指定目录的 spring.log 文件中 |
自定义配置文件log信息:
给类路径下放上每个日志框架自己的配置文件即可;SpringBoot就不使用他默认配置
日志记录系统 | 定制 |
---|---|
Logback | logback-spring.xml, logback-spring.groovy, logback.xml 或者 logback.groovy |
Log4j2 | log4j2-spring.xml 或者 log4j2.xml |
JDK (Java Util Logging) | logging.properties |
logback.xml:只要在类路径下,直接就可以被logback日志框架识别;
logback-spring.xml:logback日志框架无法识别此文件,就不直接加载日志的配置项,由SpringBoot解析日志配置,可以使用SpringBoot的高级Profile功能,进行环境切换,指定某段配置只在某个环境下生效。
<springProfile name="dev">
<!-- configuration to be enabled when the "staging" profile is active -->
可以指定某段配置只在某个环境下生效
</springProfile>
例如:
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<!--
日志输出格式:
%d表示日期时间,
%thread表示线程名,
%-5level:级别从左显示5个字符宽度
%logger{50} 表示logger名字最长50个字符,否则按照句点分割。
%msg:日志消息,
%n是换行符
-->
<layout class="ch.qos.logback.classic.PatternLayout">
<springProfile name="dev">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n</pattern>
</springProfile>
<springProfile name="!dev">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ==== %-5level %logger{50} - %msg%n</pattern>
</springProfile>
</layout>
</appender>
注意:
如果使用logback.xml作为日志配置文件,还要使用profile功能,会有以下错误:
no applicable action for [springProfile]
切换日志框架
可以按照slf4j的日志适配图,进行相关的切换;
slf4j+log4j的方式;
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 引入log4j 的 starter (注意指明版本) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
切换为log4j2
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
五、日志level的8个级别
/* 日志
*
* 1 日志级别:按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
*
* 2 调整输出的日志级别 ———— 就只会输出这个级别以及更高级别的日志
* 1 springBoot 默认使用的 日志级别 是 info 级别,
* 2 可以在配置文件 或者 注解 中 指定某个 包/类 的日志级别
* 1 配置文件 logging.level.包/类名=日志级别
* 2 注解 要自定义
* 3 指定 日志配置的 配置文件 的位置
* 1 默认输出到控制台,如果不指定 logging.file.name 和 logging.file.path
* 2 logging.file.name 指定日志文件名。如果不指定路径,默认生成在当前项目下;可以在磁盘路径
* 3 logging.file.path 指定日志文件输出的目录,默认文件名spring.log
*
* All:最低等级的,用于打开所有日志记录.
* Trace:是追踪,就是程序推进以下,你就可以写个trace输出,所以trace应该会特别多,不过没关系,我们可以设置最低日志级别不让他输出.
* Debug:指出细粒度信息事件对调试应用程序是非常有帮助的.
* Info:消息在粗粒度级别上突出强调应用程序的运行过程.打印一些你感兴趣的或者重要的信息。用于生产环境中输出程序运行的一些重要信息,但是不能滥用,避免打印过多的日志。
* Warn:输出警告及warn以下级别的日志.
* Error:输出错误信息日志.
* Fatal:输出每个严重的错误事件将会导致应用程序的退出的日志.
* OFF:最高等级的,用于关闭所有日志记录.
*/
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/69778.html