KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > protomatter > syslog > TimeRolloverLog


1 package com.protomatter.syslog;
2
3 /**
4  * The Protomatter Software License, Version 1.0
5  * derived from The Apache Software License, Version 1.1
6  *
7  * Copyright (c) 1998-2002 Nate Sammons. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution,
22  * if any, must include the following acknowledgment:
23  * "This product includes software developed for the
24  * Protomatter Software Project
25  * (http://protomatter.sourceforge.net/)."
26  * Alternately, this acknowledgment may appear in the software itself,
27  * if and wherever such third-party acknowledgments normally appear.
28  *
29  * 4. The names "Protomatter" and "Protomatter Software Project" must
30  * not be used to endorse or promote products derived from this
31  * software without prior written permission. For written
32  * permission, please contact support@protomatter.com.
33  *
34  * 5. Products derived from this software may not be called "Protomatter",
35  * nor may "Protomatter" appear in their name, without prior written
36  * permission of the Protomatter Software Project
37  * (support@protomatter.com).
38  *
39  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
40  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
41  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42  * DISCLAIMED. IN NO EVENT SHALL THE PROTOMATTER SOFTWARE PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
45  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
46  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
48  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
49  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  */

52
53 import java.io.*;
54 import java.net.*;
55 import java.util.*;
56 import java.util.zip.*;
57 import java.text.*;
58 import com.protomatter.util.*;
59
60 /**
61  * A logger that will roll files when the minute, hour, day, week or
62  * month change.
63  *
64  * @see com.protomatter.syslog.xml.TimeRolloverLog_Helper XML configuration class
65  */

