KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > log > RotateStream


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.log;
31
32 import com.caucho.config.ConfigException;
33 import com.caucho.config.types.Period;
34 import com.caucho.util.Alarm;
35 import com.caucho.util.AlarmListener;
36 import com.caucho.util.QDate;
37 import com.caucho.util.WeakAlarm;
38 import com.caucho.vfs.Path;
39 import com.caucho.vfs.StreamImpl;
40 import com.caucho.vfs.WriteStream;
41
42 import java.io.IOException JavaDoc;
43 import java.lang.ref.SoftReference JavaDoc;
44 import java.util.HashMap JavaDoc;
45 import java.util.logging.Level JavaDoc;
46 import java.util.logging.Logger JavaDoc;
47
48 /**
49  * Automatically-rotating streams. Normally, clients will call
50  * getStream instead of using the StreamImpl interface.
51  */

52 public class RotateStream extends StreamImpl implements AlarmListener {
53   private static final Logger JavaDoc log = Log.open(RotateStream.class);
54   
55   private static HashMap JavaDoc<Path,SoftReference JavaDoc<RotateStream>> _streams
56     = new HashMap JavaDoc<Path,SoftReference JavaDoc<RotateStream>>();
57   
58   private static HashMap JavaDoc<String JavaDoc,SoftReference JavaDoc<RotateStream>> _formatStreams
59     = new HashMap JavaDoc<String JavaDoc,SoftReference JavaDoc<RotateStream>>();
60
61   private final AbstractRolloverLog _rolloverLog = new AbstractRolloverLog();
62
63   private final Alarm _alarm = new WeakAlarm(this);
64
65   // calendar using the local timezone
66
private QDate _calendar = new QDate(true);
67
68   private volatile boolean _isInit;
69   private volatile boolean _isClosed;
70
71   /**
72    * Create rotate stream.
73    *
74    * @param path underlying log path
75    */

76   private RotateStream(Path path)
77   {
78     _rolloverLog.setPath(path);
79   }
80
81   /**
82    * Create rotate stream.
83    *
84    * @param path underlying log path
85    */

86   private RotateStream(String JavaDoc formatPath)
87     throws ConfigException
88   {
89     _rolloverLog.setPathFormat(formatPath);
90   }
91
92   /**
93    * Returns the rotate stream corresponding to this path
94    */

95   public static RotateStream create(Path path)
96   {
97     synchronized (_streams) {
98       SoftReference JavaDoc<RotateStream> ref = _streams.get(path);
99       RotateStream stream = ref != null ? ref.get() : null;
100
101       if (stream == null) {
102         stream = new RotateStream(path);
103
104         _streams.put(path, new SoftReference JavaDoc<RotateStream>(stream));
105       }
106
107       return stream;
108     }
109   }
110
111   /**
112    * Returns the rotate stream corresponding to this path
113    */

114   public static RotateStream create(String JavaDoc path)
115     throws ConfigException
116   {
117     synchronized (_formatStreams) {
118       SoftReference JavaDoc<RotateStream> ref = _formatStreams.get(path);
119       RotateStream stream = ref != null ? ref.get() : null;
120
121       if (stream == null) {
122         stream = new RotateStream(path);
123
124         _formatStreams.put(path, new SoftReference JavaDoc<RotateStream>(stream));
125       }
126
127       return stream;
128     }
129   }
130
131   /**
132    * Clears the streams.
133    */

134   public static void clear()
135   {
136     synchronized (_streams) {
137       for (SoftReference JavaDoc<RotateStream> streamRef : _streams.values()) {
138     try {
139       RotateStream stream = streamRef.get();
140
141       if (stream != null)
142         stream.closeImpl();
143     } catch (Throwable JavaDoc e) {
144     }
145       }
146       
147       _streams.clear();
148     }
149     
150     synchronized (_formatStreams) {
151       for (SoftReference JavaDoc<RotateStream> streamRef : _formatStreams.values()) {
152     try {
153       RotateStream stream = streamRef.get();
154
155       if (stream != null)
156         stream.closeImpl();
157     } catch (Throwable JavaDoc e) {
158     }
159       }
160       
161       _formatStreams.clear();
162     }
163   }
164
165   /**
166    * Returns the rollover log.
167    */

168   public AbstractRolloverLog getRolloverLog()
169   {
170     return _rolloverLog;
171   }
172
173   /**
174    * Sets the maximum number of rolled logs.
175    */

176   public void setMaxRolloverCount(int count)
177   {
178     _rolloverLog.setRolloverCount(count);
179   }
180
181   /**
182    * Sets the log rollover period, rounded up to the nearest hour.
183    *
184    * @param period the new rollover period in milliseconds.
185    */

186   public void setRolloverPeriod(long period)
187   {
188     _rolloverLog.setRolloverPeriod(new Period(period));
189   }
190
191   /**
192    * Sets the archive format.
193    *
194    * @param format the archive format.
195    */

196   public void setArchiveFormat(String JavaDoc format)
197   {
198     _rolloverLog.setArchiveFormat(format);
199   }
200
201   /**
202    * Initialize the stream, setting any logStream, System.out and System.err
203    * as necessary.
204    */

205   public void init()
206     throws IOException JavaDoc
207   {
208     synchronized (this) {
209       if (_isInit)
210     return;
211       _isInit = true;
212     }
213
214     _rolloverLog.init();
215
216     long now = Alarm.getCurrentTime();
217     
218     _alarm.queue(_rolloverLog.getNextRolloverCheckTime() - now);
219   }
220
221   /**
222    * Returns the Path associated with the stream.
223    */

224   public Path getPath()
225   {
226     return _rolloverLog.getPath();
227   }
228
229   /**
230    * True if the stream can write
231    */

232   public boolean canWrite()
233   {
234     return true;
235   }
236
237   /**
238    * Writes to the stream
239    */

240   public void write(byte []buffer, int offset, int length, boolean isEnd)
241     throws IOException JavaDoc
242   {
243     _rolloverLog.rollover();
244     _rolloverLog.write(buffer, offset, length);
245
246     // _alarm.queue(1000);
247
_rolloverLog.rollover();
248   }
249
250   /**
251    * Gets the current write stream
252    */

253   public WriteStream getStream()
254   {
255     return new WriteStream(this);
256   }
257
258   /**
259    * Flushes the underlying stream.
260    */

261   public void flush()
262     throws IOException JavaDoc
263   {
264     _rolloverLog.flush();
265     _rolloverLog.rollover();
266
267     long now = Alarm.getCurrentTime();
268
269     _alarm.queue(_rolloverLog.getNextRolloverCheckTime() - now);
270   }
271
272   /**
273    * The close call does nothing since the rotate stream is shared for
274    * many logs.
275    */

276   public void close()
277   {
278   }
279
280   public void handleAlarm(Alarm alarm)
281   {
282     try {
283       _rolloverLog.flush();
284       _rolloverLog.rollover();
285     } catch (Throwable JavaDoc e) {
286       log.log(Level.FINE, e.toString(), e);
287     } finally {
288       if (! _isClosed) {
289     long now = Alarm.getCurrentTime();
290
291     _alarm.queue(_rolloverLog.getNextRolloverCheckTime() - now);
292       }
293     }
294   }
295
296   /**
297    * Closes the underlying stream.
298    */

299   private void closeImpl()
300   {
301     try {
302       _isClosed = true;
303       _rolloverLog.close();
304     } catch (Throwable JavaDoc e) {
305       log.log(Level.FINE, e.toString(), e);
306     }
307   }
308
309   /**
310    * finalize.
311    */

312   public void finalize()
313   {
314     closeImpl();
315   }
316 }
317
Popular Tags