嗨!大家好吖,今天教大家如何在 Spring Boot 项目中配置日志,你要问日志有什么用?当然是为了记录系统运行记录,方便我们排错和观察系统运行状态了,在生产实际中日志处理是一个很重要的部分。

日志的级别

常见的日志级别由低到高分为: TRACE < DEBUG < INFO < WARN < ERROR < FATAL

如果你设置的日志基本是 INFO,那么它下面级别的日志就不展示/记录了,比如 TRACE 和 DEBUG,以此类推。

常见的日志框架

  • log4j
    一个基于 Java 的日志记录工具,据说官方已经不再更新。后来 Log4j 团队创建了 Log4j 的继任者,版本号为 2.0 的新版本。也就是 log4j2。
  • log4j2
    Log4j2 是对 Log4j 的升级,它比其前身 Log4j 1.x 提供了显着改进。2021 年曾爆出有漏洞,后被紧急修复。
  • logback
    Logback 是由 log4j 创始人设计的另一个开源日志组件,相比之于 log4j 性能提升了 10 以上,它也是 Spring Boot 默认的日志框架。

Spring Boot 的日志框架

Spring Boot 默认的日志框架是 logback,所以在 Spring Boot 项目中不需要重新引入 logback 的依赖。

如何在项目中打印日志?

引入 Lombok 依赖

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

然后在类上标注一个注解 @Slf4j

@Slf4j
class DemoApplicationTests {
  @Test
  public void test(){
    log.debug("输出DEBUG日志.......");
  }
}

如何定制日志级别?

Spring Boot 中默认的日志级别是 INFO,你也可以自己定制日志级别,在 Spring Boot 配置文件中添加如下配置:

logging.level.root=DEBUG

Spring Boot 还支持 package 级别的日志级别调整,在 Spring Boot 配置文件中添加如下配置:

logging.level.com.example.demo=INFO

日志如何输出到文件中?

Spring Boot 中日志默认是输出到控制台的,发布到服务器日志这样处理肯定是不行的,我们可以将日志输出到文件,然后通过 cat 后者 tail 命令在服务器上查看日志文件内容,从而查看到系统的运行记录。在 Spring Boot 配置文件中添加如下配置:

# 指定日志文件的路径
logging.file.path:
# 日志的文件名,默认为 spring.log
logging.file.name:

注意: 官方文档说这两个属性不能同时配置,否则不生效,因此只需要配置一个即可。

如何自定义日志配置?

如上操作都是在 Spring Boot 提供配置的基础上我们来配置,那么我们我们如何自定义配置呢?比如输出日志文件名称的格式等等。

Spring Boot 官方文档指出,根据不同的日志系统,可以按照如下的日志配置文件名就能够被正确加载,如下:

  1. Log4j :log4j-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml
  2. Log4j2 :log4j2-spring.xml, log4j2.xml
  3. Logback :logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
  4. JDK (Java Util Logging) :logging.properties

Spring Boot 官方推荐优先使用带有-spring 的文件名作为你的日志配置。因此只需要在 src/resources文件夹下创建 logback-spring.xml 即可,配置文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <!-- 定义日志存放目录 -->
    <property name="logPath" value="logs"/>
    <!-- 日志输出的格式-->
    <property name="PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t-%L] %-5level %logger{36} %L %M -
