You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2017/03/08 03:58:07 UTC

[01/11] logging-log4j2 git commit: add suffix options, this options is supposed to be a pattern layout

Repository: logging-log4j2
Updated Branches:
  refs/heads/master d5b5df4dc -> 5e72f2cac


add suffix options, this options is supposed to be a pattern layout


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/7e06879d
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/7e06879d
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/7e06879d

Branch: refs/heads/master
Commit: 7e06879dd025cf2b425046301f59c276160b63d5
Parents: a45fe18
Author: xnslong <xn...@outlook.com>
Authored: Sun Sep 11 23:18:06 2016 +0800
Committer: xnslong <xn...@outlook.com>
Committed: Mon Sep 12 16:53:26 2016 +0800

----------------------------------------------------------------------
 .../log4j/core/impl/ThrowableFormatOptions.java | 55 +++++++++++++-------
 .../ExtendedThrowablePatternConverter.java      |  1 +
 .../pattern/RootThrowablePatternConverter.java  |  1 +
 3 files changed, 37 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7e06879d/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
index 9890347..abb733f 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
@@ -17,12 +17,13 @@
 package org.apache.logging.log4j.core.impl;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Scanner;
 
 import org.apache.logging.log4j.core.pattern.JAnsiTextRenderer;
-import org.apache.logging.log4j.core.pattern.TextRenderer;
 import org.apache.logging.log4j.core.pattern.PlainTextRenderer;
+import org.apache.logging.log4j.core.pattern.TextRenderer;
 import org.apache.logging.log4j.core.util.Constants;
 import org.apache.logging.log4j.core.util.Loader;
 import org.apache.logging.log4j.core.util.Patterns;
