KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ejbca > appserver > jboss > ScriptrunningDailyRollingFileAppender


1 package org.ejbca.appserver.jboss;
2
3 import java.io.File JavaDoc;
4 import java.io.IOException JavaDoc;
5 import java.text.SimpleDateFormat JavaDoc;
6 import java.util.Date JavaDoc;
7 import java.util.Locale JavaDoc;
8 import java.util.TimeZone JavaDoc;
9
10 import org.apache.log4j.FileAppender;
11 import org.apache.log4j.Layout;
12 import org.apache.log4j.helpers.LogLog;
13 import org.apache.log4j.spi.LoggingEvent;
14
15 /**
16  * A shameless copy of DailyRollingFileAppender from log4j and merged (also shamelessly)
17  * with DailyRollingFileAppender from jboss.
18  *
19  * This was the only way I could find to implement the desired functionality.
20  *
21  * @author tomas
22  * @version $Id: ScriptrunningDailyRollingFileAppender.java,v 1.2 2006/12/04 12:44:38 anatom Exp $
23  */

24 public class ScriptrunningDailyRollingFileAppender extends FileAppender {
25
26     // The code assumes that the following constants are in a increasing
27
// sequence.
28
static final int TOP_OF_TROUBLE=-1;
29     static final int TOP_OF_MINUTE = 0;
30     static final int TOP_OF_HOUR = 1;
31     static final int HALF_DAY = 2;
32     static final int TOP_OF_DAY = 3;
33     static final int TOP_OF_WEEK = 4;
34     static final int TOP_OF_MONTH = 5;
35
36     private Thread JavaDoc scriptThread;
37
38     /**
39          The date pattern. By default, the pattern is set to
40          "'.'yyyy-MM-dd" meaning daily rollover.
41      */

42     private String JavaDoc datePattern = "'.'yyyy-MM-dd";
43
44     /** The script to run after rotating log */
45     private String JavaDoc script;
46
47     /**
48          The log file will be renamed to the value of the
49          scheduledFilename variable when the next interval is entered. For
50          example, if the rollover period is one hour, the log file will be
51          renamed to the value of "scheduledFilename" at the beginning of
52          the next hour.
53
54          The precise time when a rollover occurs depends on logging
55          activity.
56      */

57     private String JavaDoc scheduledFilename;
58
59     /**
60          The next time we estimate a rollover should occur. */

61     private long nextCheck = System.currentTimeMillis () - 1;
62
63     Date JavaDoc now = new Date JavaDoc();
64
65     SimpleDateFormat JavaDoc sdf;
66
67     RollingCalendar rc = new RollingCalendar();
68
69     int checkPeriod = TOP_OF_TROUBLE;
70
71     // The gmtTimeZone is used only in computeCheckPeriod() method.
72
static final TimeZone JavaDoc gmtTimeZone = TimeZone.getTimeZone("GMT");
73
74
75     /**
76          The default constructor does nothing. */

77     public ScriptrunningDailyRollingFileAppender() {
78     }
79
80     /**
81         Instantiate a <code>DailyRollingFileAppender</code> and open the
82         file designated by <code>filename</code>. The opened filename will
83         become the ouput destination for this appender.
84
85      */

86     public ScriptrunningDailyRollingFileAppender (Layout layout, String JavaDoc filename,
87             String JavaDoc datePattern) throws IOException JavaDoc {
88         super(layout, filename, true);
89         this.datePattern = datePattern;
90         activateOptions();
91     }
92
93     /** This is from org.jboss.logging.appender.DailyRollingFileAppender,
94      * which will make the directory structure for the set log file.
95      */

96     public void setFile(final String JavaDoc filename)
97     {
98         org.jboss.logging.appender.FileAppender.Helper.makePath(filename);
99         super.setFile(filename);
100     }
101
102     /**
103          The <b>DatePattern</b> takes a string in the same format as
104          expected by {@link SimpleDateFormat}. This options determines the
105          rollover schedule.
106      */

107     public void setDatePattern(String JavaDoc pattern) {
108         datePattern = pattern;
109     }
110
111     /** Returns the value of the <b>DatePattern</b> option. */
112     public String JavaDoc getDatePattern() {
113         return datePattern;
114     }
115     
116     public void activateOptions() {
117         super.activateOptions();
118         if(datePattern != null && fileName != null) {
119             now.setTime(System.currentTimeMillis());
120             sdf = new SimpleDateFormat JavaDoc(datePattern);
121             int type = computeCheckPeriod();
122             printPeriodicity(type);
123             rc.setType(type);
124             File JavaDoc file = new File JavaDoc(fileName);
125             scheduledFilename = fileName+sdf.format(new Date JavaDoc(file.lastModified()));
126
127         } else {
128             LogLog.error("Either File or DatePattern options are not set for appender ["+name+"].");
129         }
130         if (script == null) {
131             LogLog.error("Script option is not set for appender ["+name+"].");
132         }
133     }
134
135     void printPeriodicity(int type) {
136         switch(type) {
137         case TOP_OF_MINUTE:
138             LogLog.debug("Appender ["+name+"] to be rolled every minute.");
139             break;
140         case TOP_OF_HOUR:
141             LogLog.debug("Appender ["+name
142                     +"] to be rolled on top of every hour.");
143             break;
144         case HALF_DAY:
145             LogLog.debug("Appender ["+name
146                     +"] to be rolled at midday and midnight.");
147             break;
148         case TOP_OF_DAY:
149             LogLog.debug("Appender ["+name
150                     +"] to be rolled at midnight.");
151             break;
152         case TOP_OF_WEEK:
153             LogLog.debug("Appender ["+name
154                     +"] to be rolled at start of week.");
155             break;
156         case TOP_OF_MONTH:
157             LogLog.debug("Appender ["+name
158                     +"] to be rolled at start of every month.");
159             break;
160         default:
161             LogLog.warn("Unknown periodicity for appender ["+name+"].");
162         }
163     }
164
165
166     // This method computes the roll over period by looping over the
167
// periods, starting with the shortest, and stopping when the r0 is
168
// different from from r1, where r0 is the epoch formatted according
169
// the datePattern (supplied by the user) and r1 is the
170
// epoch+nextMillis(i) formatted according to datePattern. All date
171
// formatting is done in GMT and not local format because the test
172
// logic is based on comparisons relative to 1970-01-01 00:00:00
173
// GMT (the epoch).
174

175     int computeCheckPeriod() {
176         RollingCalendar rollingCalendar = new RollingCalendar(gmtTimeZone, Locale.ENGLISH);
177         // set sate to 1970-01-01 00:00:00 GMT
178
Date JavaDoc epoch = new Date JavaDoc(0);
179         if(datePattern != null) {
180             for(int i = TOP_OF_MINUTE; i <= TOP_OF_MONTH; i++) {
181                 SimpleDateFormat JavaDoc simpleDateFormat = new SimpleDateFormat JavaDoc(datePattern);
182                 simpleDateFormat.setTimeZone(gmtTimeZone); // do all date formatting in GMT
183
String JavaDoc r0 = simpleDateFormat.format(epoch);
184                 rollingCalendar.setType(i);
185                 Date JavaDoc next = new Date JavaDoc(rollingCalendar.getNextCheckMillis(epoch));
186                 String JavaDoc r1 = simpleDateFormat.format(next);
187                 if(r0 != null && r1 != null && !r0.equals(r1)) {
188                     return i;
189                 }
190             }
191         }
192         return TOP_OF_TROUBLE; // Deliberately head for trouble...
193
}
194
195     /**
196          Rollover the current file to a new file.
197      */

198     void rollOver() throws IOException JavaDoc {
199
200         /* Compute filename, but only if datePattern is specified */
201         if (datePattern == null) {
202             errorHandler.error("Missing DatePattern option in rollOver().");
203             return;
204         }
205
206         String JavaDoc datedFilename = fileName+sdf.format(now);
207         // It is too early to roll over because we are still within the
208
// bounds of the current interval. Rollover will occur once the
209
// next interval is reached.
210
if (scheduledFilename.equals(datedFilename)) {
211             return;
212         }
213
214         // close current file, and rename it to datedFilename
215
this.closeFile();
216
217         File JavaDoc target = new File JavaDoc(scheduledFilename);
218         if (target.exists()) {
219             target.delete();
220         }
221
222         File JavaDoc file = new File JavaDoc(fileName);
223         boolean result = file.renameTo(target);
224         if(result) {
225             LogLog.debug(fileName +" -> "+ scheduledFilename);
226         } else {
227             LogLog.error("Failed to rename ["+fileName+"] to ["+scheduledFilename+"].");
228         }
229
230         try {
231             // This will also close the file. This is OK since multiple
232
// close operations are safe.
233
this.setFile(fileName, false, this.bufferedIO, this.bufferSize);
234         }
235         catch(IOException JavaDoc e) {
236             errorHandler.error("setFile("+fileName+", false) call failed.");
237         }
238         if ( (script != null) && (script.length() > 0) ) {
239                 // Now call the script
240
// Check first if an old instance of the thread is blocking
241
if ( (scriptThread != null) && scriptThread.isAlive() ) {
242                     System.out.println("Stopping old hanging signerthread");
243                     scriptThread.interrupt();
244                 }
245                 scriptThread = new Thread JavaDoc(new ScriptThread(script, scheduledFilename));
246                 scriptThread.start();
247         }
248
249         scheduledFilename = datedFilename;
250     }
251
252     /**
253      * This method differentiates DailyRollingFileAppender from its
254      * super class.
255      *
256      * <p>Before actually logging, this method will check whether it is
257      * time to do a rollover. If it is, it will schedule the next
258      * rollover time and then rollover.
259      * */

260     protected void subAppend(LoggingEvent event) {
261         long n = System.currentTimeMillis();
262         if (n >= nextCheck) {
263             now.setTime(n);
264             nextCheck = rc.getNextCheckMillis(now);
265             try {
266                 rollOver();
267             }
268             catch(IOException JavaDoc ioe) {
269                 LogLog.error("rollOver() failed.", ioe);
270             }
271         }
272         super.subAppend(event);
273     }
274
275     public String JavaDoc getScript() {
276         return script;
277     }
278
279     public void setScript(String JavaDoc script) {
280         this.script = script;
281     }
282
283 }
284
285 class ScriptThread implements Runnable JavaDoc {
286     private String JavaDoc script;
287     private String JavaDoc infile;
288     public ScriptThread(String JavaDoc script, String JavaDoc infile) {
289         this.script = script;
290         this.infile = infile;
291     }
292     public void run() {
293         
294         try {
295             Runtime JavaDoc rt =Runtime.getRuntime();
296             String JavaDoc s = script +" "+infile;
297             rt.exec(s);
298             /*
299             Process p = rt.exec(s);
300             try {
301                 int e = p.exitValue();
302                 if (e != 0) {
303                     LogLog.error("Script did not terminate with 0 return value.");
304                     System.out.println("Script did not terminate with 0 return value.");
305                 }
306             } catch (IllegalThreadStateException e) {
307                 LogLog.error("Script did not terminate within the timeout, 60 seconds.");
308                 System.out.println("Script did not terminate within the timeout, 60 seconds.");
309                 p.destroy();
310             }
311             */

312         } catch (Exception JavaDoc e) {
313             LogLog.error("Exception caught while running script: ", e);
314             e.printStackTrace();
315         }
316         
317     }
318     
319 }
320
321
Popular Tags