Name direct write cron files after the rollover period they cover - #4227
Open
tupelo-schneck wants to merge 2 commits into
Open
Name direct write cron files after the rollover period they cover#4227tupelo-schneck wants to merge 2 commits into
tupelo-schneck wants to merge 2 commits into
Conversation
An appender configured without a `fileName` writes directly to the file its
pattern resolves to. `CronTriggeringPolicy.initialize()` records the start of
the current rollover period as the pattern processor's current file time, but
`DirectWriteRolloverStrategy.getCurrentFileName()` overwrote it with the
current time, so the file was named after the moment the appender started
rather than after the period it covers.
For a weekly schedule and a `%d{yyyyMMdd}` pattern that means every restart on
a new day opens another file, leaving a week with as many files as there were
restart days rather than the single file the schedule implies.
That override (LOG4J2-3339) compensated for `rollover()` passing the previous
roll date as the new file's time, which named each new file after the file just
rolled. Pass the roll time instead, so the replacement file is named after the
period it opens, and let `getCurrentFileName()` use the recorded period start.
Policies that do not track a period, such as `TimeBasedTriggeringPolicy`, leave
the current file time at 0, and `PatternProcessor.formatFileName()` already
falls back to the current time in that case, so their behaviour is unchanged.
Note that this changes direct write file names for cron based appenders.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This changes the names of direct write files for cron based appenders. That is the point of the change, but it is user visible on upgrade, so it deserves a decision rather than a rubber stamp. Details below.
An appender configured without a
fileNamewrites directly to the file its pattern resolves to. That file covers a whole rollover period, but it is currently named after the moment the appender started rather than after the period it covers.With a weekly schedule and a day-granularity pattern:
starting on Tuesday 2026-07-28 writes to
error.log-20260728. The period began on Sunday 2026-07-26, so a restart on Wednesday openserror.log-20260729instead of continuing the same file. A week with daily restarts leaves seven files where the schedule implies one, and rollover only ever closes out whichever fragment happens to be current.Cause
CronTriggeringPolicy.initialize()computes the period start and records it correctly:DirectWriteRolloverStrategy.getCurrentFileName()then discards it:That override compensates for a different problem.
CronTriggeringPolicy.rollover()passeslastRollDate, the previous period's start, as the new file's time:and
RollingFileManager.rollover(prevFileTime, prevRollTime)assigns that to the current file time, so each replacement file was named after the file just rolled. Substituting the current time hid this, and works only because at the instant of a rollover "now" is approximately the new period's start. At startup "now" is an arbitrary point inside the period, which is where it breaks.Fix
Pass the roll time rather than the previous roll date, so the replacement file is named after the period it opens, and let
getCurrentFileName()use the period start the policy already recorded.Blast radius is limited to policies that track a period.
PatternProcessor.formatFileName()already falls back to the current time when the current file time is 0:and
PatternProcessor.updateTime()resets it to 0, soTimeBasedTriggeringPolicy, which never sets it, keeps its existing behaviour unchanged. Only cron, which knows its period start, behaves differently.Compatibility
Direct write files for cron based appenders change name, from the start time of the process to the start of the rollover period. For the example above that is
error.log-20260726rather thanerror.log-20260728. Existing files are untouched and are neither read nor renamed; a restart after upgrading simply begins writing to the period's file. The changelog entry calls this out.Appenders configured with a
fileNameare unaffected, sincegetCurrentFileName()is only consulted on the direct write path.Testing
CronTriggeringPolicyTest#testDirectWriteFileNameUsesPeriodStartasserts the manager's file name matches the period start computed independently from the same cron expression. Against2.xwithout the fix it fails with:RollingAppenderDirectCronTest, the regression test added with LOG4J2-3339, still passes; it asserts that a rolled file's name matches the timestamp of its first line, which this change preserves../mvnw verifypasses across all 41 modules: 11088 tests, 0 failures, 0 errors, 40 pre-existing environment-conditional skips.Relationship to the other PR
Independent of the startup-delay fix in the companion PR; the two touch different code paths and can merge in either order. They surfaced from the same investigation, which is why both concern
CronTriggeringPolicy.Checklist
2.x./mvnw verifysucceedssrc/changelog/.2.x.x