You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ck...@apache.org on 2018/04/07 14:02:59 UTC

logging-log4j2 git commit: LOG4J2-2307: RingBufferLogEvent and MutableLogEvent memento to MementoLogEvent

Repository: logging-log4j2
Updated Branches:
  refs/heads/master 78c43c5b5 -> 0738cf970


LOG4J2-2307: RingBufferLogEvent and MutableLogEvent memento to MementoLogEvent

MementoLogEvent provides the original format string and parameters
in addition to the formatted text.


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

Branch: refs/heads/master
Commit: 0738cf970c111a07a7307549b8c16af4d44af8a4
Parents: 78c43c5
Author: Carter Kozak <ck...@apache.org>
Authored: Mon Apr 2 23:49:09 2018 -0400
Committer: Carter Kozak <ck...@apache.org>
Committed: Sat Apr 7 10:01:53 2018 -0400

----------------------------------------------------------------------
 .../log4j/core/async/RingBufferLogEvent.java    |  3 +-
 .../logging/log4j/core/impl/MementoMessage.java | 83 ++++++++++++++++++++
 .../log4j/core/impl/MutableLogEvent.java        |  2 +-
 .../apache/logging/log4j/core/LoggerTest.java   | 11 ++-
 .../core/async/RingBufferLogEventTest.java      | 26 ++++++
 .../log4j/core/impl/MutableLogEventTest.java    |  4 +
 src/changes/changes.xml                         |  3 +
 7 files changed, 124 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0738cf97/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java
index 27e7197..5e24d14 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java
@@ -26,6 +26,7 @@ import org.apache.logging.log4j.ThreadContext.ContextStack;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.impl.ContextDataFactory;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
+import org.apache.logging.log4j.core.impl.MementoMessage;
 import org.apache.logging.log4j.core.impl.ThrowableProxy;
 import org.apache.logging.log4j.core.time.Clock;
 import org.apache.logging.log4j.core.time.NanoClock;
