You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by ca...@apache.org on 2008/09/20 04:37:56 UTC
svn commit: r697315 - in /logging/log4j/trunk: src/changes/
src/main/java/org/apache/log4j/ src/main/java/org/apache/log4j/spi/
src/main/java/org/apache/log4j/xml/
src/main/resources/org/apache/log4j/xml/ tests/input/xml/
tests/src/java/org/apache/log4...
Author: carnold
Date: Fri Sep 19 19:37:56 2008
New Revision: 697315
URL: http://svn.apache.org/viewvc?rev=697315&view=rev
Log:
Bug 45721: Add configurable ThrowableRenderers
Added:
logging/log4j/trunk/src/main/java/org/apache/log4j/DefaultThrowableRenderer.java
logging/log4j/trunk/src/main/java/org/apache/log4j/EnhancedThrowableRenderer.java
logging/log4j/trunk/src/main/java/org/apache/log4j/spi/ThrowableRenderer.java
logging/log4j/trunk/src/main/java/org/apache/log4j/spi/ThrowableRendererSupport.java
logging/log4j/trunk/tests/input/xml/throwableRenderer1.xml
logging/log4j/trunk/tests/src/java/org/apache/log4j/DefaultThrowableRendererTest.java
logging/log4j/trunk/tests/src/java/org/apache/log4j/EnhancedThrowableRendererTest.java
Modified:
logging/log4j/trunk/src/changes/changes.xml
logging/log4j/trunk/src/main/java/org/apache/log4j/Hierarchy.java
logging/log4j/trunk/src/main/java/org/apache/log4j/PropertyConfigurator.java
logging/log4j/trunk/src/main/java/org/apache/log4j/spi/LoggingEvent.java
logging/log4j/trunk/src/main/java/org/apache/log4j/spi/ThrowableInformation.java
logging/log4j/trunk/src/main/java/org/apache/log4j/xml/DOMConfigurator.java
logging/log4j/trunk/src/main/resources/org/apache/log4j/xml/log4j.dtd
logging/log4j/trunk/tests/src/java/org/apache/log4j/CoreTestSuite.java
logging/log4j/trunk/tests/src/java/org/apache/log4j/PatternLayoutTestCase.java
logging/log4j/trunk/tests/src/java/org/apache/log4j/PropertyConfiguratorTest.java
logging/log4j/trunk/tests/src/java/org/apache/log4j/xml/DOMTestCase.java
Modified: logging/log4j/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/src/changes/changes.xml?rev=697315&r1=697314&r2=697315&view=diff
==============================================================================
--- logging/log4j/trunk/src/changes/changes.xml (original)
+++ logging/log4j/trunk/src/changes/changes.xml Fri Sep 19 19:37:56 2008
@@ -61,6 +61,7 @@
<action action="fix" issue="45636">2 tests for DateLayout are failing because of ill initialized DateFormat.</action>
<action action="fix" issue="45659">Incorrect user mailing list URL.</action>
<action action="fix" issue="44386">NTEventLogAppender.dll for 64-bit editions for Microsoft Windows.</action>
+ <action action="fix" issue="45721">Add configuration of ThrowableRenderers and add org.apache.log4j.EnhancedThrowableRenderer.</action>
</release>
Added: logging/log4j/trunk/src/main/java/org/apache/log4j/DefaultThrowableRenderer.java
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/src/main/java/org/apache/log4j/DefaultThrowableRenderer.java?rev=697315&view=auto
==============================================================================
--- logging/log4j/trunk/src/main/java/org/apache/log4j/DefaultThrowableRenderer.java (added)
+++ logging/log4j/trunk/src/main/java/org/apache/log4j/DefaultThrowableRenderer.java Fri Sep 19 19:37:56 2008
@@ -0,0 +1,80 @@
+/*
+ * 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.ThrowableRenderer;
+
+import java.io.StringWriter;
+import java.io.PrintWriter;
+import java.io.LineNumberReader;
+import java.io.StringReader;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.util.ArrayList;
+
+/**
+ * Default implementation of ThrowableRenderer using
+ * Throwable.printStackTrace.
+ *
+ * @since 1.2.16
+ */
+public final class DefaultThrowableRenderer implements ThrowableRenderer {
+ /**
+ * Construct new instance.
+ */
+ public DefaultThrowableRenderer() {
+
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public String[] doRender(final Throwable throwable) {
+ return render(throwable);
+ }
+
+ /**
+ * Render throwable using Throwable.printStackTrace.
+ * @param throwable throwable, may not be null.
+ * @return string representation.
+ */
+ public static String[] render(final Throwable throwable) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ throwable.printStackTrace(pw);
+ pw.flush();
+ LineNumberReader reader = new LineNumberReader(
+ new StringReader(sw.toString()));
+ ArrayList lines = new ArrayList();
+ try {
+ String line = reader.readLine();
+ while(line != null) {
+ lines.add(line);
+ line = reader.readLine();
+ }
+ } catch(IOException ex) {
+ if (ex instanceof InterruptedIOException) {
+ Thread.currentThread().interrupt();
+ }
+ lines.add(ex.toString());
+ }
+ String[] tempRep = new String[lines.size()];
+ lines.toArray(tempRep);
+ return tempRep;
+ }
+}
Added: logging/log4j/trunk/src/main/java/org/apache/log4j/EnhancedThrowableRenderer.java
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/src/main/java/org/apache/log4j/EnhancedThrowableRenderer.java?rev=697315&view=auto
==============================================================================
--- logging/log4j/trunk/src/main/java/org/apache/log4j/EnhancedThrowableRenderer.java (added)
+++ logging/log4j/trunk/src/main/java/org/apache/log4j/EnhancedThrowableRenderer.java Fri Sep 19 19:37:56 2008
@@ -0,0 +1,157 @@
+/*
+ * 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.ThrowableRenderer;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.security.CodeSource;
+
+/**
+ * Enhanced implementation of ThrowableRenderer. Uses Throwable.getStackTrace
+ * if running on JDK 1.4 or later and delegates to DefaultThrowableRenderer.render
+ * on earlier virtual machines.
+ *
+ * @since 1.2.16
+ */
+public final class EnhancedThrowableRenderer implements ThrowableRenderer {
+ /**
+ * Throwable.getStackTrace() method.
+ */
+ private Method getStackTraceMethod;
+ /**
+ * StackTraceElement.getClassName() method.
+ */
+ private Method getClassNameMethod;
+
+
+ /**
+ * Construct new instance.
+ */
+ public EnhancedThrowableRenderer() {
+ try {
+ Class[] noArgs = null;
+ getStackTraceMethod = Throwable.class.getMethod("getStackTrace", noArgs);
+ Class ste = Class.forName("java.lang.StackTraceElement");
+ getClassNameMethod = ste.getMethod("getClassName", noArgs);
+ } catch(Exception ex) {
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String[] doRender(final Throwable throwable) {
+ if (getStackTraceMethod != null) {
+ try {
+ Object[] noArgs = null;
+ Object[] elements = (Object[]) getStackTraceMethod.invoke(throwable, noArgs);
+ String[] lines = new String[elements.length + 1];
+ lines[0] = throwable.toString();
+ for(int i = 0; i < elements.length; i++) {
+ lines[i+1] = formatElement(elements[i]);
+ }
+ return lines;
+ } catch(Exception ex) {
+ }
+ }
+ return DefaultThrowableRenderer.render(throwable);
+ }
+
+ /**
+ * Format one element from stack trace.
+ * @param element element, may not be null.
+ * @return string representation of element.
+ */
+ private String formatElement(final Object element) {
+ StringBuffer buf = new StringBuffer("\tat ");
+ buf.append(element);
+ try {
+ String className = getClassNameMethod.invoke(element, (Object[]) null).toString();
+ Class cls = findClass(className);
+ buf.append('[');
+ try {
+ CodeSource source = cls.getProtectionDomain().getCodeSource();
+ if (source != null) {
+ URL locationURL = source.getLocation();
+ if (locationURL != null) {
+ //
+ // if a file: URL
+ //
+ if ("file".equals(locationURL.getProtocol())) {
+ String path = locationURL.getPath();
+ if (path != null) {
+ //
+ // find the last file separator character
+ //
+ int lastSlash = path.lastIndexOf('/');
+ int lastBack = path.lastIndexOf(File.separatorChar);
+ if (lastBack > lastSlash) {
+ lastSlash = lastBack;
+ }
+ //
+ // if no separator or ends with separator (a directory)
+ // then output the URL, otherwise just the file name.
+ //
+ if (lastSlash <= 0 || lastSlash == path.length() - 1) {
+ buf.append(locationURL);
+ } else {
+ buf.append(path.substring(lastSlash + 1));
+ }
+ }
+ } else {
+ buf.append(locationURL);
+ }
+ }
+ }
+ } catch(SecurityException ex) {
+ }
+ buf.append(':');
+ Package pkg = cls.getPackage();
+ if (pkg != null) {
+ String implVersion = pkg.getImplementationVersion();
+ if (implVersion != null) {
+ buf.append(implVersion);
+ }
+ }
+ buf.append(']');
+ } catch(Exception ex) {
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Find class given class name.
+ * @param className class name, may not be null.
+ * @return class, will not be null.
+ * @throws ClassNotFoundException thrown if class can not be found.
+ */
+ private Class findClass(final String className) throws ClassNotFoundException {
+ try {
+ return Thread.currentThread().getContextClassLoader().loadClass(className);
+ } catch (ClassNotFoundException e) {
+ try {
+ return Class.forName(className);
+ } catch (ClassNotFoundException e1) {
+ return getClass().getClassLoader().loadClass(className);
+ }
+ }
+ }
+
+}
Modified: logging/log4j/trunk/src/main/java/org/apache/log4j/Hierarchy.java
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/src/main/java/org/apache/log4j/Hierarchy.java?rev=697315&r1=697314&r2=697315&view=diff
==============================================================================
--- logging/log4j/trunk/src/main/java/org/apache/log4j/Hierarchy.java (original)
+++ logging/log4j/trunk/src/main/java/org/apache/log4j/Hierarchy.java Fri Sep 19 19:37:56 2008
@@ -36,10 +36,11 @@
import org.apache.log4j.spi.HierarchyEventListener;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.RendererSupport;
-import org.apache.log4j.Appender;
import org.apache.log4j.or.RendererMap;
import org.apache.log4j.or.ObjectRenderer;
import org.apache.log4j.helpers.LogLog;
+import org.apache.log4j.spi.ThrowableRendererSupport;
+import org.apache.log4j.spi.ThrowableRenderer;
/**
This class is specialized in retrieving loggers by name and also
@@ -62,7 +63,7 @@
@author Ceki Gülcü
*/
-public class Hierarchy implements LoggerRepository, RendererSupport {
+public class Hierarchy implements LoggerRepository, RendererSupport, ThrowableRendererSupport {
private LoggerFactory defaultFactory;
private Vector listeners;
@@ -77,6 +78,8 @@
boolean emittedNoAppenderWarning = false;
boolean emittedNoResourceBundleWarning = false;
+ private ThrowableRenderer throwableRenderer = null;
+
/**
Create a new logger hierarchy.
@@ -396,10 +399,11 @@
}
}
rendererMap.clear();
+ throwableRenderer = null;
}
/**
- Does mothing.
+ Does nothing.
@deprecated Deprecated with no replacement.
*/
@@ -418,6 +422,20 @@
rendererMap.put(renderedClass, renderer);
}
+ /**
+ * {@inheritDoc}
+ */
+ public void setThrowableRenderer(final ThrowableRenderer renderer) {
+ throwableRenderer = renderer;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ThrowableRenderer getThrowableRenderer() {
+ return throwableRenderer;
+ }
+
/**
Shutting down a hierarchy will <em>safely</em> close and remove
Modified: logging/log4j/trunk/src/main/java/org/apache/log4j/PropertyConfigurator.java
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/src/main/java/org/apache/log4j/PropertyConfigurator.java?rev=697315&r1=697314&r2=697315&view=diff
==============================================================================
--- logging/log4j/trunk/src/main/java/org/apache/log4j/PropertyConfigurator.java (original)
+++ logging/log4j/trunk/src/main/java/org/apache/log4j/PropertyConfigurator.java Fri Sep 19 19:37:56 2008
@@ -32,6 +32,8 @@
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.OptionHandler;
import org.apache.log4j.spi.RendererSupport;
+import org.apache.log4j.spi.ThrowableRenderer;
+import org.apache.log4j.spi.ThrowableRendererSupport;
import java.io.FileInputStream;
import java.io.InputStream;
@@ -100,6 +102,7 @@
static final String APPENDER_PREFIX = "log4j.appender.";
static final String RENDERER_PREFIX = "log4j.renderer.";
static final String THRESHOLD_PREFIX = "log4j.threshold";
+ private static final String THROWABLE_RENDERER_PREFIX = "log4j.throwableRenderer";
/** Key for specifying the {@link org.apache.log4j.spi.LoggerFactory
LoggerFactory}. Currently set to "<code>log4j.loggerFactory</code>". */
@@ -232,6 +235,24 @@
log4j.renderer.my.Fruit=my.FruitRenderer
</pre>
+ <h3>ThrowableRenderer</h3>
+
+ You can customize the way an instance of Throwable is
+ converted to String before being logged. This is done by
+ specifying an {@link org.apache.log4j.spi.ThrowableRenderer ThrowableRenderer}.
+
+ <p>The syntax is:
+
+ <pre>
+ log4j.throwableRenderer=fully.qualified.name.of.rendering.class
+ log4j.throwableRenderer.paramName=paramValue
+ </pre>
+
+ As in,
+ <pre>
+ log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer
+ </pre>
+
<h3>Logger Factories</h3>
The usage of custom logger factories is discouraged and no longer
@@ -588,6 +609,23 @@
RendererMap.addRenderer((RendererSupport) hierarchy, renderedClass,
renderingClass);
}
+ } else if (key.equals(THROWABLE_RENDERER_PREFIX)) {
+ if (hierarchy instanceof ThrowableRendererSupport) {
+ ThrowableRenderer tr = (ThrowableRenderer)
+ OptionConverter.instantiateByKey(props,
+ THROWABLE_RENDERER_PREFIX,
+ org.apache.log4j.spi.ThrowableRenderer.class,
+ null);
+ if(tr == null) {
+ LogLog.error(
+ "Could not instantiate throwableRenderer.");
+ } else {
+ PropertySetter setter = new PropertySetter(tr);
+ setter.setProperties(props, THROWABLE_RENDERER_PREFIX + ".");
+ ((ThrowableRendererSupport) hierarchy).setThrowableRenderer(tr);
+
+ }
+ }
}
}
}
Modified: logging/log4j/trunk/src/main/java/org/apache/log4j/spi/LoggingEvent.java
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/src/main/java/org/apache/log4j/spi/LoggingEvent.java?rev=697315&r1=697314&r2=697315&view=diff
==============================================================================
--- logging/log4j/trunk/src/main/java/org/apache/log4j/spi/LoggingEvent.java (original)
+++ logging/log4j/trunk/src/main/java/org/apache/log4j/spi/LoggingEvent.java Fri Sep 19 19:37:56 2008
@@ -162,7 +162,7 @@
this.level = level;
this.message = message;
if(throwable != null) {
- this.throwableInfo = new ThrowableInformation(throwable);
+ this.throwableInfo = new ThrowableInformation(throwable, logger);
}
timeStamp = System.currentTimeMillis();
}
@@ -187,7 +187,7 @@
this.level = level;
this.message = message;
if(throwable != null) {
- this.throwableInfo = new ThrowableInformation(throwable);
+ this.throwableInfo = new ThrowableInformation(throwable, logger);
}
this.timeStamp = timeStamp;
Modified: logging/log4j/trunk/src/main/java/org/apache/log4j/spi/ThrowableInformation.java
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/src/main/java/org/apache/log4j/spi/ThrowableInformation.java?rev=697315&r1=697314&r2=697315&view=diff
==============================================================================
--- logging/log4j/trunk/src/main/java/org/apache/log4j/spi/ThrowableInformation.java (original)
+++ logging/log4j/trunk/src/main/java/org/apache/log4j/spi/ThrowableInformation.java Fri Sep 19 19:37:56 2008
@@ -17,8 +17,8 @@
package org.apache.log4j.spi;
-import java.io.*;
-import java.util.ArrayList;
+import org.apache.log4j.Category;
+import org.apache.log4j.DefaultThrowableRenderer;
/**
* ThrowableInformation is log4j's internal representation of
@@ -38,6 +38,7 @@
static final long serialVersionUID = -4748765566864322735L;
private transient Throwable throwable;
+ private transient Category category;
private String[] rep;
public
@@ -46,6 +47,17 @@
}
/**
+ * Create a new instance.
+ * @param throwable throwable, may not be null.
+ * @param category category used to obtain ThrowableRenderer, may be null.
+ * @since 1.2.16
+ */
+ public ThrowableInformation(Throwable throwable, Category category) {
+ this.throwable = throwable;
+ this.category = category;
+ }
+
+ /**
* Create new instance.
* @since 1.2.15
* @param r String representation of throwable.
@@ -62,31 +74,20 @@
return throwable;
}
- public
- String[] getThrowableStrRep() {
+ public synchronized String[] getThrowableStrRep() {
if(rep == null) {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- throwable.printStackTrace(pw);
- pw.flush();
- LineNumberReader reader = new LineNumberReader(
- new StringReader(sw.toString()));
- ArrayList lines = new ArrayList();
- try {
- String line = reader.readLine();
- while(line != null) {
- lines.add(line);
- line = reader.readLine();
- }
- } catch(IOException ex) {
- if (ex instanceof InterruptedIOException) {
- Thread.currentThread().interrupt();
+ ThrowableRenderer renderer = null;
+ if (category != null) {
+ LoggerRepository repo = category.getLoggerRepository();
+ if (repo instanceof ThrowableRendererSupport) {
+ renderer = ((ThrowableRendererSupport) repo).getThrowableRenderer();
}
- lines.add(ex.toString());
}
- String[] tempRep = new String[lines.size()];
- lines.toArray(tempRep);
- rep = tempRep;
+ if (renderer == null) {
+ rep = DefaultThrowableRenderer.render(throwable);
+ } else {
+ rep = renderer.doRender(throwable);
+ }
}
return (String[]) rep.clone();
}
Added: logging/log4j/trunk/src/main/java/org/apache/log4j/spi/ThrowableRenderer.java
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/src/main/java/org/apache/log4j/spi/ThrowableRenderer.java?rev=697315&view=auto
==============================================================================
--- logging/log4j/trunk/src/main/java/org/apache/log4j/spi/ThrowableRenderer.java (added)
+++ logging/log4j/trunk/src/main/java/org/apache/log4j/spi/ThrowableRenderer.java Fri Sep 19 19:37:56 2008
@@ -0,0 +1,33 @@
+/*
+ * 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.spi;
+
+/**
+ * Implemented by classes that render instances of
+ * java.lang.Throwable (exceptions and errors)
+ * into a string representation.
+ *
+ * @since 1.2.16
+ */
+public interface ThrowableRenderer {
+ /**
+ * Render Throwable.
+ * @param t throwable, may not be null.
+ * @return String representation.
+ */
+ public String[] doRender(Throwable t);
+}
Added: logging/log4j/trunk/src/main/java/org/apache/log4j/spi/ThrowableRendererSupport.java
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/src/main/java/org/apache/log4j/spi/ThrowableRendererSupport.java?rev=697315&view=auto
==============================================================================
--- logging/log4j/trunk/src/main/java/org/apache/log4j/spi/ThrowableRendererSupport.java (added)
+++ logging/log4j/trunk/src/main/java/org/apache/log4j/spi/ThrowableRendererSupport.java Fri Sep 19 19:37:56 2008
@@ -0,0 +1,37 @@
+/*
+ * 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.spi;
+
+/**
+ * Implemented by logger repositories that support configurable
+ * rendering of Throwables.
+ *
+ * @since 1.2.16
+ */
+public interface ThrowableRendererSupport {
+ /**
+ * Get throwable renderer.
+ * @return throwable renderer, may be null.
+ */
+ ThrowableRenderer getThrowableRenderer();
+
+ /**
+ * Set throwable renderer.
+ * @param renderer renderer, may be null.
+ */
+ void setThrowableRenderer(ThrowableRenderer renderer);
+}
Modified: logging/log4j/trunk/src/main/java/org/apache/log4j/xml/DOMConfigurator.java
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/src/main/java/org/apache/log4j/xml/DOMConfigurator.java?rev=697315&r1=697314&r2=697315&view=diff
==============================================================================
--- logging/log4j/trunk/src/main/java/org/apache/log4j/xml/DOMConfigurator.java (original)
+++ logging/log4j/trunk/src/main/java/org/apache/log4j/xml/DOMConfigurator.java Fri Sep 19 19:37:56 2008
@@ -35,6 +35,8 @@
import org.apache.log4j.spi.LoggerFactory;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.RendererSupport;
+import org.apache.log4j.spi.ThrowableRenderer;
+import org.apache.log4j.spi.ThrowableRendererSupport;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
@@ -89,6 +91,7 @@
static final String CONFIGURATION_TAG = "log4j:configuration";
static final String OLD_CONFIGURATION_TAG = "configuration";
static final String RENDERER_TAG = "renderer";
+ private static final String THROWABLE_RENDERER_TAG = "throwableRenderer";
static final String APPENDER_TAG = "appender";
static final String APPENDER_REF_TAG = "appender-ref";
static final String PARAM_TAG = "param";
@@ -591,6 +594,49 @@
}
}
+ /**
+ * Parses throwable renderer.
+ * @param element throwableRenderer element.
+ * @return configured throwable renderer.
+ * @since 1.2.16.
+ */
+ protected ThrowableRenderer parseThrowableRenderer(final Element element) {
+ String className = subst(element.getAttribute(CLASS_ATTR));
+ LogLog.debug("Parsing throwableRenderer of class: \""+className+"\"");
+ try {
+ Object instance = Loader.loadClass(className).newInstance();
+ ThrowableRenderer tr = (ThrowableRenderer)instance;
+ PropertySetter propSetter = new PropertySetter(tr);
+
+ NodeList params = element.getChildNodes();
+ final int length = params.getLength();
+
+ for (int loop = 0; loop < length; loop++) {
+ Node currentNode = (Node)params.item(loop);
+ if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
+ Element currentElement = (Element) currentNode;
+ String tagName = currentElement.getTagName();
+ if(tagName.equals(PARAM_TAG)) {
+ setParameter(currentElement, propSetter);
+ } else {
+ parseUnrecognizedElement(instance, currentElement, props);
+ }
+ }
+ }
+
+ propSetter.activate();
+ return tr;
+ }
+ catch (Exception oops) {
+ if (oops instanceof InterruptedException || oops instanceof InterruptedIOException) {
+ Thread.currentThread().interrupt();
+ }
+ LogLog.error("Could not create the ThrowableRenderer. Reported error follows.",
+ oops);
+ return null;
+ }
+ }
+
/**
Used internally to parse a level element.
*/
@@ -950,7 +996,14 @@
parseRoot(currentElement);
} else if(tagName.equals(RENDERER_TAG)) {
parseRenderer(currentElement);
- } else if (!(tagName.equals(APPENDER_TAG)
+ } else if(tagName.equals(THROWABLE_RENDERER_TAG)) {
+ if (repository instanceof ThrowableRendererSupport) {
+ ThrowableRenderer tr = parseThrowableRenderer(currentElement);
+ if (tr != null) {
+ ((ThrowableRendererSupport) repository).setThrowableRenderer(tr);
+ }
+ }
+ } else if (!(tagName.equals(APPENDER_TAG)
|| tagName.equals(CATEGORY_FACTORY_TAG)
|| tagName.equals(LOGGER_FACTORY_TAG))) {
quietParseUnrecognizedElement(repository, currentElement, props);
Modified: logging/log4j/trunk/src/main/resources/org/apache/log4j/xml/log4j.dtd
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/src/main/resources/org/apache/log4j/xml/log4j.dtd?rev=697315&r1=697314&r2=697315&view=diff
==============================================================================
--- logging/log4j/trunk/src/main/resources/org/apache/log4j/xml/log4j.dtd (original)
+++ logging/log4j/trunk/src/main/resources/org/apache/log4j/xml/log4j.dtd Fri Sep 19 19:37:56 2008
@@ -24,7 +24,8 @@
elements,appender elements, categories and an optional root
element. -->
-<!ELEMENT log4j:configuration (renderer*, appender*,plugin*, (category|logger)*,root?,
+<!ELEMENT log4j:configuration (renderer*, throwableRenderer?,
+ appender*,plugin*, (category|logger)*,root?,
(categoryFactory|loggerFactory)?)>
<!-- The "threshold" attribute takes a level value below which -->
@@ -56,6 +57,14 @@
renderingClass CDATA #REQUIRED
>
+<!-- throwableRenderer allows the user to customize the conversion
+ of exceptions to a string representation. -->
+<!ELEMENT throwableRenderer (param*)>
+<!ATTLIST throwableRenderer
+ class CDATA #REQUIRED
+>
+
+
<!-- Appenders must have a name and a class. -->
<!-- Appenders may contain an error handler, a layout, optional parameters -->
<!-- and filters. They may also reference (or include) other appenders. -->
Added: logging/log4j/trunk/tests/input/xml/throwableRenderer1.xml
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/tests/input/xml/throwableRenderer1.xml?rev=697315&view=auto
==============================================================================
--- logging/log4j/trunk/tests/input/xml/throwableRenderer1.xml (added)
+++ logging/log4j/trunk/tests/input/xml/throwableRenderer1.xml Fri Sep 19 19:37:56 2008
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<!--
+ 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.
+-->
+
+<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
+
+ <throwableRenderer class="org.apache.log4j.xml.DOMTestCase$MockThrowableRenderer">
+ <param name="showVersion" value="false"/>
+ </throwableRenderer>
+</log4j:configuration>
Modified: logging/log4j/trunk/tests/src/java/org/apache/log4j/CoreTestSuite.java
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/tests/src/java/org/apache/log4j/CoreTestSuite.java?rev=697315&r1=697314&r2=697315&view=diff
==============================================================================
--- logging/log4j/trunk/tests/src/java/org/apache/log4j/CoreTestSuite.java (original)
+++ logging/log4j/trunk/tests/src/java/org/apache/log4j/CoreTestSuite.java Fri Sep 19 19:37:56 2008
@@ -52,6 +52,8 @@
s.addTestSuite(org.apache.log4j.PropertyConfiguratorTest.class);
s.addTestSuite(org.apache.log4j.net.SMTPAppenderTest.class);
s.addTestSuite(org.apache.log4j.net.TelnetAppenderTest.class);
+ s.addTestSuite(org.apache.log4j.DefaultThrowableRendererTest.class);
+ s.addTestSuite(org.apache.log4j.EnhancedThrowableRendererTest.class);
return s;
}
}
Added: logging/log4j/trunk/tests/src/java/org/apache/log4j/DefaultThrowableRendererTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/tests/src/java/org/apache/log4j/DefaultThrowableRendererTest.java?rev=697315&view=auto
==============================================================================
--- logging/log4j/trunk/tests/src/java/org/apache/log4j/DefaultThrowableRendererTest.java (added)
+++ logging/log4j/trunk/tests/src/java/org/apache/log4j/DefaultThrowableRendererTest.java Fri Sep 19 19:37:56 2008
@@ -0,0 +1,37 @@
+/*
+ * 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 junit.framework.TestCase;
+import org.apache.log4j.spi.ThrowableRenderer;
+
+public class DefaultThrowableRendererTest extends TestCase {
+ public DefaultThrowableRendererTest(final String name) {
+ super(name);
+ }
+
+ public void testDefaultRender() {
+ ThrowableRenderer r = new DefaultThrowableRenderer();
+ Exception ex = new Exception();
+ String[] strRep = r.doRender(ex);
+ assertNotNull(strRep);
+ assertTrue(strRep.length > 0);
+ for(int i = 0; i < strRep.length; i++) {
+ assertNotNull(strRep[i]);
+ }
+ }
+}
Added: logging/log4j/trunk/tests/src/java/org/apache/log4j/EnhancedThrowableRendererTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/tests/src/java/org/apache/log4j/EnhancedThrowableRendererTest.java?rev=697315&view=auto
==============================================================================
--- logging/log4j/trunk/tests/src/java/org/apache/log4j/EnhancedThrowableRendererTest.java (added)
+++ logging/log4j/trunk/tests/src/java/org/apache/log4j/EnhancedThrowableRendererTest.java Fri Sep 19 19:37:56 2008
@@ -0,0 +1,48 @@
+/*
+ * 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 junit.framework.TestCase;
+import org.apache.log4j.spi.ThrowableRenderer;
+
+/**
+ * Test for EnhancedThrowableRenderer.
+ *
+ */
+public class EnhancedThrowableRendererTest extends TestCase {
+ /**
+ * Construct new instance.
+ * @param name test name.
+ */
+ public EnhancedThrowableRendererTest(final String name) {
+ super(name);
+ }
+
+ /**
+ * Render simple exception.
+ */
+ public void testEnhancedRender() {
+ ThrowableRenderer r = new EnhancedThrowableRenderer();
+ Exception ex = new Exception();
+ String[] strRep = r.doRender(ex);
+ assertNotNull(strRep);
+ assertTrue(strRep.length > 0);
+ for(int i = 0; i < strRep.length; i++) {
+ assertNotNull(strRep[i]);
+ }
+ }
+}
Modified: logging/log4j/trunk/tests/src/java/org/apache/log4j/PatternLayoutTestCase.java
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/tests/src/java/org/apache/log4j/PatternLayoutTestCase.java?rev=697315&r1=697314&r2=697315&view=diff
==============================================================================
--- logging/log4j/trunk/tests/src/java/org/apache/log4j/PatternLayoutTestCase.java (original)
+++ logging/log4j/trunk/tests/src/java/org/apache/log4j/PatternLayoutTestCase.java Fri Sep 19 19:37:56 2008
@@ -285,6 +285,7 @@
assertTrue(Compare.compare(FILTERED, "witness/patternLayout.14"));
}
+
void common() {
String oldThreadName = Thread.currentThread().getName();
Thread.currentThread().setName("main");
Modified: logging/log4j/trunk/tests/src/java/org/apache/log4j/PropertyConfiguratorTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/tests/src/java/org/apache/log4j/PropertyConfiguratorTest.java?rev=697315&r1=697314&r2=697315&view=diff
==============================================================================
--- logging/log4j/trunk/tests/src/java/org/apache/log4j/PropertyConfiguratorTest.java (original)
+++ logging/log4j/trunk/tests/src/java/org/apache/log4j/PropertyConfiguratorTest.java Fri Sep 19 19:37:56 2008
@@ -27,7 +27,10 @@
import org.apache.log4j.spi.OptionHandler;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
+import org.apache.log4j.spi.ThrowableRenderer;
+import org.apache.log4j.spi.ThrowableRendererSupport;
import org.apache.log4j.varia.LevelRangeFilter;
+import org.apache.log4j.helpers.OptionConverter;
/**
* Test property configurator.
@@ -267,4 +270,51 @@
LogManager.resetConfiguration();
}
+
+ /**
+ * Mock ThrowableRenderer for testThrowableRenderer. See bug 45721.
+ */
+ public static class MockThrowableRenderer implements ThrowableRenderer, OptionHandler {
+ private boolean activated = false;
+ private boolean showVersion = true;
+
+ public MockThrowableRenderer() {
+ }
+
+ public void activateOptions() {
+ activated = true;
+ }
+
+ public boolean isActivated() {
+ return activated;
+ }
+
+ public String[] doRender(final Throwable t) {
+ return new String[0];
+ }
+
+ public void setShowVersion(boolean v) {
+ showVersion = v;
+ }
+
+ public boolean getShowVersion() {
+ return showVersion;
+ }
+ }
+
+ /**
+ * Test of log4j.throwableRenderer support. See bug 45721.
+ */
+ public void testThrowableRenderer() {
+ Properties props = new Properties();
+ props.put("log4j.throwableRenderer", "org.apache.log4j.PropertyConfiguratorTest$MockThrowableRenderer");
+ props.put("log4j.throwableRenderer.showVersion", "false");
+ PropertyConfigurator.configure(props);
+ ThrowableRendererSupport repo = (ThrowableRendererSupport) LogManager.getLoggerRepository();
+ MockThrowableRenderer renderer = (MockThrowableRenderer) repo.getThrowableRenderer();
+ LogManager.resetConfiguration();
+ assertNotNull(renderer);
+ assertEquals(true, renderer.isActivated());
+ assertEquals(false, renderer.getShowVersion());
+ }
}
Modified: logging/log4j/trunk/tests/src/java/org/apache/log4j/xml/DOMTestCase.java
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/tests/src/java/org/apache/log4j/xml/DOMTestCase.java?rev=697315&r1=697314&r2=697315&view=diff
==============================================================================
--- logging/log4j/trunk/tests/src/java/org/apache/log4j/xml/DOMTestCase.java (original)
+++ logging/log4j/trunk/tests/src/java/org/apache/log4j/xml/DOMTestCase.java Fri Sep 19 19:37:56 2008
@@ -24,9 +24,13 @@
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.VectorAppender;
+import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.spi.ErrorHandler;
import org.apache.log4j.spi.LoggerFactory;
import org.apache.log4j.spi.LoggingEvent;
+import org.apache.log4j.spi.ThrowableRenderer;
+import org.apache.log4j.spi.OptionHandler;
+import org.apache.log4j.spi.ThrowableRendererSupport;
import org.apache.log4j.util.Compare;
import org.apache.log4j.util.ControlFilter;
import org.apache.log4j.util.Filter;
@@ -36,6 +40,8 @@
import org.apache.log4j.util.SunReflectFilter;
import org.apache.log4j.util.Transformer;
+import java.util.Properties;
+
public class DOMTestCase extends TestCase {
static String TEMP_A1 = "output/temp.A1";
@@ -332,4 +338,48 @@
assertEquals("output/subst-test.A1", file);
}
+ /**
+ * Mock ThrowableRenderer for testThrowableRenderer. See bug 45721.
+ */
+ public static class MockThrowableRenderer implements ThrowableRenderer, OptionHandler {
+ private boolean activated = false;
+ private boolean showVersion = true;
+
+ public MockThrowableRenderer() {
+ }
+
+ public void activateOptions() {
+ activated = true;
+ }
+
+ public boolean isActivated() {
+ return activated;
+ }
+
+ public String[] doRender(final Throwable t) {
+ return new String[0];
+ }
+
+ public void setShowVersion(boolean v) {
+ showVersion = v;
+ }
+
+ public boolean getShowVersion() {
+ return showVersion;
+ }
+ }
+
+ /**
+ * Test of log4j.throwableRenderer support. See bug 45721.
+ */
+ public void testThrowableRenderer1() {
+ DOMConfigurator.configure("input/xml/throwableRenderer1.xml");
+ ThrowableRendererSupport repo = (ThrowableRendererSupport) LogManager.getLoggerRepository();
+ MockThrowableRenderer renderer = (MockThrowableRenderer) repo.getThrowableRenderer();
+ LogManager.resetConfiguration();
+ assertNotNull(renderer);
+ assertEquals(true, renderer.isActivated());
+ assertEquals(false, renderer.getShowVersion());
+ }
+
}
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org