How does Log4j2 DefaultRolloverStrategy's max attribute really work?
Asked Answered
D

1

40

I've configured a RollingRandomAccessFileAppender with only the OnStartupTriggeringPolicy set, but when I set the max attribute of the DefaultRolloverStrategy to some number, the logs keep generating past that amount indefinitely.

Here's my 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{[email protected]}.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>

Is it because I don't have an iterator in my name pattern?

Is it because my file name precision is set to seconds?

Is it because I only have the OnStartupTriggeringPolicy set?

Or what's going on here?

My goal here was to set up a rolling configuration that will log the last 5 application runs.

Disfrock answered 3/7, 2014 at 10:53 Comment(3)
Should you use <TimeBasedTriggeringPolicy /> since you are using date in the name pattern?Sphalerite
@Sphalerite Adding/changing that doesn't change much, it keeps generating logs indefinitely. If I add an iterator %i and lower the precision to a point where I am able to generate 5 logs with the same precision then it overwrites old logs as expected (e.g. if precision is set to minutes and I generate 5 logs in 1 minute), but as soon as the date changes (next minute arrives) it will allow it to generate 5 more logs. Ideally I just wanted the date in the filename for convenience not functionality, as I can just omit the date from the name and go with a plain iterator to achieve what I want.Disfrock
I have observed the same behaviour and agree with @Ceiling-Gecko, the max attribute on DefaultRolloverStrategy apprently applies only to the iterator and the iterator only iterates when the remaining file name is repeated, therefore it doesn't seem possible to me to auto-remove old log files when the names are different. Nonetheless, it is really odd that this functionality does not exist when the API is so largelly used for so many people...Bornholm
D
41

The DefaultRolloverStrategy will use the date pattern specified in the filePattern if a TimeBasedTriggeringPolicy is specified. To use the max attribute, specify a %i pattern in the filePattern, and add <SizeBasedTriggeringPolicy size="20 MB" /> to the rollover policies. (Or some other size of course.)

The value for max in <DefaultRolloverStrategy max="5"/> will then ensure that within the same rollover period (one second for you since you specified a date pattern of %d{[email protected]}) no more than 5 files will be created when a size-based rollover was triggered.

This is more useful if your rollover window is longer, like rolling over to a new folder every day, and within that folder, ensure that no more than 5 files are created with max size=20 MB.


Update:

Log4j 2.5 added the ability to configure custom delete actions. Out of the box you can delete files based on age, count or how much disk space they take up (accumulated file size).

Droll answered 4/7, 2014 at 4:22 Comment(6)
Is there perhaps a way to add a timestamp to the name pattern that the rollover strategy will ignore as plain text? That way I could just add a %i at the end of the pattern and it will then only look at the %i and ignore the date when rolling over to a new file. I saw in the docs a pattern like $${date:[email protected]} but it seems it's analogous to the %d pattern.Disfrock
Not sure if I understand correctly, but what about using a very large rollover period like every year or every era $${date:G}?Droll
Yeah, I understand that. I wouldn't mind going even with just "logs/app-%i.log" pattern, I just thought maybe there is a way I could squeeze in a timestamp for personal viewing convenience.Disfrock
@RemkoPopma: I have used DefaultRolloverStrategy along with SizeBasedTriggeringPolicy as 10 MB. Sometimes, I am getting: "Unable to delete file" or "Unable to move file" - The process cannot access the file because it is being used by another process" which is related to rolling log files. I am using Windows. Why does it happen so? How to avoid this?Hedron
Can you ask on the log4j-user mailing list to get input from the whole Log4j2 community?Droll
@Hedron I have the same issue as yours: "Unable to delete file" or "Unable to move file", have you found a solution please?Boggess

© 2022 - 2024 — McMap. All rights reserved.