@@ -76,6 +77,8 @@ public final class ThrowableFormatOptions {
      */
     private final List<String> ignorePackages;
 
+    private final List<String> mdcKeys;
+
     public static final String CLASS_NAME = "short.className";
     public static final String METHOD_NAME = "short.methodName";
     public static final String LINE_NUMBER = "short.lineNumber";
@@ -85,44 +88,44 @@ public final class ThrowableFormatOptions {
 
     /**
      * Constructs the options for printing stack trace.
-     * 
-     * @param lines
+     *  @param lines
      *            The number of lines.
      * @param separator
      *            The stack trace separator.
      * @param ignorePackages
-     *            The packages to filter.
+ *            The packages to filter.
      * @param textRenderer
-     *            The ANSI renderer
+     * @param mdcKeys
      */
     protected ThrowableFormatOptions(final int lines, final String separator, final List<String> ignorePackages,
-            TextRenderer textRenderer) {
+                                     TextRenderer textRenderer, final List<String> mdcKeys) {
         this.lines = lines;
         this.separator = separator == null ? Constants.LINE_SEPARATOR : separator;
         this.ignorePackages = ignorePackages;
         this.textRenderer = textRenderer == null ? PlainTextRenderer.getInstance() : textRenderer;
+        this.mdcKeys = mdcKeys;
     }
 
     /**
      * Constructs the options for printing stack trace.
-     * 
+     *
      * @param packages
      *            The packages to filter.
      */
     protected ThrowableFormatOptions(final List<String> packages) {
-        this(DEFAULT_LINES, null, packages, null);
+        this(DEFAULT_LINES, null, packages, null, null);
     }
 
     /**
      * Constructs the options for printing stack trace.
      */
     protected ThrowableFormatOptions() {
-        this(DEFAULT_LINES, null, null, null);
+        this(DEFAULT_LINES, null, null, null, null);
     }
 
     /**
      * Returns the number of lines to write.
-     * 
+     *
      * @return The number of lines to write.
      */
     public int getLines() {
@@ -131,7 +134,7 @@ public final class ThrowableFormatOptions {
 
     /**
      * Returns the stack trace separator.
-     * 
+     *
      * @return The stack trace separator.
      */
     public String getSeparator() {
@@ -140,7 +143,7 @@ public final class ThrowableFormatOptions {
 
     /**
      * Returns the message rendered.
-     * 
+     *
      * @return the message rendered.
      */
     public TextRenderer getTextRenderer() {
@@ -149,7 +152,7 @@ public final class ThrowableFormatOptions {
 
     /**
      * Returns the list of packages to ignore (filter out).
-     * 
+     *
      * @return The list of packages to ignore (filter out).
      */
     public List<String> getIgnorePackages() {
@@ -158,7 +161,7 @@ public final class ThrowableFormatOptions {
 
     /**
      * Determines if all lines should be printed.
-     * 
+     *
      * @return true for all lines, false otherwise.
      */
     public boolean allLines() {
@@ -167,7 +170,7 @@ public final class ThrowableFormatOptions {
 
     /**
      * Determines if any lines should be printed.
-     * 
+     *
      * @return true for any lines, false otherwise.
      */
     public boolean anyLines() {
@@ -176,7 +179,7 @@ public final class ThrowableFormatOptions {
 
     /**
      * Returns the minimum between the lines and the max lines.
-     * 
+     *
      * @param maxLines
      *            The maximum number of lines.
      * @return The number of lines to print.
@@ -187,7 +190,7 @@ public final class ThrowableFormatOptions {
 
     /**
      * Determines if there are any packages to filter.
-     * 
+     *
      * @return true if there are packages, false otherwise.
      */
     public boolean hasPackages() {
@@ -217,7 +220,7 @@ public final class ThrowableFormatOptions {
 
     /**
      * Creates a new instance based on the array of options.
-     * 
+     *
      * @param options
      *            The array of options.
      * @return A new initialized instance.
@@ -247,6 +250,7 @@ public final class ThrowableFormatOptions {
         String separator = DEFAULT.separator;
         List<String> packages = DEFAULT.ignorePackages;
         TextRenderer ansiRenderer = DEFAULT.textRenderer;
+        List<String> mdcKeys = DEFAULT.mdcKeys;
         for (final String rawOption : options) {
             if (rawOption != null) {
                 final String option = rawOption.trim();
@@ -279,18 +283,29 @@ public final class ThrowableFormatOptions {
                     if (Loader.isJansiAvailable()) {
                         String styleMapStr = option.equals("ansi") ? Strings.EMPTY
                                 : option.substring("ansi(".length(), option.length() - 1);
-                        ansiRenderer = new JAnsiTextRenderer(new String[] { null, styleMapStr },
+                        ansiRenderer = new JAnsiTextRenderer(new String[] {null, styleMapStr},
                                 JAnsiTextRenderer.DefaultExceptionStyleMap);
                     } else {
                         StatusLogger.getLogger().warn(
                                 "You requested ANSI exception rendering but JANSI is not on the classpath. Please see https://logging.apache.org/log4j/2.x/runtime-dependencies.html");
                     }
+                } else if (option.startsWith("mdc(") && option.endsWith(")")){
+                    String suffixPattern = option.substring("mdc(".length(), option.length() - 1);
+                    mdcKeys = parseMdcKeys(suffixPattern);
+                } else if (option.startsWith("X(") && option.endsWith(")")){
+                    String suffixPattern = option.substring("X(".length(), option.length() - 1);
+                    mdcKeys = parseMdcKeys(suffixPattern);
                 } else if (!option.equalsIgnoreCase(FULL)) {
                     lines = Integer.parseInt(option);
                 }
             }
         }
-        return new ThrowableFormatOptions(lines, separator, packages, ansiRenderer);
+        return new ThrowableFormatOptions(lines, separator, packages, ansiRenderer, mdcKeys);
+    }
+
+    private static List<String> parseMdcKeys(final String mdcKeyExp) {
+        String[] keys = mdcKeyExp.split(",");
+        return Arrays.asList(keys);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7e06879d/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java
index 20fd733..b3adf05 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java
@@ -86,4 +86,5 @@ public final class ExtendedThrowablePatternConverter extends ThrowablePatternCon
             }
         }
     }
+
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7e06879d/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java
index b9f0b7a..7b0438d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java
@@ -45,6 +45,7 @@ public final class RootThrowablePatternConverter extends ThrowablePatternConvert
     /**
      * Gets an instance of the class.
      *
+     *
      * @param options pattern options, may be null.  If first element is "short",
      *                only the first line of the throwable will be formatted.
      * @return instance of class.


[09/11] logging-log4j2 git commit: [LOG4J2-1838]: Add documentation about throwable suffix() option

Posted by ma...@apache.org.
[LOG4J2-1838]: Add documentation about throwable suffix() option

Also added notes about related missing documentation.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/f14eadfb
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/f14eadfb
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/f14eadfb

Branch: refs/heads/master
Commit: f14eadfb7b49211c282434e5a81ba5b850f7a5bb
Parents: 4e47b38
Author: Matt Sicker <bo...@gmail.com>
Authored: Tue Mar 7 21:57:57 2017 -0600
Committer: Matt Sicker <bo...@gmail.com>
Committed: Tue Mar 7 21:58:12 2017 -0600

----------------------------------------------------------------------
 src/site/xdoc/manual/layouts.xml.vm | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/f14eadfb/src/site/xdoc/manual/layouts.xml.vm
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/layouts.xml.vm b/src/site/xdoc/manual/layouts.xml.vm
index 695c930..6fff0cb 100644
--- a/src/site/xdoc/manual/layouts.xml.vm
+++ b/src/site/xdoc/manual/layouts.xml.vm
@@ -762,7 +762,10 @@ WARN  [main]: Message 2</pre>
                 &nbsp;&nbsp;|"short.lineNumber"<br />
                 &nbsp;&nbsp;|"short.methodName"<br />
                 &nbsp;&nbsp;|"short.message"<br />
-                &nbsp;&nbsp;|"short.localizedMessage"]}
+                &nbsp;&nbsp;|"short.localizedMessage"]}<br />
+                &nbsp;&nbsp;{suffix(<i>pattern</i>)}
+                <!-- TODO: there are actually more options available in ThrowableFormatOptions that apply here -->
+                <!-- separator(), filters(), and ansi() -->
               </td>
               <td>
                 <p>
@@ -799,6 +802,11 @@ WARN  [main]: Message 2</pre>
                 <p>
                   Specifying <b>%throwable{none}</b> or <b>%throwable{0}</b> suppresses output of the exception.
                 </p>
+                <p>
+                  Specifying <b>%throwable{suffix{<i>pattern</i>}</b> adds the output of <i>pattern</i> to the
+                  output only if there is a throwable to print. This option is orthogonal with the above
+                  conversions.
+                </p>
               </td>
             </tr>
             <tr>
@@ -1223,9 +1231,11 @@ WARN  [main]: Message 2</pre>
             <tr>
               <td align="center">
                 <a name="PatternException"/>
-                <b>rEx</b>["none"|"short"|"full"|depth],[filters(packages)}<br />
-                <b>rException</b>["none"|"short"|"full"|depth],[filters(packages)}<br />
-                <b>rThrowable</b>["none"|"short"|"full"|depth],[filters(packages)}
+                <b>rEx</b>{["none"|"short"|"full"|depth]}{[filters(packages)]}{suffix(<i>pattern</i>)}<br />
+                <b>rException</b>{["none"|"short"|"full"|depth]}{[filters(packages)]}{suffix(<i>pattern</i>)}<br />
+                <b>rThrowable</b>{["none"|"short"|"full"|depth]}{[filters(packages)]}{suffix(<i>pattern</i>)}
+                <!-- TODO: more options are available in ThrowableFormatOptions -->
+                <!-- FIXME: these options are confusing! -->
               </td>
               <td>
                 <p>The same as the %throwable conversion word but the stack trace is printed starting with the
@@ -1239,6 +1249,10 @@ WARN  [main]: Message 2</pre>
                   be suppressed from stack traces. Specifying <b>%rEx{none}</b>
                   or <b>%rEx{0}</b> will suppress printing of the exception.
                 </p>
+                <p>
+                  As with the %throwable conversion, using <b>rEx{suffix(<i>pattern</i>)</b> will add the output
+                  of <i>pattern</i> to the output only if there is a throwable to print.
+                </p>
               </td>
             </tr>
             <tr>
@@ -1468,6 +1482,7 @@ WARN  [main]: Message 2</pre>
                 &nbsp;&nbsp;&nbsp;&nbsp;Key=Value,Value,...<br/>
                 &nbsp;&nbsp;&nbsp;&nbsp;...)<br/>
                 &nbsp;&nbsp;}<br/>
+                &nbsp;&nbsp;{suffix(<i>pattern</i>)}<br/>
               </td>
               <td>
                 <p>The same as the %throwable conversion word but also includes class packaging information.
@@ -1524,6 +1539,10 @@ WARN  [main]: Message 2</pre>
                   The special key <code>StyleMapName</code> can be set to one of the following prefedined maps:
                   <code>Spock</code>, <code>Kirk</code>.
                 </p>
+                <p>
+                  As with %throwable, the <b>%xEx{suffix(<i>pattern</i>)</b> conversion will add the output of
+                  <i>pattern</i> to the output only if there is a throwable to print.
+                </p>
               </td>
             </tr>
             <tr>


[06/11] logging-log4j2 git commit: remove unnecessary differents

Posted by ma...@apache.org.
remove unnecessary differents


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/4e0eda93
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/4e0eda93
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/4e0eda93

Branch: refs/heads/master
Commit: 4e0eda930d2b1efa8314f38c529b84a1950e9c01
Parents: 4a63b63
Author: xnslong <xn...@outlook.com>
Authored: Mon Mar 6 10:08:31 2017 +0800
Committer: xnslong <xn...@outlook.com>
Committed: Mon Mar 6 10:08:31 2017 +0800

----------------------------------------------------------------------
 .../apache/logging/log4j/core/impl/ThrowableFormatOptions.java   | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4e0eda93/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
index 2d54351..88a543e 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
@@ -86,13 +86,15 @@ public final class ThrowableFormatOptions {
 
     /**
      * Constructs the options for printing stack trace.
+     *
      * @param lines
      *            The number of lines.
      * @param separator
      *            The stack trace separator.
      * @param ignorePackages
-*            The packages to filter.
+     *            The packages to filter.
      * @param textRenderer
+     *            The ANSI renderer
      * @param suffix
      */
     protected ThrowableFormatOptions(final int lines, final String separator, final List<String> ignorePackages,


[07/11] logging-log4j2 git commit: Change line seperator from CRLF back to LF

Posted by ma...@apache.org.
Change line seperator from CRLF back to LF


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/7cfc8088
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/7cfc8088
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/7cfc8088

Branch: refs/heads/master
Commit: 7cfc8088ed8707725dc6e8e53147333d2fb9a952
Parents: 4e0eda9
Author: xnslong <xn...@outlook.com>
Authored: Mon Mar 6 10:10:19 2017 +0800
Committer: xnslong <xn...@outlook.com>
Committed: Mon Mar 6 10:10:19 2017 +0800

----------------------------------------------------------------------
 .../log4j/core/impl/ThrowableFormatOptions.java | 616 +++++++++----------
 1 file changed, 308 insertions(+), 308 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7cfc8088/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
index 88a543e..3100694 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
@@ -1,308 +1,308 @@
-/*
- * 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 java.util.ArrayList;
-import java.util.List;
-import java.util.Scanner;
-
-import org.apache.logging.log4j.core.pattern.JAnsiTextRenderer;
-import org.apache.logging.log4j.core.pattern.PlainTextRenderer;
-import org.apache.logging.log4j.core.pattern.TextRenderer;
-import org.apache.logging.log4j.core.util.Loader;
-import org.apache.logging.log4j.core.util.Patterns;
-import org.apache.logging.log4j.status.StatusLogger;
-import org.apache.logging.log4j.util.Strings;
-
-/**
- * Contains options which control how a {@link Throwable} pattern is formatted.
- */
-public final class ThrowableFormatOptions {
-
-    private static final int DEFAULT_LINES = Integer.MAX_VALUE;
-
-    /**
-     * 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";
-
-    /**
-     * ANSI renderer
-     */
-    private final TextRenderer textRenderer;
-
-    /**
-     * The number of lines to write.
-     */
-    private final int lines;
-
-    /**
-     * The stack trace separator.
-     */
-    private final String separator;
-
-    private final String suffix;
-
-    /**
-     * The list of packages to filter.
-     */
-    private final List<String> ignorePackages;
-
-    public static final String CLASS_NAME = "short.className";
-    public static final String METHOD_NAME = "short.methodName";
-    public static final String LINE_NUMBER = "short.lineNumber";
-    public static final String FILE_NAME = "short.fileName";
-    public static final String MESSAGE = "short.message";
-    public static final String LOCALIZED_MESSAGE = "short.localizedMessage";
-
-    /**
-     * Constructs the options for printing stack trace.
-     *
-     * @param lines
-     *            The number of lines.
-     * @param separator
-     *            The stack trace separator.
-     * @param ignorePackages
-     *            The packages to filter.
-     * @param textRenderer
-     *            The ANSI renderer
-     * @param suffix
-     */
-    protected ThrowableFormatOptions(final int lines, final String separator, final List<String> ignorePackages,
-                                     final TextRenderer textRenderer, final String suffix) {
-        this.lines = lines;
-        this.separator = separator == null ? Strings.LINE_SEPARATOR : separator;
-        this.ignorePackages = ignorePackages;
-        this.textRenderer = textRenderer == null ? PlainTextRenderer.getInstance() : textRenderer;
-        this.suffix = suffix;
-    }
-
-    /**
-     * Constructs the options for printing stack trace.
-     *
-     * @param packages
-     *            The packages to filter.
-     */
-    protected ThrowableFormatOptions(final List<String> packages) {
-        this(DEFAULT_LINES, null, packages, null, null);
-    }
-
-    /**
-     * Constructs the options for printing stack trace.
-     */
-    protected ThrowableFormatOptions() {
-        this(DEFAULT_LINES, null, 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 message rendered.
-     *
-     * @return the message rendered.
-     */
-    public TextRenderer getTextRenderer() {
-        return textRenderer;
-    }
-
-    /**
-     * Returns the list of packages to ignore (filter out).
-     *
-     * @return The list of packages to ignore (filter out).
-     */
-    public List<String> getIgnorePackages() {
-        return this.ignorePackages;
-    }
-
-    /**
-     * Determines if all lines should be printed.
-     *
-     * @return true for all lines, false otherwise.
-     */
-    public boolean allLines() {
-        return this.lines == DEFAULT_LINES;
-    }
-
-    /**
-     * 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.ignorePackages != null && !this.ignorePackages.isEmpty();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String toString() {
-        final 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 (final String p : this.ignorePackages) {
-                s.append(p).append(',');
-            }
-            s.deleteCharAt(s.length() - 1);
-            s.append(")}");
-        }
-        return s.toString();
-    }
-
-    /**
-     * Creates a new instance based on the array of options.
-     *
-     * @param options
-     *            The array of options.
-     * @return A new initialized instance.
-     */
-    public static ThrowableFormatOptions newInstance(String[] options) {
-        if (options == null || options.length == 0) {
-            return DEFAULT;
-        }
-        // 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 && Strings.isNotEmpty(options[0])) {
-            final String[] opts = options[0].split(Patterns.COMMA_SEPARATOR, 2);
-            final String first = opts[0].trim();
-            try (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.ignorePackages;
-        TextRenderer ansiRenderer = DEFAULT.textRenderer;
-        String suffix = DEFAULT.getSuffix();
-        for (final String rawOption : options) {
-            if (rawOption != null) {
-                final String option = rawOption.trim();
-                if (option.isEmpty()) {
-                    // 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(Patterns.COMMA_SEPARATOR);
-                        if (array.length > 0) {
-                            packages = new ArrayList<>(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) || option.equalsIgnoreCase(CLASS_NAME)
-                        || option.equalsIgnoreCase(METHOD_NAME) || option.equalsIgnoreCase(LINE_NUMBER)
-                        || option.equalsIgnoreCase(FILE_NAME) || option.equalsIgnoreCase(MESSAGE)
-                        || option.equalsIgnoreCase(LOCALIZED_MESSAGE)) {
-                    lines = 2;
-                } else if (option.startsWith("ansi(") && option.endsWith(")") || option.equals("ansi")) {
-                    if (Loader.isJansiAvailable()) {
-                        final String styleMapStr = option.equals("ansi") ? Strings.EMPTY
-                                : option.substring("ansi(".length(), option.length() - 1);
-                        ansiRenderer = new JAnsiTextRenderer(new String[] { null, styleMapStr },
-                                JAnsiTextRenderer.DefaultExceptionStyleMap);
-                    } else {
-                        StatusLogger.getLogger().warn(
-                                "You requested ANSI exception rendering but JANSI is not on the classpath. Please see https://logging.apache.org/log4j/2.x/runtime-dependencies.html");
-                    }
-                } else if (option.startsWith("S(") && option.endsWith(")")){
-                    suffix = option.substring("S(".length(), option.length() - 1);
-                } else if (option.startsWith("suffix(") && option.endsWith(")")){
-                    suffix = option.substring("suffix(".length(), option.length() - 1);
-                } else if (!option.equalsIgnoreCase(FULL)) {
-                    lines = Integer.parseInt(option);
-                }
-            }
-        }
-        return new ThrowableFormatOptions(lines, separator, packages, ansiRenderer, suffix);
-    }
-
-    public String getSuffix() {
-        return suffix;
-    }
-
-}
+/*
+ * 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 java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+
+import org.apache.logging.log4j.core.pattern.JAnsiTextRenderer;
+import org.apache.logging.log4j.core.pattern.PlainTextRenderer;
+import org.apache.logging.log4j.core.pattern.TextRenderer;
+import org.apache.logging.log4j.core.util.Loader;
+import org.apache.logging.log4j.core.util.Patterns;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.Strings;
+
+/**
+ * Contains options which control how a {@link Throwable} pattern is formatted.
+ */
+public final class ThrowableFormatOptions {
+
+    private static final int DEFAULT_LINES = Integer.MAX_VALUE;
+
+    /**
+     * 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";
+
+    /**
+     * ANSI renderer
+     */
+    private final TextRenderer textRenderer;
+
+    /**
+     * The number of lines to write.
+     */
+    private final int lines;
+
+    /**
+     * The stack trace separator.
+     */
+    private final String separator;
+
+    private final String suffix;
+
+    /**
+     * The list of packages to filter.
+     */
+    private final List<String> ignorePackages;
+
+    public static final String CLASS_NAME = "short.className";
+    public static final String METHOD_NAME = "short.methodName";
+    public static final String LINE_NUMBER = "short.lineNumber";
+    public static final String FILE_NAME = "short.fileName";
+    public static final String MESSAGE = "short.message";
+    public static final String LOCALIZED_MESSAGE = "short.localizedMessage";
+
+    /**
+     * Constructs the options for printing stack trace.
+     *
+     * @param lines
+     *            The number of lines.
+     * @param separator
+     *            The stack trace separator.
+     * @param ignorePackages
+     *            The packages to filter.
+     * @param textRenderer
+     *            The ANSI renderer
+     * @param suffix
+     */
+    protected ThrowableFormatOptions(final int lines, final String separator, final List<String> ignorePackages,
+                                     final TextRenderer textRenderer, final String suffix) {
+        this.lines = lines;
+        this.separator = separator == null ? Strings.LINE_SEPARATOR : separator;
+        this.ignorePackages = ignorePackages;
+        this.textRenderer = textRenderer == null ? PlainTextRenderer.getInstance() : textRenderer;
+        this.suffix = suffix;
+    }
+
+    /**
+     * Constructs the options for printing stack trace.
+     *
+     * @param packages
+     *            The packages to filter.
+     */
+    protected ThrowableFormatOptions(final List<String> packages) {
+        this(DEFAULT_LINES, null, packages, null, null);
+    }
+
+    /**
+     * Constructs the options for printing stack trace.
+     */
+    protected ThrowableFormatOptions() {
+        this(DEFAULT_LINES, null, 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 message rendered.
+     *
+     * @return the message rendered.
+     */
+    public TextRenderer getTextRenderer() {
+        return textRenderer;
+    }
+
+    /**
+     * Returns the list of packages to ignore (filter out).
+     *
+     * @return The list of packages to ignore (filter out).
+     */
+    public List<String> getIgnorePackages() {
+        return this.ignorePackages;
+    }
+
+    /**
+     * Determines if all lines should be printed.
+     *
+     * @return true for all lines, false otherwise.
+     */
+    public boolean allLines() {
+        return this.lines == DEFAULT_LINES;
+    }
+
+    /**
+     * 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.ignorePackages != null && !this.ignorePackages.isEmpty();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        final 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 (final String p : this.ignorePackages) {
+                s.append(p).append(',');
+            }
+            s.deleteCharAt(s.length() - 1);
+            s.append(")}");
+        }
+        return s.toString();
+    }
+
+    /**
+     * Creates a new instance based on the array of options.
+     *
+     * @param options
+     *            The array of options.
+     * @return A new initialized instance.
+     */
+    public static ThrowableFormatOptions newInstance(String[] options) {
+        if (options == null || options.length == 0) {
+            return DEFAULT;
+        }
+        // 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 && Strings.isNotEmpty(options[0])) {
+            final String[] opts = options[0].split(Patterns.COMMA_SEPARATOR, 2);
+            final String first = opts[0].trim();
+            try (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.ignorePackages;
+        TextRenderer ansiRenderer = DEFAULT.textRenderer;
+        String suffix = DEFAULT.getSuffix();
+        for (final String rawOption : options) {
+            if (rawOption != null) {
+                final String option = rawOption.trim();
+                if (option.isEmpty()) {
+                    // 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(Patterns.COMMA_SEPARATOR);
+                        if (array.length > 0) {
+                            packages = new ArrayList<>(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) || option.equalsIgnoreCase(CLASS_NAME)
+                        || option.equalsIgnoreCase(METHOD_NAME) || option.equalsIgnoreCase(LINE_NUMBER)
+                        || option.equalsIgnoreCase(FILE_NAME) || option.equalsIgnoreCase(MESSAGE)
+                        || option.equalsIgnoreCase(LOCALIZED_MESSAGE)) {
+                    lines = 2;
+                } else if (option.startsWith("ansi(") && option.endsWith(")") || option.equals("ansi")) {
+                    if (Loader.isJansiAvailable()) {
+                        final String styleMapStr = option.equals("ansi") ? Strings.EMPTY
+                                : option.substring("ansi(".length(), option.length() - 1);
+                        ansiRenderer = new JAnsiTextRenderer(new String[] { null, styleMapStr },
+                                JAnsiTextRenderer.DefaultExceptionStyleMap);
+                    } else {
+                        StatusLogger.getLogger().warn(
+                                "You requested ANSI exception rendering but JANSI is not on the classpath. Please see https://logging.apache.org/log4j/2.x/runtime-dependencies.html");
+                    }
+                } else if (option.startsWith("S(") && option.endsWith(")")){
+                    suffix = option.substring("S(".length(), option.length() - 1);
+                } else if (option.startsWith("suffix(") && option.endsWith(")")){
+                    suffix = option.substring("suffix(".length(), option.length() - 1);
+                } else if (!option.equalsIgnoreCase(FULL)) {
+                    lines = Integer.parseInt(option);
+                }
+            }
+        }
+        return new ThrowableFormatOptions(lines, separator, packages, ansiRenderer, suffix);
+    }
+
+    public String getSuffix() {
+        return suffix;
+    }
+
+}


[03/11] logging-log4j2 git commit: merge master

Posted by ma...@apache.org.
merge master


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/f3be8790
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/f3be8790
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/f3be8790

Branch: refs/heads/master
Commit: f3be87900f66be98a6e84c5c8dab5986c219466f
Parents: 7e06879 9e7fe9e
Author: xnslong <xn...@outlook.com>
Authored: Sun Mar 5 22:14:41 2017 +0800
Committer: xnslong <xn...@outlook.com>
Committed: Sun Mar 5 22:14:41 2017 +0800

----------------------------------------------------------------------
 .dockerignore                                   |   27 +
 .gitattributes                                  |    1 +
 .gitignore                                      |   29 +-
 .mvn/wrapper/maven-wrapper.jar                  |  Bin 0 -> 49519 bytes
 .mvn/wrapper/maven-wrapper.properties           |   16 +
 .travis.yml                                     |   20 +
 BUILDING.md                                     |   68 +
 BUILDING.txt                                    |   51 -
 CONTRIBUTING.md                                 |   70 +
 Dockerfile                                      |   30 +
 NOTICE.txt                                      |    2 +-
 README.md                                       |  101 +-
 RELEASE-NOTES.md                                |   82 +
 RELEASE-NOTES.txt                               |   74 -
 Vagrantfile                                     |   75 -
 doap_log4j2.rdf                                 |  445 +++-
 log4j-1.2-api/.gitignore                        |    5 -
 log4j-1.2-api/pom.xml                           |   16 +-
 .../src/main/java/org/apache/log4j/Layout.java  |    4 +-
 .../apache/log4j/config/InputStreamWrapper.java |   92 +
 .../config/Log4j1ConfigurationConverter.java    |  211 ++
 .../config/Log4j1ConfigurationFactory.java      |  292 +--
 .../log4j/config/Log4j1ConfigurationParser.java |  446 ++++
 .../apache/log4j/layout/Log4j1XmlLayout.java    |   77 +-
 .../org/apache/log4j/layout/TTCCLayout.java     |   99 -
 .../pattern/Log4j1MdcPatternConverter.java      |   88 +
 .../pattern/Log4j1NdcPatternConverter.java      |   63 +
 log4j-1.2-api/src/site/markdown/index.md        |   34 +
 log4j-1.2-api/src/site/xdoc/index.xml           |   52 -
 .../apache/log4j/BasicConfigurationFactory.java |   13 +-
 .../java/org/apache/log4j/CategoryTest.java     |    3 +-
 ...bstractLog4j1ConfigurationConverterTest.java |   69 +
 .../Log4j1ConfigurationConverterHadoopTest.java |   39 +
 .../Log4j1ConfigurationConverterSparkTest.java  |   39 +
 .../config/Log4j1ConfigurationFactoryTest.java  |  240 ++-
 .../log4j/layout/Log4j1XmlLayoutTest.java       |   46 +-
 .../org/apache/log4j/layout/TTCCLayoutTest.java |   82 -
 .../equinox/EquinoxLoadApi12BundleTest.java     |   36 -
 .../osgi/felix/FelixLoadApi12BundleTest.java    |   36 -
 .../pattern/Log4j1MdcPatternConverterTest.java  |   79 +
 .../pattern/Log4j1NdcPatternConverterTest.java  |   74 +
 .../src/main/resources/log4j.properties         |   19 +
 .../src/main/conf/log4j.properties              |  323 +++
 .../src/test/resources/log4j.properties         |   18 +
 .../src/test/resources/log4j.properties         |   31 +
 .../src/main/resources/log4j.properties         |   31 +
 .../src/test/resources/log4j.properties         |   18 +
 .../src/test/resources/log4j.properties         |   49 +
 .../src/test/resources/log4j.properties         |   55 +
 .../src/test/resources/log4j.properties         |   49 +
 .../src/test/resources/log4j.properties         |   19 +
 .../src/test/resources/log4j.properties         |   19 +
 .../src/test/resources/log4j.properties         |   19 +
 .../src/test/resources/log4j.properties         |   19 +
 .../src/test/resources/log4j.properties         |   19 +
 .../src/test/resources/log4j.properties         |   19 +
 .../src/test/resources/log4j.properties         |   19 +
 .../src/test/resources/log4j.properties         |   23 +
 .../src/test/resources/log4j.properties         |   25 +
 .../src/test/resources/log4j.properties         |   42 +
 .../src/main/sample-conf/log4j.properties       |   19 +
 .../src/test/resources/log4j.properties         |   19 +
 .../src/test/resources/log4j.properties         |   37 +
 .../src/test/resources/log4j.properties         |   19 +
 .../src/test/resources/log4j.properties         |   63 +
 .../src/test/resources/log4j.properties         |   19 +
 .../src/test/resources/log4j.properties         |   19 +
 .../src/test/resources/log4j.properties         |   19 +
 .../src/test/resources/log4j.properties         |   19 +
 .../src/test/resources/log4j.properties         |   19 +
 .../src/test/resources/log4j.properties         |   19 +
 .../log4j-DailyRollingFileAppender.properties   |   26 +
 .../config-1.2/log4j-NullAppender.properties    |    9 +
 ...4j-RollingFileAppender-with-props.properties |   27 +
 .../log4j-RollingFileAppender.properties        |   22 +
 ...g4j-console-EnhancedPatternLayout.properties |    3 +-
 .../log4j-console-HtmlLayout.properties         |    3 +-
 .../log4j-console-PatternLayout.properties      |    1 -
 .../log4j-console-SimpleLayout.properties       |    1 -
 .../log4j-console-TTCCLayout.properties         |    3 +-
 .../log4j-console-XmlLayout.properties          |    3 +-
 .../log4j-file-SimpleLayout.properties          |   17 +
 .../log4j-system-properties-1.properties        |   14 +
 .../log4j-system-properties-2.properties        |   15 +
 .../config-1.2/spark/R/log4j.properties         |   28 +
 .../src/test/resources/log4j.properties         |   27 +
 .../src/test/resources/log4j.properties         |   24 +
 .../core/src/test/resources/log4j.properties    |   36 +
 .../src/test/resources/log4j.properties         |   28 +
 .../flume/src/test/resources/log4j.properties   |   28 +
 .../src/test/resources/log4j.properties         |   27 +
 .../src/test/resources/log4j.properties         |   28 +
 .../src/test/resources/log4j.properties         |   28 +
 .../src/main/resources/log4j.properties         |   37 +
 .../src/test/resources/log4j.properties         |   27 +
 .../graphx/src/test/resources/log4j.properties  |   27 +
 .../src/test/resources/log4j.properties         |   33 +
 .../mllib/src/test/resources/log4j.properties   |   28 +
 .../repl/src/test/resources/log4j.properties    |   27 +
 .../src/test/resources/log4j.properties         |   27 +
 .../core/src/test/resources/log4j.properties    |   57 +
 .../hive/src/test/resources/log4j.properties    |   61 +
 .../src/test/resources/log4j.properties         |   28 +
 .../yarn/src/test/resources/log4j.properties    |   31 +
 log4j-api-scala_2.10/pom.xml                    |  157 ++
 .../org/apache/logging/log4j/scala/Logger.scala |  592 ++++++
 .../logging/log4j/scala/LoggerMacro.scala       |  425 ++++
 .../apache/logging/log4j/scala/Logging.scala    |   30 +
 .../apache/logging/log4j/scala/LoggerTest.scala |  552 +++++
 log4j-api-scala_2.11/pom.xml                    |  157 ++
 .../org/apache/logging/log4j/scala/Logger.scala |  592 ++++++
 .../logging/log4j/scala/LoggerMacro.scala       |  425 ++++
 .../apache/logging/log4j/scala/Logging.scala    |   30 +
 .../apache/logging/log4j/scala/LoggerTest.scala |  552 +++++
 log4j-api/.gitignore                            |    5 -
 log4j-api/pom.xml                               |    7 +-
 .../logging/log4j/CloseableThreadContext.java   |   71 +-
 .../java/org/apache/logging/log4j/Logger.java   |   82 +-
 .../org/apache/logging/log4j/MarkerManager.java |   17 +-
 .../org/apache/logging/log4j/ThreadContext.java |  145 +-
 .../message/AsynchronouslyFormattable.java      |   60 +
 .../logging/log4j/message/LocalizedMessage.java |    9 +-
 .../log4j/message/LocalizedMessageFactory.java  |   18 +-
 .../logging/log4j/message/MapMessage.java       |  124 +-
 .../apache/logging/log4j/message/Message.java   |   19 +-
 .../logging/log4j/message/ObjectMessage.java    |   25 +-
 .../log4j/message/ParameterFormatter.java       |    5 +-
 .../log4j/message/ParameterizedMessage.java     |   13 +-
 .../log4j/message/ReusableMessageFactory.java   |   15 +-
 .../message/ReusableParameterizedMessage.java   |   25 +-
 .../logging/log4j/message/SimpleMessage.java    |    6 +-
 .../logging/log4j/message/StructuredDataId.java |   30 +-
 .../log4j/message/StructuredDataMessage.java    |   40 +-
 .../log4j/message/ThreadDumpMessage.java        |    1 +
 .../log4j/simple/SimpleLoggerContext.java       |   10 +-
 .../simple/SimpleLoggerContextFactory.java      |    1 +
 .../logging/log4j/spi/AbstractLogger.java       |  106 +-
 .../log4j/spi/AbstractLoggerAdapter.java        |   38 +-
 .../log4j/spi/CleanableThreadContextMap.java    |   39 +
 .../apache/logging/log4j/spi/CopyOnWrite.java   |   26 +
 .../CopyOnWriteSortedArrayThreadContextMap.java |  261 +++
 .../log4j/spi/DefaultThreadContextMap.java      |   67 +-
 .../log4j/spi/DefaultThreadContextStack.java    |   16 +-
 .../logging/log4j/spi/ExtendedLogger.java       |    2 -
 .../GarbageFreeSortedArrayThreadContextMap.java |  256 +++
 .../log4j/spi/MutableThreadContextStack.java    |   27 +-
 .../logging/log4j/spi/NoOpThreadContextMap.java |   65 +
 .../log4j/spi/ObjectThreadContextMap.java       |   54 +
 .../org/apache/logging/log4j/spi/Provider.java  |    2 +-
 .../log4j/spi/ReadOnlyThreadContextMap.java     |   96 +
 .../logging/log4j/spi/ThreadContextMap.java     |   19 +-
 .../logging/log4j/spi/ThreadContextMap2.java    |   53 +
 .../log4j/spi/ThreadContextMapFactory.java      |  106 +
 .../logging/log4j/spi/ThreadContextStack.java   |    1 +
 .../logging/log4j/status/StatusLogger.java      |   17 +-
 .../apache/logging/log4j/util/BiConsumer.java   |   35 +
 .../apache/logging/log4j/util/Constants.java    |   18 +
 .../log4j/util/IndexedReadOnlyStringMap.java    |   63 +
 .../logging/log4j/util/IndexedStringMap.java    |   33 +
 .../apache/logging/log4j/util/LoaderUtil.java   |   19 +
 .../logging/log4j/util/MessageSupplier.java     |    7 +-
 .../logging/log4j/util/PropertiesUtil.java      |   23 +
 .../apache/logging/log4j/util/ProviderUtil.java |    2 +-
 .../logging/log4j/util/ReadOnlyStringMap.java   |  107 +
 .../log4j/util/SortedArrayStringMap.java        |  558 +++++
 .../logging/log4j/util/StringBuilders.java      |   90 +-
 .../apache/logging/log4j/util/StringMap.java    |   98 +
 .../org/apache/logging/log4j/util/Strings.java  |   70 +
 .../org/apache/logging/log4j/util/Supplier.java |    2 +
 .../apache/logging/log4j/util/TriConsumer.java  |   37 +
 log4j-api/src/site/markdown/index.md            |   26 +
 log4j-api/src/site/xdoc/index.xml               |   42 -
 .../logging/log4j/AbstractLoggerTest.java       | 1974 ++++++++++--------
 .../log4j/CloseableThreadContextTest.java       |   45 +-
 .../apache/logging/log4j/ThreadContextTest.java |   17 +-
 .../apache/logging/log4j/TraceLoggingTest.java  |   16 +-
 .../apache/logging/log4j/junit/OsgiRule.java    |   73 -
 .../logging/log4j/junit/StatusLoggerRule.java   |   49 +
 .../log4j/message/FormattedMessageTest.java     |    5 +-
 .../message/LocalizedMessageFactoryTest.java    |   37 +
 .../log4j/message/LocalizedMessageTest.java     |    5 +-
 .../log4j/message/ObjectMessageTest.java        |   18 +-
 .../log4j/message/ParameterizedMessageTest.java |   24 +
 .../message/ReusableMessageFactoryTest.java     |  130 ++
 .../log4j/message/SimpleMessageTest.java        |   40 +
 .../log4j/message/ThreadDumpMessageTest.java    |   47 +-
 .../log4j/osgi/AbstractLoadBundleTest.java      |  239 ---
 .../equinox/AbstractEquinoxLoadBundleTest.java  |   33 -
 .../osgi/equinox/EquinoxLoadApiBundleTest.java  |   32 -
 .../osgi/felix/AbstractFelixLoadBundleTest.java |   39 -
 .../osgi/felix/FelixLoadApiBundleTest.java      |   32 -
 .../logging/log4j/spi/LoggerAdapterTest.java    |  126 ++
 .../logging/log4j/util/DeserializerHelper.java  |   47 +
 .../logging/log4j/util/PropertiesUtilTest.java  |   20 +
 .../log4j/util/SortedArrayStringMapTest.java    | 1117 ++++++++++
 .../apache/logging/log4j/util/Unbox1Test.java   |  170 ++
 .../log4j/util/Unbox2ConfigurableTest.java      |   91 +
 .../log4j/util/UnboxConfigurableTest.java       |   67 -
 .../apache/logging/log4j/util/UnboxTest.java    |  165 --
 .../META-INF/log4j-provider.properties          |    2 +-
 log4j-bom/.gitignore                            |    3 -
 log4j-bom/pom.xml                               |   32 +-
 log4j-core-its/pom.xml                          |  230 ++
 .../log4j/FilterPerformanceComparison.java      |  214 ++
 .../logging/log4j/PerformanceComparison.java    |  203 ++
 .../apache/logging/log4j/PerformanceRun.java    |  136 ++
 .../logging/log4j/core/SimplePerfTest.java      |  170 ++
 .../logging/log4j/core/ThreadedPerfTest.java    |   85 +
 .../apache/logging/log4j/core/ThreadedTest.java |  138 ++
 .../appender/mom/activemq/JmsAppenderIT.java    |  144 ++
 log4j-core/.gitignore                           |    6 -
 log4j-core/build.xml                            |  123 --
 log4j-core/pom.xml                              |   69 +-
 .../logging/log4j/core/AbstractLifeCycle.java   |   34 +-
 .../logging/log4j/core/AbstractLogEvent.java    |   14 +
 .../logging/log4j/core/ContextDataInjector.java |  108 +
 .../org/apache/logging/log4j/core/Core.java     |   24 +
 .../apache/logging/log4j/core/LifeCycle.java    |   11 +-
 .../apache/logging/log4j/core/LifeCycle2.java   |   37 +
 .../org/apache/logging/log4j/core/LogEvent.java |   34 +
 .../logging/log4j/core/LoggerContext.java       |   91 +-
 .../log4j/core/appender/AbstractAppender.java   |   45 +-
 .../log4j/core/appender/AbstractManager.java    |   80 +-
 .../appender/AbstractOutputStreamAppender.java  |   50 +-
 .../core/appender/AbstractWriterAppender.java   |  248 +--
 .../log4j/core/appender/AppenderSet.java        |  138 ++
 .../log4j/core/appender/AsyncAppender.java      |  185 +-
 .../core/appender/ConfigurationFactoryData.java |   50 +
 .../log4j/core/appender/ConsoleAppender.java    |   44 +-
 .../core/appender/CountingNoOpAppender.java     |    4 +-
 .../log4j/core/appender/FailoverAppender.java   |    3 +-
 .../log4j/core/appender/FailoversPlugin.java    |    3 +-
 .../log4j/core/appender/FileAppender.java       |   81 +-
 .../log4j/core/appender/FileManager.java        |  127 +-
 .../core/appender/MemoryMappedFileAppender.java |  169 +-
 .../core/appender/MemoryMappedFileManager.java  |   36 +-
 .../log4j/core/appender/NullAppender.java       |   49 +
 .../core/appender/OutputStreamAppender.java     |    4 +-
 .../core/appender/OutputStreamManager.java      |  685 +++---
 .../core/appender/RandomAccessFileAppender.java |  162 +-
 .../core/appender/RandomAccessFileManager.java  |   39 +-
 .../core/appender/RollingFileAppender.java      |  362 ++--
 .../RollingRandomAccessFileAppender.java        |  232 +-
 .../core/appender/ScriptAppenderSelector.java   |  142 ++
 .../log4j/core/appender/SmtpAppender.java       |   12 +-
 .../log4j/core/appender/SocketAppender.java     |  296 ++-
 .../log4j/core/appender/SyslogAppender.java     |  404 +++-
 .../log4j/core/appender/WriterAppender.java     |    4 +-
 .../log4j/core/appender/WriterManager.java      |  298 +--
 .../appender/db/AbstractDatabaseAppender.java   |  280 +--
 .../appender/db/AbstractDatabaseManager.java    |  457 ++--
 .../log4j/core/appender/db/ColumnMapping.java   |  173 ++
 .../core/appender/db/jdbc/ColumnConfig.java     |  186 +-
 .../db/jdbc/DataSourceConnectionSource.java     |    3 +-
 .../db/jdbc/FactoryMethodConnectionSource.java  |    7 +-
 .../core/appender/db/jdbc/JdbcAppender.java     |  178 +-
 .../appender/db/jdbc/JdbcDatabaseManager.java   |  568 ++---
 .../db/jpa/AbstractLogEventWrapperEntity.java   |   37 +-
 .../appender/db/jpa/BasicLogEventEntity.java    |    2 +-
 .../log4j/core/appender/db/jpa/JpaAppender.java |    8 +-
 .../appender/db/jpa/JpaDatabaseManager.java     |  381 ++--
 .../ContextDataAttributeConverter.java          |   46 +
 .../ContextDataJsonAttributeConverter.java      |   93 +
 .../converter/ThrowableAttributeConverter.java  |    4 +-
 .../log4j/core/appender/mom/JmsAppender.java    |   27 +-
 .../log4j/core/appender/mom/JmsManager.java     |  347 +--
 .../appender/mom/jeromq/JeroMqAppender.java     |  366 ++--
 .../core/appender/mom/jeromq/JeroMqManager.java |  442 ++--
 .../mom/kafka/DefaultKafkaProducerFactory.java  |   75 +-
 .../core/appender/mom/kafka/KafkaAppender.java  |   83 +-
 .../core/appender/mom/kafka/KafkaManager.java   |  216 +-
 .../mom/kafka/KafkaProducerFactory.java         |   65 +-
 .../rewrite/LoggerNameLevelRewritePolicy.java   |    3 +-
 .../core/appender/rewrite/MapRewritePolicy.java |    3 +-
 .../rewrite/PropertiesRewritePolicy.java        |    5 +-
 .../core/appender/rewrite/RewriteAppender.java  |    8 +-
 .../rolling/AbstractRolloverStrategy.java       |  108 +
 .../rolling/AbstractTriggeringPolicy.java       |   28 +
 .../rolling/CompositeTriggeringPolicy.java      |  188 +-
 .../appender/rolling/CronTriggeringPolicy.java  |   90 +-
 .../rolling/DefaultRolloverStrategy.java        |  444 ++--
 .../rolling/DirectFileRolloverStrategy.java     |   25 +
 .../rolling/DirectWriteRolloverStrategy.java    |  202 ++
 .../core/appender/rolling/FileExtension.java    |  125 ++
 .../rolling/OnStartupTriggeringPolicy.java      |    7 +-
 .../core/appender/rolling/PatternProcessor.java |   35 +-
 .../appender/rolling/RollingFileManager.java    |  275 ++-
 .../rolling/RollingRandomAccessFileManager.java |   42 +-
 .../rolling/SizeBasedTriggeringPolicy.java      |  207 +-
 .../rolling/TimeBasedTriggeringPolicy.java      |    5 +-
 .../core/appender/rolling/TriggeringPolicy.java |   10 +-
 .../rolling/action/CommonsCompressAction.java   |   19 +-
 .../appender/rolling/action/DeleteAction.java   |    7 +-
 .../rolling/action/IfAccumulatedFileCount.java  |  227 +-
 .../rolling/action/IfAccumulatedFileSize.java   |  233 ++-
 .../core/appender/rolling/action/IfAll.java     |    3 +-
 .../core/appender/rolling/action/IfAny.java     |    3 +-
 .../appender/rolling/action/IfFileName.java     |  299 +--
 .../appender/rolling/action/IfLastModified.java |  227 +-
 .../core/appender/rolling/action/IfNot.java     |  155 +-
 .../action/PathSortByModificationTime.java      |  179 +-
 .../rolling/action/ScriptCondition.java         |  238 +--
 .../core/appender/routing/IdlePurgePolicy.java  |   71 +-
 .../core/appender/routing/PurgePolicy.java      |    6 +-
 .../log4j/core/appender/routing/Route.java      |    3 +-
 .../log4j/core/appender/routing/Routes.java     |  179 +-
 .../core/appender/routing/RoutingAppender.java  |  238 ++-
 .../core/async/ArrayBlockingQueueFactory.java   |   42 +
 .../logging/log4j/core/async/AsyncLogger.java   |   56 +-
 .../log4j/core/async/AsyncLoggerConfig.java     |   11 +-
 .../core/async/AsyncLoggerConfigDisruptor.java  |   24 +-
 .../log4j/core/async/AsyncLoggerContext.java    |   10 +-
 .../log4j/core/async/AsyncLoggerDisruptor.java  |   33 +-
 .../log4j/core/async/AsyncQueueFullPolicy.java  |   22 +
 .../log4j/core/async/BlockingQueueFactory.java  |   42 +
 .../log4j/core/async/DaemonThreadFactory.java   |   53 -
 .../core/async/DefaultAsyncQueueFullPolicy.java |   14 +-
 .../async/DisruptorBlockingQueueFactory.java    |   53 +
 .../core/async/JCToolsBlockingQueueFactory.java |  198 ++
 .../core/async/LinkedTransferQueueFactory.java  |   43 +
 .../log4j/core/async/RingBufferLogEvent.java    |   87 +-
 .../async/RingBufferLogEventTranslator.java     |   20 +-
 .../core/config/AbstractConfiguration.java      |   82 +-
 .../log4j/core/config/AppenderControl.java      |    3 +-
 .../log4j/core/config/AppendersPlugin.java      |    3 +-
 .../log4j/core/config/Configuration.java        |   16 +
 .../core/config/ConfigurationException.java     |   14 +-
 .../log4j/core/config/ConfigurationFactory.java |   91 +-
 .../core/config/ConfigurationScheduler.java     |  137 +-
 .../core/config/ConfiguratonFileWatcher.java    |   31 +-
 .../logging/log4j/core/config/Configurator.java |   39 +-
 .../log4j/core/config/CronScheduledFuture.java  |    2 +-
 .../log4j/core/config/CustomLevelConfig.java    |    3 +-
 .../logging/log4j/core/config/CustomLevels.java |    3 +-
 .../log4j/core/config/DefaultConfiguration.java |    2 +-
 .../logging/log4j/core/config/LoggerConfig.java |  132 +-
 .../log4j/core/config/NullConfiguration.java    |    2 +-
 .../logging/log4j/core/config/Property.java     |   19 +-
 .../log4j/core/config/ScriptsPlugin.java        |    3 +-
 .../core/config/builder/api/Component.java      |    4 +-
 .../builder/api/ConfigurationBuilder.java       |   52 +-
 .../config/builder/impl/BuiltConfiguration.java |    9 +-
 .../builder/impl/DefaultComponentBuilder.java   |    4 +-
 .../impl/DefaultConfigurationBuilder.java       |  198 +-
 .../DefaultCustomLevelComponentBuilder.java     |    2 +-
 .../composite/CompositeConfiguration.java       |    6 +-
 .../config/composite/DefaultMergeStrategy.java  |  544 ++---
 .../core/config/json/JsonConfiguration.java     |   11 +-
 .../config/json/JsonConfigurationFactory.java   |    5 +-
 .../config/plugins/PluginBuilderFactory.java    |    1 +
 .../config/plugins/PluginConfiguration.java     |    1 +
 .../core/config/plugins/PluginFactory.java      |    2 +-
 .../log4j/core/config/plugins/PluginNode.java   |    1 +
 .../plugins/convert/DateTypeConverter.java      |   68 +
 .../config/plugins/convert/TypeConverters.java  |   78 +-
 .../config/plugins/processor/PluginCache.java   |    4 +-
 .../config/plugins/processor/PluginEntry.java   |    6 +
 .../plugins/processor/PluginProcessor.java      |    9 +-
 .../core/config/plugins/util/PluginBuilder.java |    2 -
 .../config/plugins/util/PluginRegistry.java     |    1 -
 .../core/config/plugins/util/ResolverUtil.java  |   34 +-
 .../validation/constraints/ValidHost.java       |   41 +
 .../validation/constraints/ValidPort.java       |   44 +
 .../validators/RequiredValidator.java           |   24 +-
 .../validators/ValidHostValidator.java          |   62 +
 .../validators/ValidPortValidator.java          |   57 +
 .../plugins/visitors/PluginElementVisitor.java  |    3 +
 .../plugins/visitors/PluginValueVisitor.java    |   17 +-
 .../properties/PropertiesConfiguration.java     |    8 +-
 .../PropertiesConfigurationBuilder.java         |   25 +-
 .../PropertiesConfigurationFactory.java         |   13 +-
 .../log4j/core/config/xml/XmlConfiguration.java |   50 +-
 .../config/xml/XmlConfigurationFactory.java     |    6 +-
 .../core/config/yaml/YamlConfiguration.java     |    7 +-
 .../config/yaml/YamlConfigurationFactory.java   |    5 +-
 .../log4j/core/filter/AbstractFilter.java       |   36 +-
 .../log4j/core/filter/AbstractFilterable.java   |   38 +-
 .../logging/log4j/core/filter/BurstFilter.java  |   75 +-
 .../log4j/core/filter/CompositeFilter.java      |   15 +-
 .../core/filter/DynamicThresholdFilter.java     |   99 +-
 .../log4j/core/filter/LevelRangeFilter.java     |   92 +-
 .../logging/log4j/core/filter/MapFilter.java    |  157 +-
 .../logging/log4j/core/filter/MarkerFilter.java |   71 +
 .../log4j/core/filter/StructuredDataFilter.java |   73 +-
 .../core/filter/ThreadContextMapFilter.java     |  100 +-
 .../log4j/core/filter/ThresholdFilter.java      |   71 +
 .../logging/log4j/core/filter/TimeFilter.java   |  144 +-
 .../log4j/core/impl/ContextDataFactory.java     |  122 ++
 .../core/impl/ContextDataInjectorFactory.java   |   94 +
 .../log4j/core/impl/ExtendedClassInfo.java      |    2 +-
 .../core/impl/ExtendedStackTraceElement.java    |    4 +-
 .../log4j/core/impl/JdkMapAdapterStringMap.java |  201 ++
 .../log4j/core/impl/Log4jContextFactory.java    |    6 +-
 .../logging/log4j/core/impl/Log4jLogEvent.java  |  179 +-
 .../log4j/core/impl/MutableLogEvent.java        |   46 +-
 .../core/impl/ReusableLogEventFactory.java      |   28 +-
 .../core/impl/ThreadContextDataInjector.java    |  199 ++
 .../log4j/core/impl/ThrowableFormatOptions.java |   27 +-
 .../logging/log4j/core/impl/ThrowableProxy.java | 1438 +++++++------
 .../ContextDataAsEntryListDeserializer.java     |   57 +
 .../ContextDataAsEntryListSerializer.java       |   58 +
 .../core/jackson/ContextDataDeserializer.java   |   65 +
 .../core/jackson/ContextDataSerializer.java     |   64 +
 .../log4j/core/jackson/Initializers.java        |   12 +-
 .../log4j/core/jackson/Log4jJsonModule.java     |    9 +-
 .../core/jackson/Log4jJsonObjectMapper.java     |    6 +-
 .../log4j/core/jackson/Log4jXmlModule.java      |    6 +-
 .../core/jackson/Log4jXmlObjectMapper.java      |    9 +-
 .../log4j/core/jackson/Log4jYamlModule.java     |    9 +-
 .../core/jackson/Log4jYamlObjectMapper.java     |    6 +-
 .../log4j/core/jackson/LogEventJsonMixIn.java   |   16 +-
 .../log4j/core/jackson/LogEventMixIn.java       |  138 --
 .../jackson/LogEventWithContextListMixIn.java   |  148 ++
 .../ThrowableProxyWithoutStacktraceMixIn.java   |   77 +
 .../log4j/core/jmx/LoggerContextAdmin.java      |    4 +-
 .../apache/logging/log4j/core/jmx/Server.java   |   31 +-
 .../log4j/core/layout/AbstractCsvLayout.java    |   15 +-
 .../core/layout/AbstractJacksonLayout.java      |   41 +
 .../log4j/core/layout/AbstractLayout.java       |   74 +-
 .../log4j/core/layout/AbstractStringLayout.java |   51 +-
 .../log4j/core/layout/CsvLogEventLayout.java    |   10 +-
 .../logging/log4j/core/layout/GelfLayout.java   |  206 +-
 .../logging/log4j/core/layout/HtmlLayout.java   |  133 +-
 .../log4j/core/layout/JacksonFactory.java       |   22 +-
 .../logging/log4j/core/layout/JsonLayout.java   |  119 +-
 .../logging/log4j/core/layout/LoggerFields.java |    2 +-
 .../core/layout/MarkerPatternSelector.java      |  143 +-
 .../log4j/core/layout/PatternLayout.java        |  216 +-
 .../log4j/core/layout/Rfc5424Layout.java        |   29 +-
 .../core/layout/ScriptPatternSelector.java      |  177 +-
 .../log4j/core/layout/SerializedLayout.java     |    1 +
 .../log4j/core/layout/StringBuilderEncoder.java |    7 +-
 .../logging/log4j/core/layout/SyslogLayout.java |   96 +-
 .../logging/log4j/core/layout/XmlLayout.java    |   23 +-
 .../logging/log4j/core/layout/YamlLayout.java   |   21 +-
 .../log4j/core/lookup/ContextMapLookup.java     |   17 +-
 .../logging/log4j/core/lookup/Interpolator.java |   64 +-
 .../logging/log4j/core/lookup/JndiLookup.java   |    5 +-
 .../log4j/core/lookup/StrSubstitutor.java       |   60 +-
 .../log4j/core/net/AbstractSocketManager.java   |    6 +-
 .../log4j/core/net/DatagramOutputStream.java    |   20 +-
 .../log4j/core/net/DatagramSocketManager.java   |   21 +-
 .../apache/logging/log4j/core/net/Facility.java |   24 +
 .../logging/log4j/core/net/JndiManager.java     |  287 +--
 .../log4j/core/net/MulticastDnsAdvertiser.java  |    9 +-
 .../log4j/core/net/Rfc1349TrafficClass.java     |   49 +
 .../logging/log4j/core/net/SmtpManager.java     |    4 +-
 .../logging/log4j/core/net/SocketAddress.java   |   99 +
 .../logging/log4j/core/net/SocketOptions.java   |  222 ++
 .../core/net/SocketPerformancePreferences.java  |   98 +
 .../log4j/core/net/SslSocketManager.java        |  126 +-
 .../log4j/core/net/TcpSocketManager.java        |  268 ++-
 .../core/net/server/AbstractSocketServer.java   |  110 +-
 .../log4j/core/net/server/JmsServer.java        |  286 +--
 .../server/JsonInputStreamLogEventBridge.java   |    2 +-
 .../log4j/core/net/server/TcpSocketServer.java  |  192 +-
 .../log4j/core/net/server/UdpSocketServer.java  |   80 +-
 .../net/ssl/AbstractKeyStoreConfiguration.java  |   38 +
 .../core/net/ssl/KeyStoreConfiguration.java     |   41 +-
 .../log4j/core/net/ssl/SslConfiguration.java    |   80 +-
 .../log4j/core/net/ssl/StoreConfiguration.java  |    3 +
 .../core/net/ssl/TrustStoreConfiguration.java   |   38 +-
 .../pattern/AbstractStyleNameConverter.java     |   14 +-
 .../logging/log4j/core/pattern/AnsiEscape.java  |    6 +-
 .../core/pattern/DatePatternConverter.java      |    7 +-
 .../core/pattern/EncodingPatternConverter.java  |   39 +-
 .../pattern/EqualsBaseReplacementConverter.java |   99 +
 .../EqualsIgnoreCaseReplacementConverter.java   |   45 +-
 .../pattern/EqualsReplacementConverter.java     |   55 +-
 .../ExtendedThrowablePatternConverter.java      |    6 +-
 .../core/pattern/FileDatePatternConverter.java  |    2 +
 .../log4j/core/pattern/FormattingInfo.java      |    3 +
 .../log4j/core/pattern/HighlightConverter.java  |   17 +-
 .../log4j/core/pattern/HtmlTextRenderer.java    |    6 +-
 .../core/pattern/IntegerPatternConverter.java   |   21 +-
 .../log4j/core/pattern/JAnsiTextRenderer.java   |  664 +++---
 .../core/pattern/LevelPatternConverter.java     |    2 +
 .../pattern/LineSeparatorPatternConverter.java  |    6 +-
 .../core/pattern/LiteralPatternConverter.java   |    8 +-
 .../core/pattern/LoggerPatternConverter.java    |    2 +
 .../log4j/core/pattern/MapPatternConverter.java |   26 +-
 .../core/pattern/MarkerPatternConverter.java    |    7 +-
 .../MarkerSimpleNamePatternConverter.java       |    2 +
 .../log4j/core/pattern/MaxLengthConverter.java  |   19 +-
 .../log4j/core/pattern/MdcPatternConverter.java |  114 +-
 .../core/pattern/MessagePatternConverter.java   |   57 +-
 .../log4j/core/pattern/NameAbbreviator.java     |    3 +
 .../core/pattern/NamePatternConverter.java      |    3 +
 .../core/pattern/NanoTimePatternConverter.java  |    2 +
 .../log4j/core/pattern/NdcPatternConverter.java |    2 +
 .../logging/log4j/core/pattern/NotANumber.java  |   32 +
 .../log4j/core/pattern/PatternParser.java       |   65 +-
 .../log4j/core/pattern/PlainTextRenderer.java   |    4 +-
 .../log4j/core/pattern/RegexReplacement.java    |    3 +-
 .../pattern/RelativeTimePatternConverter.java   |   19 +-
 .../pattern/RootThrowablePatternConverter.java  |    6 +-
 .../pattern/SequenceNumberPatternConverter.java |    8 +-
 .../log4j/core/pattern/StyleConverter.java      |   10 +-
 .../core/pattern/ThreadIdPatternConverter.java  |    4 +-
 .../pattern/ThreadNamePatternConverter.java     |    2 +
 .../pattern/ThreadPriorityPatternConverter.java |    4 +-
 .../core/pattern/ThrowablePatternConverter.java |    5 +-
 .../VariablesNotEmptyReplacementConverter.java  |   30 +-
 .../log4j/core/script/AbstractScript.java       |    5 +
 .../logging/log4j/core/script/Script.java       |    8 +-
 .../logging/log4j/core/script/ScriptFile.java   |    3 -
 .../log4j/core/script/ScriptManager.java        |   59 +-
 .../logging/log4j/core/script/ScriptRef.java    |    5 +-
 .../core/selector/BasicContextSelector.java     |  131 +-
 .../core/selector/JndiContextSelector.java      |    2 +-
 .../logging/log4j/core/tools/Generate.java      |    3 +-
 .../logging/log4j/core/util/ArrayUtils.java     |  124 ++
 .../apache/logging/log4j/core/util/Assert.java  |  107 +-
 .../core/util/BasicCommandLineArguments.java    |   47 +
 .../logging/log4j/core/util/CachedClock.java    |    2 +-
 .../apache/logging/log4j/core/util/Closer.java  |  132 +-
 .../log4j/core/util/CoarseCachedClock.java      |    2 +-
 .../logging/log4j/core/util/Constants.java      |   17 -
 .../logging/log4j/core/util/CronExpression.java |   71 +-
 .../logging/log4j/core/util/CyclicBuffer.java   |    4 +-
 .../util/DefaultShutdownCallbackRegistry.java   |   23 +-
 .../log4j/core/util/ExecutorServices.java       |   81 +
 .../logging/log4j/core/util/FileUtils.java      |   15 +
 .../logging/log4j/core/util/FileWatcher.java    |    2 +-
 .../log4j/core/util/InetAddressConverter.java   |   35 +
 .../logging/log4j/core/util/JndiCloser.java     |  118 +-
 .../logging/log4j/core/util/JsonUtils.java      |   39 +-
 .../apache/logging/log4j/core/util/Loader.java  |   36 +-
 .../logging/log4j/core/util/Log4jThread.java    |  140 +-
 .../log4j/core/util/Log4jThreadFactory.java     |   97 +
 .../log4j/core/util/NullOutputStream.java       |   20 +-
 .../log4j/core/util/OptionConverter.java        |    3 +-
 .../logging/log4j/core/util/ReflectionUtil.java |    2 +-
 .../logging/log4j/core/util/Transform.java      |    2 +-
 .../logging/log4j/core/util/TypeUtil.java       |    2 +-
 .../logging/log4j/core/util/WatchManager.java   |   14 +-
 .../log4j/core/util/datetime/DateParser.java    |   67 +-
 .../log4j/core/util/datetime/DatePrinter.java   |   40 +-
 .../core/util/datetime/FastDateFormat.java      |  550 ++---
 .../core/util/datetime/FastDateParser.java      |  904 ++++----
 .../core/util/datetime/FastDatePrinter.java     |  672 +++---
 .../core/util/datetime/FixedDateFormat.java     |   31 +-
 .../log4j/core/util/datetime/FormatCache.java   |  202 +-
 log4j-core/src/main/resources/Log4j-config.xsd  |   27 +-
 .../META-INF/log4j-provider.properties          |    2 +-
 log4j-core/src/site/manual/index.md             |   33 +
 log4j-core/src/site/xdoc/index.xml              |   48 -
 .../log4j/FilterPerformanceComparison.java      |  154 --
 .../logging/log4j/MarkerMixInJsonTest.java      |    6 +-
 .../apache/logging/log4j/MarkerMixInTest.java   |   11 +-
 .../logging/log4j/MarkerMixInXmlTest.java       |    5 +-
 .../logging/log4j/MarkerMixInYamlTest.java      |    3 +
 .../logging/log4j/PerformanceComparison.java    |  203 --
 .../apache/logging/log4j/PerformanceRun.java    |  136 --
 .../logging/log4j/ThreadContextTestAccess.java  |   34 +
 .../logging/log4j/categories/Appenders.java     |   33 +
 .../logging/log4j/categories/AsyncLoggers.java  |   23 +
 .../log4j/categories/Configurations.java        |   25 +
 .../logging/log4j/categories/Layouts.java       |   28 +
 .../logging/log4j/categories/Scripts.java       |   24 +
 .../log4j/core/AppenderRefLevelJsonTest.java    |    3 +
 .../log4j/core/BasicConfigurationFactory.java   |    6 +-
 .../logging/log4j/core/CronRolloverApp.java     |   43 +
 .../apache/logging/log4j/core/DeadlockTest.java |    2 +-
 .../core/GcFreeAsynchronousLoggingTest.java     |    5 +
 .../log4j/core/GcFreeLoggingTestUtil.java       |   40 +-
 .../core/GcFreeMixedSyncAyncLoggingTest.java    |    1 +
 .../core/GcFreeSynchronousLoggingTest.java      |    1 +
 .../apache/logging/log4j/core/HostNameTest.java |    4 +-
 .../logging/log4j/core/LoggerUpdateTest.java    |    2 +-
 .../logging/log4j/core/PatternSelectorTest.java |   16 +-
 .../core/ShutdownTimeoutConfigurationTest.java  |   44 +
 .../logging/log4j/core/SimplePerfTest.java      |  170 --
 .../logging/log4j/core/ThreadedPerfTest.java    |   85 -
 .../apache/logging/log4j/core/ThreadedTest.java |  138 --
 .../apache/logging/log4j/core/XmlEvents.java    |    2 +
 .../AsyncAppenderQueueFullPolicyTest.java       |    9 +-
 .../log4j/core/appender/AsyncAppenderTest.java  |   49 +-
 .../ConsoleAppenderAnsiMessagesMain.java        |  108 +-
 .../ConsoleAppenderAnsiStyleJira180Main.java    |  118 +-
 .../ConsoleAppenderAnsiStyleJira272Main.java    |  118 +-
 .../ConsoleAppenderAnsiStyleJira319Main.java    |  122 +-
 .../ConsoleAppenderAnsiStyleLayoutMain.java     |  146 +-
 .../appender/ConsoleAppenderBuilderTest.java    |   49 +
 ...nsoleAppenderDefaultSuppressedThrowable.java |  128 +-
 .../ConsoleAppenderJAnsiMessageMain.java        |  162 +-
 .../ConsoleAppenderJAnsiXExceptionMain.java     |  155 +-
 .../ConsoleAppenderNoAnsiStyleLayoutMain.java   |  142 +-
 .../core/appender/ConsoleAppenderTest.java      |   33 +-
 .../CsvJsonParameterLayoutFileAppenderTest.java |  120 ++
 .../core/appender/FileAppenderBuilderTest.java  |   31 +
 .../log4j/core/appender/FileAppenderTest.java   |   63 +-
 .../log4j/core/appender/HangingAppender.java    |   16 +-
 .../core/appender/InMemoryAppenderTest.java     |    4 +-
 .../log4j/core/appender/Jira739Test.java        |  100 +-
 .../appender/JsonCompleteFileAppenderTest.java  |   12 +-
 .../appender/MemoryMappedFileManagerTest.java   |   29 +-
 .../core/appender/OutputStreamAppenderTest.java |    3 +-
 .../appender/RandomAccessFileAppenderTests.java |    2 +-
 .../appender/RandomAccessFileManagerTest.java   |   26 +-
 .../appender/ScriptAppenderSelectorTest.java    |  102 +
 .../SecureSocketAppenderSocketOptionsTest.java  |  119 ++
 .../log4j/core/appender/SmtpAppenderTest.java   |    4 +-
 .../appender/SocketAppenderBufferSizeTest.java  |   77 +
 .../appender/SocketAppenderBuilderTest.java     |   32 +
 .../SocketAppenderSocketOptionsTest.java        |   99 +
 .../log4j/core/appender/SocketAppenderTest.java |  263 ++-
 .../SyslogAppenderCustomLayoutTest.java         |   38 +
 .../log4j/core/appender/SyslogAppenderTest.java |   41 +-
 .../core/appender/SyslogAppenderTestBase.java   |   65 +-
 .../core/appender/TlsSyslogAppenderTest.java    |   21 +-
 .../appender/XmlCompactFileAppenderTest.java    |    3 +
 .../XmlCompactFileAppenderValidationTest.java   |    3 +
 ...lCompactFileAsyncAppenderValidationTest.java |    3 +
 .../appender/XmlCompleteFileAppenderTest.java   |    9 +-
 .../core/appender/XmlFileAppenderTest.java      |    3 +
 .../XmlRandomAccessFileAppenderTest.java        |    3 +
 .../db/AbstractDatabaseAppenderTest.java        |  145 +-
 .../db/AbstractDatabaseManagerTest.java         |  356 ++--
 .../AbstractJdbcAppenderDataSourceTest.java     |  114 +
 .../AbstractJdbcAppenderFactoryMethodTest.java  |  112 +
 .../db/jdbc/AbstractJdbcAppenderTest.java       |  217 --
 .../core/appender/db/jdbc/ColumnConfigTest.java |  120 +-
 .../db/jdbc/DataSourceConnectionSourceTest.java |   88 +-
 .../jdbc/FactoryMethodConnectionSourceTest.java |   53 +-
 .../db/jdbc/JdbcAppenderH2DataSourceTest.java   |   46 +
 .../jdbc/JdbcAppenderH2FactoryMethodTest.java   |   51 +
 .../db/jdbc/JdbcAppenderHsqlDataSourceTest.java |   44 +
 .../jdbc/JdbcAppenderHsqlFactoryMethodTest.java |   50 +
 .../appender/db/jdbc/JdbcH2AppenderTest.java    |   55 -
 .../db/jdbc/JdbcHyperSqlAppenderTest.java       |   56 -
 .../db/jpa/AbstractJpaAppenderTest.java         |   17 +-
 .../core/appender/db/jpa/JpaH2AppenderTest.java |   31 +-
 .../db/jpa/JpaHyperSqlAppenderTest.java         |   31 +-
 .../core/appender/db/jpa/LogEventTest.java      |  122 ++
 .../core/appender/db/jpa/TestBaseEntity.java    |    8 +
 .../ContextDataAttributeConverterTest.java      |   67 +
 .../ContextDataJsonAttributeConverterTest.java  |   81 +
 .../ContextMapAttributeConverterTest.java       |    9 +-
 .../ContextMapJsonAttributeConverterTest.java   |    9 +-
 .../ContextStackAttributeConverterTest.java     |    9 +-
 .../ContextStackJsonAttributeConverterTest.java |    3 +
 .../converter/MarkerAttributeConverterTest.java |    9 +-
 .../MessageAttributeConverterTest.java          |    9 +-
 ...StackTraceElementAttributeConverterTest.java |    9 +-
 .../ThrowableAttributeConverterTest.java        |    9 +-
 .../log4j/core/appender/mom/JmsAppenderIT.java  |  128 --
 .../core/appender/mom/JmsAppenderTest.java      |  146 +-
 .../appender/mom/jeromq/JeroMqAppenderTest.java |  268 +--
 .../appender/mom/kafka/KafkaAppenderTest.java   |   16 +
 .../appender/rewrite/MapRewritePolicyTest.java  |    2 +
 .../appender/rewrite/TestRewritePolicy.java     |    3 +-
 .../rolling/CronTriggeringPolicyTest.java       |  139 ++
 .../appender/rolling/EligibleFilesTest.java     |   56 +
 .../rolling/OnStartupTriggeringPolicyTest.java  |   17 +-
 .../RandomRollingAppenderOnStartupTest.java     |    2 +-
 .../RollingAppenderCronEvery2DirectTest.java    |   86 +
 .../rolling/RollingAppenderCronEvery2Test.java  |   95 +
 .../RollingAppenderCronOnceADayTest.java        |  125 ++
 .../rolling/RollingAppenderCronTest.java        |    8 +-
 .../RollingAppenderCustomDeleteActionTest.java  |    2 +-
 ...lingAppenderDeleteAccumulatedCount1Test.java |    2 +-
 ...lingAppenderDeleteAccumulatedCount2Test.java |    2 +-
 ...ollingAppenderDeleteAccumulatedSizeTest.java |    2 +-
 .../RollingAppenderDeleteMaxDepthTest.java      |    2 +-
 .../RollingAppenderDeleteNestedTest.java        |    2 +-
 .../RollingAppenderDeleteScriptFri13thTest.java |    2 +-
 .../RollingAppenderDeleteScriptTest.java        |    2 +-
 .../rolling/RollingAppenderDirectWriteTest.java |   66 +
 ...ollingAppenderNoUnconditionalDeleteTest.java |    2 +-
 .../rolling/RollingAppenderOnStartupTest.java   |    2 +-
 .../RollingAppenderSizeNoCompressTest.java      |   97 +
 .../rolling/RollingAppenderSizeTest.java        |   73 +-
 .../RollingAppenderTimeAndSizeDirectTest.java   |   67 +
 .../rolling/RollingAppenderTimeAndSizeTest.java |    4 +-
 .../rolling/RollingAppenderTimeTest.java        |    2 +-
 .../RollingAppenderUncompressedTest.java        |    2 +-
 .../rolling/RollingFileAppenderAccessTest.java  |   61 +-
 .../rolling/RollingFileAppenderBuilderTest.java |   32 +
 .../rolling/RollingFileAppenderLayoutTest.java  |   39 +
 ...RandomAccessFileManagerHeaderFooterTest.java |    3 +-
 .../RollingRandomAccessFileManagerTest.java     |   30 +-
 .../rolling/action/ScriptConditionTest.java     |    3 +
 .../routing/DefaultRouteScriptAppenderTest.java |  152 ++
 .../routing/JsonRoutingAppender2Test.java       |    2 +-
 .../routing/JsonRoutingAppenderTest.java        |    2 +-
 .../routing/PropertiesRoutingAppenderTest.java  |    4 +-
 .../routing/RoutesScriptAppenderTest.java       |  162 ++
 .../appender/routing/RoutingAppenderTest.java   |    4 +-
 .../routing/RoutingAppenderWithJndiTest.java    |   17 +-
 .../routing/RoutingAppenderWithPurgingTest.java |   24 +-
 .../routing/RoutingDefaultAppenderTest.java     |   22 +-
 .../AbstractAsyncThreadContextTestBase.java     |  192 ++
 .../async/AsyncLoggerClassLoadDeadlock.java     |   32 +
 .../async/AsyncLoggerClassLoadDeadlockTest.java |   48 +
 .../async/AsyncLoggerConfigAutoFlushTest.java   |    3 +
 .../log4j/core/async/AsyncLoggerConfigTest.java |   11 +-
 .../core/async/AsyncLoggerConfigTest2.java      |   10 +-
 ...oggerConfigThreadContextCopyOnWriteTest.java |   30 +
 ...yncLoggerConfigThreadContextDefaultTest.java |   30 +
 ...oggerConfigThreadContextGarbageFreeTest.java |   30 +
 .../AsyncLoggerConfigUseAfterShutdownTest.java  |    3 +
 ...ncLoggerContextSelectorInitialStateTest.java |    5 +-
 .../async/AsyncLoggerContextSelectorTest.java   |    3 +
 .../core/async/AsyncLoggerContextTest.java      |    3 +
 .../core/async/AsyncLoggerLocationTest.java     |    3 +
 .../log4j/core/async/AsyncLoggerTest.java       |    3 +
 .../async/AsyncLoggerTestCachedThreadName.java  |    3 +
 .../core/async/AsyncLoggerTestNanoTime.java     |    3 +
 .../AsyncLoggerTestUncachedThreadName.java      |    3 +
 ...AsyncLoggerThreadContextCopyOnWriteTest.java |   43 +
 .../AsyncLoggerThreadContextDefaultTest.java    |   43 +
 ...AsyncLoggerThreadContextGarbageFreeTest.java |   43 +
 .../async/AsyncLoggerThreadContextTest.java     |    3 +
 .../AsyncLoggerThreadNameStrategyTest.java      |    3 +
 .../async/AsyncLoggerTimestampMessageTest.java  |    3 +
 .../async/AsyncLoggerUseAfterShutdownTest.java  |    3 +
 .../AsyncLoggersWithAsyncAppenderTest.java      |    3 +
 .../AsyncLoggersWithAsyncLoggerConfigTest.java  |    3 +
 .../async/AsyncQueueFullPolicyFactoryTest.java  |    3 +
 .../log4j/core/async/AsyncRootReloadTest.java   |    3 +
 .../async/DefaultAsyncQueueFullPolicyTest.java  |    9 +-
 .../DiscardingAsyncQueueFullPolicyTest.java     |   11 +-
 .../core/async/Log4j2Jira1688AsyncTest.java     |   97 +
 .../log4j/core/async/Log4j2Jira1688Test.java    |   94 +
 .../core/async/RingBufferLogEventTest.java      |   54 +-
 .../core/async/perftest/AbstractRunQueue.java   |   91 +
 .../core/async/perftest/ResponseTimeTest.java   |    1 +
 .../core/async/perftest/RunConversant.java      |   31 +
 .../log4j/core/async/perftest/RunJCTools.java   |   32 +
 .../core/config/CompositeConfigurationTest.java |  434 ++--
 .../log4j/core/config/ConfigurationTest.java    |    8 +-
 .../core/config/CustomConfigurationTest.java    |    3 +-
 .../log4j/core/config/InMemoryAdvertiser.java   |    3 +-
 .../core/config/JiraLog4j2_1100JsonTest.java    |    4 +
 .../core/config/JiraLog4j2_1100YamlBadTest.java |    3 +
 .../config/JiraLog4j2_1100YamlGoodTest.java     |    4 +
 .../log4j/core/config/LoggerConfigTest.java     |  102 +
 .../core/config/MissingRootLoggerTest.java      |    2 +-
 .../logging/log4j/core/config/PropertyTest.java |   85 +
 .../logging/log4j/core/config/XIncludeTest.java |    2 +-
 .../builder/ConfigurationAssemblerTest.java     |   35 +-
 .../builder/ConfigurationBuilderTest.java       |   99 +
 .../builder/CustomConfigurationFactory.java     |   18 +-
 .../plugins/convert/DateTypeConverterTest.java  |   60 +
 .../plugins/convert/TypeConvertersTest.java     |   22 +-
 .../plugins/util/PluginManagerPackagesTest.java |    2 +-
 .../util/ResolverUtilCustomProtocolTest.java    |  210 ++
 .../config/plugins/util/ResolverUtilTest.java   |  132 +-
 .../config/plugins/validation/HostAndPort.java  |   53 +
 .../PluginWithGenericSubclassFoo1Builder.java   |   18 +-
 .../validators/ValidHostValidatorTest.java      |   79 +
 .../validators/ValidPortValidatorTest.java      |   70 +
 .../core/config/xml/XmlLoggerPropsTest.java     |    4 +
 .../log4j/core/filter/AbstractFilterTest.java   |   88 +
 .../log4j/core/filter/BurstFilterTest.java      |  283 ++-
 .../core/filter/DynamicThresholdFilterTest.java |   17 +
 .../log4j/core/filter/LevelRangeFilterTest.java |    9 +
 .../filter/ScriptFileFilterPropertiesTest.java  |    3 +
 .../log4j/core/filter/ScriptFileFilterTest.java |    3 +
 .../log4j/core/filter/ScriptFilterTest.java     |    3 +
 .../log4j/core/filter/ScriptRefFilterTest.java  |    3 +
 .../log4j/core/filter/TimeFilterTest.java       |   40 +-
 ...actoryPropertySetMissingConstructorTest.java |   41 +
 .../impl/ContextDataFactoryPropertySetTest.java |   49 +
 .../log4j/core/impl/ContextDataFactoryTest.java |   47 +
 .../log4j/core/impl/FactoryTestStringMap.java   |  104 +
 ...ctoryTestStringMapWithoutIntConstructor.java |  100 +
 .../core/impl/JdkMapAdapterStringMapTest.java   |  883 ++++++++
 .../log4j/core/impl/Log4jLogEventTest.java      |  110 +-
 .../log4j/core/impl/MutableLogEventTest.java    |   41 +-
 .../impl/NestedLoggingFromToStringTest.java     |  132 ++
 .../core/impl/ReusableLogEventFactoryTest.java  |   30 +
 .../core/impl/ThrowableFormatOptionsTest.java   |   97 +-
 .../log4j/core/impl/ThrowableProxyTest.java     |   75 +
 .../jackson/JacksonIssue429MyNamesTest.java     |    3 +
 .../log4j/core/jackson/JacksonIssue429Test.java |    3 +
 .../log4j/core/jackson/LevelMixInJsonTest.java  |    5 +-
 .../log4j/core/jackson/LevelMixInTest.java      |    3 +
 .../log4j/core/jackson/LevelMixInXmlTest.java   |    3 +
 .../log4j/core/jackson/LevelMixInYamlTest.java  |    3 +
 .../jackson/StackTraceElementMixInTest.java     |    5 +-
 .../ConcurrentLoggingWithGelfLayoutTest.java    |  116 +
 .../ConcurrentLoggingWithJsonLayoutTest.java    |  118 ++
 .../core/layout/CsvLogEventLayoutTest.java      |    3 +
 .../layout/CsvParameterLayoutAllAsyncTest.java  |    3 +
 .../core/layout/CsvParameterLayoutTest.java     |   64 +-
 .../log4j/core/layout/GelfLayoutTest.java       |   65 +-
 .../log4j/core/layout/GelfLayoutTest2.java      |   50 +
 .../log4j/core/layout/JsonLayoutTest.java       |  138 +-
 .../log4j/core/layout/Log4j2_1482_CoreTest.java |   18 +-
 .../log4j/core/layout/Log4j2_1482_Test.java     |   17 +-
 .../log4j/core/layout/LogEventFixtures.java     |   11 +-
 .../layout/PatternLayoutLookupDateTest.java     |   44 +
 .../layout/PatternLayoutNoLookupDateTest.java   |   42 +
 .../log4j/core/layout/PatternLayoutTest.java    |   17 +-
 .../log4j/core/layout/Rfc5424LayoutTest.java    |    2 +-
 .../log4j/core/layout/SyslogLayoutTest.java     |   10 +-
 .../log4j/core/layout/XmlLayoutTest.java        |   62 +-
 .../log4j/core/layout/YamlLayoutTest.java       |   58 +-
 .../log4j/core/lookup/InterpolatorTest.java     |   48 +-
 .../log4j/core/lookup/JndiLookupTest.java       |   35 +-
 .../log4j/core/lookup/Log4jLookupTest.java      |   33 +-
 .../core/lookup/Log4jLookupWithSpacesTest.java  |   35 +-
 .../lookup/MainInputArgumentsMapLookup.java     |    2 +-
 .../core/lookup/ResourceBundleLookupTest.java   |    4 +-
 .../log4j/core/lookup/StrSubstitutorTest.java   |   12 +
 .../log4j/core/net/SocketReconnectTest.java     |   12 +-
 .../core/net/mock/MockUdpSyslogServer.java      |    6 +-
 .../net/server/AbstractSocketServerTest.java    |   32 +-
 .../core/net/server/SslXmlSocketServerTest.java |   23 +-
 .../core/net/ssl/KeyStoreConfigurationTest.java |    2 +-
 .../net/ssl/TrustStoreConfigurationTest.java    |    2 +-
 .../osgi/equinox/EquinoxLoadCoreBundleTest.java |   40 -
 .../osgi/felix/FelixLoadCoreBundleTest.java     |   40 -
 .../log4j/core/pattern/DisableAnsiTest.java     |   59 +
 .../pattern/EqualsReplacementConverterTest.java |    5 +-
 .../core/pattern/HighlightConverterTest.java    |    8 +-
 .../core/pattern/MapPatternConverterTest.java   |    2 +
 .../core/pattern/MessageJansiConverterTest.java |    4 +-
 .../pattern/MessagePatternConverterTest.java    |   17 +-
 .../pattern/MessageStyledConverterTest.java     |    4 +-
 .../log4j/core/pattern/NoConsoleNoAnsiTest.java |    4 +-
 .../log4j/core/pattern/PatternParserTest.java   |   12 +-
 .../log4j/core/pattern/PatternParserTest2.java  |    2 +-
 .../pattern/RegexReplacementConverterTest.java  |    4 +-
 .../core/pattern/RegexReplacementTest.java      |    6 +-
 .../log4j/core/pattern/StyleConverterTest.java  |    4 +-
 .../logging/log4j/core/util/AssertTest.java     |   68 +
 .../log4j/core/util/CronExpressionTest.java     |   89 +
 .../logging/log4j/core/util/JsonUtilsTest.java  |   74 +
 .../logging/log4j/core/util/LoaderTest.java     |   40 +
 .../logging/log4j/core/util/Profiler.java       |    5 +-
 .../core/util/ShutdownCallbackRegistryTest.java |    2 +-
 .../util/datetime/FastDateParserSDFTest.java    |  232 ++
 .../core/util/datetime/FastDateParserTest.java  |  721 +++++++
 .../datetime/FastDateParser_MoreOrLessTest.java |  115 +
 .../FastDateParser_TimeZoneStrategyTest.java    |   69 +
 .../apache/logging/log4j/junit/CleanFiles.java  |   11 +-
 .../logging/log4j/junit/CleanFolders.java       |    2 +-
 .../apache/logging/log4j/junit/JdbcRule.java    |   77 +
 .../apache/logging/log4j/junit/JndiRule.java    |   59 +
 .../logging/log4j/junit/LoggerContextRule.java  |   69 +-
 .../junit/URLStreamHandlerFactoryRule.java      |   97 +
 .../logging/log4j/test/ExtendedLevels.java      |    2 +-
 .../log4j/test/appender/AlwaysFailAppender.java |    3 +-
 .../log4j/test/appender/BlockingAppender.java   |   12 +-
 .../log4j/test/appender/DeadlockAppender.java   |   12 +-
 .../log4j/test/appender/FailOnceAppender.java   |    3 +-
 .../log4j/test/appender/InMemoryAppender.java   |    2 +-
 .../log4j/test/appender/ListAppender.java       |   52 +-
 .../test/appender/UsesLoggingAppender.java      |    4 +-
 .../logging/log4j/test/layout/BasicLayout.java  |    9 +-
 .../AsyncLoggerConfigThreadContextTest.xml      |   50 +
 .../test/resources/AsyncLoggerConsoleTest.xml   |   16 +
 .../resources/AsyncLoggerThreadContextTest.xml  |    8 +-
 .../BlockingQueueFactory-ArrayBlockingQueue.xml |   40 +
 ...ckingQueueFactory-DisruptorBlockingQueue.xml |   40 +
 ...lockingQueueFactory-JCToolsBlockingQueue.xml |   40 +
 ...BlockingQueueFactory-LinkedTransferQueue.xml |   40 +
 .../src/test/resources/GelfLayoutTest2.xml      |   34 +
 .../src/test/resources/JeroMqAppenderTest.xml   |   62 +-
 .../src/test/resources/JmsAppenderTest.xml      |    2 +-
 .../src/test/resources/KafkaAppenderTest.xml    |    5 +
 .../src/test/resources/configPropertyTest.xml   |   38 +
 log4j-core/src/test/resources/gcFreeLogging.xml |   39 +-
 .../resources/gcFreeMixedSyncAsyncLogging.xml   |   39 +-
 .../src/test/resources/log4j-advertiser.xml     |    4 +-
 .../log4j-appender-selector-groovy.xml          |   35 +
 .../log4j-appender-selector-javascript.xml      |   35 +
 .../test/resources/log4j-asynch-queue-full.xml  |    4 +-
 .../log4j-comp-logger-attr-override.json        |   38 +
 .../test/resources/log4j-comp-logger-ref.json   |   18 +
 .../test/resources/log4j-comp-logger-ref.xml    |   32 +
 .../test/resources/log4j-comp-logger-root.xml   |   44 +
 log4j-core/src/test/resources/log4j-console.xml |   29 +
 .../test/resources/log4j-cronRolloverApp.xml    |   24 +
 .../src/test/resources/log4j-customLevel.xml    |    7 +-
 .../test/resources/log4j-cvs-json-parameter.xml |   32 +
 log4j-core/src/test/resources/log4j-empty.xml   |   20 +
 .../src/test/resources/log4j-list-nolookups.xml |   29 +
 .../src/test/resources/log4j-loggerprops.xml    |    3 +-
 .../test/resources/log4j-rolling-7z-lazy.xml    |   59 +
 .../test/resources/log4j-rolling-bzip2-lazy.xml |   60 +
 .../src/test/resources/log4j-rolling-bzip2.xml  |    2 +-
 .../log4j-rolling-cron-every2-direct.xml        |   54 +
 .../resources/log4j-rolling-cron-every2.xml     |   54 +
 .../resources/log4j-rolling-cron-once-a-day.xml |   47 +
 .../src/test/resources/log4j-rolling-cron.xml   |    4 +-
 .../src/test/resources/log4j-rolling-cron2.xml  |    2 +-
 .../resources/log4j-rolling-deflate-lazy.xml    |   60 +
 .../test/resources/log4j-rolling-deflate.xml    |    4 +-
 .../src/test/resources/log4j-rolling-direct.xml |   50 +
 .../test/resources/log4j-rolling-gz-lazy.xml    |   59 +
 .../src/test/resources/log4j-rolling-gz.xml     |    2 +-
 .../resources/log4j-rolling-pack200-lazy.xml    |   60 +
 .../test/resources/log4j-rolling-pack200.xml    |    2 +-
 .../src/test/resources/log4j-rolling-size.xml   |   59 +
 .../test/resources/log4j-rolling-xz-lazy.xml    |   60 +
 .../src/test/resources/log4j-rolling-xz.xml     |    2 +-
 .../test/resources/log4j-rolling-zip-lazy.xml   |   60 +
 .../src/test/resources/log4j-rolling-zip.xml    |    2 +-
 .../test/resources/log4j-rolling3-direct.xml    |   54 +
 ...og4j-routing-default-route-script-groovy.xml |   40 +
 ...-routing-default-route-script-javascript.xml |   40 +
 .../log4j-routing-routes-script-groovy.xml      |   40 +
 .../log4j-routing-routes-script-javascript.xml  |   40 +
 .../log4j-routing-script-staticvars-groovy.xml  |   50 +
 ...g4j-routing-script-staticvars-javascript.xml |   50 +
 .../src/test/resources/log4j-script-filters.xml |    7 +-
 .../src/test/resources/log4j-socket-options.xml |   32 +
 .../test/resources/log4j-ssl-socket-options.xml |   39 +
 .../src/test/resources/log4j-sync-to-list.xml   |   35 +
 .../resources/log4j-test-shutdownTimeout.xml    |   38 +
 log4j-core/src/test/resources/log4j2-1573.xml   |   12 +
 .../resources/log4j2-console-disableAnsi.xml    |   34 +
 .../src/test/resources/log4j2-gelf-layout.xml   |   31 +
 .../src/test/resources/log4j2-json-layout.xml   |   31 +
 .../test/resources/log4j2-properties.properties |    1 +
 .../db/jdbc/log4j2-h2-factory-method.xml        |    5 +-
 .../db/jdbc/log4j2-hsqldb-factory-method.xml    |    5 +-
 .../rolloverPath/log4j.txt.20170112_00-1.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_00-2.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_01-1.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_02-1.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_02-2.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_02-3.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_02-4.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_02-5.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_03-1.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_03-2.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_03-3.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_03-4.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_03-5.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_04-1.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_04-2.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_04-3.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_04-4.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_04-5.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_05-1.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_05-2.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_05-3.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_05-4.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_05-5.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_06-1.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_06-10.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_06-11.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_06-12.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_06-13.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_06-14.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_06-15.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_06-16.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_06-17.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_06-18.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_06-19.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_06-2.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_06-20.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_06-3.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_06-4.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_06-5.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_06-6.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_06-7.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_06-8.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_06-9.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_07-1.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_07-10.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-11.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-12.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-13.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-14.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-15.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-16.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-17.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-18.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-19.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-2.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_07-20.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-21.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-22.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-23.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-24.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-25.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-26.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-27.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-28.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-29.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_07-3.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_07-4.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_07-5.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_07-6.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_07-7.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_07-8.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_07-9.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_08-1.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_08-10.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-11.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-12.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-13.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-14.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-15.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-16.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-17.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-18.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-19.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-2.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_08-20.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-21.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-22.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-23.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-24.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-25.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-26.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-27.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-28.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-29.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_08-3.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_08-4.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_08-5.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_08-6.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_08-7.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_08-8.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_08-9.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_09-1.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_09-10.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-11.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-12.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-13.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-14.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-15.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-16.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-17.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-18.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-19.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-2.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_09-20.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-21.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-22.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-23.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-24.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-25.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-26.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-27.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-28.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-29.gz    |  Bin 0 -> 47 bytes
 .../rolloverPath/log4j.txt.20170112_09-3.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_09-30       |    1 +
 .../rolloverPath/log4j.txt.20170112_09-4.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_09-5.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_09-6.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_09-7.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_09-8.gz     |  Bin 0 -> 46 bytes
 .../rolloverPath/log4j.txt.20170112_09-9.gz     |  Bin 0 -> 46 bytes
 .../src/test/resources/scripts/filter.groovy    |    7 +-
 log4j-distribution/.gitignore                   |    2 -
 log4j-distribution/pom.xml                      |   24 +-
 log4j-distribution/src/assembly/src.xml         |    1 +
 log4j-flume-ng/.gitignore                       |    4 -
 log4j-flume-ng/pom.xml                          |    4 +-
 .../flume/appender/AbstractFlumeManager.java    |    2 +-
 .../log4j/flume/appender/FlumeAppender.java     |   19 +-
 .../log4j/flume/appender/FlumeAvroManager.java  |    6 +-
 .../flume/appender/FlumeEmbeddedManager.java    |  554 ++---
 .../log4j/flume/appender/FlumeEvent.java        |   19 +-
 .../log4j/flume/appender/FlumeEventFactory.java |    3 +-
 .../flume/appender/FlumePersistentManager.java  | 1726 ++++++++-------
 log4j-flume-ng/src/site/markdown/index.md.vm    |  233 +++
 log4j-flume-ng/src/site/xdoc/index.xml.vm       |  245 ---
 .../log4j/flume/appender/FlumeAppenderTest.java |    1 -
 .../flume/appender/FlumeEmbeddedAgentTest.java  |    4 +-
 .../appender/FlumeEmbeddedAppenderTest.java     |    4 +-
 .../appender/FlumePersistentAppenderTest.java   |    4 +-
 .../flume/appender/FlumePersistentPerf.java     |    4 +-
 log4j-iostreams/.gitignore                      |  Bin 69 -> 0 bytes
 log4j-iostreams/pom.xml                         |    8 +-
 log4j-iostreams/src/site/markdown/index.md      |   55 +
 log4j-iostreams/src/site/xdoc/index.xml         |   67 -
 .../io/AbstractLoggerOutputStreamTest.java      |   15 +-
 .../log4j/io/AbstractLoggerWriterTest.java      |   15 +-
 log4j-jcl/.gitignore                            |    4 -
 log4j-jcl/pom.xml                               |    4 +-
 log4j-jcl/src/site/markdown/index.md            |   33 +
 log4j-jcl/src/site/xdoc/index.xml               |   52 -
 .../apache/logging/log4j/jcl/LoggerTest.java    |  130 +-
 log4j-jmx-gui/.gitignore                        |    4 -
 log4j-jmx-gui/pom.xml                           |    7 +-
 log4j-jmx-gui/src/site/markdown/index.md        |   33 +
 log4j-jmx-gui/src/site/xdoc/index.xml           |   50 -
 log4j-jul/.gitignore                            |    3 -
 log4j-jul/pom.xml                               |    4 +-
 .../org/apache/logging/log4j/jul/Constants.java |    1 +
 .../logging/log4j/jul/CoreLoggerAdapter.java    |    7 +-
 log4j-jul/src/site/markdown/index.md            |   76 +
 log4j-jul/src/site/xdoc/index.xml               |  127 --
 log4j-liquibase/.gitignore                      |    3 -
 log4j-liquibase/pom.xml                         |    4 +-
 log4j-liquibase/src/site/markdown/index.md      |   31 +
 log4j-liquibase/src/site/xdoc/index.xml         |   49 -
 .../ext/logging/log4j2/LoggingTest.java         |   12 +-
 log4j-nosql/.gitignore                          |    4 -
 log4j-nosql/pom.xml                             |   40 +-
 .../log4j/nosql/appender/NoSqlAppender.java     |    3 +-
 .../nosql/appender/NoSqlDatabaseManager.java    |   22 +-
 .../appender/cassandra/CassandraAppender.java   |  185 ++
 .../appender/cassandra/CassandraManager.java    |  218 ++
 .../cassandra/ClockTimestampGenerator.java      |   34 +
 .../nosql/appender/cassandra/package-info.java  |   23 +
 .../nosql/appender/couchdb/CouchDbProvider.java |   19 +-
 .../nosql/appender/mongodb/MongoDbProvider.java |   43 +-
 log4j-nosql/src/site/markdown/index.md.vm       |   79 +
 log4j-nosql/src/site/xdoc/index.xml.vm          |   86 -
 .../log4j/nosql/appender/MongoDbAuthTest.java   |    3 +
 .../log4j/nosql/appender/MongoDbTest.java       |    3 +
 .../log4j/nosql/appender/NoSqlAppenderTest.java |   30 +-
 .../appender/NoSqlDatabaseManagerTest.java      |  431 ++--
 .../appender/cassandra/CassandraAppenderIT.java |   96 +
 .../nosql/appender/cassandra/CassandraRule.java |  113 +
 .../test/resources/CassandraAppenderTest.xml    |   40 +
 log4j-nosql/src/test/resources/cassandra.yaml   |  901 ++++++++
 log4j-osgi/pom.xml                              |  221 ++
 .../osgi/tests/AbstractLoadBundleTest.java      |  321 +++
 .../tests/equinox/EquinoxLoadApiBundleTest.java |   33 +
 .../tests/felix/FelixLoadApiBundleTest.java     |   32 +
 .../log4j/osgi/tests/junit/BundleTestInfo.java  |   71 +
 .../log4j/osgi/tests/junit/OsgiRule.java        |   77 +
 log4j-perf/.gitignore                           |    4 -
 log4j-perf/pom.xml                              |   11 +-
 .../log4j/ThreadContextBenchmarkAccess.java     |   34 +
 .../perf/jmh/AnnotationVsMarkerInterface.java   |   85 +
 .../perf/jmh/AsyncAppenderLog4j2Benchmark.java  |   37 +-
 .../AsyncAppenderLog4j2LocationBenchmark.java   |   23 +-
 .../log4j/perf/jmh/FileAppenderBenchmark.java   |   46 +
 .../log4j/perf/jmh/GelfLayoutBenchmark.java     |   16 +-
 .../log4j/perf/jmh/JdbcAppenderBenchmark.java   |    4 +-
 .../log4j/perf/jmh/JpaAppenderBenchmark.java    |    4 +-
 .../log4j/perf/jmh/MDCFilterBenchmark.java      |   14 +-
 .../jmh/PatternLayoutComparisonBenchmark.java   |    5 +-
 .../logging/log4j/perf/jmh/SimpleBenchmark.java |    9 +
 .../perf/jmh/SortedArrayVsHashMapBenchmark.java |  239 +++
 .../log4j/perf/jmh/ThreadContextBenchmark.java  |  201 ++
 .../perf/jmh/ThreadLocalVsPoolBenchmark.java    |    2 +-
 .../log4j/perf/nogc/OpenHashStringMap.java      |  938 +++++++++
 .../CopyOnWriteOpenHashMapThreadContextMap.java |   46 +
 .../GarbageFreeOpenHashMapThreadContextMap.java |   49 +
 log4j-perf/src/main/resources/log4j2-perf.xml   |   24 +
 log4j-perf/src/main/resources/logback-perf.xml  |   10 +-
 .../perf5AsyncApndDsrptrNoLoc-noOpAppender.xml  |   32 +
 ...perf5AsyncApndDsrptrWithLoc-noOpAppender.xml |   32 +
 .../perf5AsyncApndMpscQNoLoc-noOpAppender.xml   |   32 +
 .../perf5AsyncApndMpscQWithLoc-noOpAppender.xml |   32 +
 .../perf5AsyncApndNoLoc-noOpAppender.xml        |    1 +
 .../perf5AsyncApndXferQNoLoc-noOpAppender.xml   |   32 +
 .../perf5AsyncApndXferQWithLoc-noOpAppender.xml |   32 +
 log4j-samples/.gitignore                        |    5 -
 log4j-samples/configuration/pom.xml             |    2 +-
 .../configuration/CustomConfiguration.java      |   13 +-
 .../CustomConfigurationFactory.java             |   12 +-
 log4j-samples/flume-common/pom.xml              |    2 +-
 log4j-samples/flume-embedded/pom.xml            |    2 +-
 log4j-samples/flume-remote/pom.xml              |    2 +-
 log4j-samples/loggerProperties/pom.xml          |    2 +-
 .../logging/log4j/lookup/CustomMapMessage.java  |    2 +
 log4j-samples/pom.xml                           |    3 +-
 log4j-samples/scala-api/.gitignore              |    3 +
 log4j-samples/scala-api/pom.xml                 |   80 +
 .../scala-api/src/main/resources/log4j2.xml     |   32 +
 .../logging/log4j/scalasample/LoggingApp.scala  |   47 +
 log4j-slf4j-impl/.gitignore                     |    4 -
 log4j-slf4j-impl/pom.xml                        |    9 +-
 log4j-slf4j-impl/src/site/markdown/index.md     |   40 +
 log4j-slf4j-impl/src/site/xdoc/index.xml        |   58 -
 .../logging/slf4j/Log4j2_1482_Slf4jTest.java    |    2 +-
 .../org/apache/logging/slf4j/LoggerTest.java    |  364 ++--
 .../org/apache/logging/slf4j/OptionalTest.java  |  138 +-
 log4j-taglib/.gitignore                         |    4 -
 log4j-taglib/pom.xml                            |    9 +-
 log4j-taglib/src/site/markdown/index.md         |   70 +
 log4j-taglib/src/site/xdoc/index.xml            |   84 -
 log4j-to-slf4j/.gitignore                       |    4 -
 log4j-to-slf4j/pom.xml                          |    6 +-
 .../org/apache/logging/slf4j/MDCContextMap.java |   40 +-
 .../META-INF/log4j-provider.properties          |    2 +-
 log4j-to-slf4j/src/site/markdown/index.md       |   41 +
 log4j-to-slf4j/src/site/xdoc/index.xml          |   58 -
 .../logging/slf4j/Log4j2Jira1688Test.java       |   71 +
 log4j-web/.gitignore                            |    4 -
 log4j-web/pom.xml                               |    8 +-
 .../log4j/web/Log4jServletContextListener.java  |   42 +-
 .../log4j/web/Log4jWebInitializerImpl.java      |  550 ++---
 .../org/apache/logging/log4j/web/WebLookup.java |    8 -
 .../log4j/web/appender/ServletAppender.java     |  104 +-
 log4j-web/src/site/markdown/index.md            |   30 +
 log4j-web/src/site/xdoc/index.xml               |   44 -
 .../Log4jServletContainerInitializerTest.java   |  164 +-
 .../web/Log4jServletContextListenerTest.java    |   58 +-
 .../log4j/web/Log4jServletFilterTest.java       |  114 +-
 .../log4j/web/Log4jWebInitializerImplTest.java  |  367 +---
 .../logging/log4j/web/ServletAppenderTest.java  |    1 +
 .../resources/WEB-INF/classes/log4j-servlet.xml |   64 +-
 mvnw                                            |  236 +++
 mvnw.cmd                                        |  146 ++
 pom.xml                                         |  260 ++-
 src/changes/announcement.vm                     |  118 +-
 src/changes/changes.xml                         |  713 ++++++-
 src/ide/Intellij/2016/CodeStyle.jar             |  Bin 0 -> 3355 bytes
 src/site/apt/download.apt.vm                    |   94 -
 src/site/markdown/articles.md                   |  183 ++
 src/site/markdown/build.md                      |   57 +
 src/site/markdown/changelog.md                  |   34 +
 src/site/markdown/download.md.vm                |  101 +
 src/site/markdown/faq.md.vm                     |  471 +++++
 src/site/markdown/index.md.vm                   |  128 ++
 src/site/markdown/javadoc.md                    |   48 +
 src/site/markdown/maven-artifacts.md.vm         |  305 +++
 src/site/resources/css/site.css                 |   19 +
 src/site/resources/images/logo.png              |  Bin 40736 -> 40517 bytes
 src/site/resources/js/site.js                   |   11 +-
 .../resources/logo/logo-pastel-stuff-2.8.1.png  |  Bin 0 -> 40517 bytes
 src/site/resources/logo/logo-pastel-stuff.xcf   |  Bin 64784 -> 66300 bytes
 .../resources/logo/logo-pool-bottom-2.7.png     |  Bin 0 -> 36964 bytes
 src/site/resources/logo/logo-stone-2.8.png      |  Bin 0 -> 42958 bytes
 src/site/resources/logo/logo-stone-2.8.xcf      |  Bin 0 -> 65661 bytes
 src/site/site.xml                               |   33 +-
 src/site/xdoc/articles.xml                      |  243 ---
 src/site/xdoc/build.xml.vm                      |   71 -
 src/site/xdoc/changelog.xml                     |   42 -
 src/site/xdoc/faq.xml                           |  379 ----
 src/site/xdoc/index.xml.vm                      |  164 --
 src/site/xdoc/javadoc.xml                       |  109 -
 src/site/xdoc/javastyle.xml                     |   69 +-
 src/site/xdoc/manual/appenders.xml              |  634 +++++-
 src/site/xdoc/manual/async.xml                  |   10 +
 src/site/xdoc/manual/configuration.xml.vm       |   99 +-
 src/site/xdoc/manual/customconfig.xml           |   10 +-
 src/site/xdoc/manual/customloglevels.xml.vm     |    6 +
 src/site/xdoc/manual/extending.xml              |   52 +-
 src/site/xdoc/manual/filters.xml                |   21 +-
 src/site/xdoc/manual/garbagefree.xml            |  101 +-
 src/site/xdoc/manual/layouts.xml.vm             |   57 +-
 src/site/xdoc/manual/plugins.xml                |   44 +-
 src/site/xdoc/manual/scala-api.xml              |   96 +
 src/site/xdoc/manual/thread-context.xml         |   36 +
 src/site/xdoc/manual/webapp.xml                 |   26 +
 src/site/xdoc/maven-artifacts.xml.vm            |  381 ----
 src/site/xdoc/runtime-dependencies.xml          |   27 +-
 1244 files changed, 58915 insertions(+), 21988 deletions(-)
----------------------------------------------------------------------



[10/11] logging-log4j2 git commit: [LOG4J2-1838]: Add to changelog

Posted by ma...@apache.org.
[LOG4J2-1838]: Add to changelog

This closes #61.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/91111231
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/91111231
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/91111231

Branch: refs/heads/master
Commit: 911112310868de5fda62302e2fd9bdd0f73f5464
Parents: f14eadf
Author: Matt Sicker <bo...@gmail.com>
Authored: Tue Mar 7 21:58:28 2017 -0600
Committer: Matt Sicker <bo...@gmail.com>
Committed: Tue Mar 7 21:58:28 2017 -0600

----------------------------------------------------------------------
 src/changes/changes.xml | 3 +++
 1 file changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/91111231/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 27774e5..451bc92 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -31,6 +31,9 @@
          - "remove" - Removed
     -->
     <release version="2.8.2" date="2017-MM-DD" description="GA Release 2.8.2">
+      <action issue="LOG4J2-1838" dev="mattsicker" type="add" due-to="Zilong Song">
+        Add support for appending common suffix to each line of throwable stack trace.
+      </action>
       <action issue="LOG4J2-1836" dev="rgoers" type="fix">
         Update the API version to 2.6.0.
       </action>


[08/11] logging-log4j2 git commit: remove unnecessary diffs

Posted by ma...@apache.org.
remove unnecessary diffs


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/4e47b38c
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/4e47b38c
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/4e47b38c

Branch: refs/heads/master
Commit: 4e47b38c4189c0b20b5b26fc982469ee76d49b95
Parents: 7cfc808
Author: xnslong <xn...@outlook.com>
Authored: Mon Mar 6 23:00:45 2017 +0800
Committer: xnslong <xn...@outlook.com>
Committed: Mon Mar 6 23:00:45 2017 +0800

----------------------------------------------------------------------
 .../org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4e47b38c/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
index 3100694..aeb4535 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
@@ -98,7 +98,7 @@ public final class ThrowableFormatOptions {
      * @param suffix
      */
     protected ThrowableFormatOptions(final int lines, final String separator, final List<String> ignorePackages,
-                                     final TextRenderer textRenderer, final String suffix) {
+            final TextRenderer textRenderer, final String suffix) {
         this.lines = lines;
         this.separator = separator == null ? Strings.LINE_SEPARATOR : separator;
         this.ignorePackages = ignorePackages;


[04/11] logging-log4j2 git commit: Allow to append a suffix to each line of the throwable stacktrace.

Posted by ma...@apache.org.
Allow to append a suffix to each line of the throwable stacktrace.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/0146bbae
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/0146bbae
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/0146bbae

Branch: refs/heads/master
Commit: 0146bbae4a94aee9e92e1ba843f0125075debfdc
Parents: f3be879
Author: xnslong <xn...@outlook.com>
Authored: Mon Mar 6 00:57:01 2017 +0800
Committer: xnslong <xn...@outlook.com>
Committed: Mon Mar 6 00:57:01 2017 +0800

----------------------------------------------------------------------
 .../log4j/core/impl/ThrowableFormatOptions.java |  38 +++----
 .../logging/log4j/core/impl/ThrowableProxy.java | 113 +++++++++++--------
 .../ExtendedThrowablePatternConverter.java      |  15 ++-
 .../log4j/core/pattern/PatternParser.java       |   2 +-
 .../pattern/RootThrowablePatternConverter.java  |  15 ++-
 .../core/pattern/ThrowablePatternConverter.java |  49 +++++++-
 .../log4j/core/impl/ThrowableProxyTest.java     |  86 ++++++++++++--
 .../ExtendedThrowablePatternConverterTest.java  |  46 +++++++-
 .../RootThrowablePatternConverterTest.java      |  48 +++++++-
 .../pattern/ThrowablePatternConverterTest.java  |  21 ++--
 10 files changed, 324 insertions(+), 109 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0146bbae/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
index 81cb5dc..2d54351 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
@@ -17,14 +17,12 @@
 package org.apache.logging.log4j.core.impl;
 
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
 import java.util.List;
 import java.util.Scanner;
 
 import org.apache.logging.log4j.core.pattern.JAnsiTextRenderer;
-import org.apache.logging.log4j.core.pattern.TextRenderer;
 import org.apache.logging.log4j.core.pattern.PlainTextRenderer;
+import org.apache.logging.log4j.core.pattern.TextRenderer;
 import org.apache.logging.log4j.core.util.Loader;
 import org.apache.logging.log4j.core.util.Patterns;
 import org.apache.logging.log4j.status.StatusLogger;
@@ -72,7 +70,7 @@ public final class ThrowableFormatOptions {
      */
     private final String separator;
 
-    private final List<String> mdcKeys;
+    private final String suffix;
 
     /**
      * The list of packages to filter.
@@ -88,22 +86,22 @@ public final class ThrowableFormatOptions {
 
     /**
      * Constructs the options for printing stack trace.
-     *  @param lines
+     * @param lines
      *            The number of lines.
      * @param separator
      *            The stack trace separator.
      * @param ignorePackages
- *            The packages to filter.
+*            The packages to filter.
      * @param textRenderer
-     * @param mdcKeys
+     * @param suffix
      */
     protected ThrowableFormatOptions(final int lines, final String separator, final List<String> ignorePackages,
-                                     final TextRenderer textRenderer, final List<String> mdcKeys) {
+                                     final TextRenderer textRenderer, final String suffix) {
         this.lines = lines;
         this.separator = separator == null ? Strings.LINE_SEPARATOR : separator;
         this.ignorePackages = ignorePackages;
         this.textRenderer = textRenderer == null ? PlainTextRenderer.getInstance() : textRenderer;
-        this.mdcKeys = mdcKeys;
+        this.suffix = suffix;
     }
 
     /**
@@ -247,10 +245,10 @@ public final class ThrowableFormatOptions {
         }
 
         int lines = DEFAULT.lines;
-        List<String> mdcKeys = DEFAULT.mdcKeys;
         String separator = DEFAULT.separator;
         List<String> packages = DEFAULT.ignorePackages;
         TextRenderer ansiRenderer = DEFAULT.textRenderer;
+        String suffix = DEFAULT.getSuffix();
         for (final String rawOption : options) {
             if (rawOption != null) {
                 final String option = rawOption.trim();
@@ -289,26 +287,20 @@ public final class ThrowableFormatOptions {
                         StatusLogger.getLogger().warn(
                                 "You requested ANSI exception rendering but JANSI is not on the classpath. Please see https://logging.apache.org/log4j/2.x/runtime-dependencies.html");
                     }
-                } else if (option.startsWith("mdc(") && option.endsWith(")")){
-                    String suffixPattern = option.substring("mdc(".length(), option.length() - 1);
-                    mdcKeys = parseMdcKeys(suffixPattern);
-                } else if (option.startsWith("X(") && option.endsWith(")")){
-                    String suffixPattern = option.substring("X(".length(), option.length() - 1);
-                    mdcKeys = parseMdcKeys(suffixPattern);
+                } else if (option.startsWith("S(") && option.endsWith(")")){
+                    suffix = option.substring("S(".length(), option.length() - 1);
+                } else if (option.startsWith("suffix(") && option.endsWith(")")){
+                    suffix = option.substring("suffix(".length(), option.length() - 1);
                 } else if (!option.equalsIgnoreCase(FULL)) {
                     lines = Integer.parseInt(option);
                 }
             }
         }
-        return new ThrowableFormatOptions(lines, separator, packages, ansiRenderer, mdcKeys);
+        return new ThrowableFormatOptions(lines, separator, packages, ansiRenderer, suffix);
     }
 
-    private static List<String> parseMdcKeys(final String suffixPattern) {
-        if (suffixPattern.trim().isEmpty()) {
-            return Collections.emptyList();
-        } else {
-            return Arrays.asList(suffixPattern.split(","));
-        }
+    public String getSuffix() {
+        return suffix;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0146bbae/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java
index 4cff083..f0db83b 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java
@@ -207,24 +207,25 @@ public class ThrowableProxy implements Serializable {
     }
 
     private void formatCause(final StringBuilder sb, final String prefix, final ThrowableProxy cause,
-                             final List<String> ignorePackages, final TextRenderer textRenderer) {
-        formatThrowableProxy(sb, prefix, CAUSED_BY_LABEL, cause, ignorePackages, textRenderer);
+                             final List<String> ignorePackages, final TextRenderer textRenderer, final String suffix) {
+        formatThrowableProxy(sb, prefix, CAUSED_BY_LABEL, cause, ignorePackages, textRenderer, suffix);
     }
 
     private void formatThrowableProxy(final StringBuilder sb, final String prefix, final String causeLabel,
                                       final ThrowableProxy throwableProxy, final List<String> ignorePackages,
-                                      final TextRenderer textRenderer) {
+                                      final TextRenderer textRenderer, final String suffix) {
         if (throwableProxy == null) {
             return;
         }
         textRenderer.render(prefix, sb, "Prefix");
         textRenderer.render(causeLabel, sb, "CauseLabel");
         throwableProxy.renderOn(sb, textRenderer);
+        renderSuffix(suffix, sb, textRenderer);
         textRenderer.render(EOL_STR, sb, "Text");
         this.formatElements(sb, prefix, throwableProxy.commonElementCount,
-            throwableProxy.getStackTrace(), throwableProxy.extendedStackTrace, ignorePackages, textRenderer);
-        this.formatSuppressed(sb, prefix + TAB, throwableProxy.suppressedProxies, ignorePackages, textRenderer);
-        this.formatCause(sb, prefix, throwableProxy.causeProxy, ignorePackages, textRenderer);
+            throwableProxy.getStackTrace(), throwableProxy.extendedStackTrace, ignorePackages, textRenderer, suffix);
+        this.formatSuppressed(sb, prefix + TAB, throwableProxy.suppressedProxies, ignorePackages, textRenderer, suffix);
+        this.formatCause(sb, prefix, throwableProxy.causeProxy, ignorePackages, textRenderer, suffix);
     }
 
     void renderOn(final StringBuilder output, final TextRenderer textRenderer) {
@@ -237,37 +238,37 @@ public class ThrowableProxy implements Serializable {
     }
 
     private void formatSuppressed(final StringBuilder sb, final String prefix, final ThrowableProxy[] suppressedProxies,
-                                  final List<String> ignorePackages, final TextRenderer textRenderer) {
+                                  final List<String> ignorePackages, final TextRenderer textRenderer, final String suffix) {
         if (suppressedProxies == null) {
             return;
         }
         for (final ThrowableProxy suppressedProxy : suppressedProxies) {
-            formatThrowableProxy(sb, prefix, SUPPRESSED_LABEL, suppressedProxy, ignorePackages, textRenderer);
+            formatThrowableProxy(sb, prefix, SUPPRESSED_LABEL, suppressedProxy, ignorePackages, textRenderer, suffix);
         }
     }
 
     private void formatElements(final StringBuilder sb, final String prefix, final int commonCount,
                                 final StackTraceElement[] causedTrace, final ExtendedStackTraceElement[] extStackTrace,
-                                final List<String> ignorePackages, final TextRenderer textRenderer) {
+                                final List<String> ignorePackages, final TextRenderer textRenderer, final String suffix) {
         if (ignorePackages == null || ignorePackages.isEmpty()) {
             for (final ExtendedStackTraceElement element : extStackTrace) {
-                this.formatEntry(element, sb, prefix, textRenderer);
+                this.formatEntry(element, sb, prefix, textRenderer, suffix);
             }
         } else {
             int count = 0;
             for (int i = 0; i < extStackTrace.length; ++i) {
                 if (!this.ignoreElement(causedTrace[i], ignorePackages)) {
                     if (count > 0) {
-                        appendSuppressedCount(sb, prefix, count, textRenderer);
+                        appendSuppressedCount(sb, prefix, count, textRenderer, suffix);
                         count = 0;
                     }
-                    this.formatEntry(extStackTrace[i], sb, prefix, textRenderer);
+                    this.formatEntry(extStackTrace[i], sb, prefix, textRenderer, suffix);
                 } else {
                     ++count;
                 }
             }
             if (count > 0) {
-                appendSuppressedCount(sb, prefix, count, textRenderer);
+                appendSuppressedCount(sb, prefix, count, textRenderer, suffix);
             }
         }
         if (commonCount != 0) {
@@ -275,12 +276,20 @@ public class ThrowableProxy implements Serializable {
             textRenderer.render("\t... ", sb, "More");
             textRenderer.render(Integer.toString(commonCount), sb, "More");
             textRenderer.render(" more", sb, "More");
+            renderSuffix(suffix, sb, textRenderer);
             textRenderer.render(EOL_STR, sb, "Text");
         }
     }
 
+    private void renderSuffix(final String suffix, final StringBuilder sb, final TextRenderer textRenderer) {
+        if (!suffix.isEmpty()) {
+            textRenderer.render(" ", sb, "Suffix");
+            textRenderer.render(suffix, sb, "Suffix");
+        }
+    }
+
     private void appendSuppressedCount(final StringBuilder sb, final String prefix, final int count,
-                                       final TextRenderer textRenderer) {
+                                       final TextRenderer textRenderer, final String suffix) {
         textRenderer.render(prefix, sb, "Prefix");
         if (count == 1) {
             textRenderer.render("\t... ", sb, "Suppressed");
@@ -289,59 +298,63 @@ public class ThrowableProxy implements Serializable {
             textRenderer.render(Integer.toString(count), sb, "Suppressed");
             textRenderer.render(" lines", sb, "Suppressed");
         }
+        renderSuffix(suffix, sb, textRenderer);
         textRenderer.render(EOL_STR, sb, "Text");
     }
 
     private void formatEntry(final ExtendedStackTraceElement extStackTraceElement, final StringBuilder sb,
-                             final String prefix, final TextRenderer textRenderer) {
+                             final String prefix, final TextRenderer textRenderer, final String suffix) {
         textRenderer.render(prefix, sb, "Prefix");
         textRenderer.render("\tat ", sb, "At");
         extStackTraceElement.renderOn(sb, textRenderer);
+        renderSuffix(suffix, sb, textRenderer);
         textRenderer.render(EOL_STR, sb, "Text");
     }
 
     /**
      * Formats the specified Throwable.
-     *
-     * @param sb    StringBuilder to contain the formatted Throwable.
+     *  @param sb    StringBuilder to contain the formatted Throwable.
      * @param cause The Throwable to format.
+     * @param suffix
      */
-    public void formatWrapper(final StringBuilder sb, final ThrowableProxy cause) {
-        this.formatWrapper(sb, cause, null, PlainTextRenderer.getInstance());
+    public void formatWrapper(final StringBuilder sb, final ThrowableProxy cause, final String suffix) {
+        this.formatWrapper(sb, cause, null, PlainTextRenderer.getInstance(), suffix);
     }
 
     /**
      * Formats the specified Throwable.
-     *
-     * @param sb             StringBuilder to contain the formatted Throwable.
+     *  @param sb             StringBuilder to contain the formatted Throwable.
      * @param cause          The Throwable to format.
      * @param ignorePackages The List of packages to be suppressed from the trace.
+     * @param suffix
      */
     @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
-    public void formatWrapper(final StringBuilder sb, final ThrowableProxy cause, final List<String> ignorePackages) {
-        this.formatWrapper(sb, cause, ignorePackages, PlainTextRenderer.getInstance());
+    public void formatWrapper(final StringBuilder sb, final ThrowableProxy cause, final List<String> ignorePackages, final String suffix) {
+        this.formatWrapper(sb, cause, ignorePackages, PlainTextRenderer.getInstance(), suffix);
     }
 
     /**
      * Formats the specified Throwable.
-     *
-     * @param sb             StringBuilder to contain the formatted Throwable.
+     *  @param sb             StringBuilder to contain the formatted Throwable.
      * @param cause          The Throwable to format.
      * @param ignorePackages The List of packages to be suppressed from the trace.
      * @param textRenderer   The text render
+     * @param suffix
      */
     @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
     public void formatWrapper(final StringBuilder sb, final ThrowableProxy cause, final List<String> ignorePackages,
-                              final TextRenderer textRenderer) {
+                              final TextRenderer textRenderer, final String suffix) {
         final Throwable caused = cause.getCauseProxy() != null ? cause.getCauseProxy().getThrowable() : null;
         if (caused != null) {
-            this.formatWrapper(sb, cause.causeProxy, ignorePackages, textRenderer);
+            this.formatWrapper(sb, cause.causeProxy, ignorePackages, textRenderer, suffix);
             sb.append(WRAPPED_BY_LABEL);
+            renderSuffix(suffix, sb, textRenderer);
         }
         cause.renderOn(sb, textRenderer);
+        renderSuffix(suffix, sb, textRenderer);
         textRenderer.render(EOL_STR, sb, "Text");
         this.formatElements(sb, Strings.EMPTY, cause.commonElementCount,
-            cause.getThrowable().getStackTrace(), cause.extendedStackTrace, ignorePackages, textRenderer);
+            cause.getThrowable().getStackTrace(), cause.extendedStackTrace, ignorePackages, textRenderer, suffix);
     }
 
     public ThrowableProxy getCauseProxy() {
@@ -352,19 +365,21 @@ public class ThrowableProxy implements Serializable {
      * Formats the Throwable that is the cause of this Throwable.
      *
      * @return The formatted Throwable that caused this Throwable.
+     * @param suffix
      */
-    public String getCauseStackTraceAsString() {
-        return this.getCauseStackTraceAsString(null, PlainTextRenderer.getInstance());
+    public String getCauseStackTraceAsString(final String suffix) {
+        return this.getCauseStackTraceAsString(null, PlainTextRenderer.getInstance(), suffix);
     }
 
     /**
      * Formats the Throwable that is the cause of this Throwable.
      *
      * @param packages The List of packages to be suppressed from the trace.
+     * @param suffix
      * @return The formatted Throwable that caused this Throwable.
      */
-    public String getCauseStackTraceAsString(final List<String> packages) {
-        return getCauseStackTraceAsString(packages, PlainTextRenderer.getInstance());
+    public String getCauseStackTraceAsString(final List<String> packages, final String suffix) {
+        return getCauseStackTraceAsString(packages, PlainTextRenderer.getInstance(), suffix);
     }
 
     /**
@@ -372,18 +387,21 @@ public class ThrowableProxy implements Serializable {
      *
      * @param ignorePackages The List of packages to be suppressed from the trace.
      * @param textRenderer   the text renderer
+     * @param suffix
      * @return The formatted Throwable that caused this Throwable.
      */
-    public String getCauseStackTraceAsString(final List<String> ignorePackages, final TextRenderer textRenderer) {
+    public String getCauseStackTraceAsString(final List<String> ignorePackages, final TextRenderer textRenderer, final String suffix) {
         final StringBuilder sb = new StringBuilder();
         if (this.causeProxy != null) {
-            this.formatWrapper(sb, this.causeProxy, ignorePackages, textRenderer);
+            this.formatWrapper(sb, this.causeProxy, ignorePackages, textRenderer, suffix);
             sb.append(WRAPPED_BY_LABEL);
+            renderSuffix(suffix, sb, textRenderer);
         }
         this.renderOn(sb, textRenderer);
+        renderSuffix(suffix, sb, textRenderer);
         textRenderer.render(EOL_STR, sb, "Text");
         this.formatElements(sb, Strings.EMPTY, 0, this.throwable.getStackTrace(), this.extendedStackTrace,
-            ignorePackages, textRenderer);
+            ignorePackages, textRenderer, suffix);
         return sb.toString();
     }
 
@@ -410,19 +428,21 @@ public class ThrowableProxy implements Serializable {
      * Format the stack trace including packaging information.
      *
      * @return The formatted stack trace including packaging information.
+     * @param suffix
      */
-    public String getExtendedStackTraceAsString() {
-        return this.getExtendedStackTraceAsString(null, PlainTextRenderer.getInstance());
+    public String getExtendedStackTraceAsString(final String suffix) {
+        return this.getExtendedStackTraceAsString(null, PlainTextRenderer.getInstance(), suffix);
     }
 
     /**
      * Format the stack trace including packaging information.
      *
      * @param ignorePackages List of packages to be ignored in the trace.
+     * @param suffix
      * @return The formatted stack trace including packaging information.
      */
-    public String getExtendedStackTraceAsString(final List<String> ignorePackages) {
-        return getExtendedStackTraceAsString(ignorePackages, PlainTextRenderer.getInstance());
+    public String getExtendedStackTraceAsString(final List<String> ignorePackages, final String suffix) {
+        return getExtendedStackTraceAsString(ignorePackages, PlainTextRenderer.getInstance(), suffix);
     }
 
     /**
@@ -430,18 +450,20 @@ public class ThrowableProxy implements Serializable {
      *
      * @param ignorePackages List of packages to be ignored in the trace.
      * @param textRenderer   The message renderer
+     * @param suffix
      * @return The formatted stack trace including packaging information.
      */
-    public String getExtendedStackTraceAsString(final List<String> ignorePackages, final TextRenderer textRenderer) {
+    public String getExtendedStackTraceAsString(final List<String> ignorePackages, final TextRenderer textRenderer, final String suffix) {
         final StringBuilder sb = new StringBuilder(1024);
         textRenderer.render(name, sb, "Name");
         textRenderer.render(": ", sb, "NameMessageSeparator");
         textRenderer.render(this.message, sb, "Message");
+        renderSuffix(suffix, sb, textRenderer);
         textRenderer.render(EOL_STR, sb, "Text");
         final StackTraceElement[] causedTrace = this.throwable != null ? this.throwable.getStackTrace() : null;
-        this.formatElements(sb, Strings.EMPTY, 0, causedTrace, this.extendedStackTrace, ignorePackages, textRenderer);
-        this.formatSuppressed(sb, TAB, this.suppressedProxies, ignorePackages, textRenderer);
-        this.formatCause(sb, Strings.EMPTY, this.causeProxy, ignorePackages, textRenderer);
+        this.formatElements(sb, Strings.EMPTY, 0, causedTrace, this.extendedStackTrace, ignorePackages, textRenderer, suffix);
+        this.formatSuppressed(sb, TAB, this.suppressedProxies, ignorePackages, textRenderer, suffix);
+        this.formatCause(sb, Strings.EMPTY, this.causeProxy, ignorePackages, textRenderer, suffix);
         return sb.toString();
     }
 
@@ -479,15 +501,16 @@ public class ThrowableProxy implements Serializable {
      * Format the suppressed Throwables.
      *
      * @return The formatted suppressed Throwables.
+     * @param suffix
      */
-    public String getSuppressedStackTrace() {
+    public String getSuppressedStackTrace(final String suffix) {
         final ThrowableProxy[] suppressed = this.getSuppressedProxies();
         if (suppressed == null || suppressed.length == 0) {
             return Strings.EMPTY;
         }
         final StringBuilder sb = new StringBuilder("Suppressed Stack Trace Elements:").append(EOL);
         for (final ThrowableProxy proxy : suppressed) {
-            sb.append(proxy.getExtendedStackTraceAsString());
+            sb.append(proxy.getExtendedStackTraceAsString(suffix));
         }
         return sb.toString();
     }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0146bbae/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java
index a5cdcda..4cd0725 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java
@@ -17,6 +17,7 @@
 package org.apache.logging.log4j.core.pattern;
 
 import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 import org.apache.logging.log4j.core.impl.ThrowableProxy;
 import org.apache.logging.log4j.util.Strings;
@@ -35,22 +36,23 @@ public final class ExtendedThrowablePatternConverter extends ThrowablePatternCon
 
     /**
      * Private constructor.
-     *
+     * @param config
      * @param options options, may be null.
      */
-    private ExtendedThrowablePatternConverter(final String[] options) {
-        super("ExtendedThrowable", "throwable", options);
+    private ExtendedThrowablePatternConverter(final Configuration config, final String[] options) {
+        super("ExtendedThrowable", "throwable", options, config);
     }
 
     /**
      * Gets an instance of the class.
      *
+     * @param config The current Configuration.
      * @param options pattern options, may be null.  If first element is "short",
      *                only the first line of the throwable will be formatted.
      * @return instance of class.
      */
-    public static ExtendedThrowablePatternConverter newInstance(final String[] options) {
-        return new ExtendedThrowablePatternConverter(options);
+    public static ExtendedThrowablePatternConverter newInstance(final Configuration config, final String[] options) {
+        return new ExtendedThrowablePatternConverter(config, options);
     }
 
     /**
@@ -65,7 +67,8 @@ public final class ExtendedThrowablePatternConverter extends ThrowablePatternCon
                 super.format(event, toAppendTo);
                 return;
             }
-            final String extStackTrace = proxy.getExtendedStackTraceAsString(options.getIgnorePackages(), options.getTextRenderer());
+            String suffix = getSuffix(event);
+            final String extStackTrace = proxy.getExtendedStackTraceAsString(options.getIgnorePackages(), options.getTextRenderer(), suffix);
             final int len = toAppendTo.length();
             if (len > 0 && !Character.isWhitespace(toAppendTo.charAt(len - 1))) {
                 toAppendTo.append(' ');

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0146bbae/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/PatternParser.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/PatternParser.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/PatternParser.java
index 8b8983c..065ab9c 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/PatternParser.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/PatternParser.java
@@ -204,7 +204,7 @@ public final class PatternParser {
             list.add(new PatternFormatter(pc, field));
         }
         if (alwaysWriteExceptions && !handlesThrowable) {
-            final LogEventPatternConverter pc = ExtendedThrowablePatternConverter.newInstance(null);
+            final LogEventPatternConverter pc = ExtendedThrowablePatternConverter.newInstance(config, null);
             list.add(new PatternFormatter(pc, FormattingInfo.getDefault()));
         }
         return list;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0146bbae/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java
index b2e101c..80beaf6 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java
@@ -17,6 +17,7 @@
 package org.apache.logging.log4j.core.pattern;
 
 import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 import org.apache.logging.log4j.core.impl.ThrowableProxy;
 import org.apache.logging.log4j.util.Strings;
@@ -36,22 +37,23 @@ public final class RootThrowablePatternConverter extends ThrowablePatternConvert
     /**
      * Private constructor.
      *
+     * @param config
      * @param options options, may be null.
      */
-    private RootThrowablePatternConverter(final String[] options) {
-        super("RootThrowable", "throwable", options);
+    private RootThrowablePatternConverter(final Configuration config, final String[] options) {
+        super("RootThrowable", "throwable", options, config);
     }
 
     /**
      * Gets an instance of the class.
      *
-     *
+     * @param config
      * @param options pattern options, may be null.  If first element is "short",
      *                only the first line of the throwable will be formatted.
      * @return instance of class.
      */
-    public static RootThrowablePatternConverter newInstance(final String[] options) {
-        return new RootThrowablePatternConverter(options);
+    public static RootThrowablePatternConverter newInstance(final Configuration config, final String[] options) {
+        return new RootThrowablePatternConverter(config, options);
     }
 
     /**
@@ -66,7 +68,8 @@ public final class RootThrowablePatternConverter extends ThrowablePatternConvert
                 super.format(event, toAppendTo);
                 return;
             }
-            final String trace = proxy.getCauseStackTraceAsString(options.getIgnorePackages());
+            String suffix = getSuffix(event);
+            final String trace = proxy.getCauseStackTraceAsString(options.getIgnorePackages(), suffix);
             final int len = toAppendTo.length();
             if (len > 0 && !Character.isWhitespace(toAppendTo.charAt(len - 1))) {
                 toAppendTo.append(' ');

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0146bbae/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverter.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverter.java
index a746130..91b6bab 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverter.java
@@ -18,10 +18,15 @@ package org.apache.logging.log4j.core.pattern;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 import org.apache.logging.log4j.core.impl.ThrowableFormatOptions;
+import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.apache.logging.log4j.util.Strings;
 
 
@@ -34,6 +39,7 @@ import org.apache.logging.log4j.util.Strings;
 @ConverterKeys({ "ex", "throwable", "exception" })
 public class ThrowablePatternConverter extends LogEventPatternConverter {
 
+    protected final List<PatternFormatter> formatters;
     private String rawOption;
 
     /**
@@ -46,24 +52,52 @@ public class ThrowablePatternConverter extends LogEventPatternConverter {
      * @param name Name of converter.
      * @param style CSS style for output.
      * @param options options, may be null.
+     * @param config
      */
-    protected ThrowablePatternConverter(final String name, final String style, final String[] options) {
+    protected ThrowablePatternConverter(final String name, final String style, final String[] options, final Configuration config) {
         super(name, style);
         this.options = ThrowableFormatOptions.newInstance(options);
         if (options != null && options.length > 0) {
             rawOption = options[0];
         }
+        if (this.options.getSuffix() != null) {
+            final PatternParser parser = PatternLayout.createPatternParser(config);
+            List<PatternFormatter> parsedFormatters = parser.parse(this.options.getSuffix());
+            // filter out nested formatters that will handle throwable
+            boolean hasThrowableFormatter = false;
+            for (PatternFormatter formatter : parsedFormatters) {
+                if (formatter.handlesThrowable()) {
+                    hasThrowableFormatter = true;
+                }
+            }
+            if (!hasThrowableFormatter) {
+                this.formatters = parsedFormatters;
+            } else {
+                List<PatternFormatter> formatters = new ArrayList<>();
+                for (PatternFormatter formatter : parsedFormatters) {
+                    if (!formatter.handlesThrowable()) {
+                        formatters.add(formatter);
+                    }
+                }
+                this.formatters = formatters;
+            }
+        } else {
+            this.formatters = Collections.emptyList();
+        }
+
     }
 
     /**
      * Gets an instance of the class.
      *
+     *
+     * @param config
      * @param options pattern options, may be null.  If first element is "short",
      *                only the first line of the throwable will be formatted.
      * @return instance of class.
      */
-    public static ThrowablePatternConverter newInstance(final String[] options) {
-        return new ThrowablePatternConverter("Throwable", "throwable", options);
+    public static ThrowablePatternConverter newInstance(final Configuration config, final String[] options) {
+        return new ThrowablePatternConverter("Throwable", "throwable", options, config);
     }
 
     /**
@@ -166,4 +200,13 @@ public class ThrowablePatternConverter extends LogEventPatternConverter {
     public boolean handlesThrowable() {
         return true;
     }
+
+    protected String getSuffix(LogEvent event) {
+        //noinspection ForLoopReplaceableByForEach
+        StringBuilder toAppendTo = new StringBuilder();
+        for (int i = 0, size = formatters.size(); i <  size; i++) {
+            formatters.get(i).format(event, toAppendTo);
+        }
+        return toAppendTo.toString();
+    }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0146bbae/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableProxyTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableProxyTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableProxyTest.java
index 76fe83b..08f10de 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableProxyTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableProxyTest.java
@@ -35,22 +35,21 @@ import java.security.SecureRandom;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Stack;
-
 import javax.crypto.BadPaddingException;
 import javax.crypto.Cipher;
 import javax.crypto.KeyGenerator;
 import javax.crypto.spec.IvParameterSpec;
 import javax.xml.bind.DatatypeConverter;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.jackson.Log4jJsonObjectMapper;
 import org.apache.logging.log4j.core.jackson.Log4jXmlObjectMapper;
+import org.apache.logging.log4j.util.Strings;
 import org.junit.Test;
 
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
 /**
  *
  */
@@ -82,6 +81,19 @@ public class ThrowableProxyTest {
         return arr.toByteArray();
     }
 
+    private boolean allLinesContain(final String text, final String containedText) {
+        String[] lines = text.split("\n");
+        for (String line : lines) {
+            if (line.isEmpty()) {
+                continue;
+            }
+            if (!line.contains(containedText)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     private void testIoContainer(final ObjectMapper objectMapper ) throws IOException {
         final Fixture expected = new Fixture();
         final String s = objectMapper.writeValueAsString(expected);
@@ -228,7 +240,7 @@ public class ThrowableProxyTest {
         final byte[] binary = serialize(proxy);
         final ThrowableProxy proxy2 = deserialize(binary);
 
-        assertEquals(proxy.getExtendedStackTraceAsString(), proxy2.getExtendedStackTraceAsString());
+        assertEquals(proxy.getExtendedStackTraceAsString(Strings.EMPTY), proxy2.getExtendedStackTraceAsString(Strings.EMPTY));
     }
 
     @Test
@@ -256,7 +268,7 @@ public class ThrowableProxyTest {
         final byte[] binary = serialize(proxy);
         final ThrowableProxy proxy2 = deserialize(binary);
 
-        assertEquals(proxy.getExtendedStackTraceAsString(), proxy2.getExtendedStackTraceAsString());
+        assertEquals(proxy.getExtendedStackTraceAsString(Strings.EMPTY), proxy2.getExtendedStackTraceAsString(Strings.EMPTY));
     }
 
     @Test
@@ -282,6 +294,64 @@ public class ThrowableProxyTest {
     }
 
     @Test
+    public void testSuffix_getExtendedStackTraceAsString() throws Exception {
+        final Throwable throwable = new IllegalArgumentException("This is a test");
+        final ThrowableProxy proxy = new ThrowableProxy(throwable);
+
+        String suffix = "some suffix";
+        assertTrue(allLinesContain(proxy.getExtendedStackTraceAsString(suffix), suffix));
+    }
+
+    @Test
+    public void testSuffix_getExtendedStackTraceAsStringWithCausedThrowable() throws Exception {
+        final Throwable throwable = new RuntimeException(new IllegalArgumentException("This is a test"));
+        final ThrowableProxy proxy = new ThrowableProxy(throwable);
+
+        String suffix = "some suffix";
+        assertTrue(allLinesContain(proxy.getExtendedStackTraceAsString(suffix), suffix));
+    }
+
+    @Test
+    public void testSuffix_getExtendedStackTraceAsStringWithSuppressedThrowable() throws Exception {
+        IllegalArgumentException cause = new IllegalArgumentException("This is a test");
+        final Throwable throwable = new RuntimeException(cause);
+        throwable.addSuppressed(new IOException("This is a test"));
+        final ThrowableProxy proxy = new ThrowableProxy(throwable);
+
+        String suffix = "some suffix";
+        assertTrue(allLinesContain(proxy.getExtendedStackTraceAsString(suffix), suffix));
+    }
+
+    @Test
+    public void testSuffix_getCauseStackTraceAsString() throws Exception {
+        final Throwable throwable = new IllegalArgumentException("This is a test");
+        final ThrowableProxy proxy = new ThrowableProxy(throwable);
+
+        String suffix = "some suffix";
+        assertTrue(allLinesContain(proxy.getCauseStackTraceAsString(suffix), suffix));
+    }
+
+    @Test
+    public void testSuffix_getCauseStackTraceAsStringWithCausedThrowable() throws Exception {
+        final Throwable throwable = new RuntimeException(new IllegalArgumentException("This is a test"));
+        final ThrowableProxy proxy = new ThrowableProxy(throwable);
+
+        String suffix = "some suffix";
+        assertTrue(allLinesContain(proxy.getCauseStackTraceAsString(suffix), suffix));
+    }
+
+    @Test
+    public void testSuffix_getCauseStackTraceAsStringWithSuppressedThrowable() throws Exception {
+        IllegalArgumentException cause = new IllegalArgumentException("This is a test");
+        final Throwable throwable = new RuntimeException(cause);
+        throwable.addSuppressed(new IOException("This is a test"));
+        final ThrowableProxy proxy = new ThrowableProxy(throwable);
+
+        String suffix = "some suffix";
+        assertTrue(allLinesContain(proxy.getCauseStackTraceAsString(suffix), suffix));
+    }
+
+    @Test
     public void testStack() {
         final Map<String, ThrowableProxy.CacheEntry> map = new HashMap<>();
         final Stack<Class<?>> stack = new Stack<>();
@@ -332,7 +402,7 @@ public class ThrowableProxyTest {
 		e.addSuppressed(new IOException("Suppressed #2"));
 		LogManager.getLogger().error("Error", e);
 		final ThrowableProxy proxy = new ThrowableProxy(e);
-		final String extendedStackTraceAsString = proxy.getExtendedStackTraceAsString();
+		final String extendedStackTraceAsString = proxy.getExtendedStackTraceAsString("same suffix");
 		assertTrue(extendedStackTraceAsString.contains("\tSuppressed: java.io.IOException: Suppressed #1"));
 		assertTrue(extendedStackTraceAsString.contains("\tSuppressed: java.io.IOException: Suppressed #1"));
 	}
@@ -344,7 +414,7 @@ public class ThrowableProxyTest {
 		cause.addSuppressed(new IOException("Suppressed #2"));
 		LogManager.getLogger().error("Error", new Exception(cause));
 		final ThrowableProxy proxy = new ThrowableProxy(new Exception("Root exception", cause));
-		final String extendedStackTraceAsString = proxy.getExtendedStackTraceAsString();
+		final String extendedStackTraceAsString = proxy.getExtendedStackTraceAsString("same suffix");
 		assertTrue(extendedStackTraceAsString.contains("\tSuppressed: java.io.IOException: Suppressed #1"));
 		assertTrue(extendedStackTraceAsString.contains("\tSuppressed: java.io.IOException: Suppressed #1"));
 	}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0146bbae/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverterTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverterTest.java
index 8dfb2f5..9bd30d4 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverterTest.java
@@ -23,6 +23,7 @@ import java.io.PrintWriter;
 import java.io.StringWriter;
 
 import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.ThreadContext;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
 import org.apache.logging.log4j.core.impl.ThrowableProxy;
@@ -36,8 +37,47 @@ import org.junit.Test;
 public class ExtendedThrowablePatternConverterTest {
 
     @Test
+    public void testSuffixFromNormalPattern() {
+        final String suffix = "suffix(%mdc{key})";
+        ThreadContext.put("key", "test suffix ");
+        final String[] options = {suffix};
+        final ExtendedThrowablePatternConverter converter = ExtendedThrowablePatternConverter.newInstance(null, options);
+        final Throwable cause = new NullPointerException("null pointer");
+        final Throwable parent = new IllegalArgumentException("IllegalArgument", cause);
+        final LogEvent event = Log4jLogEvent.newBuilder() //
+                .setLoggerName("testLogger") //
+                .setLoggerFqcn(this.getClass().getName()) //
+                .setLevel(Level.DEBUG) //
+                .setMessage(new SimpleMessage("test exception")) //
+                .setThrown(parent).build();
+        final StringBuilder sb = new StringBuilder();
+        converter.format(event, sb);
+        final String result = sb.toString();
+        assertTrue("No suffix", result.contains("test suffix"));
+    }
+
+    @Test
+    public void testSuffix() {
+        final String suffix = "suffix(test suffix)";
+        final String[] options = {suffix};
+        final ExtendedThrowablePatternConverter converter = ExtendedThrowablePatternConverter.newInstance(null, options);
+        final Throwable cause = new NullPointerException("null pointer");
+        final Throwable parent = new IllegalArgumentException("IllegalArgument", cause);
+        final LogEvent event = Log4jLogEvent.newBuilder() //
+                .setLoggerName("testLogger") //
+                .setLoggerFqcn(this.getClass().getName()) //
+                .setLevel(Level.DEBUG) //
+                .setMessage(new SimpleMessage("test exception")) //
+                .setThrown(parent).build();
+        final StringBuilder sb = new StringBuilder();
+        converter.format(event, sb);
+        final String result = sb.toString();
+        assertTrue("No suffix", result.contains("test suffix"));
+    }
+
+    @Test
 	public void testDeserializedLogEventWithThrowableProxyButNoThrowable() {
-		final ExtendedThrowablePatternConverter converter = ExtendedThrowablePatternConverter.newInstance(null);
+		final ExtendedThrowablePatternConverter converter = ExtendedThrowablePatternConverter.newInstance(null, null);
 		final Throwable originalThrowable = new Exception("something bad happened");
 		final ThrowableProxy throwableProxy = new ThrowableProxy(originalThrowable);
 		final Throwable deserializedThrowable = null;
@@ -60,7 +100,7 @@ public class ExtendedThrowablePatternConverterTest {
     public void testFiltering() {
         final String packages = "filters(org.junit, org.apache.maven, sun.reflect, java.lang.reflect)";
         final String[] options = {packages};
-        final ExtendedThrowablePatternConverter converter = ExtendedThrowablePatternConverter.newInstance(options);
+        final ExtendedThrowablePatternConverter converter = ExtendedThrowablePatternConverter.newInstance(null, options);
         final Throwable cause = new NullPointerException("null pointer");
         final Throwable parent = new IllegalArgumentException("IllegalArgument", cause);
         final LogEvent event = Log4jLogEvent.newBuilder() //
@@ -77,7 +117,7 @@ public class ExtendedThrowablePatternConverterTest {
 
     @Test
     public void testFull() {
-        final ExtendedThrowablePatternConverter converter = ExtendedThrowablePatternConverter.newInstance(null);
+        final ExtendedThrowablePatternConverter converter = ExtendedThrowablePatternConverter.newInstance(null, null);
         final Throwable cause = new NullPointerException("null pointer");
         final Throwable parent = new IllegalArgumentException("IllegalArgument", cause);
         final LogEvent event = Log4jLogEvent.newBuilder() //

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0146bbae/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverterTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverterTest.java
index 7c07d3f..3c45c7a 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverterTest.java
@@ -16,22 +16,62 @@
  */
 package org.apache.logging.log4j.core.pattern;
 
+import static org.junit.Assert.assertTrue;
+
 import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.ThreadContext;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
 import org.apache.logging.log4j.message.SimpleMessage;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
-
 /**
  *
  */
 public class RootThrowablePatternConverterTest {
 
     @Test
+    public void testSuffix() {
+        final String suffix = "suffix(test suffix)";
+        final String[] options = {suffix};
+        final RootThrowablePatternConverter converter = RootThrowablePatternConverter.newInstance(null, options);
+        final Throwable cause = new NullPointerException("null pointer");
+        final Throwable parent = new IllegalArgumentException("IllegalArgument", cause);
+        final LogEvent event = Log4jLogEvent.newBuilder() //
+                .setLoggerName("testLogger") //
+                .setLoggerFqcn(this.getClass().getName()) //
+                .setLevel(Level.DEBUG) //
+                .setMessage(new SimpleMessage("test exception")) //
+                .setThrown(parent).build();
+        final StringBuilder sb = new StringBuilder();
+        converter.format(event, sb);
+        final String result = sb.toString();
+        assertTrue("No suffix", result.contains("test suffix"));
+    }
+
+    @Test
+    public void testSuffixFromNormalPattern() {
+        final String suffix = "suffix(%mdc{key})";
+        ThreadContext.put("key", "test suffix ");
+        final String[] options = {suffix};
+        final RootThrowablePatternConverter converter = RootThrowablePatternConverter.newInstance(null, options);
+        final Throwable cause = new NullPointerException("null pointer");
+        final Throwable parent = new IllegalArgumentException("IllegalArgument", cause);
+        final LogEvent event = Log4jLogEvent.newBuilder() //
+                .setLoggerName("testLogger") //
+                .setLoggerFqcn(this.getClass().getName()) //
+                .setLevel(Level.DEBUG) //
+                .setMessage(new SimpleMessage("test exception")) //
+                .setThrown(parent).build();
+        final StringBuilder sb = new StringBuilder();
+        converter.format(event, sb);
+        final String result = sb.toString();
+        assertTrue("No suffix", result.contains("test suffix"));
+    }
+
+    @Test
     public void testFull1() {
-        final RootThrowablePatternConverter converter = RootThrowablePatternConverter.newInstance(null);
+        final RootThrowablePatternConverter converter = RootThrowablePatternConverter.newInstance(null, null);
         final Throwable cause = new NullPointerException("null pointer");
         final Throwable parent = new IllegalArgumentException("IllegalArgument", cause);
         final LogEvent event = Log4jLogEvent.newBuilder() //
@@ -55,7 +95,7 @@ public class RootThrowablePatternConverterTest {
      */
     @Test
     public void testFull2() {
-        final RootThrowablePatternConverter converter = RootThrowablePatternConverter.newInstance(null);
+        final RootThrowablePatternConverter converter = RootThrowablePatternConverter.newInstance(null, null);
         Throwable parent;
         try {
             try {

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0146bbae/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverterTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverterTest.java
index e3c1f45..55aa895 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverterTest.java
@@ -16,14 +16,15 @@
  */
 package org.apache.logging.log4j.core.pattern;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
 import org.apache.logging.log4j.message.SimpleMessage;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
-
 public class ThrowablePatternConverterTest {
 
     private final static class LocalizedException extends Exception {
@@ -42,13 +43,13 @@ public class ThrowablePatternConverterTest {
     @Test(expected = Exception.class)
     public void testBadShortOption() {
         final String[] options = { "short.UNKNOWN" };
-        ThrowablePatternConverter.newInstance(options);
+        ThrowablePatternConverter.newInstance(null, options);
     }
 
     @Test
     public void testFull() {
         final String[] options = { "full" };
-        final ThrowablePatternConverter converter = ThrowablePatternConverter.newInstance(options);
+        final ThrowablePatternConverter converter = ThrowablePatternConverter.newInstance(null, options);
         Throwable parent;
         try {
             try {
@@ -77,7 +78,7 @@ public class ThrowablePatternConverterTest {
     public void testShortClassName() {
         final String packageName = "org.apache.logging.log4j.core.pattern.";
         final String[] options = { "short.className" };
-        final ThrowablePatternConverter converter = ThrowablePatternConverter.newInstance(options);
+        final ThrowablePatternConverter converter = ThrowablePatternConverter.newInstance(null, options);
         final Throwable cause = new NullPointerException("null pointer");
         final Throwable parent = new IllegalArgumentException("IllegalArgument", cause);
         final LogEvent event = Log4jLogEvent.newBuilder() //
@@ -95,7 +96,7 @@ public class ThrowablePatternConverterTest {
     @Test
     public void testShortFileName() {
         final String[] options = { "short.fileName" };
-        final ThrowablePatternConverter converter = ThrowablePatternConverter.newInstance(options);
+        final ThrowablePatternConverter converter = ThrowablePatternConverter.newInstance(null, options);
         final Throwable cause = new NullPointerException("null pointer");
         final Throwable parent = new IllegalArgumentException("IllegalArgument", cause);
         final LogEvent event = Log4jLogEvent.newBuilder() //
@@ -113,7 +114,7 @@ public class ThrowablePatternConverterTest {
     @Test
     public void testShortLineNumber() {
         final String[] options = { "short.lineNumber" };
-        final ThrowablePatternConverter converter = ThrowablePatternConverter.newInstance(options);
+        final ThrowablePatternConverter converter = ThrowablePatternConverter.newInstance(null, options);
         final Throwable cause = new NullPointerException("null pointer");
         final Throwable parent = new IllegalArgumentException("IllegalArgument", cause);
         final StackTraceElement top = parent.getStackTrace()[0];
@@ -134,7 +135,7 @@ public class ThrowablePatternConverterTest {
     @Test
     public void testShortLocalizedMessage() {
         final String[] options = { "short.localizedMessage" };
-        final ThrowablePatternConverter converter = ThrowablePatternConverter.newInstance(options);
+        final ThrowablePatternConverter converter = ThrowablePatternConverter.newInstance(null, options);
         final Throwable parent = new LocalizedException();
         final LogEvent event = Log4jLogEvent.newBuilder() //
                 .setLoggerName("testLogger") //
@@ -151,7 +152,7 @@ public class ThrowablePatternConverterTest {
     @Test
     public void testShortMessage() {
         final String[] options = { "short.message" };
-        final ThrowablePatternConverter converter = ThrowablePatternConverter.newInstance(options);
+        final ThrowablePatternConverter converter = ThrowablePatternConverter.newInstance(null, options);
         final Throwable cause = new NullPointerException("null pointer");
         final Throwable parent = new IllegalArgumentException("IllegalArgument", cause);
         final LogEvent event = Log4jLogEvent.newBuilder() //
@@ -169,7 +170,7 @@ public class ThrowablePatternConverterTest {
     @Test
     public void testShortMethodName() {
         final String[] options = { "short.methodName" };
-        final ThrowablePatternConverter converter = ThrowablePatternConverter.newInstance(options);
+        final ThrowablePatternConverter converter = ThrowablePatternConverter.newInstance(null, options);
         final Throwable cause = new NullPointerException("null pointer");
         final Throwable parent = new IllegalArgumentException("IllegalArgument", cause);
         final LogEvent event = Log4jLogEvent.newBuilder() //


[05/11] logging-log4j2 git commit: add tests of when the suffix pattern will be ignored

Posted by ma...@apache.org.
add tests of when the suffix pattern will be ignored


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/4a63b638
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/4a63b638
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/4a63b638

Branch: refs/heads/master
Commit: 4a63b6380e43c353a56044469bc55af4bbb94b56
Parents: 0146bba
Author: xnslong <xn...@outlook.com>
Authored: Mon Mar 6 01:02:59 2017 +0800
Committer: xnslong <xn...@outlook.com>
Committed: Mon Mar 6 01:02:59 2017 +0800

----------------------------------------------------------------------
 .../ExtendedThrowablePatternConverterTest.java  | 20 ++++++++++++++++++++
 .../RootThrowablePatternConverterTest.java      | 20 ++++++++++++++++++++
 2 files changed, 40 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4a63b638/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverterTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverterTest.java
index 9bd30d4..839a3a7 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverterTest.java
@@ -17,6 +17,7 @@
 package org.apache.logging.log4j.core.pattern;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import java.io.PrintWriter;
@@ -76,6 +77,25 @@ public class ExtendedThrowablePatternConverterTest {
     }
 
     @Test
+    public void testSuffixWillIgnoreThrowablePattern() {
+        final String suffix = "suffix(%xEx{suffix(inner suffix)})";
+        final String[] options = {suffix};
+        final ExtendedThrowablePatternConverter converter = ExtendedThrowablePatternConverter.newInstance(null, options);
+        final Throwable cause = new NullPointerException("null pointer");
+        final Throwable parent = new IllegalArgumentException("IllegalArgument", cause);
+        final LogEvent event = Log4jLogEvent.newBuilder() //
+                .setLoggerName("testLogger") //
+                .setLoggerFqcn(this.getClass().getName()) //
+                .setLevel(Level.DEBUG) //
+                .setMessage(new SimpleMessage("test exception")) //
+                .setThrown(parent).build();
+        final StringBuilder sb = new StringBuilder();
+        converter.format(event, sb);
+        final String result = sb.toString();
+        assertFalse("Has unexpected suffix", result.contains("inner suffix"));
+    }
+
+    @Test
 	public void testDeserializedLogEventWithThrowableProxyButNoThrowable() {
 		final ExtendedThrowablePatternConverter converter = ExtendedThrowablePatternConverter.newInstance(null, null);
 		final Throwable originalThrowable = new Exception("something bad happened");

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4a63b638/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverterTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverterTest.java
index 3c45c7a..90d42a6 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverterTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.logging.log4j.core.pattern;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import org.apache.logging.log4j.Level;
@@ -70,6 +71,25 @@ public class RootThrowablePatternConverterTest {
     }
 
     @Test
+    public void testSuffixWillIgnoreThrowablePattern() {
+        final String suffix = "suffix(%xEx{suffix(inner suffix)})";
+        final String[] options = {suffix};
+        final RootThrowablePatternConverter converter = RootThrowablePatternConverter.newInstance(null, options);
+        final Throwable cause = new NullPointerException("null pointer");
+        final Throwable parent = new IllegalArgumentException("IllegalArgument", cause);
+        final LogEvent event = Log4jLogEvent.newBuilder() //
+                .setLoggerName("testLogger") //
+                .setLoggerFqcn(this.getClass().getName()) //
+                .setLevel(Level.DEBUG) //
+                .setMessage(new SimpleMessage("test exception")) //
+                .setThrown(parent).build();
+        final StringBuilder sb = new StringBuilder();
+        converter.format(event, sb);
+        final String result = sb.toString();
+        assertFalse("Has unexpected suffix", result.contains("inner suffix"));
+    }
+
+    @Test
     public void testFull1() {
         final RootThrowablePatternConverter converter = RootThrowablePatternConverter.newInstance(null, null);
         final Throwable cause = new NullPointerException("null pointer");


[02/11] logging-log4j2 git commit: merge master

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/f3be8790/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
----------------------------------------------------------------------
diff --cc log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
index abb733f,d6bafca..81cb5dc
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
@@@ -1,311 -1,295 +1,314 @@@
 -/*
 - * 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 java.util.ArrayList;
 -import java.util.List;
 -import java.util.Scanner;
 -
 -import org.apache.logging.log4j.core.pattern.JAnsiTextRenderer;
 -import org.apache.logging.log4j.core.pattern.TextRenderer;
 -import org.apache.logging.log4j.core.pattern.PlainTextRenderer;
 -import org.apache.logging.log4j.core.util.Loader;
 -import org.apache.logging.log4j.core.util.Patterns;
 -import org.apache.logging.log4j.status.StatusLogger;
 -import org.apache.logging.log4j.util.Strings;
 -
 -/**
 - * Contains options which control how a {@link Throwable} pattern is formatted.
 - */
 -public final class ThrowableFormatOptions {
 -
 -    private static final int DEFAULT_LINES = Integer.MAX_VALUE;
 -
 -    /**
 -     * 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";
 -
 -    /**
 -     * ANSI renderer
 -     */
 -    private final TextRenderer textRenderer;
 -
 -    /**
 -     * 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> ignorePackages;
 -
 -    public static final String CLASS_NAME = "short.className";
 -    public static final String METHOD_NAME = "short.methodName";
 -    public static final String LINE_NUMBER = "short.lineNumber";
 -    public static final String FILE_NAME = "short.fileName";
 -    public static final String MESSAGE = "short.message";
 -    public static final String LOCALIZED_MESSAGE = "short.localizedMessage";
 -
 -    /**
 -     * Constructs the options for printing stack trace.
 -     * 
 -     * @param lines
 -     *            The number of lines.
 -     * @param separator
 -     *            The stack trace separator.
 -     * @param ignorePackages
 -     *            The packages to filter.
 -     * @param textRenderer
 -     *            The ANSI renderer
 -     */
 -    protected ThrowableFormatOptions(final int lines, final String separator, final List<String> ignorePackages,
 -            final TextRenderer textRenderer) {
 -        this.lines = lines;
 -        this.separator = separator == null ? Strings.LINE_SEPARATOR : separator;
 -        this.ignorePackages = ignorePackages;
 -        this.textRenderer = textRenderer == null ? PlainTextRenderer.getInstance() : textRenderer;
 -    }
 -
 -    /**
 -     * Constructs the options for printing stack trace.
 -     * 
 -     * @param packages
 -     *            The packages to filter.
 -     */
 -    protected ThrowableFormatOptions(final List<String> packages) {
 -        this(DEFAULT_LINES, null, packages, null);
 -    }
 -
 -    /**
 -     * Constructs the options for printing stack trace.
 -     */
 -    protected ThrowableFormatOptions() {
 -        this(DEFAULT_LINES, 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 message rendered.
 -     * 
 -     * @return the message rendered.
 -     */
 -    public TextRenderer getTextRenderer() {
 -        return textRenderer;
 -    }
 -
 -    /**
 -     * Returns the list of packages to ignore (filter out).
 -     * 
 -     * @return The list of packages to ignore (filter out).
 -     */
 -    public List<String> getIgnorePackages() {
 -        return this.ignorePackages;
 -    }
 -
 -    /**
 -     * Determines if all lines should be printed.
 -     * 
 -     * @return true for all lines, false otherwise.
 -     */
 -    public boolean allLines() {
 -        return this.lines == DEFAULT_LINES;
 -    }
 -
 -    /**
 -     * 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.ignorePackages != null && !this.ignorePackages.isEmpty();
 -    }
 -
 -    /**
 -     * {@inheritDoc}
 -     */
 -    @Override
 -    public String toString() {
 -        final 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 (final String p : this.ignorePackages) {
 -                s.append(p).append(',');
 -            }
 -            s.deleteCharAt(s.length() - 1);
 -            s.append(")}");
 -        }
 -        return s.toString();
 -    }
 -
 -    /**
 -     * Creates a new instance based on the array of options.
 -     * 
 -     * @param options
 -     *            The array of options.
 -     * @return A new initialized instance.
 -     */
 -    public static ThrowableFormatOptions newInstance(String[] options) {
 -        if (options == null || options.length == 0) {
 -            return DEFAULT;
 -        }
 -        // 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 && Strings.isNotEmpty(options[0])) {
 -            final String[] opts = options[0].split(Patterns.COMMA_SEPARATOR, 2);
 -            final String first = opts[0].trim();
 -            try (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.ignorePackages;
 -        TextRenderer ansiRenderer = DEFAULT.textRenderer;
 -        for (final String rawOption : options) {
 -            if (rawOption != null) {
 -                final String option = rawOption.trim();
 -                if (option.isEmpty()) {
 -                    // 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(Patterns.COMMA_SEPARATOR);
 -                        if (array.length > 0) {
 -                            packages = new ArrayList<>(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) || option.equalsIgnoreCase(CLASS_NAME)
 -                        || option.equalsIgnoreCase(METHOD_NAME) || option.equalsIgnoreCase(LINE_NUMBER)
 -                        || option.equalsIgnoreCase(FILE_NAME) || option.equalsIgnoreCase(MESSAGE)
 -                        || option.equalsIgnoreCase(LOCALIZED_MESSAGE)) {
 -                    lines = 2;
 -                } else if (option.startsWith("ansi(") && option.endsWith(")") || option.equals("ansi")) {
 -                    if (Loader.isJansiAvailable()) {
 -                        final String styleMapStr = option.equals("ansi") ? Strings.EMPTY
 -                                : option.substring("ansi(".length(), option.length() - 1);
 -                        ansiRenderer = new JAnsiTextRenderer(new String[] { null, styleMapStr },
 -                                JAnsiTextRenderer.DefaultExceptionStyleMap);
 -                    } else {
 -                        StatusLogger.getLogger().warn(
 -                                "You requested ANSI exception rendering but JANSI is not on the classpath. Please see https://logging.apache.org/log4j/2.x/runtime-dependencies.html");
 -                    }
 -                } else if (!option.equalsIgnoreCase(FULL)) {
 -                    lines = Integer.parseInt(option);
 -                }
 -            }
 -        }
 -        return new ThrowableFormatOptions(lines, separator, packages, ansiRenderer);
 -    }
 -
 -}
 +/*
 + * 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 java.util.ArrayList;
 +import java.util.Arrays;
++import java.util.Collections;
 +import java.util.List;
 +import java.util.Scanner;
 +
 +import org.apache.logging.log4j.core.pattern.JAnsiTextRenderer;
- import org.apache.logging.log4j.core.pattern.PlainTextRenderer;
 +import org.apache.logging.log4j.core.pattern.TextRenderer;
- import org.apache.logging.log4j.core.util.Constants;
++import org.apache.logging.log4j.core.pattern.PlainTextRenderer;
 +import org.apache.logging.log4j.core.util.Loader;
 +import org.apache.logging.log4j.core.util.Patterns;
 +import org.apache.logging.log4j.status.StatusLogger;
 +import org.apache.logging.log4j.util.Strings;
 +
 +/**
 + * Contains options which control how a {@link Throwable} pattern is formatted.
 + */
 +public final class ThrowableFormatOptions {
 +
 +    private static final int DEFAULT_LINES = Integer.MAX_VALUE;
 +
 +    /**
 +     * 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";
 +
 +    /**
 +     * ANSI renderer
 +     */
 +    private final TextRenderer textRenderer;
 +
 +    /**
 +     * The number of lines to write.
 +     */
 +    private final int lines;
 +
 +    /**
 +     * The stack trace separator.
 +     */
 +    private final String separator;
 +
++    private final List<String> mdcKeys;
++
 +    /**
 +     * The list of packages to filter.
 +     */
 +    private final List<String> ignorePackages;
 +
-     private final List<String> mdcKeys;
- 
 +    public static final String CLASS_NAME = "short.className";
 +    public static final String METHOD_NAME = "short.methodName";
 +    public static final String LINE_NUMBER = "short.lineNumber";
 +    public static final String FILE_NAME = "short.fileName";
 +    public static final String MESSAGE = "short.message";
 +    public static final String LOCALIZED_MESSAGE = "short.localizedMessage";
 +
 +    /**
 +     * Constructs the options for printing stack trace.
 +     *  @param lines
 +     *            The number of lines.
 +     * @param separator
 +     *            The stack trace separator.
 +     * @param ignorePackages
 + *            The packages to filter.
 +     * @param textRenderer
 +     * @param mdcKeys
 +     */
 +    protected ThrowableFormatOptions(final int lines, final String separator, final List<String> ignorePackages,
-                                      TextRenderer textRenderer, final List<String> mdcKeys) {
++                                     final TextRenderer textRenderer, final List<String> mdcKeys) {
 +        this.lines = lines;
-         this.separator = separator == null ? Constants.LINE_SEPARATOR : separator;
++        this.separator = separator == null ? Strings.LINE_SEPARATOR : separator;
 +        this.ignorePackages = ignorePackages;
 +        this.textRenderer = textRenderer == null ? PlainTextRenderer.getInstance() : textRenderer;
 +        this.mdcKeys = mdcKeys;
 +    }
 +
 +    /**
 +     * Constructs the options for printing stack trace.
 +     *
 +     * @param packages
 +     *            The packages to filter.
 +     */
 +    protected ThrowableFormatOptions(final List<String> packages) {
 +        this(DEFAULT_LINES, null, packages, null, null);
 +    }
 +
 +    /**
 +     * Constructs the options for printing stack trace.
 +     */
 +    protected ThrowableFormatOptions() {
 +        this(DEFAULT_LINES, null, 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 message rendered.
 +     *
 +     * @return the message rendered.
 +     */
 +    public TextRenderer getTextRenderer() {
 +        return textRenderer;
 +    }
 +
 +    /**
 +     * Returns the list of packages to ignore (filter out).
 +     *
 +     * @return The list of packages to ignore (filter out).
 +     */
 +    public List<String> getIgnorePackages() {
 +        return this.ignorePackages;
 +    }
 +
 +    /**
 +     * Determines if all lines should be printed.
 +     *
 +     * @return true for all lines, false otherwise.
 +     */
 +    public boolean allLines() {
 +        return this.lines == DEFAULT_LINES;
 +    }
 +
 +    /**
 +     * 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.ignorePackages != null && !this.ignorePackages.isEmpty();
 +    }
 +
 +    /**
 +     * {@inheritDoc}
 +     */
 +    @Override
 +    public String toString() {
 +        final 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 (final String p : this.ignorePackages) {
 +                s.append(p).append(',');
 +            }
 +            s.deleteCharAt(s.length() - 1);
 +            s.append(")}");
 +        }
 +        return s.toString();
 +    }
 +
 +    /**
 +     * Creates a new instance based on the array of options.
 +     *
 +     * @param options
 +     *            The array of options.
 +     * @return A new initialized instance.
 +     */
 +    public static ThrowableFormatOptions newInstance(String[] options) {
 +        if (options == null || options.length == 0) {
 +            return DEFAULT;
 +        }
 +        // 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 && Strings.isNotEmpty(options[0])) {
 +            final String[] opts = options[0].split(Patterns.COMMA_SEPARATOR, 2);
 +            final String first = opts[0].trim();
 +            try (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;
++        List<String> mdcKeys = DEFAULT.mdcKeys;
 +        String separator = DEFAULT.separator;
 +        List<String> packages = DEFAULT.ignorePackages;
 +        TextRenderer ansiRenderer = DEFAULT.textRenderer;
-         List<String> mdcKeys = DEFAULT.mdcKeys;
 +        for (final String rawOption : options) {
 +            if (rawOption != null) {
 +                final String option = rawOption.trim();
 +                if (option.isEmpty()) {
 +                    // 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(Patterns.COMMA_SEPARATOR);
 +                        if (array.length > 0) {
 +                            packages = new ArrayList<>(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) || option.equalsIgnoreCase(CLASS_NAME)
 +                        || option.equalsIgnoreCase(METHOD_NAME) || option.equalsIgnoreCase(LINE_NUMBER)
 +                        || option.equalsIgnoreCase(FILE_NAME) || option.equalsIgnoreCase(MESSAGE)
 +                        || option.equalsIgnoreCase(LOCALIZED_MESSAGE)) {
 +                    lines = 2;
 +                } else if (option.startsWith("ansi(") && option.endsWith(")") || option.equals("ansi")) {
 +                    if (Loader.isJansiAvailable()) {
-                         String styleMapStr = option.equals("ansi") ? Strings.EMPTY
++                        final String styleMapStr = option.equals("ansi") ? Strings.EMPTY
 +                                : option.substring("ansi(".length(), option.length() - 1);
-                         ansiRenderer = new JAnsiTextRenderer(new String[] {null, styleMapStr},
++                        ansiRenderer = new JAnsiTextRenderer(new String[] { null, styleMapStr },
 +                                JAnsiTextRenderer.DefaultExceptionStyleMap);
 +                    } else {
 +                        StatusLogger.getLogger().warn(
 +                                "You requested ANSI exception rendering but JANSI is not on the classpath. Please see https://logging.apache.org/log4j/2.x/runtime-dependencies.html");
 +                    }
 +                } else if (option.startsWith("mdc(") && option.endsWith(")")){
 +                    String suffixPattern = option.substring("mdc(".length(), option.length() - 1);
 +                    mdcKeys = parseMdcKeys(suffixPattern);
 +                } else if (option.startsWith("X(") && option.endsWith(")")){
 +                    String suffixPattern = option.substring("X(".length(), option.length() - 1);
 +                    mdcKeys = parseMdcKeys(suffixPattern);
 +                } else if (!option.equalsIgnoreCase(FULL)) {
 +                    lines = Integer.parseInt(option);
 +                }
 +            }
 +        }
 +        return new ThrowableFormatOptions(lines, separator, packages, ansiRenderer, mdcKeys);
 +    }
 +
-     private static List<String> parseMdcKeys(final String mdcKeyExp) {
-         String[] keys = mdcKeyExp.split(",");
-         return Arrays.asList(keys);
++    private static List<String> parseMdcKeys(final String suffixPattern) {
++        if (suffixPattern.trim().isEmpty()) {
++            return Collections.emptyList();
++        } else {
++            return Arrays.asList(suffixPattern.split(","));
++        }
 +    }
 +
 +}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/f3be8790/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/f3be8790/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java
----------------------------------------------------------------------


[11/11] logging-log4j2 git commit: Merge branch 'pr-61'

Posted by ma...@apache.org.
Merge branch 'pr-61'


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/5e72f2ca
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/5e72f2ca
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/5e72f2ca

Branch: refs/heads/master
Commit: 5e72f2cac4ce7ea0f38f12f7fcd5f708548d33db
Parents: d5b5df4 9111123
Author: Matt Sicker <bo...@gmail.com>
Authored: Tue Mar 7 21:58:55 2017 -0600
Committer: Matt Sicker <bo...@gmail.com>
Committed: Tue Mar 7 21:58:55 2017 -0600

----------------------------------------------------------------------
 .../log4j/core/impl/ThrowableFormatOptions.java |  45 +++++---
 .../logging/log4j/core/impl/ThrowableProxy.java | 113 +++++++++++--------
 .../ExtendedThrowablePatternConverter.java      |  16 ++-
 .../log4j/core/pattern/PatternParser.java       |   2 +-
 .../pattern/RootThrowablePatternConverter.java  |  14 ++-
 .../core/pattern/ThrowablePatternConverter.java |  49 +++++++-
 .../log4j/core/impl/ThrowableProxyTest.java     |  86 ++++++++++++--
 .../ExtendedThrowablePatternConverterTest.java  |  66 ++++++++++-
 .../RootThrowablePatternConverterTest.java      |  68 ++++++++++-
 .../pattern/ThrowablePatternConverterTest.java  |  21 ++--
 src/changes/changes.xml                         |   3 +
 src/site/xdoc/manual/layouts.xml.vm             |  27 ++++-
 12 files changed, 405 insertions(+), 105 deletions(-)
----------------------------------------------------------------------