SpringBoot日志实现

SpringBoot日志实现

SpringBoot日志默认实现

SpringBoot默认的日志实现是使用slf4j+logback,这种实现类似于JDBC + 数据库驱动(统一接口+实现类)。

slf4j叫做日志门面,是一个统一的日志接口层,各种具体的日志实现都可以通过slf4j来实现,比如logback就是一个具体的日志门面的实现。

常见日志框架

市面上常见的日志框架有:JUL , JCL , Jboss-logging , logback , log4j , log4j2 , slf4j等等,他们的分类如下:

日志门面(日志的抽象层) 日志实现
JCL(Jakarta Commons Logging) , SLF4J(Simple Logging Facade for Java), Jboss-logging Log4j , JUL(java.util.logging ) , Log4j2, Logback

JCL是Apache公司开发的一个框架,Jakarta小组开发的,Spring Framework在使用,但是2014年已经停止更新了。SLF4J , Log4j , Logback是同一个人写的,这个人想优化Log4j,但是认为重新写比较麻烦,于是写了SLF4J这个抽象层日志框架,又写了Logback这个实现类。Log4j2也是Apache公司的,好多框架都没适配。Hibernate底层使用Jboss-logging实现。

我们需要在左边选一个门面(抽象层),右边选一个实现。

Slf4j的使用

通过Slf4j的LoggerFactory创建Logger来进行日志的记录;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {
  public static void main(String[] args) {
    Logger logger = LoggerFactory.getLogger(HelloWorld.class);
    logger.info("Hello World");
  }
}

slf4j官网:https://www.slf4j.org/

下图是使用slf4j如何实现各种日志框架:

SpringBoot日志实现_第1张图片

可以看到,只引入slf4j是不能够实现日志记录的,在引入slf4j-api.jar的基础上;

如果要实现logback日志框架,需要引入logback-core.jar和logback-classic.jar;

如果要实现log4j日志框架,需要引入slf4j-log412.jar(log4j适配slf4j的jar),log4j.jar。其他情况类似。

**每一个日志实现框架都有自己的配置文件,使用slf4j以后,配置文件还是做成日志实现框架自己本身的配置文件。**比如实现框架选用logback,那么配置文件就写logback.xml这种,实现框架选log4j,那么配置问价就选log4j.xml这种。

遗留问题

但是在实际项目中,我们所引入的不同框架的底层日志框架是不一样的。比如:

Spring使用JCL,Hibernate使用Jboss等等,我们就需要统一日志记录,让不同的框架统一使用slf4j进行输出,这样我们就不用写别的配置文件,统一使用logback进行配置。具体做法如下图:

SpringBoot日志实现_第2张图片

如上图,比如Spring框架,为了达到上述目标,我们需要排除掉Spring底层的commons-logging包,(不引入Spring会报包找不到的错误)然后引入包装层jcl-over-slf4j,这个包装层jar的包路径,类名等都采用commons-logging的形式进行配置,但是底层实现是slf4j,最后添加logback的jar包。

统一日志记录的思路(SpringBoot实现统一日志记录为slf4j的做法):

  1. 先排除掉其他日志框架

  2. 然后用中间包来替换排除掉的日志框架

  3. 最后再添加目标日志框架

注意:在SpringBoot2.x版本的时候,上述的实现方式发生了一些改变,中间引入了"桥接"的概念,没有直接通过模拟类名实现,比如类:SLF4JBridgeHandler,但是其底层的实现方法都是类似的,都是通过排除原有依赖实现,比如spring-boot-starter-logging的依赖:

JUL的桥接模式的实现是继承JUL的Handler抽象类,按源码上的注释所说,是实现一种redirected重定向。

<dependency>
      <groupId>org.apache.logging.log4jgroupId>
      <artifactId>log4j-to-slf4jartifactId>
      <version>2.11.2version>
      <scope>compilescope>
    dependency>
    <dependency>
      <groupId>org.slf4jgroupId>
      <artifactId>jul-to-slf4jartifactId>
      <version>1.7.26version>
      <scope>compilescope>
    dependency>

注意实现由log4j-over-slf4j变成了log4j-to-slf4j

但是其底层依然不变,还是排除jar包,比如spring-boot底层引入的Apache的commons包:

<dependency>
      <groupId>org.apache.commonsgroupId>
      <artifactId>commons-dbcp2artifactId>
      <version>2.5.0version>
      <scope>compilescope>
      <exclusions>
        <exclusion>
          <artifactId>commons-loggingartifactId>
          <groupId>commons-logginggroupId>
        exclusion>
      exclusions>
      <optional>trueoptional>
    dependency>
    <dependency>
      <groupId>org.apache.httpcomponentsgroupId>
      <artifactId>httpclientartifactId>
      <version>4.5.8version>
      <scope>compilescope>
      <exclusions>
        <exclusion>
          <artifactId>commons-loggingartifactId>
          <groupId>commons-logginggroupId>
        exclusion>
      exclusions>
      <optional>trueoptional>
    dependency>

其中关于JCL日志框架的处理是使用spring-jcl这个工程进行处理,整个spring-core都依赖于这个工程。

[外链图片转存失败(img-O5dMxV5I-1566862162637)(/Users/circleus/Library/Application Support/typora-user-images/image-20190407221811598.png)]

SpringBoot引入新框架需注意

当SpringBoot引入新框架的时候,如果此框架使用了JUL,JCL,或者log4j,这个时候我们应该排除掉原来的日志框架,避免因为现在SpringBoot中存在相同的日志实现而造成jar包冲突冲突。

SpringBoot日志配置

SpringBoot默认是info级别,如果没有指定级别就使用 info 级别,这个默认级别也叫 root级别,想要调整某个包的日志级别可以通过application.properties进行配置,例:

# com.anhe是我自己的包路径
logging.level.com.anhe=trace

有时候想查看Mybatis执行的具体sql语句可以将mapper对应的包路径日志级别设置为debug级别

logging.file logging.path Example Description
未配置 未配置 只在控制台输出
指定文件名 未配置 my.log 输出日志到my.log文件
未配置 指定目录 /var/log 输出到指定目录的spring.log文件中
指定文件名 指定目录 /Users/circleus/Documents/tmp
/Users/circleus/Documents/my.log
都指定的时候以logging.file为准
# 配置在指定目录,不指定路径的时候就是配置在项目路径下
logging.file=/Users/circleus/Documents/my.log
# 在控制台输出的日志的格式
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
# 在文件中日志输出的格式
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n

此路径配置的xml配置了项目关于日志的默认配置:spring-boot/2.1.4.RELEASE/spring-boot-2.1.4.RELEASE.jar!/org/springframework/boot/logging/logback/defaults.xml

除此之外,还可以配置日志滚动条件:比如配置日志文件满10M就记录到下一个文件,文件名以i递增,或者按天进行滚动。日志配置文件的名称:logback-spring.xml或者logback.xml,推荐使用logback-spring.xml,因为配置成logback-spring.xml是由SpringBoot自己加载,不是由日志框架直接加载,可以使用高级特性:,通过这个特性,可以配置不同环境配置不同的日志级别,比如开发环境使用debug,生产环境使用info。

你可能感兴趣的:(SpringBoot)