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ülcü 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}