Springboot 系列(四)Spring Boot 日志框架全解析

文章已经收录在 Github.com/niumoo/JavaNotes ,更有 Java 程序员所须要掌握的核心知识,欢迎Star和指教。
欢迎关注个人 公众号,文章每周更新。

注意:本 Spring Boot 系列文章基于 Spring Boot 版本 v2.1.1.RELEASE 进行学习分析,版本不一样可能会有细微差异。html

前言

Spring 框架选择使用了 JCL 做为默认日志输出。而 Spring Boot 默认选择了 SLF4J 结合 LogBack。那咱们在项目中该使用哪一种日志框架呢?在对于不一样的第三方 jar 使用了不一样的日志框架的时候,咱们该怎么处理呢?
<!-- more -->java

1. 日志框架介绍

日志对于应用程序的重要性不言而喻,不论是记录运行状况仍是追踪线上问题,都离不开对日志的分析,在 Java 领域里存在着多种日志框架,如 JUL, Log4j, Log4j2, Commons Loggin, Slf4j, Logback 等。关于 Log4j, Log4j2 和 Slf4j 直接的故事这里不作介绍,有兴趣能够自行百度。git

2. SLF4 的使用

在开发的时候不该该直接使用日志实现类,应该使用日志的抽象层。具体参考 SLF4J 官方
下图是 SLF4J 结合各类日志框架的官方示例,从图中能够清晰的看出 SLF4J API 永远做为日志的门面,直接应用与应用程序中。
SLF4程序员

同时 SLF4 官方给出了简单示例。github

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 的 jar 和 日志框架的实现 jar. 因为每个日志的实现框架都有本身的配置文件,因此在使用 SLF4 以后,配置文件仍是要使用实现日志框架的配置文件。web

3. 统一日志框架的使用

通常状况下,在项目中存在着各类不一样的第三方 jar ,且它们的日志选择也可能不尽相同,显然这样是不利于咱们使用的,那么若是咱们想为项目设置统一的日志框架该怎么办呢?面试

SLF4J 官方,也给了咱们参考的例子。spring

Bridging legacy APIs从图中咱们获得一种统一日志框架使用的方式,可使用一种和要替换的日志框架类彻底同样的 jar 进行替换,这样不至于原来的第三方 jar 报错,而这个替换的 jar 其实使用了 SLF4J API. 这样项目中的日志就均可以经过 SLF4J API 结合本身选择的框架进行日志输出。
统一日志框架使用步骤概括以下shell

  1. 排除系统中的其余日志框架。
  2. 使用中间包替换要替换的日志框架。
  3. 导入咱们选择的 SLF4J 实现。

4. Spring Boot 的日志关系

4.1. 排除其余日志框架

根据上面总结的要统一日志框架的使用,第一步要排除其余的日志框架,在 Spring Boot 的 Maven 依赖里能够清楚的看到 Spring Boot 排除了其余日志框架。
Spring Boot 排除其余日志框架咱们自行排除依赖时也只须要按照图中的方式就行了。apache

4.2. 统一框架引入替换包

其实 Spring Boot 也是使用了 SLF4J+logback 的日志框架组合,查看 Spring Boot 项目的 Maven 依赖关系能够看到 Spring Boot 的核心启动器 spring-boot-starter 引入了 spring-boot-starter-logging.

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-logging</artifactId>
      <version>2.1.1.RELEASE</version>
      <scope>compile</scope>
    </dependency>

而 spring-boot-starter-logging 的 Maven 依赖主要引入了 logback-classic (包含了日志框架 Logback 的实现),log4j-to-slf4j (在 log4j 日志框架做者开发此框架的时候尚未想到使用日志抽象层进行开发,所以出现了 log4j 向 slf4j 转换的工具),jul-to-slf4j ( Java 自带的日志框架转换为 slf4j).

<dependencies>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.3</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-to-slf4j</artifactId>
      <version>2.11.1</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>jul-to-slf4j</artifactId>
      <version>1.7.25</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>

