KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > logging > logkit > factory > FileTargetFactory


1 /*
2  * Copyright 2004 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
18 package org.apache.avalon.logging.logkit.factory;
19
20 import java.io.File JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.util.StringTokenizer JavaDoc;
23
24 import org.apache.avalon.framework.configuration.Configuration;
25 import org.apache.avalon.framework.configuration.ConfigurationException;
26 import org.apache.avalon.framework.context.ContextException;
27
28 import org.apache.avalon.logging.logkit.DefaultLoggingManager;
29 import org.apache.avalon.logging.logkit.FormatterFactory;
30 import org.apache.avalon.logging.logkit.LogTargetFactory;
31 import org.apache.avalon.logging.logkit.LogTargetException;
32
33 import org.apache.avalon.util.i18n.ResourceManager;
34 import org.apache.avalon.util.i18n.Resources;
35
36 import org.apache.log.LogTarget;
37 import org.apache.log.format.Formatter;
38 import org.apache.log.output.io.FileTarget;
39 import org.apache.log.output.io.rotate.FileStrategy;
40 import org.apache.log.output.io.rotate.OrRotateStrategy;
41 import org.apache.log.output.io.rotate.RevolvingFileStrategy;
42 import org.apache.log.output.io.rotate.RotateStrategy;
43 import org.apache.log.output.io.rotate.RotateStrategyByDate;
44 import org.apache.log.output.io.rotate.RotateStrategyBySize;
45 import org.apache.log.output.io.rotate.RotateStrategyByTime;
46 import org.apache.log.output.io.rotate.RotateStrategyByTimeOfDay;
47 import org.apache.log.output.io.rotate.RotatingFileTarget;
48 import org.apache.log.output.io.rotate.UniqueFileStrategy;
49
50
51
52 /**
53  * FileTargetFactory class.
54  *
55  * This factory is able to create different FileLogTargets according to the following
56  * configuration syntax:
57  *
58  * <pre>
59  * &lt;file id="foo"&gt;
60  * &lt;filename&gt;${context-key}/real-name/...&lt;/filename&gt;
61  * &lt;format type="avalon|raw|pattern|extended"&gt;pattern to be used if needed&lt;/format&gt;
62  * &lt;append&gt;true|false&lt;/append&gt;
63  * &lt;rotation type="revolving" init="5" max="10"&gt;
64  *
65  * or
66  *
67  * &lt;rotation type="unique" pattern="yyyy-MM-dd-hh-mm-ss" suffix=".log"&gt;
68  * &lt;or&gt;
69  * &lt;size&gt;10000000&lt;/size&gt;
70  * &lt;time&gt;24:00:00&lt;/time&gt;
71  * &lt;time&gt;12:00:00&lt;/time&gt;
72  * &lt;/or&gt;
73  * &lt;/rotation&gt;
74  * &lt;/file&gt;
75  * </pre>
76  *
77  * <p>Some explanations about the Elements used in the configuration:</p>
78  * <dl>
79  * <dt>&lt;filename&gt;</dt>
80  * <dd>
81  * This denotes the name of the file to log to. It can be constructed
82  * out of entries in the passed Context object as ${context-key}.
83  * This element is required.
84  * </dd>
85  * <dt>&lt;format&gt;</dt>
86  * <dd>
87  * The type attribute of the pattern element denotes the type of
88  * Formatter to be used and according to it the pattern to use for.
89  * This elements defaults to:
90  * <p>
91  * %7.7{priority} %5.5{time} [%8.8{category}] (%{context}): %{message}\\n%{throwable}
92  * </p>
93  * </dd>
94  * <dt>&lt;append&gt;<dt>
95  * <dd>
96  * If the log file should be deleted every time the logger is creates
97  * (normally at the start of the applcation) or not and thus the log
98  * entries will be appended. This elements defaults to false.
99  * </dd>
100  * <dt>&lt;rotation&gt;</dt>
101  * <dd>
102  * This is an optional element.
103  * The type attribute determines which FileStrategy to user
104  * (revolving=RevolvingFileStrategy, unique=UniqueFileStrategy).
105  * The required init and max attribute are used to determine the initial and
106  * maximum rotation to use on a type="revolving" attribute.
107  * The optional pattern and suffix attribute are used to form filenames on
108  * a type="unique" attribute.
109  * <p> The initial rotation
110  * can be set to -1 in which case the system will first create the maximum
111  * number of file rotations by selecting the next available rotation and thereafter
112  * will overwrite the oldest log file.
113  * </dd>
114  * <dt>&lt;or&gt;</dt>
115  * <dd>uses the OrRotateStrategy to combine the children</dd>
116  * <dt>&lt;size&gt;</dt>
117  * <dd>
118  * The number of bytes if no suffix used or kilo bytes (1024) if suffixed with
119  * 'k' or mega bytes (1024k) if suffixed with 'm' when a file rotation should
120  * occur. It doesn't make sense to specify more than one.
121  * </dd>
122  * <dt>&lt;time&gt;</dt>
123  * <dd>
124  * The time as HH:MM:SS when a rotation should occur. If you like to rotate
125  * a logfile more than once a day put an &lt;or&gt; element immediately after the
126  * &lt;rotation&gt; element and specify the times (and one size, too) inside the
127  * &lt;or&gt; element.
128  * </dd>
129  * <dt>&lt;date&gt;</dt>
130  * <dd>
131  * Rotation occur when string formatted date changed. Specify date formatting pattern.
132  * </dd>
133  * <dt>&lt;interval&gt;</dt>
134  * <dd>
135  * Interval at which a rotation should occur. The interval should be given in the
136  * format ddd:hh:mm:ss.
137  * </dd>
138  * </dl>
139  *
140  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
141  * @version CVS $Revision: 1.3 $ $Date: 2004/03/08 11:32:01 $
142  */

