SpringBoot中日志的使用log4j2

SpringBoot中日志的使用log4j2

1、log4j2介绍

Apache Log4j2 是对 Log4j 的升级,它比其前身 Log4j 1.x 提供了重大改进,并提供了 Logback 中可用的许多改

进,同时修复了 Logback 架构中的一些问题,主要有:

  • 异常处理,在logback中,Appender中的异常不会被应用感知到,但是在log4j2中,提供了一些异常处理机

    制。

  • 性能提升,log4j2 相较于log4j 和 logback 都具有明显的性能提升,有18倍性能提升,后面会有官方测试的数

    据。

  • 自动重载配置,参考了logback的设计,当然会提供自动刷新参数配置,最实用的就是我们在生产上可以动态

    的修改日志的级别而不需要重启应用。

  • 无垃圾机制,log4j2 在大部分情况下,都可以使用其设计的一套无垃圾机制【对象重用、内存缓冲】,避免频

    繁的日志收集导致的 jvm gc。

log4j、logback、log4j2都是一种日志具体实现框架,所以既可以单独使用也可以结合slf4j一起搭配使用。

官网:https://logging.apache.org/log4j/2.x

2、项目使用

2.1 pom依赖

springboot 默认使用的日志框架为 logback,要想使用 log4j2,需要从 spring-boot-starter-web 中排除对

spring-boot-starter-logging 依赖。

xml 复制代码
<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依赖:

xml 复制代码
<!--log4j2 依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

spring-boot-starter-log4j2 的依赖关系:

上面的 log4j2 已经适配了 slf4j 日志门面,内部依赖了slf4j、log4j。

SpringBoot 使用 log4j2 作为日志门面,但是最终也是通过 slf4j 调用 logback。

完整的依赖:

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.6</version>
        <relativePath/>
    </parent>

    <groupId>com.log</groupId>
    <artifactId>spring-boot-log4j2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot-log4j2</name>
    <description>spring-boot-log4j2</description>

    <properties>
        <java.version>1.8</java.version>
    </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>

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

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

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.2 log4j2配置

创建log4j2.xml文件,放在工程resources目录里。这样就可以不加任何配置。如果你需要指定配置

文件需要在Spring boot 配置文件application.yml中指定 logging.config 属性。

