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 018package org.apache.log4j.pattern; 019 020import org.apache.log4j.spi.LoggingEvent; 021import org.apache.log4j.spi.ThrowableInformation; 022 023 024/** 025 * Outputs the ThrowableInformation portion of the LoggingEvent. 026 * By default, outputs the full stack trace. %throwable{none} 027 * or %throwable{0} suppresses the stack trace. %throwable{short} 028 * or %throwable{1} outputs just the first line. %throwable{n} 029 * will output n lines for a positive integer or drop the last 030 * -n lines for a negative integer. 031 * 032 * @author Paul Smith 033 * 034 */ 035public class ThrowableInformationPatternConverter 036 extends LoggingEventPatternConverter { 037 038 /** 039 * Maximum lines of stack trace to output. 040 */ 041 private int maxLines = Integer.MAX_VALUE; 042 043 /** 044 * Private constructor. 045 * @param options options, may be null. 046 */ 047 private ThrowableInformationPatternConverter( 048 final String[] options) { 049 super("Throwable", "throwable"); 050 051 if ((options != null) && (options.length > 0)) { 052 if("none".equals(options[0])) { 053 maxLines = 0; 054 } else if("short".equals(options[0])) { 055 maxLines = 1; 056 } else { 057 try { 058 maxLines = Integer.parseInt(options[0]); 059 } catch(NumberFormatException ex) { 060 } 061 } 062 } 063 } 064 065 /** 066 * Gets an instance of the class. 067 * @param options pattern options, may be null. If first element is "short", 068 * only the first line of the throwable will be formatted. 069 * @return instance of class. 070 */ 071 public static ThrowableInformationPatternConverter newInstance( 072 final String[] options) { 073 return new ThrowableInformationPatternConverter(options); 074 } 075 076 /** 077 * {@inheritDoc} 078 */ 079 public void format(final LoggingEvent event, final StringBuffer toAppendTo) { 080 if (maxLines != 0) { 081 ThrowableInformation information = event.getThrowableInformation(); 082 083 if (information != null) { 084 String[] stringRep = information.getThrowableStrRep(); 085 086 int length = stringRep.length; 087 if (maxLines < 0) { 088 length += maxLines; 089 } else if (length > maxLines) { 090 length = maxLines; 091 } 092 093 for (int i = 0; i < length; i++) { 094 String string = stringRep[i]; 095 toAppendTo.append(string).append("\n"); 096 } 097 } 098 } 099 } 100 101 /** 102 * This converter obviously handles throwables. 103 * @return true. 104 */ 105 public boolean handlesThrowable() { 106 return true; 107 } 108}