Springboot 开发 -- 日志框架总结及实践

一、Java 日志框架简介

Java 日志框架主要分为两类:日志门面和具体的日志实现。
在这里插入图片描述

1. 日志门面

日志门面提供了统一的日志接口,使得开发者可以灵活地更换底层的日志框架而无需修改代码。常见的日志门面有:

  • Jakarta Commons Logging (JCL):只支持 JUL 和 Log4j。
  • Simple Logging Facade for Java (SLF4J):支持几乎所有主流的日志框架。

2. 日志实现

日志实现框架提供了具体的日志记录功能。常见的实现有:

  • Java Util Logging (JUL):JDK 自带的日志实现。
  • Log4j:由 Apache 软件基金会提供,是最早的日志框架之一。
  • Logback:由 Log4j 的创始人设计,性能优化,支持 SLF4J。
  • Log4j2:Log4j 的升级版,重新架构,性能和特性上有显著提升。

3.日志级别

使用日志级别的好处在于,调整级别,就可以屏蔽掉很多调试相关的日志输出。不同的日志实现定义的日志级别不太一样,不过也都大同小异。

  1. Java Util Logging

Java Util Logging 定义了 7 个日志级别,从严重到普通依次是:

  • SEVERE、WARNING、INFO、CONFIG、FINE、FINER、FINEST

  • 因为默认级别是 INFO,因此 INFO 级别以下的日志,不会被打印出来。

  1. Log4j

Log4j 定义了 8 个日志级别(除去 OFF 和 ALL,可以说分为 6 个级别),从严重到普通依次是:

  • OFF:最高等级的,用于关闭所有日志记录。
  • FATAL:重大错误,这种级别可以直接停止程序了。
  • ERROR:打印错误和异常信息,如果不想输出太多的日志,可以使用这个级别。
  • WARN:警告提示。
  • INFO:用于生产环境中输出程序运行的一些重要信息,不能滥用。
  • DEBUG:用于开发过程中打印一些运行信息。
    TRACE
  • ALL 最低等级的,用于打开所有日志记录。
  1. Logback

Logback 日志级别比较简单,从严重到普通依次是:

  • ERROR、 WARN、INFO、DEBUG、TRACE

二、 Spring Boot默认日志框架

Spring Boot默认使用的日志框架是SLF4J+Logback。这个组合是当下的最优选择,原因如下:

  • SLF4J是日志接口规范,可以通过配置不同的桥接器,来为项目接入不同的日志框架。更改日志框架无需改动代码。
  • Logback是由log4j创始人设计的又一个开源日志组件,在性能和架构上较log4j有着很大程度上的改进,并且logback是Spring Boot框架(1.x和2.x)默认集成的日志实现框架
  • Log4j2是对log4j的升级,提供了重要的改进,并提供了Logback中可用的许多改进,同时修复了Logback体系结构中的一些固有问题。可以认为log4j2是logback的加强版

打开一个SpringBoot应用的pom.xml 文件,可看到其中导入 了spring-boot-starter-web 依赖;

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

spring-boot-starter-web 依赖中包含 spring-boot-stater 依赖;

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

spring-boot-stater 依赖中包含 spring-boot-starter-logging 依赖用于配置日志相关;

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

查看 spring-boot-starter-logging 的 pom 发现依赖于如下:
在这里插入图片描述
其中:

  • logback-classic:
    这是一个具体的日志框架,即 Logback 的经典版本。Logback 是 SLF4J(Simple Logging Facade for Java)的一个实现,它提供了高效的日志记录功能。
  • log4j-to-slf4j:
    这个依赖用于将 Log4j 的日志调用重定向到 SLF4J。
  • jul-to-slf4j:
    这个依赖用于将 Java 自带的日志系统(java.util.logging,简称 JUL)的日志调用重定向到 SLF4J。

在这里插入图片描述

三、 Spring Boot默认日志框架 Logback 集成

1.引入 spring-boot-starter-logging

pom 文件添加:

    <dependency>
    	<groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-logging</artifactId>
    </dependency>

spring-boot-starter 中已经引入了 spring-boot-starter-logging ,我们可以直接在项目中使用 spring-boot-starter

<dependency>
	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

2. Logback配置文件加载顺序

在logback框架读取日志配置文件的优先级从高到低依次是:

日志加载顺序:logback.xml > application.properties > logback-spring.xml

配置文件的最佳选择

  • logback.xml:来配置日志框架,该配置文件可直接就被日志框架识别了;一般情况不推荐

  • logback-spring.xml日志框架不直接加载日志的配置项由SpringBoot解析日志配置Spring Boot 官方推荐优先使用带有 -spring 的文件名作为你的日志配置。命名为 logback-spring.xml 的日志配置文件,可以为它添加一些 spring boot 特有的配置项。

