Author: rgoers
Date: Mon Apr 1 17:52:39 2013
New Revision: 1463226
URL: http://svn.apache.org/r1463226
Log:
LOG4J2-160 - Move Throwable pattern converter options processing to
ThrowableFormatOptions class.
Added:
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/impl/
logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptionsTest.java
logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowableTest.java
logging/log4j/log4j2/trunk/core/src/test/resources/log4j-throwable.xml
Modified:
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverter.java
logging/log4j/log4j2/trunk/src/changes/changes.xml
Added:
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java?rev=1463226&view=auto
==============================================================================
---
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
(added)
+++
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
Mon Apr 1 17:52:39 2013
@@ -0,0 +1,227 @@
+/*
+ * 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.logging.log4j.core.impl;
+
+import org.apache.logging.log4j.core.helpers.Constants;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+
+/**
+ * Contains options which control how a {@code throwable} pattern is formatted.
+ */
+public final class ThrowableFormatOptions {
+
+ /**
+ * Default instance of {@code ThrowableFormatOptions}.
+ */
+ protected static final ThrowableFormatOptions DEFAULT = new
ThrowableFormatOptions();
+
+ /**
+ * Format the whole stack trace.
+ */
+ private static final String FULL = "full";
+
+ /**
+ * Do not format the exception.
+ */
+ private static final String NONE = "none";
+
+ /**
+ * Format only the first line of the throwable.
+ */
+ private static final String SHORT = "short";
+
+ /**
+ * The number of lines to write.
+ */
+ private final int lines;
+
+ /**
+ * The stack trace separator.
+ */
+ private final String separator;
+
+ /**
+ * The list of packages to filter.
+ */
+ private final List<String> packages;
+
+ /**
+ * Construct the options for printing stack trace.
+ * @param lines The number of lines.
+ * @param separator The stack trace separator.
+ * @param packages The packages to filter.
+ */
+ protected ThrowableFormatOptions(final Integer lines, final String
separator, final List<String> packages) {
+ this.lines = lines == null ? Integer.MAX_VALUE : lines;
+ this.separator = separator == null ? Constants.LINE_SEP : separator;
+ this.packages = packages;
+ }
+
+ /**
+ * Construct the options for printing stack trace.
+ * @param packages The packages to filter.
+ */
+ protected ThrowableFormatOptions(final List<String> packages) {
+ this(null, null, packages);
+ }
+
+ /**
+ * Construct the options for printing stack trace.
+ */
+ protected ThrowableFormatOptions() {
+ this(null, null, null);
+ }
+
+ /**
+ * Returns the number of lines to write.
+ * @return The number of lines to write.
+ */
+ public int getLines() {
+ return this.lines;
+ }
+
+ /**
+ * Returns the stack trace separator.
+ * @return The stack trace separator.
+ */
+ public String getSeparator() {
+ return this.separator;
+ }
+
+ /**
+ * Returns the list of packages to filter.
+ * @return The list of packages to filter.
+ */
+ public List<String> getPackages() {
+ return this.packages;
+ }
+
+ /**
+ * Determines if all lines should be printed.
+ * @return true for all lines, false otherwise.
+ */
+ public boolean allLines() {
+ return this.lines == Integer.MAX_VALUE;
+ }
+
+ /**
+ * Determines if any lines should be printed.
+ * @return true for any lines, false otherwise.
+ */
+ public boolean anyLines() {
+ return this.lines > 0;
+ }
+
+ /**
+ * Returns the minimum between the lines and the max lines.
+ * @param maxLines The maximum number of lines.
+ * @return The number of lines to print.
+ */
+ public int minLines(final int maxLines) {
+ return this.lines > maxLines ? maxLines : this.lines;
+ }
+
+ /**
+ * Determines if there are any packages to filter.
+ * @return true if there are packages, false otherwise.
+ */
+ public boolean hasPackages() {
+ return this.packages != null && !this.packages.isEmpty();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuilder s = new StringBuilder();
+ s.append("{").append(allLines() ? FULL : this.lines == 2 ? SHORT :
anyLines() ? String.valueOf(this.lines) : NONE).append("}");
+ s.append("{separator(").append(this.separator).append(")}");
+ if (hasPackages()) {
+ s.append("{filters(");
+ for (String p : this.packages) {
+ s.append(p).append(",");
+ }
+ s.deleteCharAt(s.length() - 1);
+ s.append(")}");
+ }
+ return s.toString();
+ }
+
+ /**
+ * Create a new instance based on the array of options.
+ * @param options The array of options.
+ */
+ public static ThrowableFormatOptions newInstance(String[] options) {
+ if (options == null || options.length == 0) {
+ return DEFAULT;
+ } else {
+ // NOTE: The following code is present for backward compatibility
+ // and was copied from Extended/RootThrowablePatternConverter.
+ // This supports a single option with the format:
+ // %xEx{["none"|"short"|"full"|depth],[filters(packages)}
+ // However, the convention for multiple options should be:
+ // %xEx{["none"|"short"|"full"|depth]}[{filters(packages)}]
+ if (options.length == 1 && options[0] != null &&
options[0].length() > 0) {
+ final String[] opts = options[0].split(",", 2);
+ final String first = opts[0].trim();
+ final Scanner scanner = new Scanner(first);
+ if (opts.length > 1 && (first.equalsIgnoreCase(FULL) ||
first.equalsIgnoreCase(SHORT) || first.equalsIgnoreCase(NONE) ||
scanner.hasNextInt())) {
+ options = new String[]{first, opts[1].trim()};
+ }
+ }
+
+ int lines = DEFAULT.lines;
+ String separator = DEFAULT.separator;
+ List<String> packages = DEFAULT.packages;
+ for (int i = 0; i < options.length; i++) {
+ if (options[i] != null) {
+ final String option = options[i].trim();
+ if (option.length() == 0) {
+ // continue;
+ } else if (option.startsWith("separator(") &&
option.endsWith(")")) {
+ separator = option.substring("separator(".length(),
option.length() - 1);
+ } else if (option.startsWith("filters(") &&
option.endsWith(")")) {
+ final String filterStr =
option.substring("filters(".length(), option.length() - 1);
+ if (filterStr.length() > 0) {
+ final String[] array = filterStr.split(",");
+ if (array.length > 0) {
+ packages = new ArrayList<String>(array.length);
+ for (String token : array) {
+ token = token.trim();
+ if (token.length() > 0) {
+ packages.add(token);
+ }
+ }
+ }
+ }
+ } else if (option.equalsIgnoreCase(NONE)) {
+ lines = 0;
+ } else if (option.equalsIgnoreCase(SHORT)) {
+ lines = 2;
+ } else if (!option.equalsIgnoreCase(FULL)) {
+ lines = Integer.parseInt(option);
+ }
+ }
+ }
+ return new ThrowableFormatOptions(lines, separator, packages);
+ }
+ }
+}
Modified:
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java?rev=1463226&r1=1463225&r2=1463226&view=diff
==============================================================================
---
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java
(original)
+++
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java
Mon Apr 1 17:52:39 2013
@@ -18,12 +18,9 @@ package org.apache.logging.log4j.core.pa
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.helpers.Constants;
import org.apache.logging.log4j.core.impl.ThrowableProxy;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Scanner;
-
/**
* Outputs the Throwable portion of the LoggingEvent as a full stacktrace
* unless this converter's option is 'short', where it just outputs the first
line of the trace, or if
@@ -36,10 +33,6 @@ import java.util.Scanner;
@ConverterKeys({"xEx", "xThrowable", "xException" })
public final class ExtendedThrowablePatternConverter extends
ThrowablePatternConverter {
- private static final String FILTERS = "filters(";
-
- private final List<String> packages;
-
/**
* Private constructor.
*
@@ -47,20 +40,6 @@ public final class ExtendedThrowablePatt
*/
private ExtendedThrowablePatternConverter(final String[] options) {
super("ExtendedThrowable", "throwable", options);
- List<String> tempPackages = null;
- if (options != null && options.length > 1) {
- if (options[1].startsWith(FILTERS) && options[1].endsWith(")")) {
- final String filterStr =
options[1].substring(FILTERS.length(), options[1].length() - 1);
- final String[] array = filterStr.split(",");
- if (array.length > 0) {
- tempPackages = new ArrayList<String>(array.length);
- for (final String token : array) {
- tempPackages.add(token.trim());
- }
- }
- }
- }
- packages = tempPackages;
}
/**
@@ -71,23 +50,7 @@ public final class ExtendedThrowablePatt
* @return instance of class.
*/
public static ExtendedThrowablePatternConverter newInstance(final String[]
options) {
- String type = null;
- String[] array = options;
- if (options != null && options.length == 1 && options[0].length() > 0)
{
- final String[] opts = options[0].split(",", 2);
- final String first = opts[0].trim();
- String filter;
- final Scanner scanner = new Scanner(first);
- if (first.equalsIgnoreCase(FULL) || first.equalsIgnoreCase(SHORT)
|| scanner.hasNextInt()) {
- type = first;
- filter = opts[1].trim();
- } else {
- filter = options[0].trim();
- }
- array = new String[] {type, filter};
- }
-
- return new ExtendedThrowablePatternConverter(array);
+ return new ExtendedThrowablePatternConverter(options);
}
/**
@@ -96,23 +59,26 @@ public final class ExtendedThrowablePatt
@Override
public void format(final LogEvent event, final StringBuilder toAppendTo) {
final Throwable throwable = event.getThrown();
- if (throwable != null && lines > 0) {
+ if (throwable != null && options.anyLines()) {
if (!(throwable instanceof ThrowableProxy)) {
super.format(event, toAppendTo);
return;
}
final ThrowableProxy t = (ThrowableProxy) throwable;
- final String trace = t.getExtendedStackTrace(packages);
+ final String trace =
t.getExtendedStackTrace(options.getPackages());
final int len = toAppendTo.length();
if (len > 0 && !Character.isWhitespace(toAppendTo.charAt(len -
1))) {
toAppendTo.append(" ");
}
- if (lines != Integer.MAX_VALUE) {
+ if (!options.allLines() ||
!Constants.LINE_SEP.equals(options.getSeparator())) {
final StringBuilder sb = new StringBuilder();
- final String[] array = trace.split("\n");
- final int limit = lines > array.length ? array.length : lines;
- for (int i = 0; i < limit; ++i) {
- sb.append(array[i]).append("\n");
+ final String[] array = trace.split(Constants.LINE_SEP);
+ final int limit = options.minLines(array.length) - 1;
+ for (int i = 0; i <= limit; ++i) {
+ sb.append(array[i]);
+ if (i < limit) {
+ sb.append(options.getSeparator());
+ }
}
toAppendTo.append(sb.toString());
Modified:
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java?rev=1463226&r1=1463225&r2=1463226&view=diff
==============================================================================
---
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java
(original)
+++
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java
Mon Apr 1 17:52:39 2013
@@ -18,13 +18,9 @@ package org.apache.logging.log4j.core.pa
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.helpers.Constants;
import org.apache.logging.log4j.core.impl.ThrowableProxy;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Scanner;
-
-
/**
* Outputs the Throwable portion of the LoggingEvent as a full stacktrace
* unless this converter's option is 'short', where it just outputs the first
line of the trace, or if
@@ -37,10 +33,6 @@ import java.util.Scanner;
@ConverterKeys({"rEx", "rThrowable", "rException" })
public final class RootThrowablePatternConverter extends
ThrowablePatternConverter {
- private static final String FILTERS = "filters(";
-
- private final List<String> packages;
-
/**
* Private constructor.
*
@@ -48,20 +40,6 @@ public final class RootThrowablePatternC
*/
private RootThrowablePatternConverter(final String[] options) {
super("RootThrowable", "throwable", options);
- List<String> tempPackages = null;
- if (options != null && options.length > 1) {
- if (options[1].startsWith(FILTERS) && options[1].endsWith(")")) {
- final String filterStr =
options[1].substring(FILTERS.length(), options[1].length() - 1);
- final String[] array = filterStr.split(",");
- if (array.length > 0) {
- tempPackages = new ArrayList<String>(array.length);
- for (final String token : array) {
- tempPackages.add(token.trim());
- }
- }
- }
- }
- packages = tempPackages;
}
/**
@@ -72,23 +50,7 @@ public final class RootThrowablePatternC
* @return instance of class.
*/
public static RootThrowablePatternConverter newInstance(final String[]
options) {
- String type = null;
- String[] array = options;
- if (options != null && options.length == 1 && options[0].length() > 0)
{
- final String[] opts = options[0].split(",", 2);
- final String first = opts[0].trim();
- String filter;
- final Scanner scanner = new Scanner(first);
- if (first.equalsIgnoreCase(FULL) || first.equalsIgnoreCase(SHORT)
|| scanner.hasNextInt()) {
- type = first;
- filter = opts[1].trim();
- } else {
- filter = options[0].trim();
- }
- array = new String[] {type, filter};
- }
-
- return new RootThrowablePatternConverter(array);
+ return new RootThrowablePatternConverter(options);
}
/**
@@ -97,23 +59,26 @@ public final class RootThrowablePatternC
@Override
public void format(final LogEvent event, final StringBuilder toAppendTo) {
final Throwable throwable = event.getThrown();
- if (throwable != null && lines > 0) {
+ if (throwable != null && options.anyLines()) {
if (!(throwable instanceof ThrowableProxy)) {
super.format(event, toAppendTo);
return;
}
final ThrowableProxy t = (ThrowableProxy) throwable;
- final String trace = t.getRootCauseStackTrace(packages);
+ final String trace =
t.getRootCauseStackTrace(options.getPackages());
final int len = toAppendTo.length();
if (len > 0 && !Character.isWhitespace(toAppendTo.charAt(len -
1))) {
toAppendTo.append(" ");
}
- if (lines != Integer.MAX_VALUE) {
+ if (!options.allLines() ||
!Constants.LINE_SEP.equals(options.getSeparator())) {
final StringBuilder sb = new StringBuilder();
- final String[] array = trace.split("\n");
- final int limit = lines > array.length ? array.length : lines;
- for (int i = 0; i < limit; ++i) {
- sb.append(array[i]).append("\n");
+ final String[] array = trace.split(Constants.LINE_SEP);
+ final int limit = options.minLines(array.length) - 1;
+ for (int i = 0; i <= limit; ++i) {
+ sb.append(array[i]);
+ if (i < limit) {
+ sb.append(options.getSeparator());
+ }
}
toAppendTo.append(sb.toString());
Modified:
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverter.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverter.java?rev=1463226&r1=1463225&r2=1463226&view=diff
==============================================================================
---
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverter.java
(original)
+++
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverter.java
Mon Apr 1 17:52:39 2013
@@ -18,6 +18,8 @@ package org.apache.logging.log4j.core.pa
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.helpers.Constants;
+import org.apache.logging.log4j.core.impl.ThrowableFormatOptions;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -33,28 +35,9 @@ import java.io.StringWriter;
public class ThrowablePatternConverter extends LogEventPatternConverter {
/**
- * Do not format the exception.
- */
- protected static final String NONE = "none";
- /**
- * Format the whole stack trace.
- */
- protected static final String FULL = "full";
- /**
- * Format only the first line of the throwable.
- */
- protected static final String SHORT = "short";
- /**
- * If "short", only first line of throwable report will be formatted.<br>
- * If "full", the whole stack trace will be formatted.<br>
- * If "numeric" the output will be limited to the specified number of
lines.
- */
- protected final String option;
-
- /**
* The number of lines to write.
*/
- protected final int lines;
+ protected final ThrowableFormatOptions options;
/**
* Constructor.
@@ -64,22 +47,7 @@ public class ThrowablePatternConverter e
*/
protected ThrowablePatternConverter(final String name, final String style,
final String[] options) {
super(name, style);
- int count = Integer.MAX_VALUE;
- if (options != null && options.length > 0) {
- option = options[0];
- if (option == null) {
- } else if (option.equalsIgnoreCase(NONE)) {
- count = 0;
- } else if (option.equalsIgnoreCase(SHORT)) {
- count = 2;
- } else if (!option.equalsIgnoreCase(FULL)) {
- count = Integer.parseInt(option);
- }
-
- } else {
- option = null;
- }
- lines = count;
+ this.options = ThrowableFormatOptions.newInstance(options);
}
/**
@@ -100,19 +68,22 @@ public class ThrowablePatternConverter e
public void format(final LogEvent event, final StringBuilder toAppendTo) {
final Throwable t = event.getThrown();
- if (t != null && lines > 0) {
+ if (t != null && options.anyLines()) {
final StringWriter w = new StringWriter();
t.printStackTrace(new PrintWriter(w));
final int len = toAppendTo.length();
if (len > 0 && !Character.isWhitespace(toAppendTo.charAt(len -
1))) {
toAppendTo.append(" ");
}
- if (lines != Integer.MAX_VALUE) {
+ if (!options.allLines() ||
!Constants.LINE_SEP.equals(options.getSeparator())) {
final StringBuilder sb = new StringBuilder();
- final String[] array = w.toString().split("\n");
- final int limit = lines > array.length ? array.length : lines;
- for (int i = 0; i < limit; ++i) {
- sb.append(array[i]).append("\n");
+ final String[] array = w.toString().split(Constants.LINE_SEP);
+ final int limit = options.minLines(array.length) - 1;
+ for (int i = 0; i <= limit; ++i) {
+ sb.append(array[i]);
+ if (i < limit) {
+ sb.append(options.getSeparator());
+ }
}
toAppendTo.append(sb.toString());
Added:
logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptionsTest.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptionsTest.java?rev=1463226&view=auto
==============================================================================
---
logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptionsTest.java
(added)
+++
logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptionsTest.java
Mon Apr 1 17:52:39 2013
@@ -0,0 +1,334 @@
+/*
+ * 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.logging.log4j.core.impl;
+
+import org.apache.logging.log4j.core.helpers.Constants;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Unit tests for {@code ThrowableFormatOptions}.
+ */
+public final class ThrowableFormatOptionsTest {
+
+ /**
+ * Runs a given test comparing against the expected values.
+ * @param options The list of options to parse.
+ * @param expectedLines The expected lines.
+ * @param expectedPackages The expected package filters.
+ * @param expectedSeparator The expected seperator.
+ */
+ private static void test(final String[] options, final int expectedLines,
final String expectedSeparator, final List<String> expectedPackages) {
+ final ThrowableFormatOptions o =
ThrowableFormatOptions.newInstance(options);
+ assertEquals("getLines", expectedLines, o.getLines());
+ assertEquals("getSeparator", expectedSeparator, o.getSeparator());
+ assertEquals("getPackages", expectedPackages, o.getPackages());
+ assertEquals("allLines", expectedLines == Integer.MAX_VALUE,
o.allLines());
+ assertEquals("anyLines", expectedLines != 0, o.anyLines());
+ assertEquals("minLines", 0, o.minLines(0));
+ assertEquals("minLines", expectedLines, o.minLines(Integer.MAX_VALUE));
+ assertEquals("hasPackages", expectedPackages != null &&
!expectedPackages.isEmpty(), o.hasPackages());
+ assertNotNull("toString", o.toString());
+ }
+
+ /**
+ * Test {@code %throwable } with null options.
+ */
+ @Test
+ public void testNull() {
+ test(null, Integer.MAX_VALUE, Constants.LINE_SEP, null);
+ }
+
+ /**
+ * Test {@code %throwable }
+ */
+ @Test
+ public void testEmpty() {
+ test(new String[]{}, Integer.MAX_VALUE, Constants.LINE_SEP, null);
+ }
+
+ /**
+ * Test {@code %throwable{} } with null option value.
+ */
+ @Test
+ public void testOneNullElement() {
+ test(new String[]{null}, Integer.MAX_VALUE, Constants.LINE_SEP, null);
+ }
+
+ /**
+ * Test {@code %throwable{} }
+ */
+ @Test
+ public void testOneEmptyElement() {
+ test(new String[]{""}, Integer.MAX_VALUE, Constants.LINE_SEP, null);
+ }
+
+ /**
+ * Test {@code %throwable{full} }
+ */
+ @Test
+ public void testFull() {
+ test(new String[]{"full"}, Integer.MAX_VALUE, Constants.LINE_SEP,
null);
+ }
+
+ /**
+ * Test {@code %throwable{none} }
+ */
+ @Test
+ public void testNone() {
+ test(new String[]{"none"}, 0, Constants.LINE_SEP, null);
+ }
+
+ /**
+ * Test {@code %throwable{short} }
+ */
+ @Test
+ public void testShort() {
+ test(new String[]{"short"}, 2, Constants.LINE_SEP, null);
+ }
+
+ /**
+ * Test {@code %throwable{10} }
+ */
+ @Test
+ public void testDepth() {
+ test(new String[]{"10"}, 10, Constants.LINE_SEP, null);
+ }
+
+ /**
+ * Test {@code %throwable{separator(|)} }
+ */
+ @Test
+ public void testSeparator() {
+ test(new String[]{"separator(|)"}, Integer.MAX_VALUE, "|", null);
+ }
+
+ /**
+ * Test {@code %throwable{separator()} }
+ */
+ @Test
+ public void testSeparatorAsEmpty() {
+ test(new String[]{"separator()"}, Integer.MAX_VALUE, "", null);
+ }
+
+ /**
+ * Test {@code %throwable{separator(\n)} }
+ */
+ @Test
+ public void testSeparatorAsDefaultLineSeparator() {
+ test(new String[]{"separator(\n)"}, Integer.MAX_VALUE,
Constants.LINE_SEP, null);
+ }
+
+ /**
+ * Test {@code %throwable{separator(|)} }
+ */
+ @Test
+ public void testSeparatorAsMultipleCharacters() {
+ test(new String[]{"separator( | )"}, Integer.MAX_VALUE, " | ", null);
+ }
+
+ /**
+ * Test {@code %throwable{full}{separator(|)} }
+ */
+ @Test
+ public void testFullAndSeparator() {
+ test(new String[]{"full","separator(|)"}, Integer.MAX_VALUE, "|",
null);
+ }
+
+ /**
+ * Test {@code %throwable{none}{separator(|)} }
+ */
+ @Test
+ public void testNoneAndSeparator() {
+ test(new String[]{"none","separator(|)"}, 0, "|", null);
+ }
+
+ /**
+ * Test {@code %throwable{short}{separator(|)} }
+ */
+ @Test
+ public void testShortAndSeparator() {
+ test(new String[]{"short","separator(|)"}, 2, "|", null);
+ }
+
+ /**
+ * Test {@code %throwable{10}{separator(|)} }
+ */
+ @Test
+ public void testDepthAndSeparator() {
+ test(new String[]{"10","separator(|)"}, 10, "|", null);
+ }
+
+ /**
+ * Test {@code %throwable{filters(packages)} }
+ */
+ @Test
+ public void testFilters() {
+ test(new String[]{"filters(packages)"}, Integer.MAX_VALUE,
Constants.LINE_SEP, Arrays.asList("packages"));
+ }
+
+ /**
+ * Test {@code %throwable{filters()} }
+ */
+ @Test
+ public void testFiltersAsEmpty() {
+ test(new String[]{"filters()"}, Integer.MAX_VALUE, Constants.LINE_SEP,
null);
+ }
+
+ /**
+ * Test {@code %throwable{filters(package1,package2)} }
+ */
+ @Test
+ public void testFiltersAsMultiplePackages() {
+ test(new String[]{"filters(package1,package2)"}, Integer.MAX_VALUE,
Constants.LINE_SEP, Arrays.asList("package1","package2"));
+ }
+
+ /**
+ * Test {@code %throwable{full}{filters(packages)} }
+ */
+ @Test
+ public void testFullAndFilters() {
+ test(new String[]{"full","filters(packages)"}, Integer.MAX_VALUE,
Constants.LINE_SEP, Arrays.asList("packages"));
+ }
+
+ /**
+ * Test {@code %throwable{none}{filters(packages)} }
+ */
+ @Test
+ public void testNoneAndFilters() {
+ test(new String[]{"none","filters(packages)"}, 0, Constants.LINE_SEP,
Arrays.asList("packages"));
+ }
+
+ /**
+ * Test {@code %throwable{short}{filters(packages)} }
+ */
+ @Test
+ public void testShortAndFilters() {
+ test(new String[]{"short","filters(packages)"}, 2, Constants.LINE_SEP,
Arrays.asList("packages"));
+ }
+
+ /**
+ * Test {@code %throwable{10}{filters(packages)} }
+ */
+ @Test
+ public void testDepthAndFilters() {
+ test(new String[]{"10","filters(packages)"}, 10, Constants.LINE_SEP,
Arrays.asList("packages"));
+ }
+
+ /**
+ * Test {@code %throwable{full}{separator(|)}{filters(packages)} }
+ */
+ @Test
+ public void testFullAndSeparatorAndFilters() {
+ test(new String[]{"full","separator(|)","filters(packages)"},
Integer.MAX_VALUE, "|", Arrays.asList("packages"));
+ }
+
+ /**
+ * Test {@code %throwable{none}{separator(|)}{filters(packages)} }
+ */
+ @Test
+ public void testNoneAndSeparatorAndFilters() {
+ test(new String[]{"none","separator(|)","filters(packages)"}, 0, "|",
Arrays.asList("packages"));
+ }
+
+ /**
+ * Test {@code %throwable{short}{separator(|)}{filters(packages)} }
+ */
+ @Test
+ public void testShortAndSeparatorAndFilters() {
+ test(new String[]{"short","separator(|)","filters(packages)"}, 2, "|",
Arrays.asList("packages"));
+ }
+
+ /**
+ * Test {@code %throwable{10}{separator(|)}{filters(packages)} }
+ */
+ @Test
+ public void testDepthAndSeparatorAndFilters() {
+ test(new String[]{"10","separator(|)","filters(packages)"}, 10, "|",
Arrays.asList("packages"));
+ }
+
+ /**
+ * Test {@code %throwable{full,filters(packages)} }
+ */
+ @Test
+ public void testSingleOptionFullAndFilters() {
+ test(new String[]{"full,filters(packages)"}, Integer.MAX_VALUE,
Constants.LINE_SEP, Arrays.asList("packages"));
+ }
+
+ /**
+ * Test {@code %throwable{none,filters(packages)} }
+ */
+ @Test
+ public void testSingleOptionNoneAndFilters() {
+ test(new String[]{"none,filters(packages)"}, 0, Constants.LINE_SEP,
Arrays.asList("packages"));
+ }
+
+ /**
+ * Test {@code %throwable{short,filters(packages)} }
+ */
+ @Test
+ public void testSingleOptionShortAndFilters() {
+ test(new String[]{"short,filters(packages)"}, 2, Constants.LINE_SEP,
Arrays.asList("packages"));
+ }
+
+ /**
+ * Test {@code %throwable{none,filters(packages)} }
+ */
+ @Test
+ public void testSingleOptionDepthAndFilters() {
+ test(new String[]{"10,filters(packages)"}, 10, Constants.LINE_SEP,
Arrays.asList("packages"));
+ }
+
+ /**
+ * Test {@code %throwable{full,filters(package1,package2)} }
+ */
+ @Test
+ public void testSingleOptionFullAndMultipleFilters() {
+ test(new String[]{"full,filters(package1,package2)"},
Integer.MAX_VALUE, Constants.LINE_SEP, Arrays.asList("package1","package2"));
+ }
+
+ /**
+ * Test {@code %throwable{none,filters(package1,package2)} }
+ */
+ @Test
+ public void testSingleOptionNoneAndMultipleFilters() {
+ test(new String[]{"none,filters(package1,package2)"}, 0,
Constants.LINE_SEP, Arrays.asList("package1","package2"));
+ }
+
+ /**
+ * Test {@code %throwable{short,filters(package1,package2)} }
+ */
+ @Test
+ public void testSingleOptionShortAndMultipleFilters() {
+ test(new String[]{"short,filters(package1,package2)"}, 2,
Constants.LINE_SEP, Arrays.asList("package1","package2"));
+ }
+
+ /**
+ * Test {@code %throwable{none,filters(package1,package2)} }
+ */
+ @Test
+ public void testSingleOptionDepthAndMultipleFilters() {
+ test(new String[]{"10,filters(package1,package2)"}, 10,
Constants.LINE_SEP, Arrays.asList("package1","package2"));
+ }
+}
Added:
logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowableTest.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowableTest.java?rev=1463226&view=auto
==============================================================================
---
logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowableTest.java
(added)
+++
logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowableTest.java
Mon Apr 1 17:52:39 2013
@@ -0,0 +1,76 @@
+/*
+ * 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.logging.log4j.core.pattern;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.XMLConfigurationFactory;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.test.appender.ListAppender;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+/**
+ * Unit tests for {@code throwable} pattern.
+ */
+public class ThrowableTest {
+ private static final String CONFIG = "log4j-throwable.xml";
+ private static Configuration config;
+ private static ListAppender app;
+ private static LoggerContext ctx;
+
+ @BeforeClass
+ public static void setupClass() {
+
System.setProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY, CONFIG);
+ ctx = (LoggerContext) LogManager.getContext(false);
+ config = ctx.getConfiguration();
+ for (final Map.Entry<String, Appender<?>> entry :
config.getAppenders().entrySet()) {
+ if (entry.getKey().equals("List")) {
+ app = (ListAppender) entry.getValue();
+ }
+ }
+ }
+
+ @AfterClass
+ public static void cleanupClass() {
+
System.clearProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
+ ctx.reconfigure();
+ StatusLogger.getLogger().reset();
+ }
+
+ org.apache.logging.log4j.Logger logger =
LogManager.getLogger("LoggerTest");
+
+ @Test
+ public void testException() {
+ final Throwable cause = new NullPointerException("null pointer");
+ final Throwable parent = new
IllegalArgumentException("IllegalArgument", cause);
+ logger.error("Exception", parent);
+ final List<String> msgs = app.getMessages();
+ assertNotNull(msgs);
+ assertTrue("Incorrect number of messages. Should be 1 is " +
msgs.size(), msgs.size() == 1);
+ assertFalse("No suppressed lines", msgs.get(0).contains("suppressed"));
+ app.clear();
+ }
+}
Added: logging/log4j/log4j2/trunk/core/src/test/resources/log4j-throwable.xml
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/resources/log4j-throwable.xml?rev=1463226&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/test/resources/log4j-throwable.xml
(added)
+++ logging/log4j/log4j2/trunk/core/src/test/resources/log4j-throwable.xml Mon
Apr 1 17:52:39 2013
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+
+-->
+<configuration status="warn" name="XMLConfigTest"
packages="org.apache.logging.log4j.test">
+ <properties>
+ <property
name="filters">org.junit,org.apache.maven,sun.reflect,java.lang.reflect</property>
+ </properties>
+ <ThresholdFilter level="debug"/>
+
+ <appenders>
+ <Console name="STDOUT">
+ <PatternLayout pattern="%m%ex{full}{separator( | )}%n"/>
+ </Console>
+ <List name="List">
+ <PatternLayout pattern="%m%ex{separator( | )}%n"/>
+ </List>
+ </appenders>
+
+ <loggers>
+ <root level="error">
+ <appender-ref ref="List"/>
+ </root>
+ </loggers>
+
+</configuration>
Modified: logging/log4j/log4j2/trunk/src/changes/changes.xml
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/changes/changes.xml?rev=1463226&r1=1463225&r2=1463226&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/src/changes/changes.xml (original)
+++ logging/log4j/log4j2/trunk/src/changes/changes.xml Mon Apr 1 17:52:39 2013
@@ -23,6 +23,9 @@
<body>
<release version="2.0-beta5" date="@TBD@" description="Bug fixes and
enhancements">
+ <action issue="LOG4J2-160" dev="rgoers" type="update" due-to="Joanne
Polsky">
+ Move Throwable pattern converter options processing to
ThrowableFormatOptions class.
+ </action>
<action issue="LOG4J2-157" dev="rgoers" type="update" due-to="Remko
Popma">
Allowed Loggers access to the properties in the LoggerConfig.
</action>