KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > logging > jdk > format > PatternFormatter


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

16 package org.jboss.logging.jdk.format;
17
18 import java.util.logging.Formatter JavaDoc;
19 import java.util.logging.LogRecord JavaDoc;
20
21 // Contributors: Nelson Minar <nelson@monkey.org>
22
// Anders Kristensen <akristensen@dynamicsoft.com>
23

24 /**
25  * A flexible layout configurable with pattern string.
26  * <p/>
27  * <p>The goal of this class is to {@link #format format} a {@link
28  * LoggingEvent} and return the results as a String. The results
29  * depend on the <em>conversion pattern</em>.
30  * <p/>
31  * <p>The conversion pattern is closely related to the conversion
32  * pattern of the printf function in C. A conversion pattern is
33  * composed of literal text and format control expressions called
34  * <em>conversion specifiers</em>.
35  * <p/>
36  * <p><i>You are free to insert any literal text within the conversion
37  * pattern.</i>
38  * <p/>
39  * <p>Each conversion specifier starts with a percent sign (%) and is
40  * followed by optional <em>format modifiers</em> and a <em>conversion
41  * character</em>. The conversion character specifies the type of
42  * data, e.g. category, priority, date, thread name. The format
43  * modifiers control such things as field width, padding, left and
44  * right justification. The following is a simple example.
45  * <p/>
46  * <p>Let the conversion pattern be <b>"%-5p [%t]: %m%n"</b> and assume
47  * that the log4j environment was set to use a PatternLayout. Then the
48  * statements
49  * <pre>
50  * Category root = Category.getRoot();
51  * root.debug("Message 1");
52  * root.warn("Message 2");
53  * </pre>
54  * would yield the output
55  * <pre>
56  * DEBUG [main]: Message 1
57  * WARN [main]: Message 2
58  * </pre>
59  * <p/>
60  * <p>Note that there is no explicit separator between text and
61  * conversion specifiers. The pattern parser knows when it has reached
62  * the end of a conversion specifier when it reads a conversion
63  * character. In the example above the conversion specifier
64  * <b>%-5p</b> means the priority of the logging event should be left
65  * justified to a width of five characters.
66  * <p/>
67  * The recognized conversion characters are
68  * <p/>
69  * <p/>
70  * <table border="1" CELLPADDING="8">
71  * <th>Conversion Character</th>
72  * <th>Effect</th>
73  * <p/>
74  * <tr>
75  * <td align=center><b>c</b></td>
76  * <p/>
77  * <td>Used to output the category of the logging event. The
78  * category conversion specifier can be optionally followed by
79  * <em>precision specifier</em>, that is a decimal constant in
80  * brackets.
81  * <p/>
82  * <p>If a precision specifier is given, then only the corresponding
83  * number of right most components of the category name will be
84  * printed. By default the category name is printed in full.
85  * <p/>
86  * <p>For example, for the category name "a.b.c" the pattern
87  * <b>%c{2}</b> will output "b.c".
88  * <p/>
89  * </td>
90  * </tr>
91  * <p/>
92  * <tr>
93  * <td align=center><b>C</b></td>
94  * <p/>
95  * <td>Used to output the fully qualified class name of the caller
96  * issuing the logging request. This conversion specifier
97  * can be optionally followed by <em>precision specifier</em>, that
98  * is a decimal constant in brackets.
99  * <p/>
100  * <p>If a precision specifier is given, then only the corresponding
101  * number of right most components of the class name will be
102  * printed. By default the class name is output in fully qualified form.
103  * <p/>
104  * <p>For example, for the class name "org.apache.xyz.SomeClass", the
105  * pattern <b>%C{1}</b> will output "SomeClass".
106  * <p/>
107  * <p><b>WARNING</b> Generating the caller class information is
108  * slow. Thus, it's use should be avoided unless execution speed is
109  * not an issue.
110  * <p/>
111  * </td>
112  * </tr>
113  * <p/>
114  * <tr> <td align=center><b>d</b></td> <td>Used to output the date of
115  * the logging event. The date conversion specifier may be
116  * followed by a <em>date format specifier</em> enclosed between
117  * braces. For example, <b>%d{HH:mm:ss,SSS}</b> or
118  * <b>%d{dd&nbsp;MMM&nbsp;yyyy&nbsp;HH:mm:ss,SSS}</b>. If no
119  * date format specifier is given then ISO8601 format is
120  * assumed.
121  * <p/>
122  * <p>The date format specifier admits the same syntax as the
123  * time pattern string of the {@link
124  * java.text.SimpleDateFormat}. Although part of the standard
125  * JDK, the performance of <code>SimpleDateFormat</code> is
126  * quite poor.
127  * <p/>
128  * <p>For better results it is recommended to use the log4j date
129  * formatters. These can be specified using one of the strings
130  * "ABSOLUTE", "DATE" and "ISO8601" for specifying {@link
131  * org.apache.log4j.helpers.AbsoluteTimeDateFormat
132  * AbsoluteTimeDateFormat}, {@link
133  * org.apache.log4j.helpers.DateTimeDateFormat DateTimeDateFormat}
134  * and respectively {@link
135  * org.apache.log4j.helpers.ISO8601DateFormat
136  * ISO8601DateFormat}. For example, <b>%d{ISO8601}</b> or
137  * <b>%d{ABSOLUTE}</b>.
138  * <p/>
139  * <p>These dedicated date formatters perform significantly
140  * better than {@link java.text.SimpleDateFormat}.
141  * </td>
142  * </tr>
143  * <p/>
144  * <tr>
145  * <td align=center><b>F</b></td>
146  * <p/>
147  * <td>Used to output the file name where the logging request was
148  * issued.
149  * <p/>
150  * <p><b>WARNING</b> Generating caller location information is
151  * extremely slow. It's use should be avoided unless execution speed
152  * is not an issue.
153  * <p/>
154  * </tr>
155  * <p/>
156  * <tr>
157  * <td align=center><b>l</b></td>
158  * <p/>
159  * <td>Used to output location information of the caller which generated
160  * the logging event.
161  * <p/>
162  * <p>The location information depends on the JVM implementation but
163  * usually consists of the fully qualified name of the calling
164  * method followed by the callers source the file name and line
165  * number between parentheses.
166  * <p/>
167  * <p>The location information can be very useful. However, it's
168  * generation is <em>extremely</em> slow. It's use should be avoided
169  * unless execution speed is not an issue.
170  * <p/>
171  * </td>
172  * </tr>
173  * <p/>
174  * <tr>
175  * <td align=center><b>L</b></td>
176  * <p/>
177  * <td>Used to output the line number from where the logging request
178  * was issued.
179  * <p/>
180  * <p><b>WARNING</b> Generating caller location information is
181  * extremely slow. It's use should be avoided unless execution speed
182  * is not an issue.
183  * <p/>
184  * </tr>
185  * <p/>
186  * <p/>
187  * <tr>
188  * <td align=center><b>m</b></td>
189  * <td>Used to output the application supplied message associated with
190  * the logging event.</td>
191  * </tr>
192  * <p/>
193  * <tr>
194  * <td align=center><b>M</b></td>
195  * <p/>
196  * <td>Used to output the method name where the logging request was
197  * issued.
198  * <p/>
199  * <p><b>WARNING</b> Generating caller location information is
200  * extremely slow. It's use should be avoided unless execution speed
201  * is not an issue.
202  * <p/>
203  * </tr>
204  * <p/>
205  * <tr>
206  * <td align=center><b>n</b></td>
207  * <p/>
208  * <td>Outputs the platform dependent line separator character or
209  * characters.
210  * <p/>
211  * <p>This conversion character offers practically the same
212  * performance as using non-portable line separator strings such as
213  * "\n", or "\r\n". Thus, it is the preferred way of specifying a
214  * line separator.
215  * <p/>
216  * <p/>
217  * </tr>
218  * <p/>
219  * <tr>
220  * <td align=center><b>p</b></td>
221  * <td>Used to output the priority of the logging event.</td>
222  * </tr>
223  * <p/>
224  * <tr>
225  * <p/>
226  * <td align=center><b>r</b></td>
227  * <p/>
228  * <td>Used to output the number of milliseconds elapsed since the start
229  * of the application until the creation of the logging event.</td>
230  * </tr>
231  * <p/>
232  * <p/>
233  * <tr>
234  * <td align=center><b>t</b></td>
235  * <p/>
236  * <td>Used to output the name of the thread that generated the
237  * logging event.</td>
238  * <p/>
239  * </tr>
240  * <p/>
241  * <tr>
242  * <p/>
243  * <td align=center><b>x</b></td>
244  * <p/>
245  * <td>Used to output the NDC (nested diagnostic context) associated
246  * with the thread that generated the logging event.
247  * </td>
248  * </tr>
249  * <p/>
250  * <p/>
251  * <tr>
252  * <td align=center><b>X</b></td>
253  * <p/>
254  * <td>
255  * <p/>
256  * <p>Used to output the MDC (mapped diagnostic context) associated
257  * with the thread that generated the logging event. The <b>X</b>
258  * conversion character <em>must</em> be followed by the key for the
259  * map placed between braces, as in <b>%X{clientNumber}</b> where
260  * <code>clientNumber</code> is the key. The value in the MDC
261  * corresponding to the key will be output.</p>
262  * <p/>
263  * <p>See {@link MDC} class for more details.
264  * </p>
265  * <p/>
266  * </td>
267  * </tr>
268  * <p/>
269  * <tr>
270  * <p/>
271  * <td align=center><b>%</b></td>
272  * <p/>
273  * <td>The sequence %% outputs a single percent sign.
274  * </td>
275  * </tr>
276  * <p/>
277  * </table>
278  * <p/>
279  * <p>By default the relevant information is output as is. However,
280  * with the aid of format modifiers it is possible to change the
281  * minimum field width, the maximum field width and justification.
282  * <p/>
283  * <p>The optional format modifier is placed between the percent sign
284  * and the conversion character.
285  * <p/>
286  * <p>The first optional format modifier is the <em>left justification
287  * flag</em> which is just the minus (-) character. Then comes the
288  * optional <em>minimum field width</em> modifier. This is a decimal
289  * constant that represents the minimum number of characters to
290  * output. If the data item requires fewer characters, it is padded on
291  * either the left or the right until the minimum width is
292  * reached. The default is to pad on the left (right justify) but you
293  * can specify right padding with the left justification flag. The
294  * padding character is space. If the data item is larger than the
295  * minimum field width, the field is expanded to accommodate the
296  * data. The value is never truncated.
297  * <p/>
298  * <p>This behavior can be changed using the <em>maximum field
299  * width</em> modifier which is designated by a period followed by a
300  * decimal constant. If the data item is longer than the maximum
301  * field, then the extra characters are removed from the
302  * <em>beginning</em> of the data item and not from the end. For
303  * example, it the maximum field width is eight and the data item is
304  * ten characters long, then the first two characters of the data item
305  * are dropped. This behavior deviates from the printf function in C
306  * where truncation is done from the end.
307  * <p/>
308  * <p>Below are various format modifier examples for the category
309  * conversion specifier.
310  * <p/>
311  * <p/>
312  * <TABLE BORDER=1 CELLPADDING=8>
313  * <th>Format modifier
314  * <th>left justify
315  * <th>minimum width
316  * <th>maximum width
317  * <th>comment
318  * <p/>
319  * <tr>
320  * <td align=center>%20c</td>
321  * <td align=center>false</td>
322  * <td align=center>20</td>
323  * <td align=center>none</td>
324  * <p/>
325  * <td>Left pad with spaces if the category name is less than 20
326  * characters long.
327  * <p/>
328  * <tr> <td align=center>%-20c</td> <td align=center>true</td> <td
329  * align=center>20</td> <td align=center>none</td> <td>Right pad with
330  * spaces if the category name is less than 20 characters long.
331  * <p/>
332  * <tr>
333  * <td align=center>%.30c</td>
334  * <td align=center>NA</td>
335  * <td align=center>none</td>
336  * <td align=center>30</td>
337  * <p/>
338  * <td>Truncate from the beginning if the category name is longer than 30
339  * characters.
340  * <p/>
341  * <tr>
342  * <td align=center>%20.30c</td>
343  * <td align=center>false</td>
344  * <td align=center>20</td>
345  * <td align=center>30</td>
346  * <p/>
347  * <td>Left pad with spaces if the category name is shorter than 20
348  * characters. However, if category name is longer than 30 characters,
349  * then truncate from the beginning.
350  * <p/>
351  * <tr>
352  * <td align=center>%-20.30c</td>
353  * <td align=center>true</td>
354  * <td align=center>20</td>
355  * <td align=center>30</td>
356  * <p/>
357  * <td>Right pad with spaces if the category name is shorter than 20
358  * characters. However, if category name is longer than 30 characters,
359  * then truncate from the beginning.
360  * <p/>
361  * </table>
362  * <p/>
363  * <p>Below are some examples of conversion patterns.
364  * <p/>
365  * <dl>
366  * <p/>
367  * <p><dt><b>%r [%t] %-5p %c %x - %m\n</b>
368  * <p><dd>This is essentially the TTCC layout.
369  * <p/>
370  * <p><dt><b>%-6r [%15.15t] %-5p %30.30c %x - %m\n</b>
371  * <p/>
372  * <p><dd>Similar to the TTCC layout except that the relative time is
373  * right padded if less than 6 digits, thread name is right padded if
374  * less than 15 characters and truncated if longer and the category
375  * name is left padded if shorter than 30 characters and truncated if
376  * longer.
377  * <p/>
378  * </dl>
379  * <p/>
380  * <p>The above text is largely inspired from Peter A. Darnell and
381  * Philip E. Margolis' highly recommended book "C -- a Software
382  * Engineering Approach", ISBN 0-387-97389-3.
383  *
384  * @author <a HREF="mailto:cakalijp@Maritz.com">James P. Cakalic</a>
385  * @author Ceki G&uuml;lc&uuml;
386  * @author Scott.Stark@jboss.org
387  * @version $Revision: 1958 $
388  *
389  */