下面是一份比较详细的 log4j2.xml 配置文件 :

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高优先级为: ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF -->
<!-- configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出 -->
<!--monitorInterval: 监视配置文件变化间隔时间,单位秒,Log4j2能够自动检测配置文件是否修改,同时更新配置 -->
<configuration monitorInterval="5">
    <!-- 变量配置 -->
    <!-- 定义属性,在下方方便维护引用 -->
    <Properties>
        <!--当天文件保存目录,建议不要配置相对路径-->
        <property name="LOG_DIR">./logs</property>
        <!--历史文件保存目录-->
        <property name="HISTORY_LOG_DIR">./logs/history</property>
        <!--项目名称-->
        <property name="FILE_NAME" value="log4j2"/>
        <!--如果当天日志文件大于100MB,则存档-->
        <property name="SPLIT_SIZE">100MB</property>
        <!--文件保存个数,这里的30说明可保留30个,即30天-->
        <property name="FILE_COUNT">30</property>
        <!--interval属性用来指定多久滚动一次,默认是1 hour-->
        <property name="INTERVAL">30</property>
        <!--输出日志的格式:%d表示日期时间,%thread表示线程名,%-5level级别从左显示5个字符宽度,%logger{50}表示logger名字最长50个字符,否则按照句点分割,%line表示行号,%msg日志消息,%n换行符-->
        <property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} => [%thread] => %-5level %logger{50}:(%line) - %msg%n
        </property>
    </Properties>

    <!--先定义所有的appender附加器-->
    <appenders>
        <!--1、控制台输出配置-->
        <console name="Console" target="SYSTEM_OUT">
            <!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <!--<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>-->
            <filters>
                <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            </filters>
            <!--输出日志的格式-->
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </console>

        <!-- 2、输出日志信息到文件存储 -->
        <!--文件存储文件设置-->
        <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,适合临时测试用-->
        <File name="FileLog" fileName="${LOG_DIR}/test.log" append="false">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </File>

        <!-- 3、输出日志信息滚动到文件存储 -->
        <!--fileName:文件存储路径及名称,可以是绝对路径或者相对路径,存储的永远是最新的日志信息-->
        <!--filePattern:当fileName指定的文件大小超过限制,就会根据此文件名规则新建存档目录与文件,同时将fileName文件中的
         内容剪切到存档文件中,如下配置,会新建存档路径 logs/history/log4j2-DEBUG-2021-03-26-1.log.gz -->
        <!-- 这个会打印出所有的debug级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <!--以下只保存debug信息-->
        <RollingFile name="RollingFileDebug" fileName="${LOG_DIR}/debug.log"
                     filePattern="${HISTORY_LOG_DIR}/${FILE_NAME}-DEBUG-%d{yyyy-MM-dd}-%i.log.gz">
            <!--控制台只输出level级别的信息-->
            <!--
            <LevelFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
            -->
            <!--
            onMatch和onMismatch都有三个属性值,分别为Accept、DENY和NEUTRAL
            onMatch="ACCEPT" 表示匹配该级别及以上
            onMatch="DENY" 表示不匹配该级别及以上
            onMatch="NEUTRAL" 表示该级别及以上的,由下一个filter处理,如果当前是最后一个,则表示匹配该级别及以上
            onMismatch="ACCEPT" 表示匹配该级别以下
            onMismatch="NEUTRAL" 表示该级别及以下的,由下一个filter处理,如果当前是最后一个,则不匹配该级别以下的
            onMismatch="DENY" 表示不匹配该级别以下的
            -->
            <filters>
                <ThresholdFilter level="INFO" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
            </filters>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="${INTERVAL}"/>
                <!--日志文件大小超过多少时进行存档-->
                <SizeBasedTriggeringPolicy size="${SPLIT_SIZE}"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="${FILE_COUNT}"/>
        </RollingFile>

        <!--以下只保存info信息-->
        <RollingFile name="RollingFileInfo" fileName="${LOG_DIR}/info.log"
                     filePattern="${HISTORY_LOG_DIR}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}-%i.log.gz">
            <!--控制台只输出level级别的信息-->
            <!--
            <LevelFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            -->
            <filters>
                <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            </filters>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="${INTERVAL}"/>
                <!--日志文件大小超过多少时进行存档-->
                <SizeBasedTriggeringPolicy size="${SPLIT_SIZE}"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="${FILE_COUNT}"/>
        </RollingFile>

        <!--以下只保存warn信息-->
        <RollingFile name="RollingFileWarn" fileName="${LOG_DIR}/warn.log"
                     filePattern="${HISTORY_LOG_DIR}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}-%i.log.gz">
            <!--控制台只输出level级别的信息-->
            <!--
            <LevelFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
            -->
            <filters>
                <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
            </filters>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="${INTERVAL}"/>
                <!--日志文件大小超过多少时进行存档-->
                <SizeBasedTriggeringPolicy size="${SPLIT_SIZE}"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="${FILE_COUNT}"/>
        </RollingFile>

        <!--以下只保存error信息-->
        <RollingFile name="RollingFileError" fileName="${LOG_DIR}/error.log"
                     filePattern="${HISTORY_LOG_DIR}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}-%i.log.gz">
            <!--控制台只输出level级别的信息-->
            <!--
            <LevelFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            -->
            <filters>
                <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            </filters>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="${INTERVAL}"/>
                <!--日志文件大小超过多少时进行存档-->
                <SizeBasedTriggeringPolicy size="${SPLIT_SIZE}"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="${FILE_COUNT}"/>
        </RollingFile>

        <!--以下保存api请求信息-->
        <RollingFile name="ApiInfo" fileName="${LOG_DIR}/api.log"
                     filePattern="${HISTORY_LOG_DIR}/${FILE_NAME}-API-%d{yyyy-MM-dd}-%i.log.gz">
            <filters>
                <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            </filters>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="${INTERVAL}"/>
                <!--日志文件大小超过多少时进行存档-->
                <SizeBasedTriggeringPolicy size="${SPLIT_SIZE}"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="${FILE_COUNT}"/>
        </RollingFile>

        <!-- 整合elk -->
        <Socket name="Logstash" host="127.0.0.1" port="4560" protocol="TCP">
            <PatternLayout pattern="${logPattern}"/>
        </Socket>

    </appenders>

    <!--
    1、root与logger是父子关系,没有特别定义logger的都默认为root。
    2、任何一个类只会和一个logger对应,要么是定义的logger,要么是root,判断的关键在于找到这个logger,然后判断这个logger的appender和level
    3、appender-ref用于引用上面定义好的appender日志追加器,只有引用了,上面的appender才能生效
    -->
    <!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等 -->
    <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
    <loggers>
        <!--过滤掉spring和mybatis的一些无用的DEBUG信息;也可以单独指定自己的某个包-->
        <!--以下包中ERROR级别以上日志在root中将被记录-->
        <!--
        <logger name="org.springframework" level="ERROR"></logger>
        <logger name="org.mybatis" level="ERROR"></logger>
        <logger name="org.hibernate" level="ERROR"></logger>
        <logger name="org.apache" level="ERROR"></logger>
        <logger name="com.baomidou" level="ERROR"></logger>
        <logger name="com.zaxxer" level="ERROR"></logger>
        <logger name="springfox.documentation" level="ERROR"></logger>
        -->
        <!-- 控制该包下的日志等级 -->
        <!--com.log.controller包中的DEBUG以上信息在以下的appender中输出,additivity所有日志还要向控制台和allLog中输出-->
        <!--
        <logger name="com.log.controller" level="DEBUG" additivity="true">
            <appender-ref ref="RollingFileDebug"/>
            <appender-ref ref="RollingFileInfo"/>
            <appender-ref ref="RollingFileWarn"/>
            <appender-ref ref="RollingFileError"/>
            <appender-ref ref="Console"/>
            <appender-ref ref="FileLog"/>
        </logger>
        -->
        <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
        <logger name="org.mybatis" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </logger>
        <!--监控系统信息-->
        <!--若是additivity设为false,则子Logger只会在自己的appender里输出,而不会在父Logger的appender里输出 -->
        <Logger name="org.springframework" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>

        <!-- 控制整个项目的日志等级 -->
        <root level="info">
            <appender-ref ref="Console"/>
            <appender-ref ref="FileLog"/>
            <appender-ref ref="RollingFileDebug"/>
            <appender-ref ref="RollingFileInfo"/>
            <appender-ref ref="RollingFileWarn"/>
            <appender-ref ref="RollingFileError"/>
        </root>

    </loggers>
