| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.log4j; |
| |
| import org.apache.log4j.spi.LoggingEvent; |
| import org.apache.log4j.spi.LocationInfo; |
| import org.apache.log4j.helpers.Transform; |
| |
| /** |
| * This layout outputs events in a HTML table. |
| * |
| * Appenders using this layout should have their encoding |
| * set to UTF-8 or UTF-16, otherwise events containing |
| * non ASCII characters could result in corrupted |
| * log files. |
| * |
| * @author Ceki Gülcü |
| */ |
| public class HTMLLayout extends Layout { |
| |
| protected final int BUF_SIZE = 256; |
| protected final int MAX_CAPACITY = 1024; |
| |
| static String TRACE_PREFIX = "<br> "; |
| |
| // output buffer appended to when format() is invoked |
| private StringBuffer sbuf = new StringBuffer(BUF_SIZE); |
| |
| /** |
| A string constant used in naming the option for setting the the |
| location information flag. Current value of this string |
| constant is <b>LocationInfo</b>. |
| |
| <p>Note that all option keys are case sensitive. |
| |
| @deprecated Options are now handled using the JavaBeans paradigm. |
| This constant is not longer needed and will be removed in the |
| <em>near</em> term. |
| |
| */ |
| public static final String LOCATION_INFO_OPTION = "LocationInfo"; |
| |
| /** |
| A string constant used in naming the option for setting the the |
| HTML document title. Current value of this string |
| constant is <b>Title</b>. |
| */ |
| public static final String TITLE_OPTION = "Title"; |
| |
| // Print no location info by default |
| boolean locationInfo = false; |
| |
| String title = "Log4J Log Messages"; |
| |
| /** |
| The <b>LocationInfo</b> option takes a boolean value. By |
| default, it is set to false which means there will be no location |
| information output by this layout. If the the option is set to |
| true, then the file name and line number of the statement |
| at the origin of the log statement will be output. |
| |
| <p>If you are embedding this layout within an {@link |
| org.apache.log4j.net.SMTPAppender} then make sure to set the |
| <b>LocationInfo</b> option of that appender as well. |
| */ |
| public |
| void setLocationInfo(boolean flag) { |
| locationInfo = flag; |
| } |
| |
| /** |
| Returns the current value of the <b>LocationInfo</b> option. |
| */ |
| public |
| boolean getLocationInfo() { |
| return locationInfo; |
| } |
| |
| /** |
| The <b>Title</b> option takes a String value. This option sets the |
| document title of the generated HTML document. |
| |
| <p>Defaults to 'Log4J Log Messages'. |
| */ |
| public |
| void setTitle(String title) { |
| this.title = title; |
| } |
| |
| /** |
| Returns the current value of the <b>Title</b> option. |
| */ |
| public |
| String getTitle() { |
| return title; |
| } |
| |
| /** |
| Returns the content type output by this layout, i.e "text/html". |
| */ |
| public |
| String getContentType() { |
| return "text/html"; |
| } |
| |
| /** |
| No options to activate. |
| */ |
| public |
| void activateOptions() { |
| } |
| |
| public |
| String format(LoggingEvent event) { |
| |
| if(sbuf.capacity() > MAX_CAPACITY) { |
| sbuf = new StringBuffer(BUF_SIZE); |
| } else { |
| sbuf.setLength(0); |
| } |
| |
| sbuf.append(Layout.LINE_SEP + "<tr>" + Layout.LINE_SEP); |
| |
| sbuf.append("<td>"); |
| sbuf.append(event.timeStamp - LoggingEvent.getStartTime()); |
| sbuf.append("</td>" + Layout.LINE_SEP); |
| |
| String escapedThread = Transform.escapeTags(event.getThreadName()); |
| sbuf.append("<td title=\"" + escapedThread + " thread\">"); |
| sbuf.append(escapedThread); |
| sbuf.append("</td>" + Layout.LINE_SEP); |
| |
| sbuf.append("<td title=\"Level\">"); |
| if (event.getLevel().equals(Level.DEBUG)) { |
| sbuf.append("<font color=\"#339933\">"); |
| sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel()))); |
| sbuf.append("</font>"); |
| } |
| else if(event.getLevel().isGreaterOrEqual(Level.WARN)) { |
| sbuf.append("<font color=\"#993300\"><strong>"); |
| sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel()))); |
| sbuf.append("</strong></font>"); |
| } else { |
| sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel()))); |
| } |
| sbuf.append("</td>" + Layout.LINE_SEP); |
| |
| String escapedLogger = Transform.escapeTags(event.getLoggerName()); |
| sbuf.append("<td title=\"" + escapedLogger + " category\">"); |
| sbuf.append(escapedLogger); |
| sbuf.append("</td>" + Layout.LINE_SEP); |
| |
| if(locationInfo) { |
| LocationInfo locInfo = event.getLocationInformation(); |
| sbuf.append("<td>"); |
| sbuf.append(Transform.escapeTags(locInfo.getFileName())); |
| sbuf.append(':'); |
| sbuf.append(locInfo.getLineNumber()); |
| sbuf.append("</td>" + Layout.LINE_SEP); |
| } |
| |
| sbuf.append("<td title=\"Message\">"); |
| sbuf.append(Transform.escapeTags(event.getRenderedMessage())); |
| sbuf.append("</td>" + Layout.LINE_SEP); |
| sbuf.append("</tr>" + Layout.LINE_SEP); |
| |
| if (event.getNDC() != null) { |
| sbuf.append("<tr><td bgcolor=\"#EEEEEE\" style=\"font-size : xx-small;\" colspan=\"6\" title=\"Nested Diagnostic Context\">"); |
| sbuf.append("NDC: " + Transform.escapeTags(event.getNDC())); |
| sbuf.append("</td></tr>" + Layout.LINE_SEP); |
| } |
| |
| String[] s = event.getThrowableStrRep(); |
| if(s != null) { |
| sbuf.append("<tr><td bgcolor=\"#993300\" style=\"color:White; font-size : xx-small;\" colspan=\"6\">"); |
| appendThrowableAsHTML(s, sbuf); |
| sbuf.append("</td></tr>" + Layout.LINE_SEP); |
| } |
| |
| return sbuf.toString(); |
| } |
| |
| void appendThrowableAsHTML(String[] s, StringBuffer sbuf) { |
| if(s != null) { |
| int len = s.length; |
| if(len == 0) |
| return; |
| sbuf.append(Transform.escapeTags(s[0])); |
| sbuf.append(Layout.LINE_SEP); |
| for(int i = 1; i < len; i++) { |
| sbuf.append(TRACE_PREFIX); |
| sbuf.append(Transform.escapeTags(s[i])); |
| sbuf.append(Layout.LINE_SEP); |
| } |
| } |
| } |
| |
| /** |
| Returns appropriate HTML headers. |
| */ |
| public |
| String getHeader() { |
| StringBuffer sbuf = new StringBuffer(); |
| sbuf.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">" + Layout.LINE_SEP); |
| sbuf.append("<html>" + Layout.LINE_SEP); |
| sbuf.append("<head>" + Layout.LINE_SEP); |
| sbuf.append("<title>" + title + "</title>" + Layout.LINE_SEP); |
| sbuf.append("<style type=\"text/css\">" + Layout.LINE_SEP); |
| sbuf.append("<!--" + Layout.LINE_SEP); |
| sbuf.append("body, table {font-family: arial,sans-serif; font-size: x-small;}" + Layout.LINE_SEP); |
| sbuf.append("th {background: #336699; color: #FFFFFF; text-align: left;}" + Layout.LINE_SEP); |
| sbuf.append("-->" + Layout.LINE_SEP); |
| sbuf.append("</style>" + Layout.LINE_SEP); |
| sbuf.append("</head>" + Layout.LINE_SEP); |
| sbuf.append("<body bgcolor=\"#FFFFFF\" topmargin=\"6\" leftmargin=\"6\">" + Layout.LINE_SEP); |
| sbuf.append("<hr size=\"1\" noshade>" + Layout.LINE_SEP); |
| sbuf.append("Log session start time " + new java.util.Date() + "<br>" + Layout.LINE_SEP); |
| sbuf.append("<br>" + Layout.LINE_SEP); |
| sbuf.append("<table cellspacing=\"0\" cellpadding=\"4\" border=\"1\" bordercolor=\"#224466\" width=\"100%\">" + Layout.LINE_SEP); |
| sbuf.append("<tr>" + Layout.LINE_SEP); |
| sbuf.append("<th>Time</th>" + Layout.LINE_SEP); |
| sbuf.append("<th>Thread</th>" + Layout.LINE_SEP); |
| sbuf.append("<th>Level</th>" + Layout.LINE_SEP); |
| sbuf.append("<th>Category</th>" + Layout.LINE_SEP); |
| if(locationInfo) { |
| sbuf.append("<th>File:Line</th>" + Layout.LINE_SEP); |
| } |
| sbuf.append("<th>Message</th>" + Layout.LINE_SEP); |
| sbuf.append("</tr>" + Layout.LINE_SEP); |
| return sbuf.toString(); |
| } |
| |
| /** |
| Returns the appropriate HTML footers. |
| */ |
| public |
| String getFooter() { |
| StringBuffer sbuf = new StringBuffer(); |
| sbuf.append("</table>" + Layout.LINE_SEP); |
| sbuf.append("<br>" + Layout.LINE_SEP); |
| sbuf.append("</body></html>"); |
| return sbuf.toString(); |
| } |
| |
| /** |
| The HTML layout handles the throwable contained in logging |
| events. Hence, this method return <code>false</code>. */ |
| public |
| boolean ignoresThrowable() { |
| return false; |
| } |
| } |