java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Springboot处理log4j2日志文件

在Springboot中处理log4j2日志文件过程

作者:记录Java学习的三木

日志切割、分离和清理是日志管理的重要环节,本文介绍了在SpringBoot项目中配置日志切割、分离和清理的步骤,并详细解释了实现原理

简单介绍

日志切割

日志切割指的是将一个持续增长的、庞大的日志文件,按照某种规则分割成多个较小的、易于管理的文件。(在本配置中我们将日志按天切割,同时限制了单个日志文件不能超过64MB)

效果如图:

切割策略有两个,每天零点会将昨天的日志文件加日期保存然后生成一个新的日志文件,当天如果单个日志文件超出规定(例如本配置的64MB),会自动将此日志文件加日期保存并生成一个新的日志文件

日志分离

日志分离指的是将不同种类、不同级别或来自不同模块的日志信息,输出到不同的、独立的日志文件中。

效果如图:

日志被根据不同级别分层保存

日志清理

日志清理指的是自动删除旧的、不再需要的日志归档文件,以防止日志文件无限制地占用磁盘空间,最终导致磁盘写满。

这是生产环境中至关重要的一环。(比如本配置的清理就是会删除超过N(比如Info30天,Warn60天,Error90天)天的日志归档文件以及每个类型的日志文件总大小不超过某个GB的大小(比如Info6GB,Warn3GB,Error2GB))

如何在SpringBoot项目中配置使用

第一步,导入如下依赖到pom.xml文件当中

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <exclusions>
                <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-log4j2</artifactId>
        </dependency>

第二步,在yaml文件中添加如下配置

logging:
  config: classpath:log4j2.xml

第三步,将xml文件放到resource目录下,下次启动项目,日志会自动被记录到logs目录(这个目录会在项目启动时自动生成)并分离清洗

xml文件名: log4j2.xml

文件代码:

<Configuration status="WARN">
    <Properties>
        <Property name="LOG_PATH">logs</Property>
        <Property name="APP_NAME">app</Property>
        <Property name="FILE_SIZE">64MB</Property>
        <Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t] %c{1.} [%X{traceId:-}] - %m%n%ex</Property>
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </Console>
        <RollingFile name="InfoFile" fileName="${LOG_PATH}/${APP_NAME}-info.log" filePattern="${LOG_PATH}/$${date:yyyy-MM}/${APP_NAME}-info-%d{yyyy-MM-dd}-%i.log">
            <Filters>
                <LevelMatchFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="${FILE_SIZE}"/>
            </Policies>
            <DefaultRolloverStrategy>
                <max>64</max>
                <Delete basePath="${LOG_PATH}" maxDepth="2">
                    <IfFileName glob="*/app-info*.log"/>
                    <IfLastModified age="30d"/>
                </Delete>
                <Delete basePath="${LOG_PATH}" maxDepth="2">
                    <IfFileName glob="*/app-info*.log"/>
                    <IfAccumulatedFileSize exceeds="6GB"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
        <RollingFile name="WarnFile" fileName="${LOG_PATH}/${APP_NAME}-warn.log" filePattern="${LOG_PATH}/$${date:yyyy-MM}/${APP_NAME}-warn-%d{yyyy-MM-dd}-%i.log">
            <Filters>
                <LevelMatchFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="${FILE_SIZE}"/>
            </Policies>
            <DefaultRolloverStrategy>
                <max>64</max>
                <Delete basePath="${LOG_PATH}" maxDepth="2">
                    <IfFileName glob="*/app-warn*.log"/>
                    <IfLastModified age="60d"/>
                </Delete>
                <Delete basePath="${LOG_PATH}" maxDepth="2">
                    <IfFileName glob="*/app-warn*.log"/>
                    <IfAccumulatedFileSize exceeds="3GB"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
        <RollingFile name="ErrorFile" fileName="${LOG_PATH}/${APP_NAME}-error.log" filePattern="${LOG_PATH}/$${date:yyyy-MM}/${APP_NAME}-error-%d{yyyy-MM-dd}-%i.log">
            <Filters>
                <LevelMatchFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="${FILE_SIZE}"/>
            </Policies>
            <DefaultRolloverStrategy>
                <max>64</max>
                <Delete basePath="${LOG_PATH}" maxDepth="2">
                    <IfFileName glob="*/app-error*.log"/>
                    <IfLastModified age="90d"/>
                </Delete>
                <Delete basePath="${LOG_PATH}" maxDepth="2">
                    <IfFileName glob="*/app-error*.log"/>
                    <IfAccumulatedFileSize exceeds="2GB"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
        <RollingFile name="DebugFile" fileName="${LOG_PATH}/${APP_NAME}-debug.log" filePattern="${LOG_PATH}/$${date:yyyy-MM}/${APP_NAME}-debug-%d{yyyy-MM-dd}-%i.log">
            <Filters>
                <LevelMatchFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="${FILE_SIZE}"/>
            </Policies>
            <DefaultRolloverStrategy>
                <max>64</max>
                <Delete basePath="${LOG_PATH}" maxDepth="2">
                    <IfFileName glob="*/app-debug*.log"/>
                    <IfLastModified age="7d"/>
                </Delete>
                <Delete basePath="${LOG_PATH}" maxDepth="2">
                    <IfFileName glob="*/app-debug*.log"/>
                    <IfAccumulatedFileSize exceeds="5GB"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Logger name="org.springframework" level="info" additivity="false">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="InfoFile"/>
            <AppenderRef ref="WarnFile"/>
            <AppenderRef ref="ErrorFile"/>
        </Logger>
        <Logger name="org.hibernate" level="warn"/>
        <Root level="info">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="InfoFile"/>
            <AppenderRef ref="WarnFile"/>
            <AppenderRef ref="ErrorFile"/>
        </Root>
    </Loggers>