</configuration>

基本上你拿上面的配置根据你自己的需要更改一下即可生效。

注意 windows 下 ${sys:user.home} 会将日志打印到用户目录下。

2.3 启动类

java 复制代码
package com.log;

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);
    }

}

2.4 测试

java 复制代码
package com.log;

import com.log.controller.LogController;
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 {

    /**
     * 声明日志记录器对象(slf4j包)
     */
    public static final Logger logger = LoggerFactory.getLogger(LogController.class);

    @Test
    void contextLoads() {
        logger.error("error");
        logger.warn("warn");
        logger.info("info");
        logger.debug("debug");
        logger.trace("trace");
    }
}

执行输出:

shell 复制代码
2023-11-19 10:46:45.238 => [main] => ERROR com.log.controller.LogController:(19) - error
2023-11-19 10:46:45.250 => [main] => WARN  com.log.controller.LogController:(20) - warn
2023-11-19 10:46:45.250 => [main] => INFO  com.log.controller.LogController:(21) - info

查看生成的文件:

由于设置了日志等级<root level="info">为info,所以debug不会有输出。

2.5 使用@Slf4j注解输出日志

lombok中的@Slf4j 注解可以很方便的使用 org.slf4j.Logger 对象。

日常开发尽量使用Slf4j门面来处理日志,尽量避免使用具体的日志框架。

