KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > log > output > AsyncLogTarget


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12  * implied.
13  *
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.log.output;
18
19 import java.util.LinkedList JavaDoc;
20 import org.apache.log.ErrorAware;
21 import org.apache.log.ErrorHandler;
22 import org.apache.log.LogEvent;
23 import org.apache.log.LogTarget;
24
25 /**
26  * An asynchronous LogTarget that sends entries on in another thread.
27  * It is the responsibility of the user of this class to start
28  * the thread etc.
29  *
30  * <pre>
31  * LogTarget mySlowTarget = ...;
32  * AsyncLogTarget asyncTarget = new AsyncLogTarget( mySlowTarget );
33  * Thread thread = new Thread( asyncTarget );
34  * thread.setPriority( Thread.MIN_PRIORITY );
35  * thread.start();
36  *
37  * logger.setLogTargets( new LogTarget[] { asyncTarget } );
38  * </pre>
39  *
40  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
41  * @author Peter Donald
42  */

43 public class AsyncLogTarget
44     extends AbstractWrappingTarget
45     implements Runnable JavaDoc
46 {
47     private final LinkedList JavaDoc m_list;
48     private final int m_queueSize;
49
50     /**
51      * Creation of a new async log target.
52      * @param logTarget the underlying target
53      */

54     public AsyncLogTarget( final LogTarget logTarget )
55     {
56         this( logTarget, 15 );
57     }
58
59     /**
60      * Creation of a new async log target.
61      * @param logTarget the underlying target
62      * @param queueSize the queue size
63      */

64     public AsyncLogTarget( final LogTarget logTarget, final int queueSize )
65     {
66         this( logTarget, queueSize, false );
67     }
68
69     /**
70      * Creation of a new async log target.
71      * @param logTarget the underlying target
72      * @param closeTarget close the underlying target when this target is closed. This flag
73      * has no effect unless the logTarget implements Closeable.
74      */

75     public AsyncLogTarget( final LogTarget logTarget, final boolean closeTarget )
76     {
77         this( logTarget, 15, closeTarget );
78     }
79
80     /**
81      * Creation of a new async log target.
82      * @param logTarget the underlying target
83      * @param queueSize the queue size
84      * @param closeTarget close the underlying target when this target is closed. This flag
85      * has no effect unless the logTarget implements Closeable.
86      */

87     public AsyncLogTarget( final LogTarget logTarget, final int queueSize, final boolean closeTarget )
88     {
89         super( logTarget, closeTarget );
90         m_list = new LinkedList JavaDoc();
91         m_queueSize = queueSize;
92         open();
93     }
94
95     /**
96      * Provide component with ErrorHandler.
97      *
98      * @param errorHandler the errorHandler
99      */

100     public synchronized void setErrorHandler( final ErrorHandler errorHandler )
101     {
102         super.setErrorHandler( errorHandler );
103
104         if( this.getLogTarget() instanceof ErrorAware )
105         {
106             ( (ErrorAware)this.getLogTarget() ).setErrorHandler( errorHandler );
107         }
108     }
109
110     /**
111      * Process a log event by adding it to queue.
112      *
113      * @param event the log event
114      */

115     public void doProcessEvent( final LogEvent event )
116     {
117         synchronized( m_list )
118         {
119             int size = m_list.size();
120             while( m_queueSize <= size )
121             {
122                 try
123                 {
124                     m_list.wait();
125                 }
126                 catch( final InterruptedException JavaDoc ie )
127                 {
128                     //This really should not occur ...
129
//Maybe we should log it though for
130
//now lets ignore it
131
}
132                 size = m_list.size();
133             }
134
135             m_list.addFirst( event );
136
137             if( size == 0 )
138             {
139                 //tell the "server" thread to wake up
140
//if it is waiting for a queue to contain some items
141
m_list.notify();
142             }
143         }
144     }
145
146     /**
147      * Thread startup.
148      */

149     public void run()
150     {
151         //set this variable when thread is interupted
152
//so we know we can shutdown thread soon.
153
boolean interupted = false;
154
155         while( true )
156         {
157             LogEvent event = null;
158
159             synchronized( m_list )
160             {
161                 while( null == event )
162                 {
163                     final int size = m_list.size();
164
165                     if( size > 0 )
166                     {
167                         event = (LogEvent)m_list.removeLast();
168
169                         if( size == m_queueSize )
170                         {
171                             //tell the "client" thread to wake up
172
//if it is waiting for a queue position to open up
173
m_list.notify();
174                         }
175
176                     }
177                     else if( interupted || Thread.interrupted() )
178                     {
179                         //ie there is nothing in queue and thread is interrupted
180
//thus we stop thread
181
return;
182                     }
183                     else
184                     {
185                         try
186                         {
187                             m_list.wait();
188                         }
189                         catch( final InterruptedException JavaDoc ie )
190                         {
191                             //Ignore this and let it be dealt in next loop
192
//Need to set variable as the exception throw cleared status
193
interupted = true;
194                         }
195                     }
196                 }
197             }
198
199             try
200             {
201                 //actually process an event
202
this.getLogTarget().processEvent( event );
203             }
204             catch( final Throwable JavaDoc throwable )
205             {
206                 getErrorHandler().error( "Unknown error writing event.", throwable, event );
207             }
208         }
209     }
210 }
211
Popular Tags