Spring Boot 整合Log4j2框架教程

211 阅读3分钟

介绍

本篇文章介绍Spring Boot整合Log4j2日志框架实现日志功能。

1. 初次日志测试

创建一个项目

使用IDEA创建一个名为Spring_Boot_log4j2_Learning的项目。

引入依赖

在pom.xml中引入依赖:

......
    <properties>
        <spring.boot.version>2.3.0.RELEASE</spring.boot.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!--Spring Boot的版本-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <!-- 排除logback依赖 -->
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- 引入log4j2依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>

        <!-- 简化开发 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
......
  • spring-boot-dependencies:用于统一Spring Boot的版本管理
  • spring-boot-starter-web:用于引入Spring Boot的Web依赖,快速开始Web项目的开发;另外排除spring-boot-starter-logging,是因为spring-boot-starter-logging会默认引入logback作为日志框架,会和log4j2依赖冲突
  • spring-boot-starter-log4j2:引入Spring Boot log4j2整合依赖
  • lombok:仅用于简化开发过程

创建日志打印类

创建一个Controller,用于测试日志。

package com.ldh.logging.controller;

@Slf4j
@RestController
public class LoggingController {

    /**
     * 用于打印日志级别
     * @return
     */
    @GetMapping("level")
    public Boolean level() {
        log.trace("trace level");
        log.debug("debug level");
        log.info("info level");
        log.warn("warn level");
        log.error("error level");
        return true;
    }
}

创建启动类,启动项目

创建一个LoggingLearningApp启动类,代码如下:

package com.ldh.logging;
@SpringBootApplication
public class LoggingLearningApp {
    public static void main(String[] args) {
        SpringApplication.run(LoggingLearningApp.class, args);
    }
}

启动项目。

启动日志如下:

......
2023-08-08 19:34:47.559  INFO [main] c.l.l.LoggingLearningApp                 :No active profile set, falling back to default profiles: default
2023-08-08 19:34:48.613  INFO [main] c.l.l.LoggingLearningApp                 :Started LoggingLearningApp in 1.275 seconds (JVM running for 2.006)

说明项目正常启动。

测试日志

打开浏览器,访问地址http://localhost:8080/level,可以看到浏览器返回了true

访问LoggingController.png

我们再看下后台日志:

2023-08-08 19:41:17.203  INFO 508 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/]                        : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-08-08 19:41:17.203  INFO 508 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet                : Initializing Servlet 'dispatcherServlet'
2023-08-08 19:41:17.207  INFO 508 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet                : Completed initialization in 4 ms
2023-08-08 19:41:17.223  INFO 508 --- [nio-8080-exec-1] c.l.l.c.LoggingController                : info level
2023-08-08 19:41:17.223  WARN 508 --- [nio-8080-exec-1] c.l.l.c.LoggingController                : warn level
2023-08-08 19:41:17.223 ERROR 508 --- [nio-8080-exec-1] c.l.l.c.LoggingController                : error level

可以看出来默认的日志级别是info级别。且除了LoggingController的日志还会产生一部分框架日志。

2. 引入配置文件(log4j2.xml)

src/resource下创建log4j2.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!-- 1. monitorInterval:指定log4j自动重新配置的监测间隔时间,单位是s,最小是5s -->
<Configuration monitorInterval="5">
    <Properties>
        <Property name="PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p [%t] %-40.40c{1.} :%m%n"/>
        <property name="logPath">./logs</property>
    </Properties>
    <Appenders>
        <!-- 2. 输出到控制台 -->
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${PATTERN}"/>
        </Console>
    </Appenders>

    <Loggers>
        <!--3. 默认的Root Logger 级别-->
        <Root level="warn">
            <!--这里需要区分下环境(配合maven profile之类的)-->
            <!-- 开发环境使用Console Appender,生产环境使用File Appender -->
            <AppenderRef ref="Console"/>
        </Root>

        <!-- 4. 覆盖父级的日志级别 -->
        <logger name = "com.ldh.logging" level="error">

        </logger>

    </Loggers>
</Configuration>
  • 1处:<Configuration monitorInterval="5">,配置了自动检测配置的时间间隔,如果使用IDEA,记得修改target目录下的log4j2.xml,而不是src/resources目录下
  • 2处:这里仅创建了一个输出到控制台的Appender
  • 3处:指定根Logger的配置。
    • 指定level=warn:默认的日志级别为WARN级别,会过滤掉大量INFO级别的日志
    • AppenderRef:将Console绑定Root Logger,注意Root绑定的Appender是可以被后续的Logger继承的,所以后续的Logger可以不用指定Appender
  • 4处:指定了com.ldh.logging Logger的日志级别为info,可以覆盖到com.ldh.logging.LoggingLearningAppcom.ldh.logging.controller.LoggingController的Logger。

查看启动项目日志

重启项目,日志如下:

2023-08-08 19:49:48.608  INFO [main] c.l.l.LoggingLearningApp                 :Starting LoggingLearningApp on DESKTOP-RMSPHN7 with PID 13208 (D:\Project\personal\Spring_Boot_log4j2_Learning\target\classes started by bangsun in D:\Project\personal\Spring_Boot_log4j2_Learning)
2023-08-08 19:49:48.650  INFO [main] c.l.l.LoggingLearningApp                 :No active profile set, falling back to default profiles: default
2023-08-08 19:49:49.818  INFO [main] c.l.l.LoggingLearningApp                 :Started LoggingLearningApp in 1.545 seconds (JVM running for 2.579)