</Configuration>

实现原理

日志切割

Appender 就是日志的输出目的地。Appender 中的 RollingFile都设置了两种触发策略,它们之间是“或”的关系,只要满足任一条件,就会触发日志切割

参数 ${FILE_SIZE}被定义为 64MB

这意味着,即使在同一天内,只要当前正在写入的日志文件大小达到 64MB,也会立即触发切割,并生成一个新的日志文件 。

            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="${FILE_SIZE}"/>
            </Policies>

日志的分离

可以看到,在Appenders中RollingFile被分为了四种,分别是Info,Warn,Error,Debug级别的文件

当日志文件被切割后,其归档文件的命名和存放位置由 filePattern属性精确控制:

filePattern="${LOG_PATH}/$${date:yyyy-MM}/${APP_NAME}-info-%d{yyyy-MM-dd}-%i.log.gz"

这个配置实现了以下效果:

日志清理

日志清理有三个策略

<max>64</max>在这里表示:当天最多可以生成 64 个归档日志文件(例如 app-info-2025-10-15-1.log.gzapp-info-2025-10-15-64.log.gz)。

当同一天内的第 65 次滚动触发时,最早的那个文件(如 ...-1.log.gz)将会被删除 。

<IfFileName glob="*/app-info*.log"/>
<IfLastModified age="30d"/>

这个代表如果超过30天会把info类型的最旧日志删除

<IfFileName glob="*/app-info*.log"/>
<IfAccumulatedFileSize exceeds="6GB"/>

这个代表如果超过6GB会把info类型的最旧日志删除

            <DefaultRolloverStrategy>
                <max>64</max>
                <Delete basePath="${LOG_PATH}" maxDepth="2">
                    <IfFileName glob="*/app-info*.log"/>
                    <IfLastModified age="30d"/>
                </Delete>
                <Delete basePath="${LOG_PATH}" maxDepth="2">
                    <IfFileName glob="*/app-info*.log"/>
                    <IfAccumulatedFileSize exceeds="6GB"/>
                </Delete>
            </DefaultRolloverStrategy>

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文