@@ -318,7 +319,7 @@ public class RingBufferLogEvent implements LogEvent, ReusableMessage, CharSequen
 
 
     private Message getNonNullImmutableMessage() {
-        return message != null ? message : new SimpleMessage(String.valueOf(messageText));
+        return message != null ? message : new MementoMessage(String.valueOf(messageText), messageFormat, getParameters());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0738cf97/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MementoMessage.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MementoMessage.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MementoMessage.java
new file mode 100644
index 0000000..c867ce4
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MementoMessage.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.impl;
+
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.util.StringBuilderFormattable;
+
+import java.util.Arrays;
+
+/**
+ * <em>Consider this class private.</em>
+ *
+ * {@link MementoMessage} is intended to be used when we need to make an
+ * immutable copy of a {@link Message} without forgetting the original
+ * {@link Message#getFormat()} and {@link Message#getParameters()} values.
+ *
+ * @since 3.0
+ */
+public final class MementoMessage implements Message, StringBuilderFormattable {
+
+    private final String formattedMessage;
+    private final String format;
+    private final Object[] parameters;
+
+    public MementoMessage(String formattedMessage, String format, Object[] parameters) {
+        this.formattedMessage = formattedMessage;
+        this.format = format;
+        this.parameters = parameters;
+    }
+
+    @Override
+    public String getFormattedMessage() {
+        return formattedMessage;
+    }
+
+    @Override
+    public String getFormat() {
+        return format;
+    }
+
+    @Override
+    public Object[] getParameters() {
+        return parameters;
+    }
+
+    /**
+     * Always returns null.
+     *
+     * @return null
+     */
+    @Override
+    public Throwable getThrowable() {
+        return null;
+    }
+
+    @Override
+    public void formatTo(StringBuilder buffer) {
+        buffer.append(formattedMessage);
+    }
+
+    @Override
+    public String toString() {
+        return "MementoMessage{" +
+                "formattedMessage='" + formattedMessage + '\'' +
+                ", format='" + format + '\'' +
+                ", parameters=" + Arrays.toString(parameters) +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0738cf97/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MutableLogEvent.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MutableLogEvent.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MutableLogEvent.java
index ecabcbc..be374a0 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MutableLogEvent.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MutableLogEvent.java
@@ -309,7 +309,7 @@ public class MutableLogEvent implements LogEvent, ReusableMessage, ParameterVisi
             return message;
         }
         final Object[] params = parameters == null ? new Object[0] : Arrays.copyOf(parameters, parameterCount);
-        return new ParameterizedMessage(messageText.toString(), params);
+        return new MementoMessage(messageText.toString(), messageFormat, params);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0738cf97/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java
index ba213ff..4cafb7b 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.logging.log4j.core;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNotSame;
@@ -39,9 +40,7 @@ import org.apache.logging.log4j.core.config.LoggerConfig;
 import org.apache.logging.log4j.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.MessageFactory;
-import org.apache.logging.log4j.message.ParameterizedMessage;
 import org.apache.logging.log4j.message.ParameterizedMessageFactory;
-import org.apache.logging.log4j.message.ReusableParameterizedMessage;
 import org.apache.logging.log4j.message.StringFormatterMessageFactory;
 import org.apache.logging.log4j.message.StructuredDataMessage;
 import org.apache.logging.log4j.spi.AbstractLogger;
@@ -415,14 +414,14 @@ public class LoggerTest {
         logger.error("Throwing with parameters {}", "TestParam", new NullPointerException("Test Exception"));
         final List<LogEvent> events = app.getEvents();
         assertNotNull("Log event list not returned", events);
-        assertTrue("Incorrect number of log events: expected 1, actual " + events.size(), events.size() == 1);
+        assertEquals("Incorrect number of log events", 1, events.size());
         final LogEvent event = events.get(0);
         final Throwable thrown = event.getThrown();
         assertNotNull("No throwable present in log event", thrown);
         final Message msg = event.getMessage();
-        assertTrue("Incorrect message type. Expected ParameterizedMessage/ReusableParameterizedMessage, actual " + msg.getClass().getSimpleName(),
-                msg instanceof ParameterizedMessage || msg instanceof ReusableParameterizedMessage);
-
+        assertEquals("Throwing with parameters {}", msg.getFormat());
+        assertEquals("Throwing with parameters TestParam", msg.getFormattedMessage());
+        assertArrayEquals(new Object[] { "TestParam", thrown }, msg.getParameters());
     }
 }
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0738cf97/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java
index 1d34921..f89a101 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java
@@ -33,6 +33,7 @@ import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.time.internal.DummyNanoClock;
 import org.apache.logging.log4j.core.time.internal.FixedPreciseClock;
 import org.apache.logging.log4j.message.ParameterConsumer;
+import org.apache.logging.log4j.message.ReusableMessageFactory;
 import org.apache.logging.log4j.util.FilteredObjectInputStream;
 import org.apache.logging.log4j.util.StringMap;
 import org.apache.logging.log4j.core.impl.ThrowableProxy;
@@ -182,6 +183,31 @@ public class RingBufferLogEventTest {
     }
 
     @Test
+    public void testCreateMementoRetainsParametersAndFormat() {
+        final RingBufferLogEvent evt = new RingBufferLogEvent();
+        // Initialize the event with parameters
+        evt.swapParameters(new Object[10]);
+        final String loggerName = "logger.name";
+        final Marker marker = MarkerManager.getMarker("marked man");
+        final String fqcn = "f.q.c.n";
+        final Level level = Level.TRACE;
+        ReusableMessageFactory factory = new ReusableMessageFactory();
+        Message message = factory.newMessage("Hello {}!", "World");
+        final Throwable t = new InternalError("not a real error");
+        final ContextStack contextStack = new MutableThreadContextStack(Arrays.asList("a", "b"));
+        final String threadName = "main";
+        final StackTraceElement location = null;
+        evt.setValues(null, loggerName, marker, fqcn, level, message, t, (StringMap) evt.getContextData(),
+                contextStack, -1, threadName, -1, location, new FixedPreciseClock(12345, 678), new DummyNanoClock(1));
+        ((StringMap) evt.getContextData()).putValue("key", "value");
+
+        final Message actual = evt.createMemento().getMessage();
+        assertEquals("Hello {}!", actual.getFormat());
+        assertArrayEquals(new String[] { "World" }, actual.getParameters());
+        assertEquals("Hello World!", actual.getFormattedMessage());
+    }
+
+    @Test
     public void testMessageTextNeverThrowsNpe() {
         final RingBufferLogEvent evt = new RingBufferLogEvent();
         try {

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0738cf97/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java
index 2bee6fb..655b561 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java
@@ -138,6 +138,10 @@ public class MutableLogEventTest {
         assertEquals("format", "msg in a {}", mutable.getFormat());
         assertEquals("formatted", "msg in a bottle", mutable.getFormattedMessage());
         assertEquals("parameters", new String[] {"bottle"}, mutable.getParameters());
+        Message memento = mutable.memento();
+        assertEquals("format", "msg in a {}", memento.getFormat());
+        assertEquals("formatted", "msg in a bottle", memento.getFormattedMessage());
+        assertEquals("parameters", new String[] {"bottle"}, memento.getParameters());
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0738cf97/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index f172b52..d7ca266 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -118,6 +118,9 @@
       <action issue="LOG4J2-2306" dev="ckozak" type="fix">
         FixedDateFormat parses timezone offsets, -8:00 is interpreted as GMT-8:00.
       </action>
+      <action issue="LOG4J2-2307" dev="ckozak" type="fix">
+        MutableLogEvent and RingBufferLogEvent message mementos retain the original format string.
+      </action>
     </release>
     <release version="2.11.1" date="2018-MM-DD" description="GA Release 2.11.1">
       <action issue="LOG4J2-2268" dev="rgoers" type="fix" due-to="Tilman Hausherr">