可以看到仅LoggingLearningApp的INFO级别的日志展示在控制台,说明<logger name = "com.ldh.logging" level="info">配置生效了。

访问LoggingController

  1. 修改log4j2.xml<logger name = "com.ldh.logging" level="error">,重启项目。

  2. 再次访问地址http://localhost:8080/level

可以看到如下日志:

2023-08-08 19:54:34.966 ERROR [http-nio-8080-exec-2] c.l.l.c.LoggingController                :error level

仅有error级别的日志会展示在控制台,说明配置已经生效

3. 引入applicantion.yml,增加Spring Boot日志配置

步骤2是基于log4j2框架本身支持的日志方式,接下来介绍Spring Boot支持的日志配置方式。

首先,在src/resources目录下,创建一个application.yml文件。

指定自定义的配置文件

Spring Boot默认支持的log4j2的配置文件有:log4j2.xmllog4j2-spring.xml。如果需要指定自定义配置文件,可以添加logging.config配置:

logging:
	config: classpath:log4j2-custom.xml

log4j2-custom.xml内容如下:

log4j2-custom.xmlsrc/resources目录下

<?xml version="1.0" encoding="UTF-8"?>
<!-- monitorInterval:指定log4j自动重新配置的监测间隔时间,单位是s,最小是5s -->
<Configuration monitorInterval="5">
    <Properties>
        <Property name="PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p [%t] %-40.40c{1.} :%m%n"/>
        <property name="logPath">./logs</property>
        <property name ="appName">myLog</property>
    </Properties>
    <Appenders>
        <!-- 输出到控制台 -->
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${PATTERN}"/>
        </Console>

        <!-- 输出到日志文件,滚动分割日志文件,自动打包 -->
        <!-- 相对路径会相对于当前项目所在根路径 -->
        <RollingFile name="File" fileName="${logPath}/${appName}.log"
                     filePattern="${logPath}/archives/${appName}-%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout pattern="${PATTERN}"/>
            <Policies>
                <!--默认一天一个文件-->
                <TimeBasedTriggeringPolicy/>
                <!--一天内大于size就单独分隔-->
                <SizeBasedTriggeringPolicy size="1 GB"/>
            </Policies>
        </RollingFile>
    </Appenders>

    <Loggers>
        <!--默认的Root Logger 级别-->
        <Root level="warn">
            <!--这里需要区分下环境(配合maven profile之类的)-->
            <!-- 开发环境使用Console Appender,生产环境使用File Appender -->
            <AppenderRef ref="Console"/>
        </Root>

        <!-- 覆盖父级的日志级别 -->
        <logger name = "com.ldh.logging.controller.LoggingController" level="debug">
            <AppenderRef ref="File"/>
        </logger>

    </Loggers>
</Configuration>
  • 主要关注<logger name = "com.ldh.logging.controller.LoggingController" level="debug">配置
    • 添加了一个File Appender,不仅会将日志输出到控制台,还会输出到日志文件中。另外,File Appender的fileName是一个相对路径,会相对于当前项目的根目录创建日志文件。也可以指定绝对路径。
    • level="debug":指定日志级别为debug。大于等于该级别的日志都会被输出到当前Logger绑定的Appender,即Console和File。

测试

重启项目,再次访问http://localhost:8080/level

日志如下:

2023-08-08 20:05:39.577 DEBUG [http-nio-8080-exec-1] c.l.l.c.LoggingController                :debug level
2023-08-08 20:05:39.583  INFO [http-nio-8080-exec-1] c.l.l.c.LoggingController                :info level
2023-08-08 20:05:39.583  WARN [http-nio-8080-exec-1] c.l.l.c.LoggingController                :warn level
2023-08-08 20:05:39.583 ERROR [http-nio-8080-exec-1] c.l.l.c.LoggingController                :error level

符合预期输出了DEBUG及以上级别的日志。

通过Spring Boot指定日志级别

Spring Boot提供了logging.level配置,用于指定logger的日志级别。

注意:logging.level中指定的Logger的日志级会覆盖log4j2.xml指定的配置。

添加如下配置:

logging:
  # 指定logger的日志级别,会覆盖log4j2.xml中的配置
  level:
    root: warn
    com.ldh.logging.controller.LoggingController: trace

重启项目,再次访问http://localhost:8080/level

日志如下:

2023-08-08 20:13:59.031 TRACE [http-nio-8080-exec-1] c.l.l.c.LoggingController                :trace level
2023-08-08 20:13:59.035 DEBUG [http-nio-8080-exec-1] c.l.l.c.LoggingController                :debug level
2023-08-08 20:13:59.035  INFO [http-nio-8080-exec-1] c.l.l.c.LoggingController                :info level
2023-08-08 20:13:59.035  WARN [http-nio-8080-exec-1] c.l.l.c.LoggingController                :warn level
2023-08-08 20:13:59.035 ERROR [http-nio-8080-exec-1] c.l.l.c.LoggingController                :error level

符合我们的预期,输出了TRACE及以上日志级别的信息。

参考