Log4j2的DefaultRolloverStrategy的max属性是如何工作的?

39

我已经配置了一个RollingRandomAccessFileAppender,只设置了OnStartupTriggeringPolicy,但是当我将DefaultRolloverStrategy的max属性设置为某个数字时,日志会无限制地继续生成。

这是我的log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <RollingRandomAccessFile 
            name="RollingRAF" 
            fileName="logs/app.log"
            filePattern="logs/app-%d{dd-MMM-yyyy@HH.mm.ss}.log">
            <PatternLayout>
                <Pattern>%d %p %c{1.} %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次应用程序运行。


1
你是否应该使用 <TimeBasedTriggeringPolicy />,因为你在名称模式中使用了日期? - Sionnach733
2
@Sionnach733 添加/更改并不会有太大变化,它会无限地生成日志。如果我添加一个迭代器%i,并将精度降低到能够生成5个具有相同精度的日志,则会按预期覆盖旧日志(例如,如果将精度设置为分钟并在1分钟内生成5个日志),但是一旦日期更改(下一分钟到来),它将允许生成5个以上的日志。理想情况下,我只是想在文件名中加入日期以方便使用,而不是功能,因为我可以从名称中省略日期并使用普通迭代器来实现我想要的效果。 - Ceiling Gecko
1
我观察到了相同的行为,并且同意@Ceiling-Gecko的看法,DefaultRolloverStrategy上的max属性显然仅适用于迭代器,而迭代器仅在剩余文件名重复时进行迭代,因此当名称不同时,我认为自动删除旧日志文件似乎是不可能的。尽管如此,当API被如此多的人广泛使用时,这种功能不存在真的很奇怪... - Felipe Leão
1个回答

40
默认滚动策略将使用文件模式中指定的日期模式,如果指定了基于时间的触发策略。要使用max属性,在文件模式中指定%i模式,并添加<SizeBasedTriggeringPolicy size="20 MB" />到滚动策略中。(当然也可以使用其他大小。)
<DefaultRolloverStrategy max="5"/>中的max值将确保在同一滚动周期内(对于您来说是一秒钟,因为您指定了一个%d{dd-MMM-yyyy@HH.mm.ss}日期模式)当基于大小的滚动被触发时不会创建超过5个文件。
如果您的滚动窗口更长,比如每天滚动到一个新文件夹,并且在该文件夹中确保不会创建超过大小为20MB的5个文件,则此方法更有用。

更新:

Log4j 2.5增加了配置自定义删除操作的功能。开箱即用,您可以根据文件的年龄、数量或占用的磁盘空间(累计文件大小)来删除文件。


1
也许有一种方法可以将时间戳添加到名称模式中,使rollover策略将其忽略为纯文本?这样,我只需在模式末尾添加%i,它就只会查看%i并在滚动到新文件时忽略日期。我在文档中看到了一个类似于$${date:dd-MMM-yyyy@HH.mm.ss}的模式,但似乎它类似于%d模式。 - Ceiling Gecko
我不确定我是否理解正确,但是使用非常长的滚动周期,例如每年或每个时代 $${date:G} 怎么样? - Remko Popma
6
是的,我明白。即使只有“logs/app-%i.log”模式,我也不介意去,我只是想知道是否有一种方法可以为个人观看方便添加时间戳。 - Ceiling Gecko
1
@RemkoPopma:我使用了DefaultRolloverStrategy和SizeBasedTriggeringPolicy,大小为10 MB。有时候,我会遇到“无法删除文件”或“无法移动文件”的问题——进程无法访问该文件,因为它正在被另一个进程使用,这与滚动日志文件有关。我正在使用Windows。为什么会发生这种情况?如何避免这种情况? - a3.14_Infinity
你能否在log4j-user邮件列表上询问,以获取整个Log4j2社区的意见? - Remko Popma
@a3.14_无穷大 我和你一样遇到了相同的问题: “无法删除文件”或“无法移动文件”, 请问你找到解决方案了吗? - Timothy.Li

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接