从上面的分析,Spring Boot 对日志框架的使用已是清晰明了了,咱们使用 IDEA 工具查看 Maven 依赖关系,能够清晰的看到日志框架的引用。若是没有 IDEA 工具,也可使用 Maven 命令查看依赖关系。

mvn dependency:tree

Spring Boot Maven 依赖因而可知,Spring Boot 能够自动的适配日志框架,并且底层使用 SLF4 + LogBack 记录日志,若是咱们自行引入其余框架,须要排除其日志框架。

5. Spring Boot 的日志使用

5.1. 日志级别和格式

从上面的分析,发现 Spring Boot 默认已经使用了 SLF4J + LogBack . 因此咱们在不进行任何额外操做的状况下就可使用 SLF4J + Logback 进行日志输出。
编写 Java 测试类进行测试。

import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * <p>
 * 测试日志输出,
 * SLF4J 日志级别从小到大trace,debug,info,warn,error
 *
 * @Author niujinpeng
 * @Date 2018/12/11 21:12
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class LogbackTest {
    
    Logger logger = LoggerFactory.getLogger(getClass());

    @Test
    public void testLog() {
        logger.trace("Trace 日志...");
        logger.debug("Debug 日志...");
        logger.info("Info 日志...");
        logger.warn("Warn 日志...");
        logger.error("Error 日志...");
    }
}

已知日志级别从小到大为 trace < debug < info < warn < error . 运行获得输出以下。因而可知 Spring Boot 默认日志级别为 INFO.

2018-12-11 23:02:58.028 [main] INFO  n.c.boot.LogbackTest - Info 日志...
2018-12-11 23:02:58.029 [main] WARN  n.c.boot.LogbackTest - Warn 日志...
2018-12-11 23:02:58.029 [main] ERROR n.c.boot.LogbackTest - Error 日志...

从上面的日志结合 Logback 日志格式能够知道 Spring Boot 默认日志格式是。

%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
# %d{yyyy-MM-dd HH:mm:ss.SSS} 时间
# %thread 线程名称
# %-5level 日志级别从左显示5个字符宽度
# %logger{50} 类名
# %msg%n 日志信息加换行

至于为何 Spring Boot 的默认日志输出格式是这样?
Spring Boot 默认日志输出咱们能够在 Spring Boot 的源码里找到答案。

5.2 自定义日志输出

能够直接在配置文件编写日志相关配置。

# 日志配置
# 指定具体包的日志级别
logging.level.net.codingme=debug
# 控制台和日志文件输出格式
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
# 日志文件大小
logging.file.max-size=10MB
# 保留的日志时间
logging.file.max-history=10
# 日志输出路径,默认文件spring.log
logging.path=systemlog
#logging.file=log.log

关于日志的输出路径,可使用 logging.file 或者 logging.path 进行定义,二者存在关系以下表。

logging.file logging.path 例子 描述
(没有) (没有) 仅控制台记录。
具体文件 (没有) my.log 写入指定的日志文件,名称能够是精确位置或相对于当前目录。
(没有) 具体目录 /var/log 写入spring.log指定的目录,名称能够是精确位置或相对于当前目录。

6. 替换日志框架

由于 Log4j 日志框架已经年久失修,原做者都以为写的很差,因此下面演示替换日志框架为 Log4j2 的方式。根据官网咱们 Log4j2 与 logging 须要二选一,所以修改 pom以下。

<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>

文章代码已经上传到 GitHub Spring Boot 日志系统

最后的话

文章已经收录在 Github.com/niumoo/JavaNotes ,欢迎Star和指教。更有一线大厂面试点,Java程序员须要掌握的核心知识等文章,也整理了不少个人文字,欢迎 Star 和完善,但愿咱们一块儿变得优秀。

文章有帮助能够点个「」或「分享」,都是支持,我都喜欢!
文章每周持续更新,要实时关注我更新的文章以及分享的干货,能够关注「 未读代码 」公众号或者个人博客

公众号

相关文章
相关标签/搜索