7

我正在尝试保留 Spring Boot 应用程序的日志,但是,由于生成的日志很大,我尝试使用 logback.xml 将大于 350MB 的文件滚动到压缩文件中。

我每天可以滚动几个 MB,但中途服务开始写入临时文件。我已经使用“SizeAndTimeBasedFNATP”的触发策略尝试了“TimeBasedRollingPolicy”和“Size AndTimeBasedRollingPolicy”,但结果没有改变。每次都会生成 .tmp 文件。

我的 Logback.xml 看起来像这样:

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

<configuration>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>/home/xyz/logs/ProdLog.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/home/xyz/logs/log_%d{yyyy-MM-dd}_%i.log.zip</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- or whenever the file size reaches 350MB -->
                <maxFileSize>350MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>5</maxHistory>
            <!--<maxFileSize>350MB</maxFileSize>-->
        </rollingPolicy>
        <encoder>
            <pattern>%date [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
        <Pattern>
        %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
        </Pattern>
        </layout>
    </appender>
    <root level="INFO">
        <appender-ref ref="FILE"/>
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

在此处输入图像描述

我看到 logback .tmp 文件问题的票证在 Jira 上标记为已关闭。有人可以帮助这里需要修改什么以避免生成临时文件吗?

4

1 回答 1

8

我在使用 logback 1.2.3 时遇到了同样的问题,显然该错误已在 1.3.0 版本中修复,但我找到了负责生成这些 tmp 文件的代码行并设法避免它。

这是来自 TimeBasedRollingPolicy.java 的代码:

public void rollover() throws RolloverFailure {

    // when rollover is called the elapsed period's file has
    // been already closed. This is a working assumption of this method.

    String elapsedPeriodsFileName = timeBasedFileNamingAndTriggeringPolicy.getElapsedPeriodsFileName();

    String elapsedPeriodStem = FileFilterUtil.afterLastSlash(elapsedPeriodsFileName);

    if (compressionMode == CompressionMode.NONE) {
        if (getParentsRawFileProperty() != null) {
            renameUtil.rename(getParentsRawFileProperty(), elapsedPeriodsFileName);
        } // else { nothing to do if CompressionMode == NONE and parentsRawFileProperty == null }
    } else {
        if (getParentsRawFileProperty() == null) {
            compressionFuture = compressor.asyncCompress(elapsedPeriodsFileName, elapsedPeriodsFileName, elapsedPeriodStem);
        } else {
            compressionFuture = renameRawAndAsyncCompress(elapsedPeriodsFileName, elapsedPeriodStem);
        }
    }

    if (archiveRemover != null) {
        Date now = new Date(timeBasedFileNamingAndTriggeringPolicy.getCurrentTime());
        this.cleanUpFuture = archiveRemover.cleanAsynchronously(now);
    }
}

Future<?> renameRawAndAsyncCompress(String nameOfCompressedFile, String innerEntryName) throws RolloverFailure {
    String parentsRawFile = getParentsRawFileProperty();
    String tmpTarget = nameOfCompressedFile + System.nanoTime() + ".tmp";
    renameUtil.rename(parentsRawFile, tmpTarget);
    return compressor.asyncCompress(tmpTarget, nameOfCompressedFile, innerEntryName);
}

正如您在此处看到的,如果您在 appender 中设置了“fileName”,则会调用该方法并生成一个 tmp 文件(这还不错)。我认为当有线程不停止登录该 tmp 文件时,问题就出现了,所以最后有线程在 tmp 文件上写入,而其他线程在新的“fileName”文件上写入。

如果您只设置 fileNamePattern 标签而不是文件标签,则不应生成 tmp 文件。

我希望这可以帮助你!

于 2019-10-28T11:33:44.167 回答