[
https://issues.apache.org/jira/browse/LOG4J2-385?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13887524#comment-13887524
]
Remko Popma commented on LOG4J2-385:
------------------------------------
After checking the behaviour of Log4J-1.2 and Logback there seem to be a few
bugs in the current {{PatternProcessor.getNextTime()}} logic.
Current {{PatternProcessor.getNextTime()}} results (dates in {{yyyy/MM/dd}}
format):
# Monthly rollover from 2014/01/31 gives 2014/02/01
# Monthly rollover from 2014/10/15 gives 2014/{color:red}02/01{color} *<-- BUG*
# Weekly rollover from 2014/03/4 Tue gives 2014/{color:red}01/08 Wed{color}
*<-- BUG*
# Hourly rollover from 2014/03/04 10:31 gives 2014/03/04 11:00 when run in the
morning
# Hourly rollover from 2014/03/04 10:31 gives 2014/03/04
{color:red}23{color}:00 when run in the afternoon *<-- BUG*
# Minutely rollover from 2014/03/04 10:31 gives 2014/03/04
{color:red}22{color}:00 when run in the afternoon *<-- BUG*
The following patch fixes the above issues:
{code}
Index:
src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java
===================================================================
---
src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java
(revision 1563035)
+++
src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java
(working copy)
@@ -102,6 +102,7 @@
nextFileTime = cal.getTimeInMillis();
return nextTime;
}
+ cal.set(Calendar.MONTH, currentCal.get(Calendar.MONTH));
if (frequency == RolloverFrequency.MONTHLY) {
increment(cal, Calendar.MONTH, increment, modulus);
nextTime = cal.getTimeInMillis();
@@ -110,7 +111,9 @@
return nextTime;
}
if (frequency == RolloverFrequency.WEEKLY) {
+ cal.set(Calendar.WEEK_OF_YEAR,
currentCal.get(Calendar.WEEK_OF_YEAR));
increment(cal, Calendar.WEEK_OF_YEAR, increment, modulus);
+ cal.set(Calendar.DAY_OF_WEEK, currentCal.getFirstDayOfWeek());
nextTime = cal.getTimeInMillis();
cal.add(Calendar.WEEK_OF_YEAR, -1);
nextFileTime = cal.getTimeInMillis();
@@ -124,11 +127,11 @@
nextFileTime = cal.getTimeInMillis();
return nextTime;
}
- cal.set(Calendar.HOUR, currentCal.get(Calendar.HOUR));
+ cal.set(Calendar.HOUR_OF_DAY, currentCal.get(Calendar.HOUR_OF_DAY));
if (frequency == RolloverFrequency.HOURLY) {
- increment(cal, Calendar.HOUR, increment, modulus);
+ increment(cal, Calendar.HOUR_OF_DAY, increment, modulus);
nextTime = cal.getTimeInMillis();
- cal.add(Calendar.HOUR, -1);
+ cal.add(Calendar.HOUR_OF_DAY, -1);
nextFileTime = cal.getTimeInMillis();
return nextTime;
}
{code}
Updated JUnit tests:
{code}
private String format(long time) {
String actualStr = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS")
.format(new Date(time));
return actualStr;
}
@Test
public void testGetNextTimeMonthlyReturnsFirstDayOfNextMonth() {
PatternProcessor pp = new PatternProcessor(
"logs/app-%d{yyyy-MM}.log.gz");
Calendar initial = Calendar.getInstance();
initial.set(2014, 9, 15, 10, 31, 59); // Oct 15th
long actual = pp.getNextTime(initial.getTimeInMillis(), 1, false);
// We expect 1st day of next month
Calendar expected = Calendar.getInstance();
expected.set(2014, 10, 1, 0, 0, 00);
expected.set(Calendar.MILLISECOND, 0);
assertEquals(format(expected.getTimeInMillis()), format(actual));
}
@Test
public void testGetNextTimeMonthlyReturnsFirstDayOfNextMonth2() {
PatternProcessor pp = new PatternProcessor(
"logs/app-%d{yyyy-MM}.log.gz");
Calendar initial = Calendar.getInstance();
initial.set(2014, 0, 31, 10, 31, 59); // 2014 Jan 31st
long actual = pp.getNextTime(initial.getTimeInMillis(), 1, false);
// Expect 1st of next month: 2014 Feb 1st
Calendar expected = Calendar.getInstance();
expected.set(2014, 1, 1, 0, 0, 00);
expected.set(Calendar.MILLISECOND, 0);
assertEquals(format(expected.getTimeInMillis()), format(actual));
}
@Test
public void testGetNextTimeWeeklyReturnsFirstDayOfNextWeek_US() {
Locale old = Locale.getDefault();
Locale.setDefault(Locale.US); // force 1st day to be Sunday
try {
PatternProcessor pp = new PatternProcessor(
"logs/app-%d{yyyy-MM-W}.log.gz");
Calendar initial = Calendar.getInstance();
initial.set(2014, 2, 4, 10, 31, 59); // Tue, March 4, 2014
long actual = pp.getNextTime(initial.getTimeInMillis(), 1, false);
// expect Sun, March 9, 2014
Calendar expected = Calendar.getInstance();
expected.set(2014, 2, 9, 0, 0, 00);
expected.set(Calendar.MILLISECOND, 0);
assertEquals(format(expected.getTimeInMillis()), format(actual));
} finally {
Locale.setDefault(old);
}
}
@Test
public void testGetNextTimeWeeklyReturnsFirstDayOfNextWeek_FRANCE() {
Locale old = Locale.getDefault();
Locale.setDefault(Locale.FRANCE); // force 1st day to be Monday
try {
PatternProcessor pp = new PatternProcessor(
"logs/app-%d{yyyy-MM-W}.log.gz");
Calendar initial = Calendar.getInstance();
initial.set(2014, 2, 4, 10, 31, 59); // Tue, March 4, 2014
long actual = pp.getNextTime(initial.getTimeInMillis(), 1, false);
// expect Monday, March 10, 2014
Calendar expected = Calendar.getInstance();
expected.set(2014, 2, 10, 0, 0, 00);
expected.set(Calendar.MILLISECOND, 0);
assertEquals(format(expected.getTimeInMillis()), format(actual));
} finally {
Locale.setDefault(old);
}
}
@Test
public void testGetNextTimeHourlyReturnsFirstMinuteOfNextHour() {
PatternProcessor pp = new PatternProcessor(
"logs/app-%d{yyyy-MM-dd-HH}.log.gz");
Calendar initial = Calendar.getInstance();
initial.set(2014, 2, 4, 10, 31, 59); // Tue, March 4, 2014, 10:31
long actual = pp.getNextTime(initial.getTimeInMillis(), 1, false);
// expect Wed, March 4, 2014, 11:00
Calendar expected = Calendar.getInstance();
expected.set(2014, 2, 4, 11, 00, 00);
expected.set(Calendar.MILLISECOND, 0);
assertEquals(format(expected.getTimeInMillis()), format(actual));
}
@Test
public void testGetNextTimeMinutelyReturnsFirstSecondOfNextMinute() {
PatternProcessor pp = new PatternProcessor(
"logs/app-%d{yyyy-MM-dd-HH-mm}.log.gz");
Calendar initial = Calendar.getInstance();
initial.set(2014, 2, 4, 10, 31, 59); // Tue, March 4, 2014, 10:31
initial.set(Calendar.MILLISECOND, 0);
assertEquals("2014/03/04 10:31:59.000",
format(initial.getTimeInMillis()));
long actual = pp.getNextTime(initial.getTimeInMillis(), 1, false);
// expect Tue, March 4, 2014, 10:32
Calendar expected = Calendar.getInstance();
expected.set(2014, 2, 4, 10, 32, 00);
expected.set(Calendar.MILLISECOND, 0);
assertEquals(format(expected.getTimeInMillis()), format(actual));
}
{code}
> Unable to roll log files monthly
> --------------------------------
>
> Key: LOG4J2-385
> URL: https://issues.apache.org/jira/browse/LOG4J2-385
> Project: Log4j 2
> Issue Type: Bug
> Components: Appenders
> Affects Versions: 2.0-beta8
> Environment: Java 1.7.0_25, Windows 7 64bit, IntelliJ IDEA 12 Ultimate
> Reporter: Ace Funk
> Assignee: Remko Popma
> Attachments: LOG4J2-385.patch
>
>
> Attempting to use FastRollingFile appender and configure log file rollover to
> occur monthly. When {{filePattern="logs/app-%d\{yyyy-MM}.log.gz"}} is used,
> at application startup an archive file is created immediately
> (app-2013-01.log.gz) even if no log previously existed. A log file is
> created, but only a single entry is made into the log.
--
This message was sent by Atlassian JIRA
(v6.1.5#6160)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]