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&uuml;lc&uuml;
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]

Reply via email to