KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > log4j > DailyFileAppender1


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
17
18
19 package org.apache.log4j;
20
21 import java.io.IOException JavaDoc;
22 import java.io.Writer JavaDoc;
23 import java.io.FileWriter JavaDoc;
24 import java.io.File JavaDoc;
25 import java.io.OutputStream JavaDoc;
26 import java.io.OutputStreamWriter JavaDoc;
27 import java.text.SimpleDateFormat JavaDoc;
28 import java.util.Date JavaDoc;
29 import org.apache.log4j.helpers.OptionConverter;
30 import org.apache.log4j.helpers.QuietWriter;
31 import org.apache.log4j.helpers.CountingQuietWriter;
32 import org.apache.log4j.spi.LoggingEvent;
33 import org.apache.log4j.spi.ErrorCode;
34
35 /**
36    DailyFileAppender extends FileAppender to use filenames formatted with
37    date/time information. The filename is recomputed every day at midnight.
38    Note that the filename doesn't have to change every day, making it possible
39    to have logfiles which are per-week or per-month.
40
41    The appender computes the proper filename using the formats specified in
42    <a HREF="http://java.sun.com/j2se/1.3/docs/api/java/text/SimpleDateFormat.html">
43    java.text.SimpleDateFormat</a>. The format requires that most static text is
44    enclosed in single quotes, which are removed. The examples below show how
45    quotes are used to embed static information in the format.
46
47    Sample filenames:
48
49 <code>
50      Filename pattern Filename
51      "'/logs/trace-'yyyy-MM-dd'.log'" /logs/trace-2000-12-31.log
52      "'/logs/trace-'yyyy-ww'.log'" /logs/trace-2000-52.log
53 </code>
54
55    @author <a HREF="mailto:eirik.lygre@evita.no">Eirik Lygre</a>
56 */