引入依赖:

xml 复制代码
<!-- lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

编写controller:

java 复制代码
package com.log.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author tom
 */
@Slf4j
@RestController
@RequestMapping("/logging")
public class LogController {

    @GetMapping("/do")
    public String log() {
        log.error("error......");
        log.warn("warn......");
        log.info("info......");
        log.debug("debug......");
        log.trace("trace......");
        return "log4j2";
    }
}

2.6 测试

启动应用,访问http://localhost:8080/logging/do

3、log4j2配置文件详解

要想使 log4j2 配置生效,需要在 resources 目录下新建 log4j2.xml,springboot 会自动找到配置文件,并加载。

3.1 日志级别

log4j2共分8个日志级别,按从低到高排列为:ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF:

properties 复制代码
ALL: 最低等级日志级别,输出所有日志
TRACE: 追踪日志,如程序启动进程日志
DEBUG: 程序调试信息
INFO: 应用程序提示信息
WARN: 告警信息
ERROR: 程序报错信息
FATAL: 程序出错,导致应用程序退出
OFF: 关闭日志

设置应用程序的日志级别后,将输出该级别及以上的日志。如,设置日志级别为INFO,那么程序会输出INFO、

WARN、ERROR及FATAL日志。

3.2 monitorInterval

监视配置文件变化间隔时间。如设置为30,表示每隔30s,程序会自动检测配置文件是否修改,如果修改,就更新

配置文件。

3.3 properties

定义属性,方便在配置文件中引用。我们在这配置了 LOG_DIR、HISTORY_LOG_DIR、FILE_NAME、SPLIT_SIZE、

FILE_COUNT、INTERVAL 及 LOG_PATTERN 属性。

properties 复制代码
LOG_DIR: 日志输出目录
HISTORY_LOG_DIR: 日志输出历史目录
FILE_NAME: 日志文件的名字
SPLIT_SIZE: 日志存档临界值,如果当天日志大于临界值,则存档,在这配置为100M
FILE_COUNT: 存档文件个数,在这里配置为30,相当于保留最近30天的日志记录
INTERVAL: 用来指定多久滚动一次
LOG_PATTERN: 日志输出格式

3.4 appenders

定义一系列的日志输出,可输出至控制台或者文件中。主要有三种日志输出方式:

  • Console:定义输出至控制台的方式;

  • File:定义输出至文件的方式;

  • RollingFile:定义输出至文件的方式,但会以一定的策略删除旧日志文件,并创建新的日志文件;

    三种方式有共同的子节点。

3.4.1filters

定义日志输出等级。

如果想输出某个等级及其以上的日志,可做如下配置:

xml 复制代码
<filters>
    <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY" />
</filters>

以上配置过滤INFO级别及其以上的日志。

如果想单独输出某个等级的日志,可做如下配置:

xml 复制代码
<filters>
    <ThresholdFilter level="INFO" onMatch="DENY" onMismatch="NEUTRAL" />
    <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY" />
</filters>

以上配置只过滤DEBUG日志,INFO及其以上等级的日志将被拒绝。

3.4.2 Console日志输出

定义日志输出至控制台,主要属性有name、target、filters和PatternLayout。

properties 复制代码
name: 自己定义
target: 一般配置为SYSTEM_OUT,即将日志通过System.out输出
filters: 定义日志输出等级,这里配置等级为INFO,即INFO及以上等级的日志输出到控制台
PatternLayout: 定义日志输出格式
3.4.3 File日志输出

定义日志输出至文件,示例配置如下:

xml 复制代码
<File name="fileLog" fileName="${logDir}/file.log" append="true">
    <filters>
        <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
    </filters>
    <PatternLayout pattern="${logPattern}" />
</File>

主要属性和子节点有name、fileName、append、filters和PatternLayout。

  • fileName:定义输出文件名;
  • append:当为true时,新增日志将被追加至文件末尾;如果为false,那么新日志将覆盖旧日志;
3.4.4 RollingFile日志输出

