Log4j2 DefaultRolloverStrategy 的 max 属性如何真正起作用?

Posted

技术标签:

【中文标题】Log4j2 DefaultRolloverStrategy 的 max 属性如何真正起作用?【英文标题】:How does Log4j2 DefaultRolloverStrategy's max attribute really work? 【发布时间】:2014-08-24 11:07:05 【问题描述】:

我已经配置了一个RollingRandomAccessFileAppender 只设置了OnStartupTriggeringPolicy,但是当我将DefaultRolloverStrategy 的最大属性设置为某个数字时,日志会无限期地生成超过该数量。

这是我的 log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%dHH:mm:ss.SSS [%t] %-5level %logger36 - %msg%n"/>
        </Console>
        <RollingRandomAccessFile 
            name="RollingRAF" 
            fileName="logs/app.log"
            filePattern="logs/app-%ddd-MMM-yyyy@HH.mm.ss.log">
            <PatternLayout>
                <Pattern>%d %p %c1. %m%n</Pattern>
            </PatternLayout>
            <Policies>
                <OnStartupTriggeringPolicy />
            </Policies>
            <DefaultRolloverStrategy max="5"/>
        </RollingRandomAccessFile>
    </Appenders>
    <Loggers>
        <Logger name="myLogger" level="warn">
            <AppenderRef ref="RollingRAF"/>
        </Logger>
        <Root level="error">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

是因为我的名称模式中没有迭代器吗?

是不是因为我的文件名精度设置为秒?

是因为我只有OnStartupTriggeringPolicy 集吗?

或者这里发生了什么?

我的目标是设置一个滚动配置来记录最近 5 次应用程序运行。

【问题讨论】:

您是否应该使用&lt;TimeBasedTriggeringPolicy /&gt;,因为您在名称模式中使用日期? @Sionnach733 添加/更改并没有太大变化,它会无限期地生成日志。如果我添加一个迭代器 %i 并将精度降低到能够生成 5 个具有相同精度的日志的程度,那么它会按预期覆盖旧日志(例如,如果精度设置为分钟并且我在 1 分钟内生成 5 个日志) ,但是一旦日期发生变化(下一分钟到来),它将允许它再生成 5 个日志。理想情况下,为了方便起见,我只想要文件名中的日期而不是功能,因为我可以省略名称中的日期并使用普通迭代器来实现我想要的。 我观察到相同的行为并同意@Ceiling-Gecko,DefaultRolloverStrategy 上的 max 属性显然仅适用于迭代器,并且迭代器仅在剩余文件名重复时进行迭代,因此它不会当名称不同时,我似乎不可能自动删除旧的日志文件。尽管如此,当 API 大量用于这么多人时,这个功能却不存在,这真的很奇怪...... 【参考方案1】:

如果指定了 TimeBasedTriggeringPolicy,DefaultRolloverStrategy 将使用 filePattern 中指定的日期模式。要使用max 属性,请在filePattern 中指定%i 模式,并将&lt;SizeBasedTriggeringPolicy size="20 MB" /&gt; 添加到翻转策略中。 (当然也可以是其他尺寸。)

&lt;DefaultRolloverStrategy max="5"/&gt; 中的 max 值将确保在相同的翻转周期内(自您指定日期模式 %ddd-MMM-yyyy@HH.mm.ss 起为您一秒)在基于大小的翻转时创建的文件不超过 5 个被触发了。

如果您的翻转窗口较长,这将更有用,例如每天翻转到一个新文件夹,并确保在该文件夹中创建的文件不超过 5 个,最大大小为 20 MB。


更新:

Log4j 2.5 添加了配置custom delete actions 的功能。开箱即用,您可以根据使用时间、计数或它们占用的磁盘空间(累积文件大小)删除文件。

【讨论】:

有没有办法向名称模式添加时间戳,翻转策略将作为纯文本忽略?这样我就可以在模式的末尾添加一个%i,然后它只会查看%i,并在滚动到新文件时忽略日期。我在文档中看到了类似$$date:dd-MMM-yyyy@HH.mm.ss 的模式,但它似乎类似于%d 模式。 不知道我是否理解正确,但是像每年或每个时代那样使用一个非常大的翻转期怎么样$$date:G 是的,我明白了。我不介意只使用"logs/app-%i.log" 模式,我只是想也许有一种方法可以挤进时间戳以方便个人查看。 @RemkoPopma:我使用 DefaultRolloverStrategy 和 SizeBasedTriggeringPolicy 为 10 MB。有时,我得到:“无法删除文件”或“无法移动文件” - 该进程无法访问该文件,因为它正在被另一个进程使用“这与滚动日志文件有关。我使用的是 Windows。为什么发生这种情况?如何避免这种情况? 您能否在 log4j-user 邮件列表中询问以获取整个 Log4j2 社区的意见?

以上是关于Log4j2 DefaultRolloverStrategy 的 max 属性如何真正起作用?的主要内容,如果未能解决你的问题,请参考以下文章

log4j2漏洞复现与利用

日志框架之log4j2的使用

如何在 IDE 中使用一个 log4j2 配置文件进行运行时,使用另一个 log4j2 配置文件进行打包/部署?

Log4j2配置

Log4j2 简单使用

你知道 log4j2 各项配置的全部含义吗?带你了解 log4j2 的全部组件