143 public class FileTargetFactory implements LogTargetFactory
144 {
145     //--------------------------------------------------------------
146
// static
147
//--------------------------------------------------------------
148

149     private static final Resources REZ =
150       ResourceManager.getPackageResources( FileTargetFactory.class );
151
152     private static final long SECOND = 1000;
153     private static final long MINUTE = 60 * SECOND;
154     private static final long HOUR = 60 * MINUTE;
155     private static final long DAY = 24 * HOUR;
156
157     private static final long KILOBYTE = 1000;
158     private static final long MEGABYTE = 1000 * KILOBYTE;
159
160     //--------------------------------------------------------------
161
// immutable state
162
//--------------------------------------------------------------
163

164     private final File JavaDoc m_basedir;
165     private final FormatterFactory m_formatter;
166
167     //--------------------------------------------------------------
168
// constructor
169
//--------------------------------------------------------------
170

171     public FileTargetFactory( File JavaDoc basedir, FormatterFactory formatter )
172     {
173         m_basedir = basedir;
174         m_formatter = formatter;
175     }
176
177     //--------------------------------------------------------------
178
// LogFactory
179
//--------------------------------------------------------------
180

181     /**
182      * Create a LogTarget based on a Configuration
183      */

184     public final LogTarget createTarget( final Configuration configuration )
185         throws LogTargetException
186     {
187         try
188         {
189             final Configuration confFilename =
190               configuration.getChild( "filename" );
191             final String JavaDoc filename =
192               confFilename.getValue();
193
194             final Configuration confRotation =
195               configuration.getChild( "rotation", false );
196
197             final Configuration confFormat =
198               configuration.getChild( "format", false );
199
200             final Configuration confAppend =
201               configuration.getChild( "append" );
202             final boolean append =
203               confAppend.getValueAsBoolean( false );
204
205             final LogTarget logtarget;
206    
207             final File JavaDoc file = resolveFile( filename );
208           
209             final Formatter formatter =
210               m_formatter.createFormatter( confFormat );
211
212             if( null == confRotation )
213             {
214                 return new FileTarget( file, append, formatter );
215             }
216             else
217             {
218                 if( confRotation.getChildren().length == 0 )
219                 {
220                     final String JavaDoc error =
221                       REZ.getString( "file.error.missing-rotation" );
222                     throw new LogTargetException( error );
223                 }
224                 final Configuration confStrategy =
225                   confRotation.getChildren()[ 0 ];
226                 final RotateStrategy rotateStrategy =
227                   getRotateStrategy( confStrategy );
228                 final FileStrategy fileStrategy =
229                   getFileStrategy( confRotation, file );
230
231                 try
232                 {
233                     return new RotatingFileTarget(
234                       append, formatter, rotateStrategy, fileStrategy );
235                 }
236                 catch( Throwable JavaDoc e )
237                 {
238                     final String JavaDoc error =
239                       REZ.getString( "file.error.logkit-rotation" );
240                     throw new LogTargetException( error, e );
241                 }
242             }
243         }
244         catch( final IOException JavaDoc e )
245         {
246             final String JavaDoc error =
247               REZ.getString( "file.error.io" );
248             throw new LogTargetException( error, e );
249         }
250         catch( ConfigurationException e )
251         {
252             final String JavaDoc error =
253               REZ.getString( "file.error.config" );
254             throw new LogTargetException( error, e );
255         }
256         catch( Throwable JavaDoc e )
257         {
258             final String JavaDoc error =
259               REZ.getString( "file.error.internal" );
260             throw new LogTargetException( error, e );
261         }
262     }
263
264     private File JavaDoc resolveFile( final String JavaDoc filename )
265     {
266         final File JavaDoc file = new File JavaDoc( filename );
267         if( file.isAbsolute() ) return file;
268         return new File JavaDoc( m_basedir, filename );
269     }
270
271     private RotateStrategy getRotateStrategy( final Configuration conf )
272     {
273         final String JavaDoc type = conf.getName();
274
275         if( "or".equals( type ) )
276         {
277             final Configuration[] configurations = conf.getChildren();
278             final int size = configurations.length;
279
280             final RotateStrategy[] strategies = new RotateStrategy[ size ];
281             for( int i = 0; i < size; i++ )
282             {
283                 strategies[ i ] = getRotateStrategy( configurations[ i ] );
284             }
285
286             return new OrRotateStrategy( strategies );
287         }
288         else if( "size".equals( type ) )
289         {
290             final String JavaDoc value = conf.getValue( "2m" );
291
292             final int count = value.length();
293             final char end = value.charAt( count - 1 );
294             final long no;
295             final long size;
296
297             switch( end )
298             {
299                 case 'm':
300                     no = Long.parseLong( value.substring( 0, count - 1 ) );
301                     size = no * MEGABYTE;
302                     break;
303                 case 'k':
304                     no = Long.parseLong( value.substring( 0, count - 1 ) );
305                     size = no * KILOBYTE;
306                     break;
307                 default:
308                     size = Long.parseLong( value );
309             }
310
311             return new RotateStrategyBySize( size );
312         }
313         else if( "date".equals( type ) )
314         {
315             final String JavaDoc value = conf.getValue( "yyyyMMdd" );
316             return new RotateStrategyByDate( value );
317         }
318         else if( "interval".equals( type ) )
319         {
320             // default rotate strategy
321
final String JavaDoc value = conf.getValue( "24:00:00" );
322
323             // interpret a string like: ddd:hh:mm:ss ...
324
final StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc( value, ":" );
325             final int count = tokenizer.countTokens();
326             long time = 0;
327             for( int i = count; i > 0; i-- )
328             {
329                 final long no = Long.parseLong( tokenizer.nextToken() );
330                 if( 4 == i )
331                 {
332                     time += no * DAY;
333                 }
334                 if( 3 == i )
335                 {
336                     time += no * HOUR;
337                 }
338                 if( 2 == i )
339                 {
340                     time += no * MINUTE;
341                 }
342                 if( 1 == i )
343                 {
344                     time += no * SECOND;
345                 }
346             }
347
348             return new RotateStrategyByTime( time );
349         }
350         else // "time"
351
{
352             // default rotate strategy
353
final String JavaDoc value = conf.getValue( "24:00:00" );
354
355             // interpret a string like: hh:mm:ss ...
356
final StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc( value, ":" );
357             final int count = tokenizer.countTokens();
358             long time = 0;
359             for( int i = count; i > 0; i-- )
360             {
361                 final long no = Long.parseLong( tokenizer.nextToken() );
362                 if( 3 == i )
363                 {
364                     time += no * HOUR;
365                 }
366                 if( 2 == i )
367                 {
368                     time += no * MINUTE;
369                 }
370                 if( 1 == i )
371                 {
372                     time += no * SECOND;
373                 }
374             }
375
376             return new RotateStrategyByTimeOfDay( time );
377         }
378     }
379
380     protected FileStrategy getFileStrategy( final Configuration conf, final File JavaDoc file )
381     {
382         final String JavaDoc type = conf.getAttribute( "type", "unique" );
383
384         if( "revolving".equals( type ) )
385         {
386             final int initialRotation =
387                 conf.getAttributeAsInteger( "init", 5 );
388             final int maxRotation =
389                 conf.getAttributeAsInteger( "max", 10 );
390
391             return new RevolvingFileStrategy( file, initialRotation, maxRotation );
392         }
393
394         // default file strategy
395
final String JavaDoc pattern = conf.getAttribute( "pattern", null );
396         final String JavaDoc suffix = conf.getAttribute( "suffix", null );
397         if( pattern == null )
398         {
399             return new UniqueFileStrategy( file );
400         }
401         else
402         {
403             if( suffix == null )
404             {
405                 return new UniqueFileStrategy( file, pattern );
406             }
407             else
408             {
409                 return new UniqueFileStrategy( file, pattern, suffix );
410             }
411         }
412     }
413 }
414
415
Popular Tags