DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG· RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://issues.apache.org/bugzilla/show_bug.cgi?id=41945>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND· INSERTED IN THE BUG DATABASE.
http://issues.apache.org/bugzilla/show_bug.cgi?id=41945 Summary: DailyRollingFileAppender.java has a bug Product: Log4j Version: unspecified Platform: All OS/Version: other Status: NEW Severity: normal Priority: P2 Component: Appender AssignedTo: [email protected] ReportedBy: [EMAIL PROTECTED] bug description: the first logfile name does not format with datePattern ; example: if my log4j.properties is: log4j.appender.LOGFILE=org.apache.log4j.DailyRollingFileAppender log4j.appender.LOGFILE.File=./logs/hhhh.log log4j.appender.LOGFILE.DatePattern='_'yyyyMMdd'.log' ... then the logger filename are : first day is :hhhh.log second day is : hhhh.log.20070322.log .... so i think the first day logger filename mush "hhhh.log.20070321.log" i think code as below is right; these codes are i append or edit at: line 193; activateOptions() function; rollOver() function; code: 1 /* 2 * Copyright 1999-2005 The Apache Software Foundation. 3 * 4 * Licensed under the Apache License, Version 2.0 (the License); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an AS IS BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package org.apache.log4j; 17 import java.io.IOException; 18 import java.io.File; 19 import java.text.SimpleDateFormat; 20 import java.util.Date; 21 import java.util.GregorianCalendar; 22 import java.util.Calendar; 23 import java.util.TimeZone; 24 import java.util.Locale; 25 import org.apache.log4j.helpers.LogLog; 26 import org.apache.log4j.spi.LoggingEvent; 27 /** 28 * DailyRollingFileAppender extends [EMAIL PROTECTED] FileAppender} so that the underlying 29 * file is rolled over at a user chosen frequency. 30 * 31 * <p> 32 * The rolling schedule is specified by the <b>DatePattern</b> option. This 33 * pattern should follow the [EMAIL PROTECTED] SimpleDateFormat} conventions. In 34 * particular, you <em>must</em> escape literal text within a pair of single 35 * quotes. A formatted version of the date pattern is used as the suffix for the 36 * rolled file name. 37 * 38 * <p> 39 * For example, if the <b>File</b> option is set to <code>/foo/bar.log</code> 40 * and the <b>DatePattern</b> set to <code>'.'yyyy-MM-dd</code>, on 41 * 2001-02-16 at midnight, the logging file <code>/foo/bar.log</code> will be 42 * copied to <code>/foo/bar.log.2001-02-16</code> and logging for 2001- 02-17 43 * will continue in <code>/foo/bar.log</code> until it rolls over the next 44 * day. 45 * 46 * <p> 47 * Is is possible to specify monthly, weekly, half-daily, daily, hourly, or 48 * minutely rollover schedules. 49 * 50 * <p> 51 * <table border="1" cellpadding="2"> 52 * <tr> 53 * <th>DatePattern</th> 54 * <th>Rollover schedule</th> 55 * <th>Example</th> 56 * 57 * <tr> 58 * <td><code>'.'yyyy-MM</code> 59 * <td>Rollover at the beginning of each month</td> 60 * 61 * <td>At midnight of May 31st, 2002 <code>/foo/bar.log</code> will be copied 62 * to <code>/foo/bar.log.2002-05</code>. Logging for the month of June will 63 * be output to <code>/foo/bar.log</code> until it is also rolled over the 64 * next month. 65 * 66 * <tr> 67 * <td><code>'.'yyyy-ww</code> 68 * 69 * <td>Rollover at the first day of each week. The first day of the week 70 * depends on the locale.</td> 71 * 72 * <td>Assuming the first day of the week is Sunday, on Saturday midnight, June 73 * 9th 2002, the file <i>/foo/bar.log</i> will be copied to 74 * <i>/foo/bar.log.2002-23</i>. Logging for the 24th week of 2002 will be 75 * output to <code>/foo/bar.log</code> until it is rolled over the next week. 76 * 77 * <tr> 78 * <td><code>'.'yyyy-MM-dd</code> 79 * 80 * <td>Rollover at midnight each day.</td> 81 * 82 * <td>At midnight, on March 8th, 2002, <code>/foo/bar.log</code> will be 83 * copied to <code>/foo/bar.log.2002-03-08</code>. Logging for the 9th day of 84 * March will be output to <code>/foo/bar.log</code> until it is rolled over 85 * the next day. 86 * 87 * <tr> 88 * <td><code>'.'yyyy-MM-dd-a</code> 89 * 90 * <td>Rollover at midnight and midday of each day.</td> 91 * 92 * <td>At noon, on March 9th, 2002, <code>/foo/bar.log</code> will be copied 93 * to <code>/foo/bar.log.2002-03-09-AM</code>. Logging for the afternoon of 94 * the 9th will be output to <code>/foo/bar.log</code> until it is rolled over 95 * at midnight. 96 * 97 * <tr> 98 * <td><code>'.'yyyy-MM-dd-HH</code> 99 * 100 * <td>Rollover at the top of every hour.</td> 101 * 102 * <td>At approximately 11:00.000 o'clock on March 9th, 2002, 103 * <code>/foo/bar.log</code> will be copied to 104 * <code>/foo/bar.log.2002-03-09-10</code>. Logging for the 11th hour of the 105 * 9th of March will be output to <code>/foo/bar.log</code> until it is rolled 106 * over at the beginning of the next hour. 107 * 108 * 109 * <tr> 110 * <td><code>'.'yyyy-MM-dd-HH-mm</code> 111 * 112 * <td>Rollover at the beginning of every minute.</td> 113 * 114 * <td>At approximately 11:23,000, on March 9th, 2001, 115 * <code>/foo/bar.log</code> will be copied to 116 * <code>/foo/bar.log.2001-03-09-10-22</code>. Logging for the minute of 117 * 11:23 (9th of March) will be output to <code>/foo/bar.log</code> until it 118 * is rolled over the next minute. 119 * 120 * </table> 121 * 122 * <p> 123 * Do not use the colon ":" character in anywhere in the <b>DatePattern</b> 124 * option. The text before the colon is interpeted as the protocol specificaion 125 * of a URL which is probably not what you want. 126 * 127 * 128 * @author Eirik Lygre 129 * @author Ceki Gülcü 130 */ 131 public class DailyRollingFileAppender extends FileAppender { 132 // The code assumes that the following constants are in a increasing 133 // sequence. 134 static final int TOP_OF_TROUBLE = -1; 135 static final int TOP_OF_MINUTE = 0; 136 static final int TOP_OF_HOUR = 1; 137 static final int HALF_DAY = 2; 138 static final int TOP_OF_DAY = 3; 139 static final int TOP_OF_WEEK = 4; 140 static final int TOP_OF_MONTH = 5; 141 /** 142 * The date pattern. By default, the pattern is set to "'.'yyyy-MM-dd" 143 * meaning daily rollover. 144 */ 145 private String datePattern = '.'yyyy-MM-dd; 146 /** 147 * The log file will be renamed to the value of the scheduledFilename 148 * variable when the next interval is entered. For example, if the rollover 149 * period is one hour, the log file will be renamed to the value of 150 * scheduledFilename at the beginning of the next hour. 151 * 152 * The precise time when a rollover occurs depends on logging activity. 153 */ 154 private String scheduledFilename; 155 /** 156 * The next time we estimate a rollover should occur. 157 */ 158 private long nextCheck = System.currentTimeMillis() - 1; 159 Date now = new Date(); 160 SimpleDateFormat sdf; 161 RollingCalendar rc = new RollingCalendar(); 162 int checkPeriod = TOP_OF_TROUBLE; 163 // The gmtTimeZone is used only in computeCheckPeriod() method. 164 static final TimeZone gmtTimeZone = TimeZone.getTimeZone ("GMT"); 165 /** 166 * The default constructor does nothing. 167 */ 168 public DailyRollingFileAppender() { 169 } 170 /** 171 * Instantiate a <code>DailyRollingFileAppender</code> and open the file 172 * designated by <code>filename</code>. The opened filename will become 173 * the ouput destination for this appender. 174 * 175 */ 176 public DailyRollingFileAppender(Layout layout, String filename, 177 String datePattern) throws IOException { 178 super(layout, filename, true); 179 this.datePattern = datePattern; 180 activateOptions(); 181 } 182 /** 183 * The <b>DatePattern</b> takes a string in the same format as expected by 184 * [EMAIL PROTECTED] SimpleDateFormat}. This options determines the rollover schedule. 185 */ 186 public void setDatePattern(String pattern) { 187 datePattern = pattern; 188 } 189 /** Returns the value of the <b>DatePattern</b> option. */ 190 public String getDatePattern() { 191 return datePattern; 192 } 193 private String tempFileName=null;//ÕâÊÇÎÒÌí¼ÓÒ»¸ö±äÁ¿£¬ÓÃÀ´¼Ç Òä¡°log4j.appender.LOGFILE.File=./logs/logfile.log¡± 194 public void activateOptions() { 195 if (datePattern != null && fileName != null) { 196 tempFileName=fileName;//°Ñ¡°./logs/logfile.log¡±¸½ ¸øtempFileName 197 now.setTime(System.currentTimeMillis()); 198 sdf = new SimpleDateFormat(datePattern); 199 int type = computeCheckPeriod(); 200 printPeriodicity(type); 201 rc.setType(type); 202 File file = new File(fileName); 203 //--------------ÎҸ͝µÄµØ·½--------------------- --- 204 Date d=new Date(); 205 if(file.exists()) 206 { 207 d=new Date(file.lastModified()); 208 } 209 scheduledFilename = fileName 210 + sdf.format(d);//¸ñʽ»¯ÎļþÃû 211 setFile(scheduledFilename);//°Ñ¸ñʽ»¯ºÃµÄÎļþÃû£¬ ÉèÖÃΪÈÕÖ¾ÎļþÃû 212 now.setTime(System.currentTimeMillis());//ÉèÖõ± ǰÈÕÆÚ 213 nextCheck = rc.getNextCheckMillis(now);//»ñȡϠ´Î¸üÐÂÎļþÃûµÄÈÕÆÚ 214 //--------------------------------------------- ------- 215 } else { 216 LogLog 217 .error("Either File or DatePattern options are not set for appender [" 218 + name + "]."); 219 } 220 super.activateOptions();//Õâ¸ö±ØÐë·Åµ½Õâ×îºó£¬ÒòΪËüÀïÃæ»áµ÷ Ó÷½·¨¡°this.setFile(datedFilename, false, this.bufferedIO, this.bufferSize);¡± 221 } 222 void printPeriodicity(int type) { 223 switch (type) { 224 case TOP_OF_MINUTE: 225 LogLog.debug("Appender [" + name + "] to be rolled every minute."); 226 break; 227 case TOP_OF_HOUR: 228 LogLog.debug("Appender [" + name 229 + "] to be rolled on top of every hour."); 230 break; 231 case HALF_DAY: 232 LogLog.debug("Appender [" + name 233 + "] to be rolled at midday and midnight."); 234 break; 235 case TOP_OF_DAY: 236 LogLog.debug("Appender [" + name + "] to be rolled at midnight."); 237 break; 238 case TOP_OF_WEEK: 239 LogLog.debug("Appender [" + name 240 + "] to be rolled at start of week."); 241 break; 242 case TOP_OF_MONTH: 243 LogLog.debug("Appender [" + name 244 + "] to be rolled at start of every month."); 245 break; 246 default: 247 LogLog.warn("Unknown periodicity for appender [" + name + "]."); 248 } 249 } 250 // This method computes the roll over period by looping over the 251 // periods, starting with the shortest, and stopping when the r0 is 252 // different from from r1, where r0 is the epoch formatted according 253 // the datePattern (supplied by the user) and r1 is the 254 // epoch+nextMillis(i) formatted according to datePattern. All date 255 // formatting is done in GMT and not local format because the test 256 // logic is based on comparisons relative to 1970-01-01 00:00:00 257 // GMT (the epoch). 258 int computeCheckPeriod() { 259 RollingCalendar rollingCalendar = new RollingCalendar (gmtTimeZone, 260 Locale.ENGLISH); 261 // set sate to 1970-01-01 00:00:00 GMT 262 Date epoch = new Date(0); 263 if (datePattern != null) { 264 for (int i = TOP_OF_MINUTE; i <= TOP_OF_MONTH; i++) { 265 SimpleDateFormat simpleDateFormat = new SimpleDateFormat( 266 datePattern); 267 simpleDateFormat.setTimeZone (gmtTimeZone); // do all date 268 // formatting in GMT 269 String r0 = simpleDateFormat.format (epoch); 270 rollingCalendar.setType(i); 271 Date next = new Date (rollingCalendar.getNextCheckMillis(epoch)); 272 String r1 = simpleDateFormat.format (next); 273 // System.out.println("Type = "+i+", r0 = "+r0+", r1 = "+r1); 274 if (r0 != null && r1 != null && ! r0.equals(r1)) { 275 return i; 276 } 277 } 278 } 279 return TOP_OF_TROUBLE; // Deliberately head for trouble... 280 } 281 /** 282 * Rollover the current file to a new file. 283 */ 284 void rollOver() throws IOException { 285 /* Compute filename, but only if datePattern is specified */ 286 if (datePattern == null) { 287 errorHandler.error("Missing DatePattern option in rollOver()."); 288 return; 289 } 290 String datedFilename =tempFileName+sdf.format(now);//µ± ǰµÄÎļþÃû 291 // It is too early to roll over because we are still within the 292 // bounds of the current interval. Rollover will occur once the 293 // next interval is reached. 294 if (scheduledFilename.equals(datedFilename)) { 295 return; 296 } 297 // close current file, and rename it to datedFilename 298 this.closeFile(); 299 File target = new File(datedFilename); 300 if (target.exists()) { 301 target.delete(); 302 } 303 //------------------------²»ÐèÒªÕâ¶Î´úÂë----------- 304 // File file = new File(fileName); 305 // boolean result = file.renameTo(target); 306 // if (result) { 307 // LogLog.debug(fileName + " -> " + scheduledFilename); 308 // } else { 309 // LogLog.error("Failed to rename [" + fileName + "] to [" 310 // + scheduledFilename + "]."); 311 // } 312 //------------------------------------------------ 313 try { 314 // This will also close the file. This is OK since multiple 315 // close operations are safe. 316 this.setFile(datedFilename, false, this.bufferedIO, this.bufferSize); 317 } catch (IOException e) { 318 errorHandler.error("setFile(" + fileName + ", false) call failed."); 319 } 320 scheduledFilename = datedFilename; 321 } 322 /** 323 * This method differentiates DailyRollingFileAppender from its super class. 324 * 325 * <p> 326 * Before actually logging, this method will check whether it is time to do 327 * a rollover. If it is, it will schedule the next rollover time and then 328 * rollover. 329 */ 330 protected void subAppend(LoggingEvent event) { 331 long n = System.currentTimeMillis(); 332 if (n >= nextCheck) { 333 now.setTime(n); 334 nextCheck = rc.getNextCheckMillis(now); 335 try { 336 rollOver(); 337 } catch (IOException ioe) { 338 LogLog.error("rollOver() failed.", ioe); 339 } 340 } 341 super.subAppend(event); 342 } 343 } 344 /** 345 * RollingCalendar is a helper class to DailyRollingFileAppender. Given a 346 * periodicity type and the current time, it computes the start of the next 347 * interval. 348 */ 349 class RollingCalendar extends GregorianCalendar { 350 int type = DailyRollingFileAppender.TOP_OF_TROUBLE; 351 RollingCalendar() { 352 super(); 353 } 354 RollingCalendar(TimeZone tz, Locale locale) { 355 super(tz, locale); 356 } 357 void setType(int type) { 358 this.type = type; 359 } 360 public long getNextCheckMillis(Date now) { 361 return getNextCheckDate(now).getTime(); 362 } 363 public Date getNextCheckDate(Date now) { 364 this.setTime(now); 365 switch (type) { 366 case DailyRollingFileAppender.TOP_OF_MINUTE: 367 this.set(Calendar.SECOND, 0); 368 this.set(Calendar.MILLISECOND, 0); 369 this.add(Calendar.MINUTE, 1); 370 break; 371 case DailyRollingFileAppender.TOP_OF_HOUR: 372 this.set(Calendar.MINUTE, 0); 373 this.set(Calendar.SECOND, 0); 374 this.set(Calendar.MILLISECOND, 0); 375 this.add(Calendar.HOUR_OF_DAY, 1); 376 break; 377 case DailyRollingFileAppender.HALF_DAY: 378 this.set(Calendar.MINUTE, 0); 379 this.set(Calendar.SECOND, 0); 380 this.set(Calendar.MILLISECOND, 0); 381 int hour = get(Calendar.HOUR_OF_DAY); 382 if (hour < 12) { 383 this.set(Calendar.HOUR_OF_DAY, 12); 384 } else { 385 this.set(Calendar.HOUR_OF_DAY, 0); 386 this.add(Calendar.DAY_OF_MONTH, 1); 387 } 388 break; 389 case DailyRollingFileAppender.TOP_OF_DAY: 390 this.set(Calendar.HOUR_OF_DAY, 0); 391 this.set(Calendar.MINUTE, 0); 392 this.set(Calendar.SECOND, 0); 393 this.set(Calendar.MILLISECOND, 0); 394 this.add(Calendar.DATE, 1); 395 break; 396 case DailyRollingFileAppender.TOP_OF_WEEK: 397 this.set(Calendar.DAY_OF_WEEK, getFirstDayOfWeek()); 398 this.set(Calendar.HOUR_OF_DAY, 0); 399 this.set(Calendar.MINUTE, 0); 400 this.set(Calendar.SECOND, 0); 401 this.set(Calendar.MILLISECOND, 0); 402 this.add(Calendar.WEEK_OF_YEAR, 1); 403 break; 404 case DailyRollingFileAppender.TOP_OF_MONTH: 405 this.set(Calendar.DATE, 1); 406 this.set(Calendar.HOUR_OF_DAY, 0); 407 this.set(Calendar.MINUTE, 0); 408 this.set(Calendar.SECOND, 0); 409 this.set(Calendar.MILLISECOND, 0); 410 this.add(Calendar.MONTH, 1); 411 break; 412 default: 413 throw new IllegalStateException("Unknown periodicity type."); 414 } 415 return getTime(); 416 } 417 } -- Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are the assignee for the bug, or are watching the assignee. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