57 public class DailyFileAppender extends FileAppender {
58
59   /**
60      A string constant used in naming the option for setting the
61      filename pattern. Current value of this string constant is
62      <strong>FileNamePattern</strong>.
63    */

64   static final public String JavaDoc FILE_NAME_PATTERN_OPTION = "FilePattern";
65   
66   /**
67      The filename pattern
68   */

69   private String JavaDoc fileNamePattern = null;
70
71   /**
72      The actual formatted filename that is currently being written to
73   */

74   private String JavaDoc currentFileName = null;
75
76   /**
77      The timestamp when we shall next recompute the filename
78   */

79   private long nextFilenameComputingMillis = System.currentTimeMillis () - 1;
80
81   /**
82      The default constructor does no longer set a default layout nor a
83      default output target. */

84   public
85   DailyFileAppender() {
86   }
87
88   /**
89     Instantiate a RollingFileAppender and open the file designated by
90     <code>filename</code>. The opened filename will become the ouput
91     destination for this appender.
92
93     <p>If the <code>append</code> parameter is true, the file will be
94     appended to. Otherwise, the file desginated by
95     <code>filename</code> will be truncated before being opened.
96   */

97   public DailyFileAppender (Layout layout,String JavaDoc filename,boolean append) throws IOException JavaDoc {
98     super(layout, filename, append);
99   }
100
101   /**
102      Instantiate a FileAppender and open the file designated by
103     <code>filename</code>. The opened filename will become the output
104     destination for this appender.
105
106     <p>The file will be appended to. */

107   public DailyFileAppender (Layout layout,String JavaDoc filename) throws IOException JavaDoc {
108     super(layout, filename);
109   }
110   
111   /**
112      Set the current output file.
113
114      The function will compute a new filename, and open a new file only
115      when the name has changed.
116
117      The function is automatically called once a day, to allow for
118      daily files -- the purpose of this class.
119   */

120
121   public
122   synchronized
123   void setFile(String JavaDoc fileName, boolean append) throws IOException JavaDoc {
124
125     /* Compute filename, but only if fileNamePattern is specified */
126     if (fileNamePattern == null) {
127       errorHandler.error("Missing file pattern (" + FILE_NAME_PATTERN_OPTION + ") in setFile().");
128       return;
129     }
130
131     Date JavaDoc now = new Date JavaDoc();
132
133     fileName = new SimpleDateFormat JavaDoc(fileNamePattern).format (now);
134     if (fileName.equals(currentFileName))
135       return;
136
137     /* Set up next filename checkpoint */
138     DailyFileAppenderCalendar c = new DailyFileAppenderCalendar();
139     c.rollToNextDay ();
140     nextFilenameComputingMillis = c.getTimeInMillis ();
141
142     currentFileName = fileName;
143
144     super.setFile(fileName, append);
145   }
146
147   /**
148      This method differentiates RollingFileAppender from its super
149      class.
150
151   */

152   protected
153   void subAppend(LoggingEvent event) {
154      
155      if (System.currentTimeMillis () >= nextFilenameComputingMillis) {
156       try {
157         setFile (super.fileName, super.fileAppend);
158       }
159       catch(IOException JavaDoc e) {
160         System.err.println("setFile(null, false) call failed.");
161         e.printStackTrace();
162       }
163     }
164
165     super.subAppend(event);
166   }
167
168   /**
169      Retuns the option names for this component, namely {@link
170      #FILE_NAME_PATTERN_OPTION} in
171      addition to the options of {@link FileAppender#getOptionStrings
172      FileAppender}.
173   */

174   public
175   String JavaDoc[] getOptionStrings() {
176
177     return OptionConverter.concatanateArrays(super.getOptionStrings(),
178          new String JavaDoc[] {FILE_NAME_PATTERN_OPTION});
179   }
180
181   /**
182      Set the options for the appender
183   */

184   public
185   void setOption(String JavaDoc key, String JavaDoc value) {
186     super.setOption(key, value);
187     if(key.equalsIgnoreCase(FILE_NAME_PATTERN_OPTION)) {
188       fileNamePattern = value;
189     }
190   }
191   
192   /**
193      If the a value for {@link #FILE_OPTION} is non-null, then {@link
194      #setFile} is called with the values of {@link #FILE_OPTION} and
195      {@link #APPEND_OPTION}.
196
197      @since 0.8.1 */

198   public
199   void activateOptions() {
200     try {
201        setFile(null, super.fileAppend);
202     }
203     catch(java.io.IOException JavaDoc e) {
204        errorHandler.error("setFile(null,"+fileAppend+") call failed.",
205                e, ErrorCode.FILE_OPEN_FAILURE);
206     }
207   }
208 }
209
210 /**
211    DailyFileAppenderCalendar is a helper class to DailyFileAppender. Using
212    this class, it is easy to compute and access the next Millis()
213  
214    It subclasses the standard
215    <a HREF="http://java.sun.com/j2se/1.3/docs/api/java/text/GregorianCalendar.html">
216    java.util.GregorianCalendar</a>-object, to allow access to the protected
217    function getTimeInMillis(), which it then exports.
218
219    @author <a HREF="mailto:eirik.lygre@evita.no">Eirik Lygre</a>
220 */

221 class DailyFileAppenderCalendar extends java.util.GregorianCalendar JavaDoc
222 {
223   /**
224      Returns the current time in Millis
225   */

226   public long getTimeInMillis() {
227     return super.getTimeInMillis();
228   }
229
230   /**
231      Roll the date to the next hour, with minute, second and millisecond
232      set to zero.
233   */

234   public void rollToNextDay () {
235     this.add(java.util.Calendar.DATE, 0);
236     this.add(java.util.Calendar.HOUR, 0);
237     this.set(java.util.Calendar.MINUTE, 0);
238     this.set(java.util.Calendar.SECOND, 0);
239     this.set(java.util.Calendar.MILLISECOND, 0);
240   }
241 }
Popular Tags