也是定义日志输出至文件,不同的是RollingFile可以定义日志文件存档策略。比如按照时间存档,每天备份一次,

最大存档30天等等。

xml 复制代码
<!--以下只保存info信息-->
<RollingFile name="RollingFileInfo" fileName="${LOG_DIR}/info.log"
             filePattern="${HISTORY_LOG_DIR}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}-%i.log.gz">
    <!--控制台只输出level级别的信息-->
    <!--
    <LevelFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
    -->
    <filters>
        <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
        <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
    </filters>
    <PatternLayout pattern="${LOG_PATTERN}"/>
    <Policies>
        <!--interval属性用来指定多久滚动一次,默认是1 hour-->
        <TimeBasedTriggeringPolicy interval="${INTERVAL}"/>
        <!--日志文件大小超过多少时进行存档-->
        <SizeBasedTriggeringPolicy size="${SPLIT_SIZE}"/>
    </Policies>
    <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
    <DefaultRolloverStrategy max="${FILE_COUNT}"/>
</RollingFile>

主要属性和子节点有name、fileName、filePattern、filters、PatternLayout、Policies、

TimeBasedTriggeringPolicy、SizeBasedTriggeringPolicy 和 DefaultRolloverStrategy。

properties 复制代码
fileName: 定义现在日志输出文件名
filePattern: 定义历史日志文件名格式
filters: 以上只输出debug日志
Policies: 定义日志输出策略
TimeBasedTriggeringPolicy: 指定多长时间触发日志备份策略这里默认为一天,还可以设置interval和modulate属性
SizeBasedTriggeringPolicy: 指定日志文件多大时触发日志备份策略这里设置为100MB,即如果当天日志一次超过100MB备份为DEBUG-2023-05-02-1.log;如果再次超过100MB则备份为DEBUG-2023-05-02-2.log
DefaultRolloverStrategy: 设置日志文档存档个数max指定能保存的文件个数,超过后之前的文件将被删除
3.4.5 Socket日志输出

定义日志输出至数据库或者其它日志管理系统,如elk等。

xml 复制代码
<!-- 整合elk -->
<Socket name="Logstash" host="127.0.0.1" port="4560" protocol="TCP">
    <PatternLayout pattern="${logPattern}"/>
</Socket>

以上定义日志输出至127.0.0.1:4560服务器,也就是我本地创建的elk日志管理系统。

3.5 loggers

所有在 appenders 里定义的 appender 都需要在 logger 下引用,否则 appender 的配置就不会生效。

如果要过滤掉一些 debug 信息,可以在 logger 中屏蔽掉,如下屏蔽掉 org.mybatis 中 info 级别以下的日志:

xml 复制代码
<logger name="org.mybatis" level="info" additivity="false">
    <AppenderRef ref="Console"/>
</logger>

设置项目中的日志输出至指定的文件,并且在控制台中输出,配置如下:

xml 复制代码
<logger name="com.log.controller" level="DEBUG" additivity="true">
    <appender-ref ref="RollingFileDebug"/>
    <appender-ref ref="RollingFileInfo"/>
    <appender-ref ref="RollingFileWarn"/>
    <appender-ref ref="RollingFileError"/>
    <appender-ref ref="Console"/>
    <appender-ref ref="FileLog"/>
</logger>

root 节点为兜底操作,所有在 appenders 中配置的,但没有在其它 logger 中输出的,都会在 root 的 logger 中

输出。

xml 复制代码
<root level="info">
    <appender-ref ref="Console"/>
    <appender-ref ref="FileLog"/>
    <appender-ref ref="RollingFileDebug"/>
    <appender-ref ref="RollingFileInfo"/>
    <appender-ref ref="RollingFileWarn"/>
    <appender-ref ref="RollingFileError"/>
</root>

4、log4j与log4j2的不同配置

log4j与log4j2的配置文件中的属性有所不同,具体请参考:

https://logging.apache.org/log4j/2.x/manual/migration.html

5、log4j2的其它功能

5.1 占位符

使用{}占位符格式化参数。

java 复制代码
package com.log;

