2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 package org.apache.log4j;
20 import org.apache.log4j.spi.LoggingEvent;
21 import org.apache.log4j.spi.LocationInfo;
22 import org.apache.log4j.helpers.Transform;
25 * This layout outputs events in a HTML table.
27 * Appenders using this layout should have their encoding
28 * set to UTF-8 or UTF-16, otherwise events containing
29 * non ASCII characters could result in corrupted
32 * @author Ceki Gülcü
34 public class HTMLLayout extends Layout {
36 protected final int BUF_SIZE = 256;
37 protected final int MAX_CAPACITY = 1024;
39 static String TRACE_PREFIX = "<br> ";
41 // output buffer appended to when format() is invoked
42 private StringBuffer sbuf = new StringBuffer(BUF_SIZE);
45 A string constant used in naming the option for setting the the
46 location information flag. Current value of this string
47 constant is <b>LocationInfo</b>.
49 <p>Note that all option keys are case sensitive.
51 @deprecated Options are now handled using the JavaBeans paradigm.
52 This constant is not longer needed and will be removed in the
56 public static final String LOCATION_INFO_OPTION = "LocationInfo";
59 A string constant used in naming the option for setting the the
60 HTML document title. Current value of this string
61 constant is <b>Title</b>.
63 public static final String TITLE_OPTION = "Title";
65 // Print no location info by default
66 boolean locationInfo = false;
68 String title = "Log4J Log Messages";
71 The <b>LocationInfo</b> option takes a boolean value. By
72 default, it is set to false which means there will be no location
73 information output by this layout. If the the option is set to
74 true, then the file name and line number of the statement
75 at the origin of the log statement will be output.
77 <p>If you are embedding this layout within an {@link
78 org.apache.log4j.net.SMTPAppender} then make sure to set the
79 <b>LocationInfo</b> option of that appender as well.
82 void setLocationInfo(boolean flag) {
87 Returns the current value of the <b>LocationInfo</b> option.
90 boolean getLocationInfo() {
95 The <b>Title</b> option takes a String value. This option sets the
96 document title of the generated HTML document.
98 <p>Defaults to 'Log4J Log Messages'.
101 void setTitle(String title) {
106 Returns the current value of the <b>Title</b> option.
114 Returns the content type output by this layout, i.e "text/html".
117 String getContentType() {
122 No options to activate.
125 void activateOptions() {
129 String format(LoggingEvent event) {
131 if(sbuf.capacity() > MAX_CAPACITY) {
132 sbuf = new StringBuffer(BUF_SIZE);
137 sbuf.append(Layout.LINE_SEP + "<tr>" + Layout.LINE_SEP);
140 sbuf.append(event.timeStamp - LoggingEvent.getStartTime());
141 sbuf.append("</td>" + Layout.LINE_SEP);
143 String escapedThread = Transform.escapeTags(event.getThreadName());
144 sbuf.append("<td title=\"" + escapedThread + " thread\">");
145 sbuf.append(escapedThread);
146 sbuf.append("</td>" + Layout.LINE_SEP);
148 sbuf.append("<td title=\"Level\">");
149 if (event.getLevel().equals(Level.DEBUG)) {
150 sbuf.append("<font color=\"#339933\">");
151 sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel())));
152 sbuf.append("</font>");
154 else if(event.getLevel().isGreaterOrEqual(Level.WARN)) {
155 sbuf.append("<font color=\"#993300\"><strong>");
156 sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel())));
157 sbuf.append("</strong></font>");
159 sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel())));
161 sbuf.append("</td>" + Layout.LINE_SEP);
163 String escapedLogger = Transform.escapeTags(event.getLoggerName());
164 sbuf.append("<td title=\"" + escapedLogger + " category\">");
165 sbuf.append(escapedLogger);
166 sbuf.append("</td>" + Layout.LINE_SEP);
169 LocationInfo locInfo = event.getLocationInformation();
171 sbuf.append(Transform.escapeTags(locInfo.getFileName()));
173 sbuf.append(locInfo.getLineNumber());
174 sbuf.append("</td>" + Layout.LINE_SEP);
177 sbuf.append("<td title=\"Message\">");
178 sbuf.append(Transform.escapeTags(event.getRenderedMessage()));
179 sbuf.append("</td>" + Layout.LINE_SEP);
180 sbuf.append("</tr>" + Layout.LINE_SEP);
182 if (event.getNDC() != null) {
183 sbuf.append("<tr><td bgcolor=\"#EEEEEE\" style=\"font-size : xx-small;\" colspan=\"6\" title=\"Nested Diagnostic Context\">");
184 sbuf.append("NDC: " + Transform.escapeTags(event.getNDC()));
185 sbuf.append("</td></tr>" + Layout.LINE_SEP);
188 String[] s = event.getThrowableStrRep();
190 sbuf.append("<tr><td bgcolor=\"#993300\" style=\"color:White; font-size : xx-small;\" colspan=\"6\">");
191 appendThrowableAsHTML(s, sbuf);
192 sbuf.append("</td></tr>" + Layout.LINE_SEP);
195 return sbuf.toString();
198 void appendThrowableAsHTML(String[] s, StringBuffer sbuf) {
204 sbuf.append(Transform.escapeTags(s[0]));
205 sbuf.append(Layout.LINE_SEP);
206 for(int i = 1; i < len; i++) {
207 sbuf.append(TRACE_PREFIX);
208 sbuf.append(Transform.escapeTags(s[i]));
209 sbuf.append(Layout.LINE_SEP);
215 Returns appropriate HTML headers.
219 StringBuffer sbuf = new StringBuffer();
220 sbuf.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">" + Layout.LINE_SEP);
221 sbuf.append("<html>" + Layout.LINE_SEP);
222 sbuf.append("<head>" + Layout.LINE_SEP);
223 sbuf.append("<title>" + title + "</title>" + Layout.LINE_SEP);
224 sbuf.append("<style type=\"text/css\">" + Layout.LINE_SEP);
225 sbuf.append("<!--" + Layout.LINE_SEP);
226 sbuf.append("body, table {font-family: arial,sans-serif; font-size: x-small;}" + Layout.LINE_SEP);
227 sbuf.append("th {background: #336699; color: #FFFFFF; text-align: left;}" + Layout.LINE_SEP);
228 sbuf.append("-->" + Layout.LINE_SEP);
229 sbuf.append("</style>" + Layout.LINE_SEP);
230 sbuf.append("</head>" + Layout.LINE_SEP);
231 sbuf.append("<body bgcolor=\"#FFFFFF\" topmargin=\"6\" leftmargin=\"6\">" + Layout.LINE_SEP);
232 sbuf.append("<hr size=\"1\" noshade>" + Layout.LINE_SEP);
233 sbuf.append("Log session start time " + new java.util.Date() + "<br>" + Layout.LINE_SEP);
234 sbuf.append("<br>" + Layout.LINE_SEP);
235 sbuf.append("<table cellspacing=\"0\" cellpadding=\"4\" border=\"1\" bordercolor=\"#224466\" width=\"100%\">" + Layout.LINE_SEP);
236 sbuf.append("<tr>" + Layout.LINE_SEP);
237 sbuf.append("<th>Time</th>" + Layout.LINE_SEP);
238 sbuf.append("<th>Thread</th>" + Layout.LINE_SEP);
239 sbuf.append("<th>Level</th>" + Layout.LINE_SEP);
240 sbuf.append("<th>Category</th>" + Layout.LINE_SEP);
242 sbuf.append("<th>File:Line</th>" + Layout.LINE_SEP);
244 sbuf.append("<th>Message</th>" + Layout.LINE_SEP);
245 sbuf.append("</tr>" + Layout.LINE_SEP);
246 return sbuf.toString();
250 Returns the appropriate HTML footers.
254 StringBuffer sbuf = new StringBuffer();
255 sbuf.append("</table>" + Layout.LINE_SEP);
256 sbuf.append("<br>" + Layout.LINE_SEP);
257 sbuf.append("</body></html>");
258 return sbuf.toString();
262 The HTML layout handles the throwable contained in logging
263 events. Hence, this method return <code>false</code>. */
265 boolean ignoresThrowable() {