001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 * 
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 * 
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018// Contributors: Christopher Williams
019//               Mathias Bogaert
020
021package org.apache.log4j;
022
023import org.apache.log4j.helpers.DateLayout;
024import org.apache.log4j.spi.LoggingEvent;
025
026/**
027 TTCC layout format consists of time, thread, category and nested
028 diagnostic context information, hence the name.
029
030 <p>Each of the four fields can be individually enabled or
031 disabled. The time format depends on the <code>DateFormat</code>
032 used.
033
034 <p>Here is an example TTCCLayout output with the
035 {@link org.apache.log4j.helpers.RelativeTimeDateFormat}.
036
037 <pre>
038176 [main] INFO  org.apache.log4j.examples.Sort - Populating an array of 2 elements in reverse order.
039225 [main] INFO  org.apache.log4j.examples.SortAlgo - Entered the sort method.
040262 [main] DEBUG org.apache.log4j.examples.SortAlgo.OUTER i=1 - Outer loop.
041276 [main] DEBUG org.apache.log4j.examples.SortAlgo.SWAP i=1 j=0 - Swapping intArray[0] = 1 and intArray[1] = 0
042290 [main] DEBUG org.apache.log4j.examples.SortAlgo.OUTER i=0 - Outer loop.
043304 [main] INFO  org.apache.log4j.examples.SortAlgo.DUMP - Dump of interger array:
044317 [main] INFO  org.apache.log4j.examples.SortAlgo.DUMP - Element [0] = 0
045331 [main] INFO  org.apache.log4j.examples.SortAlgo.DUMP - Element [1] = 1
046343 [main] INFO  org.apache.log4j.examples.Sort - The next log statement should be an error message.
047346 [main] ERROR org.apache.log4j.examples.SortAlgo.DUMP - Tried to dump an uninitialized array.
048        at org.apache.log4j.examples.SortAlgo.dump(SortAlgo.java:58)
049        at org.apache.log4j.examples.Sort.main(Sort.java:64)
050467 [main] INFO  org.apache.log4j.examples.Sort - Exiting main method.
051</pre>
052
053  <p>The first field is the number of milliseconds elapsed since the
054  start of the program. The second field is the thread outputting the
055  log statement. The third field is the level, the fourth field is
056  the category to which the statement belongs.
057
058  <p>The fifth field (just before the '-') is the nested diagnostic
059  context.  Note the nested diagnostic context may be empty as in the
060  first two statements. The text after the '-' is the message of the
061  statement.
062
063  <p><b>WARNING</b> Do not use the same TTCCLayout instance from
064  within different appenders. The TTCCLayout is not thread safe when
065  used in his way. However, it is perfectly safe to use a TTCCLayout
066  instance from just one appender.
067
068  <p>{@link PatternLayout} offers a much more flexible alternative.
069
070  @author Ceki G&uuml;lc&uuml;
071  @author <A HREF="mailto:heinz.richter@ecmwf.int">Heinz Richter</a>
072
073*/
074public class TTCCLayout extends DateLayout {
075
076  // Internal representation of options
077  private boolean threadPrinting    = true;
078  private boolean categoryPrefixing = true;
079  private boolean contextPrinting   = true;
080
081
082  protected final StringBuffer buf = new StringBuffer(256);
083
084
085  /**
086     Instantiate a TTCCLayout object with {@link
087     org.apache.log4j.helpers.RelativeTimeDateFormat} as the date
088     formatter in the local time zone.
089
090     @since 0.7.5 */
091  public TTCCLayout() {
092    this.setDateFormat(RELATIVE_TIME_DATE_FORMAT, null);
093  }
094
095
096  /**
097     Instantiate a TTCCLayout object using the local time zone. The
098     DateFormat used will depend on the <code>dateFormatType</code>.
099
100     <p>This constructor just calls the {@link
101     DateLayout#setDateFormat} method.
102
103     */
104  public TTCCLayout(String dateFormatType) {
105    this.setDateFormat(dateFormatType);
106  }
107
108
109  /**
110     The <b>ThreadPrinting</b> option specifies whether the name of the
111     current thread is part of log output or not. This is true by default.
112   */
113  public
114  void setThreadPrinting(boolean threadPrinting) {
115    this.threadPrinting = threadPrinting;
116  }
117
118  /**
119     Returns value of the <b>ThreadPrinting</b> option.
120   */
121  public
122  boolean getThreadPrinting() {
123    return threadPrinting;
124  }
125
126  /**
127     The <b>CategoryPrefixing</b> option specifies whether {@link Category}
128     name is part of log output or not. This is true by default.
129   */
130  public
131  void setCategoryPrefixing(boolean categoryPrefixing) {
132    this.categoryPrefixing = categoryPrefixing;
133  }
134
135  /**
136     Returns value of the <b>CategoryPrefixing</b> option.
137   */
138  public
139  boolean getCategoryPrefixing() {
140    return categoryPrefixing;
141  }
142
143  /**
144     The <b>ContextPrinting</b> option specifies log output will include
145     the nested context information belonging to the current thread.
146     This is true by default.
147   */
148  public
149  void setContextPrinting(boolean contextPrinting) {
150    this.contextPrinting = contextPrinting;
151  }
152
153  /**
154     Returns value of the <b>ContextPrinting</b> option.
155   */
156  public
157  boolean getContextPrinting() {
158    return contextPrinting;
159  }
160
161  /**
162   In addition to the level of the statement and message, the
163   returned byte array includes time, thread, category and {@link NDC}
164   information.
165
166   <p>Time, thread, category and diagnostic context are printed
167   depending on options.
168
169    @param event The event to format
170
171  */
172  public
173  String format(LoggingEvent event) {
174
175    // Reset buf
176    buf.setLength(0);
177
178    dateFormat(buf, event);
179
180    if(this.threadPrinting) {
181      buf.append('[');
182      buf.append(event.getThreadName());
183      buf.append("] ");
184    }
185    buf.append(event.getLevel().toString());
186    buf.append(' ');
187
188    if(this.categoryPrefixing) {
189      buf.append(event.getLoggerName());
190      buf.append(' ');
191    }
192
193    if(this.contextPrinting) {
194       String ndc = event.getNDC();
195
196      if(ndc != null) {
197        buf.append(ndc);
198        buf.append(' ');
199      }
200    }
201    buf.append("- ");
202    buf.append(event.getRenderedMessage());
203    buf.append(LINE_SEP);
204    return buf.toString();
205  }
206
207 /**
208     The TTCCLayout does not handle the throwable contained within
209     {@link LoggingEvent LoggingEvents}. Thus, it returns
210     <code>true</code>.
211
212     @since version 0.8.4 */
213  public
214  boolean ignoresThrowable() {
215    return true;
216  }
217}