%msg%xEx%n"/>
    <contextName>logback</contextName>
    <!--输出到控制台 ConsoleAppender-->
    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <!--展示格式 layout-->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>${PATTERN}</pattern>
        </layout>
        <!--过滤器,只有过滤到指定级别的日志信息才会输出,如果level为ERROR,那么控制台只会输出
        ERROR日志-->
        <!-- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">-->
        <!-- <level>ERROR</level>-->
        <!-- </filter>-->
    </appender>
    <!--正常的日志文件,输出到文件中-->
    <appender name="fileDEBUGLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--如果只是想要 Info 级别的日志,只是过滤 info 还是会输出 Error 日志,因为 Error 的级别高,
        所以我们使用下面的策略,可以避免输出 Error 的日志-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--过滤 Error-->
            <level>Error</level>
            <!--匹配到就禁止-->
            <onMatch>DENY</onMatch>
            <!--没有匹配到就允许-->
            <onMismatch>ACCEPT</onMismatch>
        </filter>
        <!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则
        如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天
        的日志改名为今天的日期。即,<File> 的日志都是当天的。
        -->
        <File>${logPath}/log_demo.log</File>
        <!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个
            磁盘空间-->
            <FileNamePattern>${logPath}/log_demo_%d{yyyy-MM-dd}.log</FileNamePattern>
            <!--只保留最近90天的日志-->
            <maxHistory>90</maxHistory>
            <!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志-->
            <!--<totalSizeCap>1GB</totalSizeCap>-->
        </rollingPolicy>
        <!--日志输出编码格式化-->
        <encoder>
            <charset>UTF-8</charset>
            <pattern>${PATTERN}</pattern>
        </encoder>
    </appender>
    <!--输出ERROR日志到指定的文件中-->
    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--如果只是想要 Error 级别的日志,那么需要过滤一下,默认是 info 级别的,ThresholdFilter-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>Error</level>
        </filter>
        <!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则
        如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天
        的日志改名为今天的日期。即,<File> 的日志都是当天的。
        -->
        <File>${logPath}/error.log</File>
        <!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个
            磁盘空间-->
            <FileNamePattern>${logPath}/error_%d{yyyy-MM-dd}.log</FileNamePattern>
            <!--只保留最近90天的日志-->
            <maxHistory>90</maxHistory>
            <!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志-->
            <!--<totalSizeCap>1GB</totalSizeCap>-->
        </rollingPolicy>
        <!--日志输出编码格式化-->
        <encoder>
            <charset>UTF-8</charset>
            <pattern>${PATTERN}</pattern>
        </encoder>
    </appender>
    <!--指定最基础的日志输出级别-->
    <root level="DEBUG">
        <!--appender将会添加到这个loger-->
        <appender-ref ref="consoleLog"/>
        <appender-ref ref="fileDEBUGLog"/>
        <appender-ref ref="fileErrorLog"/>
    </root>
    <!-- 定义指定package的日志级别-->
    <logger name="org.springframework" level="DEBUG"></logger>
    <logger name="org.mybatis" level="DEBUG"></logger>
    <logger name="java.sql.Connection" level="DEBUG"></logger>
    <logger name="java.sql.Statement" level="DEBUG"></logger>
    <logger name="java.sql.PreparedStatement" level="DEBUG"></logger>
    <logger name="io.lettuce.*" level="INFO"></logger>
    <logger name="io.netty.*" level="ERROR"></logger>
    <logger name="com.rabbitmq.*" level="DEBUG"></logger>
    <logger name="org.springframework.amqp.*" level="DEBUG"></logger>
    <logger name="org.springframework.scheduling.*" level="DEBUG"></logger>
    <!--定义com.xxx..xx..xx包下的日志信息不上传,直接输出到fileDEBUGLog和fileErrorLog这个两个appender
    中,日志级别为DEBUG-->
    <logger name="com.xxx.xxx.xx" additivity="false" level="DEBUG">
        <appender-ref ref="fileDEBUGLog"/>
        <appender-ref ref="fileErrorLog"/>
    </logger>
</configuration>

你也可以自定义配置文件的名称,在 Spring Boot 配置文件中添加如下配置:

logging.config=classpath:logging-config.xml

配置文件解释:

  1. configuration 节点
  • scan: 当此属性设置为 true 时,配置文件如果发生改变,将会被重新加载,默认值为 true。
  • scanPeriod :设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当 scan 为 true 时,此属性生效。默认的时间间隔为 1 分钟。
  • debug :当此属性设置为 true 时,将打印出 logback 内部日志信息,实时查看 logback 运行状态。默认值为 false。
  1. root 节点
    这是一个必须节点,用来指定基础的日志级别,只有一个 level 属性,默认值是 DEBUG 。
    该节点可以包含零个或者多个元素,子节点是 appender-ref ,标记这个 appender 将会添加到这个 logger
    中。
  2. contextName 节点
    标识一个上下文名称,默认为 default,一般用不到。
  3. property 节点
    标记一个上下文变量,属性有 name 和 value,定义变量之后可以使用 ${} 来获取。
  4. appender 节点
    用来格式化日志输出节点,有两个属性 name 和 class ,class 用来指定哪种输出策略,常用就是控制台输出策略和文件输出策略。
    通常的日志文件需要定义三个 appender,分别是控制台输出,常规日志文件输出,异常日志文件输出。
    该节点有几个重要的子节点,如下:
  1. filter :日志输出拦截器,没有特殊定制一般使用系统自带的即可,但是如果要将日志分开,比如将 ERROR 级别的日志输出到一个文件中,将除了 ERROR 级别的日志输出到另外一个文件中,此时就要拦截 ERROR 级别的日志了。
  2. encoder : 和 pattern 节点组合用于具体输出的日志格式和编码方式。
  3. file : 节点用来指明日志文件的输出位置,可以是绝对路径也可以是相对路径
  4. rollingPolicy : 日志回滚策略,在这里我们用了 TimeBasedRollingPolicy,基于时间的回滚策略,有以下子节点 fileNamePattern,必要节点,可以用来设置指定时间的日志归档。
  5. maxHistory : 可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件,,例如设置为 30 的话,则 30 天之后,旧的日志就会被删除
  6. totalSizeCap : 可选节点,用来指定日志文件的上限大小,例如设置为 3GB 的话,那么到了这个值,就会删除旧的日志
  1. logger 节点
    可选节点,用来具体指明包的日志输出级别,它将会覆盖 root 的输出级别。
    该节点有几个重要的属性如下:
  1. name :指定的包名
  2. level :可选,日志的级别
  3. addtivity :可选,默认为 true,将此 logger 的信息向上级传递,将有 root 节点定义日志打印。如果设置为 false,将不会上传,此时需要定义一个 appender-ref 节点才会输出。

以上就是本期的全部内容了,喜欢的小伙伴别忘了点赞关注,我们下期见,拜拜。