import com.log.controller.LogController;
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 SpringBootLogApplicationTests1 {

    /**
     * 声明日志记录器对象(slf4j包)
     */
    public static final Logger logger = LoggerFactory.getLogger(LogController.class);

    @Test
    void contextLoads() {
        String param="springboot 课程";
        logger.info("请求参数:{},结果:{}",param,"hello slf4j");
    }

}

输出:

shell 复制代码
2023-11-19 14:36:44.293 => [main] => INFO  com.log.controller.LogController:(21) - 请求参数:springboot 课程,结果:hello slf4j

5.2 String.format的形式格式化参数

log4j2 中除了支持{}的参数占位符,还支持String.format的形式。

注意,如果想使用String.format的形式,需要使用LogManager.getFormatterLogger

java 复制代码
package com.log;

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

@SpringBootTest
public class SpringBootLogApplicationTests2 {

    // 使用的是org.apache.logging.log4j包
    public static Logger formatterLogger = LogManager.getFormatterLogger(SpringBootLogApplicationTests2.class);

    @Test
    void contextLoads() {
        formatterLogger.info("Integer.MAX_VALUE = %d", Integer.MAX_VALUE);
    }

}

输出:

shell 复制代码
2023-11-19 14:40:55.730 => [main] => INFO  MyLogger:(15) - Integer.MAX_VALUE = 2147483647

5.3 使用logger.printf格式化参数

log4j2 的 Logger 接口中,还有一个 printf 方法,无需创建LogManager.getFormatterLogger,就可以使用

String.format的形式。

java 复制代码
package com.log;

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

@SpringBootTest
public class SpringBootLogApplicationTests3 {

    // 使用的是org.apache.logging.log4j包
    public static Logger logger = LogManager.getLogger(SpringBootLogApplicationTests3.class);

    @Test
    void contextLoads() {
        logger.printf(Level.INFO, "Integer.MAX_VALUE = %d", Integer.MAX_VALUE);
    }
}

输出:

shell 复制代码
2023-11-19 14:46:17.133 => [main] => INFO  MyLogger:(18) - Integer.MAX_VALUE = 2147483647

5.4 惰性打日志(lazy logging)

java 复制代码
package com.log;

import com.log.controller.LogController;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class SpringBootLogApplicationTests4 {

    /**
     * 声明日志记录器对象(slf4j包)
     */
    public static final Logger logger = LoggerFactory.getLogger(LogController.class);

    @Test
    void contextLoads() {
        if (logger.isInfoEnabled()) {
            String param = "springboot 课程";
            logger.info("请求参数:{},结果:{}", param, "hello slf4j");
        }
    }
}

输出:

shell 复制代码
2023-11-19 14:49:30.652 => [main] => INFO  com.log.controller.LogController:(21) - 请求参数:springboot 课程,结果:hello slf4j
相关推荐
二哈喇子!8 小时前
SpringBoot项目右上角选择ProjectNameApplication的配置
java·spring boot
二哈喇子!8 小时前
基于Spring Boot框架的车库停车管理系统的设计与实现
java·spring boot·后端·计算机毕业设计
二哈喇子!8 小时前
基于SpringBoot框架的水之森海底世界游玩系统
spring boot·旅游
二哈喇子!8 小时前
Java框架精品项目【用于个人学习】
java·spring boot·学习
二哈喇子!9 小时前
基于SpringBoot框架的网上购书系统的设计与实现
java·大数据·spring boot
二哈喇子!10 小时前
基于JavaSE的淘宝卖鞋后端管理系统的设计与实现
java·spring boot·spring
Coder_Boy_10 小时前
基于SpringAI的在线考试系统-智能考试系统-学习分析模块
java·开发语言·数据库·spring boot·ddd·tdd
高山上有一只小老虎11 小时前
mybatisplus实现分页查询
java·spring boot·mybatis
毕设源码-朱学姐11 小时前
【开题答辩全过程】以 基于SpringBoot的律师事务所管理系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
毕设源码-朱学姐12 小时前
【开题答辩全过程】以 基于springboot的日用药品仓库管理系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端