KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > logging > jdk > handlers > WriterHandler


1 package org.jboss.logging.jdk.handlers;
2
3 import java.io.BufferedWriter JavaDoc;
4 import java.io.IOException JavaDoc;
5 import java.io.OutputStream JavaDoc;
6 import java.io.OutputStreamWriter JavaDoc;
7 import java.io.UnsupportedEncodingException JavaDoc;
8 import java.io.Writer JavaDoc;
9 import java.util.logging.ErrorManager JavaDoc;
10 import java.util.logging.Formatter JavaDoc;
11 import java.util.logging.LogRecord JavaDoc;
12
13 /**
14  * A base handler that outputs log messages to a Writer
15  *
16  * @author Scott.Stark@jboss.org
17  * @version $Revision: 1958 $
18  */

19 public class WriterHandler extends HandlerSkeleton
20 {
21    /**
22     * Immediate flush means that the underlying writer or output stream
23     * will be flushed at the end of each append operation. Immediate
24     * flush is slower but ensures that each append request is actually
25     * written. If <code>immediateFlush</code> is set to
26     * <code>false</code>, then there is a good chance that the last few
27     * logs events are not actually written to persistent media if and
28     * when the application crashes.
29     * <p/>
30     * <p>The <code>immediateFlush</code> variable is set to
31     * <code>true</code> by default.
32     */

33    protected boolean immediateFlush = true;
34    /**
35     * Do we do bufferedIO?
36     */

37    protected boolean bufferedIO = false;
38    /**
39     * Determines the size of IO buffer be. Default is 8K.
40     */

41    protected int bufferSize = 8 * 1024;
42
43    private OutputStream JavaDoc msgOutput;
44    private Writer JavaDoc msgWriter;
45    /**
46     * Has the
47     */

48    private boolean wroteHeader;
49
50    public WriterHandler()
51    {
52       super();
53    }
54
55    public WriterHandler(OutputStream JavaDoc output, Formatter JavaDoc formatter)
56    {
57       setFormatter(formatter);
58       setOutputStream(output);
59    }
60
61    /**
62     * If the <b>ImmediateFlush</b> option is set to
63     * <code>true</code>, the appender will flush at the end of each
64     * write. This is the default behavior. If the option is set to
65     * <code>false</code>, then the underlying stream can defer writing
66     * to physical medium to a later time.
67     * <p/>
68     * <p>Avoiding the flush operation at the end of each append results in
69     * a performance gain of 10 to 20 percent. However, there is safety
70     * tradeoff involved in skipping flushing. Indeed, when flushing is
71     * skipped, then it is likely that the last few log events will not
72     * be recorded on disk when the application exits. This is a high
73     * price to pay even for a 20% performance gain.
74     */

75    public void setImmediateFlush(boolean value)
76    {
77       immediateFlush = value;
78    }
79
80    /**
81     * Returns value of the <b>ImmediateFlush</b> option.
82     */

83    public boolean getImmediateFlush()
84    {
85       return immediateFlush;
86    }
87
88    public boolean isBufferedIO()
89    {
90       return bufferedIO;
91    }
92
93    /**
94     * The <b>BufferedIO</b> option takes a boolean value. It is set to
95     * <code>false</code> by default. If true, then <code>File</code>
96     * will be opened and the resulting {@link java.io.Writer} wrapped
97     * around a {@link java.io.BufferedWriter}.
98     * <p/>
99     * BufferedIO will significatnly increase performance on heavily
100     * loaded systems.
101     */

102    public void setBufferedIO(boolean bufferedIO)
103    {
104       this.bufferedIO = bufferedIO;
105       if (bufferedIO)
106       {
107          immediateFlush = false;
108       }
109    }
110
111    public int getBufferSize()
112    {
113       return bufferSize;
114    }
115
116    /**
117     * Set the size of the IO buffer.
118     */

119    public void setBufferSize(int bufferSize)
120    {
121       this.bufferSize = bufferSize;
122    }
123
124    public void setEncoding(String JavaDoc encoding)
125       throws SecurityException JavaDoc, UnsupportedEncodingException JavaDoc
126    {
127       super.setEncoding(encoding);
128       if (msgOutput == null)
129       {
130          return;
131       }
132       // Replace the current writer with a writer for the new encoding.
133
flush();
134       if (encoding == null)
135       {
136          msgWriter = new OutputStreamWriter JavaDoc(msgOutput);
137       }
138       else
139       {
140          msgWriter = new OutputStreamWriter JavaDoc(msgOutput, encoding);
141       }
142    }
143
144    public synchronized void flush()
145    {
146       if (msgWriter != null)
147       {
148          try
149          {
150             msgWriter.flush();
151          }
152          catch (IOException JavaDoc e)
153          {
154             reportError("Failed to flush writer", e, ErrorManager.FLUSH_FAILURE);
155          }
156       }
157    }
158
159    public synchronized void close()
160    {
161       if (msgWriter != null)
162       {
163          try
164          {
165             if (!wroteHeader)
166             {
167                msgWriter.write(getFormatter().getHead(this));
168                wroteHeader = true;
169             }
170             msgWriter.write(getFormatter().getTail(this));
171             msgWriter.flush();
172             msgWriter.close();
173          }
174          catch (Exception JavaDoc ex)
175          {
176             // We don't want to throw an exception here, but we
177
// report the exception to any registered ErrorManager.
178
reportError(null, ex, ErrorManager.CLOSE_FAILURE);
179          }
180          msgWriter = null;
181          msgOutput = null;
182       }
183
184    }
185
186    public void publish(LogRecord JavaDoc record)
187    {
188       if(checkEntryConditions(record) == false)
189       {
190          return;
191       }
192       subPublish(record);
193    }
194
195    protected boolean checkEntryConditions(LogRecord JavaDoc record)
196    {
197       boolean canWrite = super.isLoggable(record);
198       if( canWrite )
199       {
200          canWrite = msgWriter != null;
201       }
202       return canWrite;
203    }
204
205    /**
206     * Actual writing occurs here.
207     * Most subclasses of WriterHandler will need to
208     * override this method.
209     */

210    protected void subPublish(LogRecord JavaDoc record)
211    {
212       Formatter JavaDoc fmt = getFormatter();
213       String JavaDoc msg = fmt.format(record);
214       synchronized (this)
215       {
216          try
217          {
218             msgWriter.write(msg);
219          }
220          catch (IOException JavaDoc e)
221          {
222             reportError("Failed to publish recored", e, ErrorManager.WRITE_FAILURE);
223          }
224          if (this.immediateFlush)
225          {
226             flush();
227          }
228       }
229    }
230
231    /**
232     * Change the output stream.
233     * <p/>
234     * If there is a current output stream then the <tt>Formatter</tt>'s
235     * tail string is written and the stream is flushed and closed.
236     * Then the output stream is replaced with the new output stream.
237     *
238     * @param out New output stream. May not be null.
239     * @throws SecurityException if a security manager exists and if
240     * the caller does not have <tt>LoggingPermission("control")</tt>.
241     */

242    protected synchronized void setOutputStream(OutputStream JavaDoc out)
243    {
244       if (out == null)
245       {
246          throw new NullPointerException JavaDoc("The out argument cannot be null");
247       }
248       close();
249       msgOutput = out;
250       wroteHeader = false;
251       String JavaDoc encoding = getEncoding();
252       if (encoding == null)
253       {
254          msgWriter = new OutputStreamWriter JavaDoc(msgOutput);
255       }
256       else
257       {
258          try
259          {
260             msgWriter = new OutputStreamWriter JavaDoc(msgOutput, encoding);
261          }
262          catch (UnsupportedEncodingException JavaDoc ex)
263          {
264             // This shouldn't happen. The setEncoding method
265
// should have validated that the encoding is OK.
266
throw new Error JavaDoc("Unexpected exception " + ex);
267          }
268       }
269       if (bufferedIO)
270       {
271          msgWriter = new BufferedWriter JavaDoc(msgWriter, bufferSize);
272       }
273    }
274
275
276 }
277
Popular Tags