[SpringBoot] 统一日志框架

✨✨个人主页:沫洺的主页

📚📚系列专栏: 📖 JavaWeb专栏📖 JavaSE专栏 📖 Java基础专栏📖vue3专栏 

                           📖MyBatis专栏📖Spring专栏📖SpringMVC专栏📖SpringBoot专栏

                           📖Docker专栏📖Reids专栏📖MQ专栏📖SpringCloud专栏     

💖💖如果文章对你有所帮助请留下三连✨✨

🍖Spring Boot统一日志框架

🍗日志框架的选择

在项目开发中,日志十分的重要,不管是记录运行情况还是定位线上问题,都离不开对日志的分析。市面上常见的日志框架有很多,它们可以被分为两类:日志门面(日志抽象层)和日志实现,如下表

日志分类描述举例
日志门面(日志抽象层)为 Java 日志访问提供一套标准和规范的 API 框架,其主要意义在于提供接口JCL(Jakarta Commons Logging)、SLF4j(Simple Logging Facade for Java)、jboss-logging
日志实现日志门面的具体的实现Log4j、JUL(java.util.logging)、Log4j2、Logback

通常情况下,日志由一个日志门面与一个日志实现组合搭建而成,Spring Boot 选用 SLF4J + Logback 的组合来搭建日志系统。

SLF4J 是目前市面上最流行的日志门面,使用 Slf4j 可以很灵活的使用占位符进行参数占位,简化代码,拥有更好的可读性。

Logback 是 Slf4j 的原生实现框架,它与 Log4j 出自一个人之手,但拥有比 log4j 更多的优点、特性和更做强的性能,现在基本都用来代替 log4j 成为主流。

🥩SLF4J 的使用

在项目开发中,记录日志时不应该直接调用日志实现层的方法,而应该调用日志门面(日志抽象层)的方法。

在使用 SLF4J 记录日志时,我们需要在应用中导入 SLF4J 及日志实现,并在记录日志时调用 SLF4J 的方法,例如:

package com.moming;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@Slf4j
public class App {
    //与@Slf4j 二选一
    //private static final Logger log = LoggerFactory.getLogger(App.class);
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
        //级别由高到低
        log.error("你好,我是error日志");
        log.warn("你好,我是warn日志");
        log.info("你好,我是info日志");
        log.debug("你好,我是debug日志");
        log.trace("你好,我是trace日志");
    }
}

级别低的会将比自己级别高的级别都打印出来

​​

