I have a problem using DailyRollingFileAppender with weekly rotation. The problem is that the appender rolls over every month instead of every week. The date pattern is: log4j.appender.A1.DatePattern='.'yyyy-ww log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender Log4j version: 1.2.14, java 1.5.0_06-b05 on Fedora Core 5. OS environment settings: LANG=hu_HU TZ=Europe/Budapest I debugged the DailyRollingFileAppender and found that when determining the rotation period, method computeCheckPeriod() returns TOP_OF_MONTH instead of TOP_OF_WEEK. The cause probably is that the getFirstDayOfWeek() call in RollingCalendar.getNextCheckDate() returns Sunday instead of Monday as it should in Hungary and in most part of Europe. Because the epoch and the first Sunday after the epoch are on the same week, the method computeCheckPeriod() advances to the next period type, monthly rotation. Replacing getFirstDayOfWeek() with Calendar.getInstance().getFirstDayOfWeek() resolves the problem for us. This simple test program logs the week number within the current year, and the log should be rotates when a new week starts (if you change the system time). import java.util.GregorianCalendar; import org.apache.log4j.Logger; public class LogTest { private static final Logger log = Logger.getLogger(LogTest.class); public static void main(String args[]) { GregorianCalendar cal = new GregorianCalendar(); System.out.println("Sunday: " + cal.SUNDAY); System.out.println("Monday: " + cal.MONDAY); System.out.println("First day: " + cal.getFirstDayOfWeek()); System.out.println("TimeZone: " + cal.getTimeZone().getDisplayName()); try { for(int i = 0; i < 100;i++) { cal = new GregorianCalendar(); log.warn("Hello, " + "week number: " + cal.get(cal.WEEK_OF_YEAR)); Thread.currentThread().sleep(10 * 1000); // sleep 10 seconds System.out.println(i); } } catch(Exception ex) { log.error(ex); } } } I tested with the following settings and got the same result: LANG=en_GB TZ=Europe/London Thanks, Laszlo
This does not appear to have been addressed yet. The code in question is that the "roll over"-time is calculated to be case DailyRollingFileAppender.TOP_OF_WEEK: this.set(Calendar.DAY_OF_WEEK, getFirstDayOfWeek()); this.set(Calendar.HOUR_OF_DAY, 0); this.set(Calendar.MINUTE, 0); this.set(Calendar.SECOND, 0); this.set(Calendar.MILLISECOND, 0); this.add(Calendar.WEEK_OF_YEAR, 1); break; and the loop is for(int i = TOP_OF_MINUTE; i <= TOP_OF_MONTH; i++) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat(datePattern); simpleDateFormat.setTimeZone(gmtTimeZone); // do all date formatting in GMT String r0 = simpleDateFormat.format(epoch); rollingCalendar.setType(i); Date next = new Date(rollingCalendar.getNextCheckMillis(epoch)); String r1 = simpleDateFormat.format(next); //System.out.println("Type = "+i+", r0 = "+r0+", r1 = "+r1); if(r0 != null && r1 != null && !r0.equals(r1)) { return i; } } The r1 and r0 will be identical in the case described by the original poster. Will it be sufficient in all cases to just ask the Calendar what the first day of the week is as suggested in the bug report?
Created attachment 22420 [details] removal of locale to rollingcalendar
The problem is that RollingCalendar is using Locale.ENGLISH, and SimpleDateFormatter is using the default locale from the surroundings. The default locale for the original poster has first day of the week to Monday, but RollingCalendar calculated to Sunday which is the first day of the week in Locale.English. Hence this fails. The patch sets RollingCalendar to use the default locale too. (I am in a similar locale so I see the bug too)
Created attachment 22421 [details] test case
Committed slightly different change in 685338. Attached patches changed the signature of RollingCalendar which is not private so would be considered a breaking API change. Was simpler just to pass Locale.getDefault() instead of Locale.ENGLISH in the call to new RollingCalendar.
*** Bug 46851 has been marked as a duplicate of this bug. ***