Spring Boot 切换日志实现

来自姬鸿昌的知识库
跳到导航 跳到搜索

https://www.bilibili.com/video/BV1iJ411H74S?p=38

因为 Log4j 2 异步日志效率比 Logback 高很多,所以要切换成 Log4j 2 作为日志实现:

示例 切换日志实现

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.2.2.RELEASE</version>
    </parent>

    <groupId>io.github.jihch</groupId>
    <artifactId>spring-boot-log</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

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

        <!-- 添加 Log4j 2 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

</project>

application.properties

# 指定自定义 logger 对象日志级别
logging.level.io.github.jihch=trace

# 指定控制台输出消息格式
logging.pattern.console=[%-5level] %d{yyyy-MM-dd HH:mm:ss} %c [%thread]===== %msg%n

# 指定存放日志文件的具体路径
# logging.file=/logs/springboot.log #已经被废弃的属性

# 指定日志文件存放的目录,默认的文件名 spring.log
logging.file.path=/logs/springboot/

# 指定日志文件消息格式
logging.pattern.file=[%-5level] %d{yyyy-MM-dd HH:mm:ss} %c [%thread]===== %msg%n

# 指定项目使用的具体环境
spring.profiles.active=pro

logback-spring.xml

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!--
        配置集中管理属性
        可以直接该属性的 value 值
        格式:${name}
    -->
    <property name="pattern" value="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L [%thread] -------- %m%n"></property>

    <!-- 控制台日志输出的 appender -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 控制输出流对象 默认 System.out 改为 System.err -->
        <target>System.err</target>
        <!-- 日志消息格式配置 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <springProfile name="dev">
                <pattern>${pattern}</pattern>
            </springProfile>
            <springProfile name="pro">
                <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L [%thread] xxxxxxxx %m%n</pattern>
            </springProfile>
        </encoder>
    </appender>

    <!-- 自定义 logger 对象
        additivity="false" 自定义 logger 对象是否继承 rootLogger
    -->
    <logger name="io.github.jihch" level="info" additivity="false">
        <appender-ref ref="console"/>
    </logger>
</configuration>

SpringBootLogApplication.java

package io.github.jihch;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootLogApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootLogApplication.class, args);
    }

}

SpringBootLogApplicationTests.java

package io.github.jihch;

import org.apache.logging.log4j.LogManager;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class SpringBootLogApplicationTests {

    // 声明日志记录器对象
    public static final Logger LOGGER = LoggerFactory.getLogger(SpringBootLogApplicationTests.class);

    @Test
    public void contextLoads() {
        // 打印日志信息
        LOGGER.error("error");
        LOGGER.warn("warn");
        LOGGER.info("info"); // 默认日志级别
        LOGGER.debug("debug");
        LOGGER.trace("trace");

        // 使用 Log4j 2 进行日志记录也还是会通过桥接器切换为 SLF4J 日志门面和 Logback 日志实现
        org.apache.logging.log4j.Logger logger = LogManager.getLogger(SpringBootLogApplicationTests.class);
        logger.info("log4j 2 info");

    }

}
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.2.RELEASE)

[INFO ] 2023-02-28 22:29:33 io.github.jihch.SpringBootLogApplicationTests [main]===== Starting SpringBootLogApplicationTests on SK-20210414CLPG with PID 20100 (started by Administrator in E:\record\2023\2\27\spring-boot-log)
[DEBUG] 2023-02-28 22:29:33 io.github.jihch.SpringBootLogApplicationTests [main]===== Running with Spring Boot v2.2.2.RELEASE, Spring v5.2.2.RELEASE
[INFO ] 2023-02-28 22:29:33 io.github.jihch.SpringBootLogApplicationTests [main]===== The following profiles are active: pro
[INFO ] 2023-02-28 22:29:34 org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor [main]===== Initializing ExecutorService 'applicationTaskExecutor'
[INFO ] 2023-02-28 22:29:34 io.github.jihch.SpringBootLogApplicationTests [main]===== Started SpringBootLogApplicationTests in 1.169 seconds (JVM running for 2.791)
[ERROR] 2023-02-28 22:29:34 io.github.jihch.SpringBootLogApplicationTests [main]===== error
[WARN ] 2023-02-28 22:29:34 io.github.jihch.SpringBootLogApplicationTests [main]===== warn
[INFO ] 2023-02-28 22:29:34 io.github.jihch.SpringBootLogApplicationTests [main]===== info
[DEBUG] 2023-02-28 22:29:34 io.github.jihch.SpringBootLogApplicationTests [main]===== debug
[TRACE] 2023-02-28 22:29:34 io.github.jihch.SpringBootLogApplicationTests [main]===== trace
[INFO ] 2023-02-28 22:29:34 io.github.jihch.SpringBootLogApplicationTests [main]===== log4j 2 info
[INFO ] 2023-02-28 22:29:34 org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor [SpringContextShutdownHook]===== Shutting down ExecutorService 'applicationTaskExecutor'

Process finished with exit code 0



示例 使用 Log4j 2 的配置文件

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>

<!--
    status="warn" 日志框架本身的日志输出级别
    monitorInterval="5" 自动加载配置文件的间隔时间,不低于 5 秒
-->
<Configuration status="debug" monitorInterval="5">

    <!-- 日志处理 -->
    <Appenders>

        <!--
            控制台输出 appender
            target="SYSTEM_OUT" 或 target="SYSTEM_ERR"
        -->
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] [%-5level] %c{36}:%L --- %m%n" />
        </Console>

    </Appenders>

    <!-- logger 定义 -->
    <Loggers>

        <!-- 使用 rootLogger 配置日志级别 level="trace" -->
        <Root level="trace">
            <!-- 指定 logger 使用的 appender -->
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>

</Configuration>

其他不变,trace 的日志太多,不粘输出了