390 public class PatternFormatter extends Formatter JavaDoc
391 {
392
393    /**
394     * Default pattern string for log output. Currently set to the
395     * string <b>"%m%n"</b> which just prints the application supplied
396     * message.
397     */

398    public final static String JavaDoc DEFAULT_CONVERSION_PATTERN = "%m%n";
399
400    /**
401     * A conversion pattern equivalent to the TTCCCLayout.
402     * Current value is <b>%r [%t] %p %c %x - %m%n</b>.
403     */

404    public final static String JavaDoc TTCC_CONVERSION_PATTERN
405       = "%r [%t] %p %c %x - %m%n";
406
407
408    protected final int BUF_SIZE = 256;
409    protected final int MAX_CAPACITY = 1024;
410
411    private String JavaDoc pattern;
412
413    private PatternConverter head;
414
415    private String JavaDoc timezone;
416
417    /**
418     * Constructs a PatternLayout using the DEFAULT_LAYOUT_PATTERN.
419     * <p/>
420     * The default pattern just produces the application supplied message.
421     */

422    public PatternFormatter()
423    {
424       this(DEFAULT_CONVERSION_PATTERN);
425    }
426
427    /**
428     * Constructs a PatternLayout using the supplied conversion pattern.
429     */

430    public PatternFormatter(String JavaDoc pattern)
431    {
432       this.pattern = pattern;
433       head = createPatternParser((pattern == null) ? DEFAULT_CONVERSION_PATTERN :
434          pattern).parse();
435    }
436
437    /**
438     * Set the <b>ConversionPattern</b> option. This is the string which
439     * controls formatting and consists of a mix of literal content and
440     * conversion specifiers.
441     */

442    public void setConversionPattern(String JavaDoc conversionPattern)
443    {
444       pattern = conversionPattern;
445       head = createPatternParser(conversionPattern).parse();
446    }
447
448    /**
449     * Returns the value of the <b>ConversionPattern</b> option.
450     */

451    public String JavaDoc getConversionPattern()
452    {
453       return pattern;
454    }
455
456    /**
457     * Does not do anything as options become effective
458     */

459    public void activateOptions()
460    {
461       // nothing to do.
462
}
463
464    /**
465     * The PatternLayout does not handle the throwable contained within
466     * {@link LoggingEvent LoggingEvents}. Thus, it returns
467     * <code>true</code>.
468     *
469     * @since 0.8.4
470     */

471    public boolean ignoresThrowable()
472    {
473       return true;
474    }
475
476    /**
477     * Returns PatternParser used to parse the conversion string. Subclasses
478     * may override this to return a subclass of PatternParser which recognize
479     * custom conversion characters.
480     *
481     * @since 0.9.0
482     */

483    protected PatternParser createPatternParser(String JavaDoc pattern)
484    {
485       return new PatternParser(pattern);
486    }
487
488
489    /**
490     * Produces a formatted string as specified by the conversion pattern.
491     */

492    public String JavaDoc format(LogRecord JavaDoc event)
493    {
494       // output buffer appended to when format() is invoked
495
StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc(BUF_SIZE);
496       PatternConverter c = head;
497       while (c != null)
498       {
499          c.format(sbuf, event);
500          c = c.next;
501       }
502       return sbuf.toString();
503    }
504 }
505
506
Popular Tags