View Javadoc
1   package ch.qos.logback.classic.layout;
2   
3   import ch.qos.logback.classic.pattern.ThrowableProxyConverter;
4   import ch.qos.logback.classic.spi.ILoggingEvent;
5   import ch.qos.logback.classic.spi.IThrowableProxy;
6   import ch.qos.logback.core.CoreConstants;
7   import ch.qos.logback.core.LayoutBase;
8   import ch.qos.logback.core.util.CachingDateFormatter;
9   import org.slf4j.event.KeyValuePair;
10  
11  import java.util.List;
12  
13  /**
14   * A layout with a fixed format. The output is equivalent to that produced by
15   * {@link ch.qos.logback.classic.PatternLayout PatternLayout} with the pattern:
16   * </p>
17   * 
18   * <pre>
19   * %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%kvp- %msg%n
20   * </pre>
21   * 
22   * <p>
23   * TTLLLayout has the advantage of faster load time whereas
24   * {@link ch.qos.logback.classic.PatternLayout PatternLayout} requires roughly
25   * 40 milliseconds to load its parser classes. Note that the second run of
26   * PatternLayout will be much much faster (approx. 10 micro-seconds).
27   * </p>
28   * 
29   * <p>
30   * Fixed format layouts such as TTLLLayout should be considered as an
31   * alternative to PatternLayout only if the extra 40 milliseconds at application
32   * start-up is considered significant.
33   * </p>
34   * 
35   * @author Ceki G&uuml;lc&uuml;
36   * @since 1.1.6
37   */
38  public class TTLLLayout extends LayoutBase<ILoggingEvent> {
39  
40      CachingDateFormatter cachingDateFormatter = new CachingDateFormatter("HH:mm:ss.SSS");
41      ThrowableProxyConverter tpc = new ThrowableProxyConverter();
42  
43      @Override
44      public void start() {
45          tpc.start();
46          super.start();
47      }
48  
49      @Override
50      public String doLayout(ILoggingEvent event) {
51          if (!isStarted()) {
52              return CoreConstants.EMPTY_STRING;
53          }
54          StringBuilder sb = new StringBuilder();
55  
56          long timestamp = event.getTimeStamp();
57  
58          sb.append(cachingDateFormatter.format(timestamp));
59          sb.append(" [");
60          sb.append(event.getThreadName());
61          sb.append("] ");
62          sb.append(event.getLevel().toString());
63          sb.append(" ");
64          sb.append(event.getLoggerName());
65          sb.append(" -");
66          kvp(event, sb);
67          sb.append("- ");
68          sb.append(event.getFormattedMessage());
69          sb.append(CoreConstants.LINE_SEPARATOR);
70          IThrowableProxy tp = event.getThrowableProxy();
71          if (tp != null) {
72              String stackTrace = tpc.convert(event);
73              sb.append(stackTrace);
74          }
75          return sb.toString();
76      }
77  
78      static final char DOUBLE_QUOTE_CHAR = '"';
79      private void kvp(ILoggingEvent event, StringBuilder sb) {
80          List<KeyValuePair> kvpList = event.getKeyValuePairs();
81          if (kvpList == null || kvpList.isEmpty()) {
82              return;
83          }
84  
85          int len = kvpList.size();
86  
87          for (int i = 0; i < len; i++) {
88              KeyValuePair kvp = kvpList.get(i);
89              if (i != 0)
90                  sb.append(' ');
91              sb.append(String.valueOf(kvp.key));
92              sb.append('=');
93              sb.append(DOUBLE_QUOTE_CHAR);
94              sb.append(String.valueOf(kvp.value));
95              sb.append(DOUBLE_QUOTE_CHAR);
96          }
97      }
98  
99  }