3. logback-spring.xml 配置实例

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--定义日志文件的存储地址,使用Spring的属性文件配置方式-->
    <springProperty scope="context" name="log.home" source="log.home" defaultValue="logs"/>

    <!--定义日志文件的路径-->
    <property name="LOG_PATH" value="${log.home}"/>

    <!--定义控制台输出-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%-5relative [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>

    <!--定义 INFO 及以上级别信息输出到控制台-->
    <root level="INFO">
        <appender-ref ref="console"/>
    </root>

    <!--定义所有组件的日志级别,如所有 DEBUG-->
    <logger name="com.example" level="DEBUG"/>

    <!-- date 格式定义 -->
    <property name="LOG_DATEFORMAT" value="yyyy-MM-dd"/>

    <!-- 定义日志归档文件名称格式,每天生成一个日志文件 -->
    <property name="ARCHIVE_PATTERN" value="${LOG_PATH}/%d{${LOG_DATEFORMAT}}/app-%d{${LOG_DATEFORMAT}}-%i.log.gz"/>

    <!--定义文件输出,会根据定义的阈值进行切割,支持自动归档压缩过期日志-->
    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/app.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--定义日志文件切割的阈值,本例是 50MB-->
            <maxFileSize>50MB</maxFileSize>
            <!--定义日志文件保留时间,本例是每天生成一个日志文件-->
            <fileNamePattern>${ARCHIVE_PATTERN}</fileNamePattern>
            <maxHistory>30</maxHistory>
            <!-- zip 压缩生成的归档文件 -->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>50MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!-- 删除过期文件 -->
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>

    <!--定义 ERROR 级别以上信息输出到文件-->
    <logger name="com.example.demo" level="ERROR" additivity="false">
        <appender-ref ref="file"/>
    </logger>

    <!--异步输出日志信息-->
    <appender name="asyncFile" class="ch.qos.logback.classic.AsyncAppender">
        <discardingThreshold>0</discardingThreshold>
        <queueSize>256</queueSize>
        <appender-ref ref="file"/>
    </appender>

    <!--定义INFO及以上级别信息异步输出到文件-->
    <logger name="com.example" level="INFO" additivity="false">
        <appender-ref ref="asyncFile"/>
    </logger>

</configuration>

4. application.yml 配置文件实现日志配置

############## logback 日志自定义配置 ############## 
logging:
  level:
    root: info
    com.dz.demo.controller: debug
  file:
    path: D:\logs
    name: D:\logs\boot-launch.log
    max-size: 10MB
    max-history: 180
  pattern:
    console: '%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{10}) - %cyan(%msg%n)'
    file: '%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger : %msg%n'
  • logging.level.root=info #指定整个系统的默认日志级别是info,日志级别统一化
  • logging.level.com.dz.demo.controller=debug #指定某个特定的package的日志级别是debug,日志级别个性化。优先级角度,个性配置大于统一配置
  • logging.file.path #将日志输出到指定目录,如果不指定logging.file.name,日志文件的默认名称是spring.log。配置了 logging.file.name之后,logging.file.path配置失效。
  • 无论何种设置,Spring Boot都会自动按天分割日志文件,也就是说每天都会自动生成一个新的log文件,而之前的会自动打成GZ压缩包。# 日志文件大小
  • logging.file.max-size=10MB #分割的每个日志的文件最大容量,超过这个size之后日志继续分隔。
  • logging.file.max-history=180 #设置保留的日志时间以天为单位
  • logging.pattern.file #输出到文件中的日志的格式
  • logging.pattern.console #控制台输出日志的格式,控制台调试时候显示效果更清晰,为日志增加了颜色。red、green等等

日志格式占位符
配合这张图,看一下占位符和logging.pattern.console格式配置之间的关系
在这里插入图片描述

  • %d{HH:mm:ss.SSS}:日志输出时间(red)
  • %thread:输出日志的进程名字,这在Web应用以及异步任务处理中很有用 (green)
  • %-5level:日志级别,并且使用5个字符靠左对齐 (highlight高亮蓝色)
  • %logger:日志输出类的名字 (boldMagenta粗体洋红色)
  • %msg:日志消息 (cyan蓝绿色)
  • %n:平台的换行符

四、日志使用

  1. 在使用 SLF4J 进行日志记录时,通常都需要在每个需要记录日志的类中定义 Logger 变量,如下所示:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@RestController
public class LogController {
    private static final Logger logger = LoggerFactory.getLogger(LogController.class);

    @GetMapping("/test")
    public void test(){
        logger.trace("Trace 日志...");
        logger.debug("Debug 日志...");
        logger.info("Info 日志...");
        logger.warn("Warn 日志...");
        logger.error("Error 日志...");
    }
}
  1. 当我们在项目中引入了 Lombok,可以使用它提供的 @Slf4j 注解来自动生成上面那个变量,默认的变量名是 log
@Slf4j
@RestController
public class LogController {
   
    @GetMapping("/test")
    public void test(){
        log.trace("Trace 日志...");
        log.debug("Debug 日志...");
        log.info("Info 日志...");
        log.warn("Warn 日志...");
        log.error("Error 日志...");
    }
}

如果我们想采用 LOGGER 变量名,可以增加 lombok.config 文件,
并在文件中增加 lombok.log.fieldName=LOGGER 的配置项即可

参考文档:
https://cloud.tencent.com/developer/article/1914231
https://cloud.tencent.com/developer/article/2354562

  • 45
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值