1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.log4j;
19
20 import org.apache.log4j.helpers.OptionConverter;
21 import org.apache.log4j.helpers.PatternConverter;
22 import org.apache.log4j.pattern.BridgePatternConverter;
23 import org.apache.log4j.spi.LoggingEvent;
24
25
26
27
28
29 /***
30 * <p>A flexible layout configurable with pattern string. The goal of this class
31 * is to {@link #format format} a {@link LoggingEvent} and return the results
32 * in a {@link StringBuffer}. The format of the result depends on the
33 * <em>conversion pattern</em>.
34 * <p>
35 *
36 * <p>The conversion pattern is closely related to the conversion
37 * pattern of the printf function in C. A conversion pattern is
38 * composed of literal text and format control expressions called
39 * <em>conversion specifiers</em>.
40 *
41 * <p><i>Note that you are free to insert any literal text within the
42 * conversion pattern.</i>
43 * </p>
44
45 <p>Each conversion specifier starts with a percent sign (%) and is
46 followed by optional <em>format modifiers</em> and a <em>conversion
47 character</em>. The conversion character specifies the type of
48 data, e.g. category, priority, date, thread name. The format
49 modifiers control such things as field width, padding, left and
50 right justification. The following is a simple example.
51
52 <p>Let the conversion pattern be <b>"%-5p [%t]: %m%n"</b> and assume
53 that the log4j environment was set to use a EnhancedPatternLayout. Then the
54 statements
55 <pre>
56 Category root = Category.getRoot();
57 root.debug("Message 1");
58 root.warn("Message 2");
59 </pre>
60 would yield the output
61 <pre>
62 DEBUG [main]: Message 1
63 WARN [main]: Message 2
64 </pre>
65
66 <p>Note that there is no explicit separator between text and
67 conversion specifiers. The pattern parser knows when it has reached
68 the end of a conversion specifier when it reads a conversion
69 character. In the example above the conversion specifier
70 <b>%-5p</b> means the priority of the logging event should be left
71 justified to a width of five characters.
72
73 The recognized conversion characters are
74
75 <p>
76 <table border="1" CELLPADDING="8">
77 <th>Conversion Character</th>
78 <th>Effect</th>
79
80 <tr>
81 <td align=center><b>c</b></td>
82
83 <td>Used to output the category of the logging event. The
84 category conversion specifier can be optionally followed by
85 <em>precision specifier</em>, that is a decimal constant in
86 brackets.
87
88 <p>If a precision specifier is given, then only the corresponding
89 number of right most components of the category name will be
90 printed. By default the category name is printed in full.
91
92 <p>For example, for the category name "a.b.c" the pattern
93 <b>%c{2}</b> will output "b.c".
94
95 </td>
96 </tr>
97
98 <tr>
99 <td align=center><b>C</b></td>
100
101 <td>Used to output the fully qualified class name of the caller
102 issuing the logging request. This conversion specifier
103 can be optionally followed by <em>precision specifier</em>, that
104 is a decimal constant in brackets.
105
106 <p>If a precision specifier is given, then only the corresponding
107 number of right most components of the class name will be
108 printed. By default the class name is output in fully qualified form.
109
110 <p>For example, for the class name "org.apache.xyz.SomeClass", the
111 pattern <b>%C{1}</b> will output "SomeClass".
112
113 <p><b>WARNING</b> Generating the caller class information is
114 slow. Thus, it's use should be avoided unless execution speed is
115 not an issue.
116
117 </td>
118 </tr>
119
120 <tr> <td align=center><b>d</b></td> <td>Used to output the date of
121 the logging event. The date conversion specifier may be
122 followed by a set of braces containing a
123 date and time pattern strings {@link java.text.SimpleDateFormat},
124 <em>ABSOLUTE</em>, <em>DATE</em> or <em>ISO8601</em>
125 and a set of braces containing a time zone id per
126 {@link java.util.TimeZone#getTimeZone(String)}.
127 For example, <b>%d{HH:mm:ss,SSS}</b>,
128 <b>%d{dd MMM yyyy HH:mm:ss,SSS}</b>,
129 <b>%d{DATE}</b> or <b>%d{HH:mm:ss}{GMT+0}</b>. If no date format specifier is given then
130 ISO8601 format is assumed.
131 </td>
132 </tr>
133
134 <tr>
135 <td align=center><b>F</b></td>
136
137 <td>Used to output the file name where the logging request was
138 issued.
139
140 <p><b>WARNING</b> Generating caller location information is
141 extremely slow. Its use should be avoided unless execution speed
142 is not an issue.
143
144 </tr>
145
146 <tr>
147 <td align=center><b>l</b></td>
148
149 <td>Used to output location information of the caller which generated
150 the logging event.
151
152 <p>The location information depends on the JVM implementation but
153 usually consists of the fully qualified name of the calling
154 method followed by the callers source the file name and line
155 number between parentheses.
156
157 <p>The location information can be very useful. However, it's
158 generation is <em>extremely</em> slow. It's use should be avoided
159 unless execution speed is not an issue.
160
161 </td>
162 </tr>
163
164 <tr>
165 <td align=center><b>L</b></td>
166
167 <td>Used to output the line number from where the logging request
168 was issued.
169
170 <p><b>WARNING</b> Generating caller location information is
171 extremely slow. It's use should be avoided unless execution speed
172 is not an issue.
173
174 </tr>
175
176
177 <tr>
178 <td align=center><b>m</b></td>
179 <td>Used to output the application supplied message associated with
180 the logging event.</td>
181 </tr>
182
183 <tr>
184 <td align=center><b>M</b></td>
185
186 <td>Used to output the method name where the logging request was
187 issued.
188
189 <p><b>WARNING</b> Generating caller location information is
190 extremely slow. It's use should be avoided unless execution speed
191 is not an issue.
192
193 </tr>
194
195 <tr>
196 <td align=center><b>n</b></td>
197
198 <td>Outputs the platform dependent line separator character or
199 characters.
200
201 <p>This conversion character offers practically the same
202 performance as using non-portable line separator strings such as
203 "\n", or "\r\n". Thus, it is the preferred way of specifying a
204 line separator.
205
206
207 </tr>
208
209 <tr>
210 <td align=center><b>p</b></td>
211 <td>Used to output the priority of the logging event.</td>
212 </tr>
213
214 <tr>
215
216 <td align=center><b>r</b></td>
217
218 <td>Used to output the number of milliseconds elapsed since the construction
219 of the layout until the creation of the logging event.</td>
220 </tr>
221
222
223 <tr>
224 <td align=center><b>t</b></td>
225
226 <td>Used to output the name of the thread that generated the
227 logging event.</td>
228
229 </tr>
230
231 <tr>
232
233 <td align=center><b>x</b></td>
234
235 <td>Used to output the NDC (nested diagnostic context) associated
236 with the thread that generated the logging event.
237 </td>
238 </tr>
239
240
241 <tr>
242 <td align=center><b>X</b></td>
243
244 <td>
245
246 <p>Used to output the MDC (mapped diagnostic context) associated
247 with the thread that generated the logging event. The <b>X</b>
248 conversion character can be followed by the key for the
249 map placed between braces, as in <b>%X{clientNumber}</b> where
250 <code>clientNumber</code> is the key. The value in the MDC
251 corresponding to the key will be output. If no additional sub-option
252 is specified, then the entire contents of the MDC key value pair set
253 is output using a format {{key1,val1},{key2,val2}}</p>
254
255 <p>See {@link MDC} class for more details.
256 </p>
257
258 </td>
259 </tr>
260
261 <tr>
262 <td align=center><b>properties</b></td>
263
264 <td>
265 <p>Used to output the Properties associated
266 with the logging event. The <b>properties</b>
267 conversion word can be followed by the key for the
268 map placed between braces, as in <b>%properties{application}</b> where
269 <code>application</code> is the key. The value in the Properties bundle
270 corresponding to the key will be output. If no additional sub-option
271 is specified, then the entire contents of the Properties key value pair set
272 is output using a format {{key1,val1},{key2,val2}}</p>
273 </td>
274 </tr>
275
276 <tr>
277 <td align=center><b>throwable</b></td>
278
279 <td>
280 <p>Used to output the Throwable trace that has been bound to the LoggingEvent, by
281 default this will output the full trace as one would normally find by a call to Throwable.printStackTrace().
282 The throwable conversion word can be followed by an option in the form <b>%throwable{short}</b>
283 which will only output the first line of the ThrowableInformation.</p>
284 </td>
285 </tr>
286
287 <tr>
288
289 <td align=center><b>%</b></td>
290
291 <td>The sequence %% outputs a single percent sign.
292 </td>
293 </tr>
294
295 </table>
296
297 <p>By default the relevant information is output as is. However,
298 with the aid of format modifiers it is possible to change the
299 minimum field width, the maximum field width and justification.
300
301 <p>The optional format modifier is placed between the percent sign
302 and the conversion character.
303
304 <p>The first optional format modifier is the <em>left justification
305 flag</em> which is just the minus (-) character. Then comes the
306 optional <em>minimum field width</em> modifier. This is a decimal
307 constant that represents the minimum number of characters to
308 output. If the data item requires fewer characters, it is padded on
309 either the left or the right until the minimum width is
310 reached. The default is to pad on the left (right justify) but you
311 can specify right padding with the left justification flag. The
312 padding character is space. If the data item is larger than the
313 minimum field width, the field is expanded to accommodate the
314 data. The value is never truncated.
315
316 <p>This behavior can be changed using the <em>maximum field
317 width</em> modifier which is designated by a period followed by a
318 decimal constant. If the data item is longer than the maximum
319 field, then the extra characters are removed from the
320 <em>beginning</em> of the data item and not from the end. For
321 example, it the maximum field width is eight and the data item is
322 ten characters long, then the first two characters of the data item
323 are dropped. This behavior deviates from the printf function in C
324 where truncation is done from the end.
325
326 <p>Below are various format modifier examples for the category
327 conversion specifier.
328
329 <p>
330 <TABLE BORDER=1 CELLPADDING=8>
331 <th>Format modifier
332 <th>left justify
333 <th>minimum width
334 <th>maximum width
335 <th>comment
336
337 <tr>
338 <td align=center>%20c</td>
339 <td align=center>false</td>
340 <td align=center>20</td>
341 <td align=center>none</td>
342
343 <td>Left pad with spaces if the category name is less than 20
344 characters long.
345
346 <tr> <td align=center>%-20c</td> <td align=center>true</td> <td
347 align=center>20</td> <td align=center>none</td> <td>Right pad with
348 spaces if the category name is less than 20 characters long.
349
350 <tr>
351 <td align=center>%.30c</td>
352 <td align=center>NA</td>
353 <td align=center>none</td>
354 <td align=center>30</td>
355
356 <td>Truncate from the beginning if the category name is longer than 30
357 characters.
358
359 <tr>
360 <td align=center>%20.30c</td>
361 <td align=center>false</td>
362 <td align=center>20</td>
363 <td align=center>30</td>
364
365 <td>Left pad with spaces if the category name is shorter than 20
366 characters. However, if category name is longer than 30 characters,
367 then truncate from the beginning.
368
369 <tr>
370 <td align=center>%-20.30c</td>
371 <td align=center>true</td>
372 <td align=center>20</td>
373 <td align=center>30</td>
374
375 <td>Right pad with spaces if the category name is shorter than 20
376 characters. However, if category name is longer than 30 characters,
377 then truncate from the beginning.
378
379 </table>
380
381 <p>Below are some examples of conversion patterns.
382
383 <dl>
384
385 <p><dt><b>%r [%t] %-5p %c %x - %m%n</b>
386 <p><dd>This is essentially the TTCC layout.
387
388 <p><dt><b>%-6r [%15.15t] %-5p %30.30c %x - %m%n</b>
389
390 <p><dd>Similar to the TTCC layout except that the relative time is
391 right padded if less than 6 digits, thread name is right padded if
392 less than 15 characters and truncated if longer and the category
393 name is left padded if shorter than 30 characters and truncated if
394 longer.
395
396 </dl>
397
398 <p>The above text is largely inspired from Peter A. Darnell and
399 Philip E. Margolis' highly recommended book "C -- a Software
400 Engineering Approach", ISBN 0-387-97389-3.
401
402 @author <a href="mailto:cakalijp@Maritz.com">James P. Cakalic</a>
403 @author Ceki Gülcü
404
405
406 @since 0.8.2 */
407 public class EnhancedPatternLayout extends Layout {
408 /*** Default pattern string for log output. Currently set to the
409 string <b>"%m%n"</b> which just prints the application supplied
410 message. */
411 public static final String DEFAULT_CONVERSION_PATTERN = "%m%n";
412
413 /*** A conversion pattern equivalent to the TTCCCLayout.
414 Current value is <b>%r [%t] %p %c %x - %m%n</b>. */
415 public static final String TTCC_CONVERSION_PATTERN =
416 "%r [%t] %p %c %x - %m%n";
417
418 /***
419 * Initial size of internal buffer, no longer used.
420 * @deprecated since 1.3
421 */
422 protected final int BUF_SIZE = 256;
423
424 /***
425 * Maximum capacity of internal buffer, no longer used.
426 * @deprecated since 1.3
427 */
428 protected final int MAX_CAPACITY = 1024;
429
430 /***
431 * Customized pattern conversion rules are stored under this key in the
432 * {@link org.apache.log4j.spi.LoggerRepository LoggerRepository} object store.
433 */
434 public static final String PATTERN_RULE_REGISTRY = "PATTERN_RULE_REGISTRY";
435
436
437 /***
438 * Initial converter for pattern.
439 */
440 private PatternConverter head;
441
442 /***
443 * Conversion pattern.
444 */
445 private String conversionPattern;
446
447 /***
448 * True if any element in pattern formats information from exceptions.
449 */
450 private boolean handlesExceptions;
451
452 /***
453 Constructs a EnhancedPatternLayout using the DEFAULT_LAYOUT_PATTERN.
454
455 The default pattern just produces the application supplied message.
456 */
457 public EnhancedPatternLayout() {
458 this(DEFAULT_CONVERSION_PATTERN);
459 }
460
461 /***
462 * Constructs a EnhancedPatternLayout using the supplied conversion pattern.
463 * @param pattern conversion pattern.
464 */
465 public EnhancedPatternLayout(final String pattern) {
466 this.conversionPattern = pattern;
467 head = createPatternParser(
468 (pattern == null) ? DEFAULT_CONVERSION_PATTERN : pattern).parse();
469 if (head instanceof BridgePatternConverter) {
470 handlesExceptions = !((BridgePatternConverter) head).ignoresThrowable();
471 } else {
472 handlesExceptions = false;
473 }
474 }
475
476 /***
477 * Set the <b>ConversionPattern</b> option. This is the string which
478 * controls formatting and consists of a mix of literal content and
479 * conversion specifiers.
480 *
481 * @param conversionPattern conversion pattern.
482 */
483 public void setConversionPattern(final String conversionPattern) {
484 this.conversionPattern =
485 OptionConverter.convertSpecialChars(conversionPattern);
486 head = createPatternParser(this.conversionPattern).parse();
487 if (head instanceof BridgePatternConverter) {
488 handlesExceptions = !((BridgePatternConverter) head).ignoresThrowable();
489 } else {
490 handlesExceptions = false;
491 }
492 }
493
494 /***
495 * Returns the value of the <b>ConversionPattern</b> option.
496 * @return conversion pattern.
497 */
498 public String getConversionPattern() {
499 return conversionPattern;
500 }
501
502
503 /***
504 Returns PatternParser used to parse the conversion string. Subclasses
505 may override this to return a subclass of PatternParser which recognize
506 custom conversion characters.
507
508 @since 0.9.0
509 */
510 protected org.apache.log4j.helpers.PatternParser createPatternParser(String pattern) {
511 return new org.apache.log4j.pattern.BridgePatternParser(pattern);
512 }
513
514
515 /***
516 Activates the conversion pattern. Do not forget to call this method after
517 you change the parameters of the EnhancedPatternLayout instance.
518 */
519 public void activateOptions() {
520
521 }
522
523
524 /***
525 * Formats a logging event to a writer.
526 * @param event logging event to be formatted.
527 */
528 public String format(final LoggingEvent event) {
529 StringBuffer buf = new StringBuffer();
530 for(PatternConverter c = head;
531 c != null;
532 c = c.next) {
533 c.format(buf, event);
534 }
535 return buf.toString();
536 }
537
538 /***
539 * Will return false if any of the conversion specifiers in the pattern
540 * handles {@link Exception Exceptions}.
541 * @return true if the pattern formats any information from exceptions.
542 */
543 public boolean ignoresThrowable() {
544 return !handlesExceptions;
545 }
546 }