【问题标题】:Log4j Filepattern not working when SizeBasedTriggeringPolicy triggered触发 SizeBasedTriggeringPolicy 时 Log4j Filepattern 不起作用
【发布时间】:2020-04-14 17:59:22
【问题描述】:

我们的 log4j2 配置存在问题,我们几乎直接从 https://www.baeldung.com/java-logging-rolling-file-appenders 第 4.4 节获取:

<RollingFile name="roll-by-time-and-size"
  fileName="target/log4j2/roll-by-time-and-size/app.log"
  filePattern="target/log4j2/roll-by-time-and-size/app.%d{MM-dd-yyyy-HH-mm-ss.SSS}.%i.log.gz"
  ignoreExceptions="false">
    <PatternLayout>
        <Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %m%n</Pattern>
    </PatternLayout>
    <Policies>
        <SizeBasedTriggeringPolicy size="5 KB" />
        <TimeBasedTriggeringPolicy interval="5000000" />
    </Policies>
    <DefaultRolloverStrategy>
        <Delete basePath="." maxDepth="2">
            <IfFileName glob="target/log4j2/roll-by-time-and-size/app.*.log.gz" />
            <IfLastModified age="20d" />
        </Delete>
    </DefaultRolloverStrategy>
</RollingFile>

如果我减少间隔以确保它基于时间滚动,这会将正确的当前时间放在文件名中。但是,如果我将间隔增加到 5000 或其他任何值并让 SizeBasedTriggeringPolicy 受到打击,则时间戳始终是相同的,并且是文件末尾索引中唯一更改的内容。

这对我们来说是个问题,因为我们有一个 cron 作业将滚动的文件移动到远程挂载点。这意味着下一次 log4j 达到基于大小的触发策略时,索引将重置为 1,文件名中的时间戳将保持不变,即使它不应该是相同的(为什么??),我们的 cron 作业将尝试移动该文件,但它将与已移动的另一个文件的文件名相同。

使用最新的spring boot starter log4j2(截至目前)

是错误还是预期行为。作为一种预期的行为没有多大意义,但如果是这样,我们应该怎么做才能解决这个问题?

【问题讨论】:

  • 您是说文件时间戳在较小的时间间隔内永远不会改变?使用您的配置,应每 5000 秒发生一次基于时间的翻转,此时日期和时间应更改。另外,我建议尝试使用最新的 Log4j 2 版本。对这些 Log4j 组件进行了一些修复,可以修复此问题。要使用最新的 Log4j 2 jar,只需删除 spring boot starter log4j2 并替换为 log4j 依赖项。

标签: java logging log4j log4j2


【解决方案1】:

这些政策似乎按照文档中的说明起作用。我在 Spring Boot 2.2.6.RELEASE 应用程序上对其进行了测试:

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

然后我使用以下依赖项而不是启动器,以确保我使用的是最新版本:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jcl</artifactId>
    <version>5.2.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.13.2</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.13.2</version>
</dependency>

在这两种情况下,基于大小的触发策略仅在使用没有基于时间的触发策略时才会更改文件名中的时间戳。

来自documentation

当与基于时间的触发策略结合使用时,文件模式必须包含 %i,否则目标文件将在每次翻转时被覆盖,因为基于大小的触发策略不会导致文件名中的时间戳值更改。如果在没有基于时间的触发策略的情况下使用 SizeBased Triggering Policy 将导致时间戳值发生变化。

每次 TimeBasedTriggering 策略触发翻转时,都会创建一个名称中包含新时间戳的文件。下次触发 SizeBased Triggering Policy 时,它会使用最新文件中的时间戳并仅更改 %i 部分。

由于您无法更改 SizeBasedTriggerin 策略确定索引的方式,唯一明显的解决方案似乎是更改 cron 作业以不移动具有最新时间戳和索引的文件。这应该足以解决您的问题。

【讨论】:

    猜你喜欢
    • 2016-07-10
    • 1970-01-01
    • 2011-01-20
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多