66
67 public class TimeRolloverLog
68             extends BasicLogger
69 {
70     /**
71      * Roll logs on the minute.
72      */

73     public static int ROLL_MINUTELY = 0;
74
75     /**
76      * Roll logs on the hour.
77      */

78     public static int ROLL_HOURLY = 1;
79
80     /**
81      * Roll logs at midnight.
82      */

83     public static int ROLL_DAILY = 2;
84
85     /**
86      * Roll logs at midnight at the end of the month.
87      */

88     public static int ROLL_MONTHLY = 3;
89
90     /**
91      * Roll logs weekly at midnight on a given day (default is monday).
92      */

93     public static int ROLL_WEEKLY = 4;
94
95     private Writer out = null;
96     private DateFormat namefmt; // format for dates in name of log files
97
private Object JavaDoc syncObject = new Object JavaDoc();
98     private String JavaDoc basename;
99     private long nextRolloverTime = 0;
100     private int rolltype;
101     private boolean append = true;
102     private String JavaDoc extension = "";
103     private String JavaDoc nameFormatString;
104     private boolean autoFlush = true;
105     private File currentFile = null;
106     private File previousFile = null;
107
108     // day of week to roll if we're rolling weekly
109
private int weeklyRollDay = Calendar.MONDAY;
110
111     /**
112      * Get the roll type.
113      */

114     public int getRollType()
115     {
116         return this.rolltype;
117     }
118
119     /**
120      * Set the roll type.
121      */

122     public void setRollType(int type)
123     {
124         this.rolltype = type;
125     }
126
127     /**
128      * Get the day we roll logs on if we're rolling weekly.
129      */

130     public int getWeeklyRollDay()
131     {
132         return this.weeklyRollDay;
133     }
134
135     /**
136      * Set the day we roll logs on if we're rolling weekly.
137      * This should be <tt>Calendar.MONDAY</tt>, etc.
138      */

139     public void setWeeklyRollDay(int day)
140     {
141         if ( (day != Calendar.SUNDAY) &&
142              (day != Calendar.MONDAY) &&
143              (day != Calendar.TUESDAY) &&
144              (day != Calendar.WEDNESDAY) &&
145              (day != Calendar.THURSDAY) &&
146              (day != Calendar.FRIDAY) &&
147              (day != Calendar.SATURDAY))
148         {
149             throw new IllegalArgumentException JavaDoc(MessageFormat.format(
150                   Syslog.getResourceString(MessageConstants.TIMEROLLOVERLOG_BAD_ROLL_DAY_VALUE_MESSAGE),
151                   new Object JavaDoc[] { "Calendar.MONDAY", "Calendar.SUNDAY" }));
152         }
153         this.weeklyRollDay = day;
154     }
155
156     /**
157      * Get the base name for the log file.
158      */

159     public String JavaDoc getBaseFilename()
160     {
161         return this.basename;
162     }
163
164     /**
165      * Set the base name for the log file.
166      */

167     public void setBaseFilename(String JavaDoc basename)
168     {
169         this.basename = basename;
170     }
171
172     /**
173      * Get the file extension to use.
174      */

175     public String JavaDoc getFileExtension()
176     {
177         return this.extension;
178     }
179
180     /**
181      * Set the file extension to use.
182      */

183     public void setFileExtension(String JavaDoc extension)
184     {
185         this.extension = extension;
186     }
187
188     /**
189      * Set if we will append to files that already exist.
190      */

191     public void setAppend(boolean append)
192     {
193         this.append = append;
194     }
195
196     /**
197      * Determine if we will append to files that already exist.
198      */

199     public boolean getAppend()
200     {
201         return this.append;
202     }
203
204     /**
205      * Determine if we will automatically flush the writer.
206      */

207     public boolean getAutoFlush()
208     {
209         return this.autoFlush;
210     }
211
212     /**
213      * Should we will automatically flush the writer?
214      */

215     public void setAutoFlush(boolean flush)
216     {
217         this.autoFlush = flush;
218     }
219
220     /**
221      * Write log information to the given log, roll when specified.
222      * The file written to will actually be "basenamedate" where
223      * date is the date formatted as "yyyy.MM.dd-HH.mm.ss"
224      */

225     public TimeRolloverLog(String JavaDoc basename, int roll, String JavaDoc extension)
226     {
227         this(basename, extension, roll, "yyyy.MM.dd-HH.mm.ss", true, false);
228     }
229
230     /**
231      * Write log information to the given log, roll when specified.
232      * The file written to will actually be "basenamedateextension" where
233      * date is the date formatted using the given nameformat.
234      */

235     public TimeRolloverLog(String JavaDoc basename, String JavaDoc extension, int roll, String JavaDoc nameformat, boolean append, boolean autoFlush)
236     {
237         this();
238
239         if (roll < 0 || roll > 4)
240             throw new IllegalArgumentException JavaDoc(MessageFormat.format(
241                                                    Syslog.getResourceString(MessageConstants.TIMEROLLOVERLOG_BAD_ROLL_VALUE_MESSAGE),
242                                                    new Object JavaDoc[] { "0", "4" }));
243
244         this.basename = basename;
245         this.extension = extension;
246         this.rolltype = roll;
247         setNameFormat(nameformat);
248         this.append = append;
249         this.autoFlush = autoFlush;
250         rollover(new Date());
251     }
252
253     /**
254      * You must call the configure() method to configure this logger
255      * if you use this constructor.
256      */

257     public TimeRolloverLog()
258     {
259         super();
260     }
261
262     /**
263      * Roll the logs now.
264      */

265     private void rollover()
266     {
267         if (nextRolloverTime == 0)
268             nextRolloverTime = getNextRolloverTime().getTime();
269
270         rollover(new Date(nextRolloverTime));
271     }
272
273     /**
274      * Get the file we were writing to before we rolled.
275      */

276     public File getPreviousFile()
277     {
278         return this.previousFile;
279     }
280
281     /**
282      * Get the file currently being written to.
283      */

284     public File getCurrentFile()
285     {
286         return this.currentFile;
287     }
288
289     /**
290      * Roll the logs. This should only be called by configuration helpers.
291      */

292     public void rollover(Date d)
293     {
294         synchronized(syncObject)
295         {
296             if (out != null)
297             {
298                 try
299                 {
300                     out.write(formatter.getLogFooter());
301                 }
302                 catch (IOException x)
303                 {
304                     x.printStackTrace();
305                 }
306
307             }
308             resetDateFormat();
309             Writer old = out;
310
311             try
312             {
313                 File f = new File(basename + namefmt.format(d) + extension);
314                 out = new BufferedWriter(
315                           new FileWriter(f.getCanonicalPath(), append));
316                 out.write(formatter.getLogHeader());
317
318                 if (old != null)
319                 {
320                     old.flush();
321                     old.close();
322                 }
323
324                 this.previousFile = this.currentFile;
325                 this.currentFile = f;
326             }
327             catch (IOException x)
328             {
329                 System.err.println(MessageFormat.format(
330                                        Syslog.getResourceString(MessageConstants.TIMEROLLOVER_CANNOT_ROLL_MESSAGE),
331                                        new Object JavaDoc[] { "IOException" }));
332                 x.printStackTrace();
333                 out = old;
334             }
335
336             Date date = getNextRolloverTime();
337             nextRolloverTime = date.getTime(); // set the next rollover time.
338
}
339     }
340
341     /**
342      * Set the dateformat part of the name.
343      */

344     public void setNameFormat(String JavaDoc fmt)
345     {
346         this.nameFormatString = fmt;
347         namefmt = new SimpleDateFormat(fmt);
348         namefmt.setTimeZone(TimeZone.getDefault());
349     }
350
351     /**
352      * Get the dateformat part of the name.
353      */

354     public String JavaDoc getNameFormat()
355     {
356         return this.nameFormatString;
357     }
358
359     public final void log(SyslogMessage message)
360     {
361         StringBuffer JavaDoc b =
362             (message.detail == null) ?
363             (new StringBuffer JavaDoc(128)) :
364             (new StringBuffer JavaDoc(256));
365         formatLogEntry(b, message);
366
367         synchronized (syncObject)
368         {
369             if (message.time >= nextRolloverTime)
370                 rollover();
371
372             try
373             {
374                 out.write(b.toString());
375
376                 if (autoFlush)
377                     out.flush();
378             }
379             catch (IOException x)
380             {
381                 x.printStackTrace();
382             }
383
384         }
385     }
386
387     /**
388      * Calculate the next date to rollover the logs
389      * based on how often we should roll.
390      */

391     public Date getNextRolloverTime()
392     {
393         GregorianCalendar now = new GregorianCalendar();
394         GregorianCalendar c = null;
395
396         if (rolltype == ROLL_MINUTELY)
397         {
398             now.add(Calendar.MINUTE, 1);
399             c = new GregorianCalendar(
400                     now.get(Calendar.YEAR),
401                     now.get(Calendar.MONTH),
402                     now.get(Calendar.DATE),
403                     now.get(Calendar.HOUR_OF_DAY),
404                     now.get(Calendar.MINUTE)
405                 );
406         }
407         else if (rolltype == ROLL_HOURLY)
408         {
409             now.add(Calendar.HOUR_OF_DAY, 1);
410             c = new GregorianCalendar(
411                     now.get(Calendar.YEAR),
412                     now.get(Calendar.MONTH),
413                     now.get(Calendar.DATE),
414                     now.get(Calendar.HOUR_OF_DAY),
415                     0
416                 );
417         }
418         else if (rolltype == ROLL_DAILY)
419         {
420             now.add(Calendar.DATE, 1);
421             c = new GregorianCalendar(
422                     now.get(Calendar.YEAR),
423                     now.get(Calendar.MONTH),
424                     now.get(Calendar.DATE),
425                     0,
426                     0
427                 );
428         }
429         else if (rolltype == ROLL_MONTHLY)
430         {
431             now.add(Calendar.MONTH, 1);
432             c = new GregorianCalendar(
433                     now.get(Calendar.YEAR),
434                     now.get(Calendar.MONTH),
435                     1,
436                     0,
437                     0
438                 );
439         }
440         else if (rolltype == ROLL_WEEKLY)
441         {
442             // look for the next day that is the
443
// given weekly roll day
444
while (now.get(Calendar.DAY_OF_WEEK) != weeklyRollDay)
445             {
446                 now.add(Calendar.DATE, 1);
447             }
448             c = new GregorianCalendar(
449                     now.get(Calendar.YEAR),
450                     now.get(Calendar.MONTH),
451                     now.get(Calendar.DATE),
452                     0,
453                     0
454                 );
455             if (c.getTime().before(new Date()))
456             {
457                 c.add(Calendar.DATE, 7);
458             }
459         }
460
461         return c.getTime();
462     }
463
464     /**
465      * Cleanup and prepare for shutdown.
466      */

467     public void shutdown()
468     {
469         if (out != null)
470         {
471             try
472             {
473                 out.write(formatter.getLogFooter());
474                 out.flush();
475                 out.close();
476                 out = null;
477             }
478             catch (IOException x)
479             {
480                 x.printStackTrace();
481             }
482
483         }
484     }
485
486     public void flush()
487     {
488         try
489         {
490             if (out != null)
491                 out.flush();
492         }
493         catch (IOException x)
494         {
495             x.printStackTrace();
496         }
497     }
498 }
499
Popular Tags