You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by mi...@apache.org on 2017/11/11 21:48:10 UTC

[04/12] logging-log4j2 git commit: LOG4J2-2107: MapMessage allocation-free pattern conversion

LOG4J2-2107: MapMessage allocation-free pattern conversion

Fixes an issue causing MessagePatternConverter to greedily format
MapMessage instances as StringBuilderFormattable ignoring format.


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

Branch: refs/heads/master
Commit: 93a7235da78c562026993cdc4e3e5775c47e8099
Parents: 6757d39
Author: Carter Kozak <c4...@gmail.com>
Authored: Wed Nov 8 16:53:31 2017 -0500
Committer: Mikael Ståldal <mi...@staldal.nu>
Committed: Sat Nov 11 22:08:09 2017 +0100

----------------------------------------------------------------------
 .../logging/log4j/message/MapMessage.java       | 22 +++++++++++------
 .../MultiFormatStringBuilderFormattable.java    | 25 ++++++++++++++++++++
 .../core/pattern/MessagePatternConverter.java   |  8 +++++--
 3 files changed, 46 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/93a7235d/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessage.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessage.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessage.java
index 48f7ec7..57894b8 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessage.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessage.java
@@ -25,10 +25,10 @@ import org.apache.logging.log4j.util.Chars;
 import org.apache.logging.log4j.util.EnglishEnums;
 import org.apache.logging.log4j.util.IndexedReadOnlyStringMap;
 import org.apache.logging.log4j.util.IndexedStringMap;
+import org.apache.logging.log4j.util.MultiFormatStringBuilderFormattable;
 import org.apache.logging.log4j.util.PerformanceSensitive;
 import org.apache.logging.log4j.util.ReadOnlyStringMap;
 import org.apache.logging.log4j.util.SortedArrayStringMap;
-import org.apache.logging.log4j.util.StringBuilderFormattable;
 import org.apache.logging.log4j.util.StringBuilders;
 import org.apache.logging.log4j.util.Strings;
 import org.apache.logging.log4j.util.TriConsumer;
@@ -49,9 +49,9 @@ import org.apache.logging.log4j.util.TriConsumer;
  */
 @PerformanceSensitive("allocation")
 @AsynchronouslyFormattable
-public class MapMessage<M extends MapMessage<M, V>, V> implements MultiformatMessage, StringBuilderFormattable {
+public class MapMessage<M extends MapMessage<M, V>, V> implements MultiFormatStringBuilderFormattable {
 
-    private static final long serialVersionUID = -5031471831131487120L;    
+    private static final long serialVersionUID = -5031471831131487120L;
 
     /**
      * When set as the format specifier causes the Map to be formatted as XML.
@@ -375,17 +375,20 @@ public class MapMessage<M extends MapMessage<M, V>, V> implements MultiformatMes
      */
     @Override
     public String getFormattedMessage(final String[] formats) {
+        return format(getFormat(formats), new StringBuilder()).toString();
+    }
+
+    private MapFormat getFormat(final String[] formats) {
         if (formats == null || formats.length == 0) {
-            return asString();
+            return null;
         }
         for (int i = 0; i < formats.length; i++) {
             final MapFormat mapFormat = MapFormat.lookupIgnoreCase(formats[i]);
             if (mapFormat != null) {
-                return format(mapFormat, new StringBuilder()).toString();
+                return mapFormat;
             }
         }
-        return asString();
-
+        return null;
     }
 
     protected void appendMap(final StringBuilder sb) {
@@ -449,6 +452,11 @@ public class MapMessage<M extends MapMessage<M, V>, V> implements MultiformatMes
     }
 
     @Override
+    public void formatTo(String[] formats, StringBuilder buffer) {
+        format(getFormat(formats), buffer);
+    }
+
+    @Override
     public boolean equals(final Object o) {
         if (this == o) {
             return true;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/93a7235d/log4j-api/src/main/java/org/apache/logging/log4j/util/MultiFormatStringBuilderFormattable.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/MultiFormatStringBuilderFormattable.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/MultiFormatStringBuilderFormattable.java
new file mode 100644
index 0000000..4b7cb3e
--- /dev/null
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/MultiFormatStringBuilderFormattable.java
@@ -0,0 +1,25 @@
+package org.apache.logging.log4j.util;
+
+import org.apache.logging.log4j.message.MultiformatMessage;
+
+/**
+ * A Message that can render itself in more than one way. The format string is used by the
+ * Message implementation as extra information that it may use to help it to determine how
+ * to format itself. For example, MapMessage accepts a format of "XML" to tell it to render
+ * the Map as XML instead of its default format of {key1="value1" key2="value2"}.
+ *
+ * @since 2.10
+ */
+public interface MultiFormatStringBuilderFormattable extends MultiformatMessage, StringBuilderFormattable {
+
+    /**
+     * Writes a text representation of this object into the specified {@code StringBuilder}, ideally without allocating
+     * temporary objects.
+     *
+     * @param formats An array of Strings that provide extra information about how to format the message.
+     * Each MultiFormatStringBuilderFormattable implementation is free to use the provided formats however they choose.
+     * @param buffer the StringBuilder to write into
+     */
+    void formatTo(String[] formats, StringBuilder buffer);
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/93a7235d/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MessagePatternConverter.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MessagePatternConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MessagePatternConverter.java
index 1cecfd5..7b1d77e 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MessagePatternConverter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MessagePatternConverter.java
@@ -26,6 +26,7 @@ import org.apache.logging.log4j.core.util.Loader;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.MultiformatMessage;
 import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.MultiFormatStringBuilderFormattable;
 import org.apache.logging.log4j.util.PerformanceSensitive;
 import org.apache.logging.log4j.util.StringBuilderFormattable;
 
@@ -114,9 +115,12 @@ public final class MessagePatternConverter extends LogEventPatternConverter {
             final boolean doRender = textRenderer != null;
             final StringBuilder workingBuilder = doRender ? new StringBuilder(80) : toAppendTo;
 
-            final StringBuilderFormattable stringBuilderFormattable = (StringBuilderFormattable) msg;
             final int offset = workingBuilder.length();
-            stringBuilderFormattable.formatTo(workingBuilder);
+            if (msg instanceof MultiFormatStringBuilderFormattable) {
+                ((MultiFormatStringBuilderFormattable) msg).formatTo(formats, workingBuilder);
+            } else {
+                ((StringBuilderFormattable) msg).formatTo(workingBuilder);
+            }
 
             // TODO can we optimize this?
             if (config != null && !noLookups) {