SLF4J 作为一款优秀的日志门面或者日志抽象层,它可以与各种日志实现框架组合使用,以达到记录日志的目的如下图,(参考自SLF4J 官方

​​

从 SLF4J 官方给出的方案可以看出:

Logback 作为 Slf4j 的原生实现框架,当应用使用 SLF4J+Logback 的组合记录日志时,只需要引入 SLF4J 和 Logback 的 Jar 包即可;其它亦如此。

这里我们需要注意一点,每一个日志的实现框架都有自己的配置文件。使用 slf4j 记录日志时,配置文件应该使用日志实现框架(例如 logback、log4j 和 JUL 等等)自己本身的配置文件。

🍠统一日志框架(通用) 

通常一个完整的应用下会依赖于多种不同的框架,而且它们记录日志使用的日志框架也不尽相同,例如,Spring Boot(slf4j+logback),Spring(commons-logging)、Hibernate(jboss-logging)等等。那么如何统一日志框架的使用呢?

对此,SLF4J 官方也给出了相应的解决方案,如下图。

​​

从上图中可以看出,统一日志框架一共需要以下 3 步

  • 排除应用中的原来的日志框架;

  • 引入替换包替换被排除的日志框架;

  • 导入 SLF4J 实现

SLF4J 官方给出的统一日志框架的方案是“狸猫换太子”,即使用一个替换包来替换原来的日志框架,例如 log4j-over-slf4j 替换 Log4j(Commons Logging API)、jul-to-slf4j.jar 替换 JUL(java.util.logging API)等等。

替换包内包含被替换的日志框架中的所有类,这样就可以保证应用不会报错,但替换包内部实际使用的是 SLF4J API,以达到统一日主框架的目的。

🥟统一日志框架(Spring Boot)

我们在使用 Spring Boot 时,同样可能用到其他的框架,例如 Mybatis、Spring MVC、 Hibernate 等等,这些框架的底层都有自己的日志框架,此时我们也需要对日志框架进行统一。

我们知道,统一日志框架的使用一共分为 3 步,Soring Boot 作为一款优秀的开箱即用的框架,已经为用户完成了其中 2 步:引入替换包和导入 SLF4J 实现。

Spring Boot 的核心启动器 spring-boot-starter 引入了 spring-boot-starter-logging,使用 IDEA 查看其依赖关系,如下图。

​​

从上图可知,spring-boot-starter-logging 的 Maven 依赖不但引入了 logback-classic (包含了日志框架 SLF4J 的实现),还引入了 log4j-to-slf4j(log4j 的替换包),jul-to-slf4j (JUL 的替换包),即 Spring Boot 已经为我们完成了统一日志框架的 3 个步骤中的 2 步。

SpringBoot 底层使用 slf4j+logback 的方式记录日志,当我们引入了依赖了其他日志框架的第三方框架(例如 Hibernate)时,只需要把这个框架所依赖的日志框架排除,即可实现日志框架的统一,示例代码如下。

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.3.19</version>
            <exclusions>
                <exclusion>
                        <groupId>commons-logging</groupId>
                        <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

🥠Spring Boot日志配置及输出

🥯默认配置

Spring Boot 默认使用 SLF4J+Logback 记录日志,并提供了默认配置,即使我们不进行任何额外配,也可以使用 SLF4J+Logback 进行日志输出。

常见的日志配置包括日志级别、日志的输入出格式等内容。

日志级别

日志的输出都是分级别的,当一条日志信息的级别大于或等于配置文件的级别时,就对这条日志进行记录。

常见的日志级别如下

级别级别名称说明
5error错误信息,(生产环境)使用较多
4warn

警告,使用较多

3info输出重要的信息,使用较多
2debug调试,实际应用中一般将其作为最低级别,而 trace 则很少使用
1trace追踪,指明程序运行轨迹

输出格式

我们可以通过以下常用日志参数对日志的输出格式进行修改,如下表

序号输出格式说明
1%d{yyyy-MM-dd HH:mm:ss, SSS}日志生产时间,输出到毫秒的时间
2%-5level输出日志级别,-5 表示左对齐并且固定输出 5 个字符,如果不足在右边补 0
3%logger 或 %clogger 的名称
4%thread 或 %t输出当前线程名称
5%p日志输出格式
6%message 或 %msg 或 %m日志内容,即 logger.info("message")
7%n换行符
8%class 或 %C输出 Java 类名
9%file 或 %F输出文件名
10%L输出错误行号
11%method 或 %M输出方法名
12hostName本地机器名
13hostAddress

本地 ip 地址

🥖自定义日志配置

在 Spring Boot 的配置文件 application.porperties/yml 中,可以对日志的一些默认配置进行修改,但这种方式只能修改个别的日志配置,想要修改更多的配置或者使用更高级的功能,则需要通过日志实现框架自己的配置文件进行配置。

Spring 官方提供了各个日志实现框架所需的配置文件,用户只要将指定的配置文件放置到项目的类路径下即可。

日志框架配置文件
Logbacklogback-spring.xml、logback-spring.groovy、logback.xml、logback.groovy
Log4j2log4j2-spring.xml、log4j2.xml
JUL (Java Util Logging)logging.properties

从上表可以看出,日志框架的配置文件基本上被分为 2 类:

  • 普通日志配置文件,即不带 srping 标识的配置文件,例如 logback.xml

  • 带有 spring 表示的日志配置文件,例如 logback-spring.xml

Spring Boot官方推荐优先使用带有-spring的文件名作为你的日志配置(如使用logback-spring.xml,而不是logback.xml),如果想自定义文件名,可以通过logging.config属性指定自定义的名字:

application.porperties

logging.config=classpath:my-logging-config.xml

logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--scan="true" 当发生变化 自动重载文件-->
<!--scanPeriod="1000" 自动重载文件时间间隔-->
<!--debug="true" 打印出logback内部日志信息-->
<configuration debug="false" scan="true">
    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
    <!--app.name服务名称 log.path日志文件存放路径-->
    <property name="app.name" value="scm-app"/>
    <property name="log.path" value="./logs/" />
    <!--console控制台日志的输出格式-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!--格式化输出:
             %d:日期; %thread:线程名; %-5level:级别从左显示5个字符宽度; %class:全类名; %logger{36}:当前类,最长36个字符; %msg:日志消息; %n是换行符-->
            <pattern>
                ${app.name} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %class %logger{36} [--%method--] #:%L--- %msg%n
            </pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <!--文件输出-->
    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--文件存放路径-->
        <file>${log.path}/${app.name}.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--文件超过1MB后就新建一个文件-->
            <fileNamePattern>${log.path}/${app.name}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!--日志文件保留天数-->
            <maxHistory>7</maxHistory>
            <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!--日志文件最大的大小-->
                <maxFileSize>1MB</maxFileSize>
            </TimeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <!--文件日志的输出格式-->
        <encoder>
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符
            %logger{36}表示logger是class的全名,36表示限制最长字符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{36} [%file:%line] %msg%n</pattern>
            <charset>utf-8</charset>
        </encoder>
    </appender>
    <!--根日志输出级别-->
    <root level="error">
        <!--输出到控制台-->
        <appender-ref ref="console" />
        <!--输出到文件-->
        <appender-ref ref="file" />
    </root>
    <!--和application.porperties/yml协调使用二选一,同时使用时application.porperties/yml配置级别高-->
    <!--自定义日志级别配置,指定我们项目都是info级别-->
    <logger name="com.moming" level="info" />

</configuration>

输出到控制台

​​

输出到文件

文件位置:根目录下logs文件夹里

​​

​​

🍤彩色日志

官网:Coloring

 <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr"
                    converterClass="org.springframework.boot.logging.logback.ColorConverter" />

logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--scan="true" 当发生变化 自动重载文件-->
<!--scanPeriod="1000" 自动重载文件时间间隔-->
<!--debug="true" 打印出logback内部日志信息-->
<configuration debug="false" scan="true">
    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
    <!--app.name服务名称 log.path日志文件存放路径-->
    <property name="app.name" value="scm-app"/>
    <property name="log.path" value="./logs/" />
    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr"
                    converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <!--console控制台日志的输出格式-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!--格式化输出:
             %d:日期; %thread:线程名; %-5level:级别从左显示5个字符宽度; %class:全类名; %logger{36}:当前类,最长36个字符; %msg:日志消息; %n是换行符-->
            <pattern>
                %magenta(${app.name}) %d{yyyy-MM-dd HH:mm:ss.SSS} %blue(%thread) %clr(%-5level) %logger{36} %red(%method) %cyan(%L)--- %green(%msg) %n
            </pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <!--文件输出-->
    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--文件存放路径-->
        <file>${log.path}/${app.name}.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--文件超过1MB后就新建一个文件-->
            <fileNamePattern>${log.path}/${app.name}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!--日志文件保留天数-->
            <maxHistory>7</maxHistory>
            <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!--日志文件最大的大小-->
                <maxFileSize>1MB</maxFileSize>
            </TimeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <!--文件日志的输出格式-->
        <encoder>
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符
            %logger{36}表示logger是class的全名,36表示限制最长字符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{36} [%file:%line] %msg%n</pattern>
            <charset>utf-8</charset>
        </encoder>
    </appender>
    <!--根日志输出级别-->
    <root level="error">
        <!--输出到控制台-->
        <appender-ref ref="console" />
        <!--输出到文件-->
        <appender-ref ref="file" />
    </root>
    <!--和application.porperties/yml协调使用二选一,同时使用时application.porperties/yml配置级别高-->
    <!--自定义日志级别配置,指定我们项目都是info级别-->
    <logger name="com.moming" level="info" />

</configuration>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沫洺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值