[LOG4J2-1145] Add %equals to PatternLayout to test and replace patterns
with strings. Also split out a test method that relies on source code
line numbers to be fixed.


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

Branch: refs/heads/LOG4J2-1136
Commit: e72d2dc7f3d82a08e787688fae21706c1991505a
Parents: 1e8f2cd
Author: ggregory <[email protected]>
Authored: Thu Oct 1 15:13:21 2015 -0700
Committer: Ralph Goers <[email protected]>
Committed: Sat Oct 3 23:08:06 2015 -0700

----------------------------------------------------------------------
 .../pattern/EqualsReplacementConverter.java     | 102 +++++++++++++++++++
 .../log4j/core/layout/PatternLayoutTest.java    |  52 ++++------
 .../log4j/core/layout/PatternSelectorTest.java  |  65 ++++++++++++
 .../pattern/EqualsReplacementConverterTest.java |  63 ++++++++++++
 src/changes/changes.xml                         |   3 +
 src/site/xdoc/manual/layouts.xml.vm             |  15 ++-
 6 files changed, 269 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e72d2dc7/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/EqualsReplacementConverter.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/EqualsReplacementConverter.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/EqualsReplacementConverter.java
new file mode 100644
index 0000000..c564dc9
--- /dev/null
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/EqualsReplacementConverter.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.pattern;
+
+import 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.layout.PatternLayout;
+
+/**
+ * Equals pattern converter.
+ */
+@Plugin(name = "equals", category = PatternConverter.CATEGORY)
+@ConverterKeys({ "equals" })
+public final class EqualsReplacementConverter extends LogEventPatternConverter 
{
+
+    /**
+     * 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 EqualsReplacementConverter newInstance(final Configuration 
config, final String[] options) {
+        if (options.length != 3) {
+            LOGGER.error("Incorrect number of options on equals. Expected 3 
received " + options.length);
+            return null;
+        }
+        if (options[0] == null) {
+            LOGGER.error("No pattern supplied on equals");
+            return null;
+        }
+        if (options[1] == null) {
+            LOGGER.error("No test string supplied on equals");
+            return null;
+        }
+        if (options[2] == null) {
+            LOGGER.error("No substitution supplied on equals");
+            return null;
+        }
+        final String p = options[1];
+        final PatternParser parser = PatternLayout.createPatternParser(config);
+        final List<PatternFormatter> formatters = parser.parse(options[0]);
+        return new EqualsReplacementConverter(formatters, p, options[2]);
+    }
+
+    private final List<PatternFormatter> formatters;
+
+    private final String substitution;
+
+    private final String testString;
+
+    /**
+     * Construct the converter.
+     * 
+     * @param formatters
+     *            The PatternFormatters to generate the text to manipulate.
+     * @param testString
+     *            The test string.
+     * @param substitution
+     *            The substitution string.
+     */
+    private EqualsReplacementConverter(final List<PatternFormatter> 
formatters, final String testString,
+            final String substitution) {
+        super("equals", "equals");
+        this.testString = testString;
+        this.substitution = substitution;
+        this.formatters = formatters;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void format(final LogEvent event, final StringBuilder toAppendTo) {
+        final StringBuilder buf = new StringBuilder();
+        for (final PatternFormatter formatter : formatters) {
+            formatter.format(event, buf);
+        }
+        final String string = buf.toString();
+        toAppendTo.append(testString.equals(string) ? substitution : string);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e72d2dc7/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutTest.java
index 664c469..5ac73a5 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutTest.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutTest.java
@@ -201,6 +201,28 @@ public class PatternLayoutTest {
     }
 
     @Test
+    public void testEqualsEmptyMarker() throws Exception {
+        // replace "[]" with the empty string
+        final PatternLayout layout = 
PatternLayout.newBuilder().withPattern("[%logger]%equals{[%marker]}{[]}{} %msg")
+                .withConfiguration(ctx.getConfiguration()).build();
+        // Not empty marker
+        final LogEvent event1 = Log4jLogEvent.newBuilder() //
+                
.setLoggerName(this.getClass().getName()).setLoggerFqcn("org.apache.logging.log4j.core.Logger")
 //
+                .setLevel(Level.INFO) //
+                .setMarker(MarkerManager.getMarker("TestMarker")) //
+                .setMessage(new SimpleMessage("Hello, world!")).build();
+        final byte[] result1 = layout.toByteArray(event1);
+        
assertEquals("[org.apache.logging.log4j.core.layout.PatternLayoutTest][TestMarker]
 Hello, world!", new String(result1));
+        // empty marker
+        final LogEvent event2 = Log4jLogEvent.newBuilder() //
+                
.setLoggerName(this.getClass().getName()).setLoggerFqcn("org.apache.logging.log4j.core.Logger")
 //
+                .setLevel(Level.INFO) //
+                .setMessage(new SimpleMessage("Hello, world!")).build();
+        final byte[] result2 = layout.toByteArray(event2);
+        assertEquals("[org.apache.logging.log4j.core.layout.PatternLayoutTest] 
Hello, world!", new String(result2));
+    }
+
+    @Test
     public void testSpecialChars() throws Exception {
         final PatternLayout layout = 
PatternLayout.newBuilder().withPattern("\\\\%level\\t%msg\\n\\t%logger\\r\\n\\f")
                 .withConfiguration(ctx.getConfiguration()).build();
@@ -287,34 +309,4 @@ public class PatternLayoutTest {
         assertEquals(StandardCharsets.UTF_8, layout.getCharset());
     }
 
-    @Test
-    public void testPatternSelector() throws Exception {
-        PatternMatch[] patterns = new PatternMatch[1];
-        patterns[0] = new PatternMatch("FLOW", "%d %-5p [%t]: ====== 
%C{1}.%M:%L %m ======%n");
-        PatternSelector selector = 
MarkerPatternSelector.createSelector(patterns, "%d %-5p [%t]: %m%n", true, 
true, ctx.getConfiguration());
-        final PatternLayout layout = 
PatternLayout.newBuilder().withPatternSelector(selector)
-                .withConfiguration(ctx.getConfiguration()).build();
-        final LogEvent event1 = Log4jLogEvent.newBuilder() //
-                
.setLoggerName(this.getClass().getName()).setLoggerFqcn("org.apache.logging.log4j.core.layout.PatternLayoutTest$FauxLogger")
-                .setMarker(MarkerManager.getMarker("FLOW"))
-                .setLevel(Level.TRACE) //
-                .setIncludeLocation(true)
-                .setMessage(new SimpleMessage("entry")).build();
-        final String result1 = new FauxLogger().formatEvent(event1, layout);
-        final String expectSuffix1 = String.format("====== 
PatternLayoutTest.testPatternSelector:303 entry ======%n");
-        assertTrue("Unexpected result: " + result1, 
result1.endsWith(expectSuffix1));
-        final LogEvent event2 = Log4jLogEvent.newBuilder() //
-                
.setLoggerName(this.getClass().getName()).setLoggerFqcn("org.apache.logging.log4j.core.Logger")
 //
-                .setLevel(Level.INFO) //
-                .setMessage(new SimpleMessage("Hello, world 1!")).build();
-        final String result2 = new String(layout.toByteArray(event2));
-        final String expectSuffix2 = String.format("Hello, world 1!%n");
-        assertTrue("Unexpected result: " + result2, 
result2.endsWith(expectSuffix2));
-    }
-
-    public class FauxLogger {
-        public String formatEvent(LogEvent event, Layout<?> layout) {
-            return new String(layout.toByteArray(event));
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e72d2dc7/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternSelectorTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternSelectorTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternSelectorTest.java
new file mode 100644
index 0000000..5fb0d74
--- /dev/null
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternSelectorTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.layout;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.MarkerManager;
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.impl.Log4jLogEvent;
+import org.apache.logging.log4j.message.SimpleMessage;
+import org.junit.Test;
+
+public class PatternSelectorTest {
+
+    public class FauxLogger {
+        public String formatEvent(LogEvent event, Layout<?> layout) {
+            return new String(layout.toByteArray(event));
+        }
+    }
+
+    LoggerContext ctx = LoggerContext.getContext();
+
+    @Test
+    public void testPatternSelector() throws Exception {
+        PatternMatch[] patterns = new PatternMatch[1];
+        patterns[0] = new PatternMatch("FLOW", "%d %-5p [%t]: ====== 
%C{1}.%M:%L %m ======%n");
+        PatternSelector selector = 
MarkerPatternSelector.createSelector(patterns, "%d %-5p [%t]: %m%n", true, 
true, ctx.getConfiguration());
+        final PatternLayout layout = 
PatternLayout.newBuilder().withPatternSelector(selector)
+                .withConfiguration(ctx.getConfiguration()).build();
+        final LogEvent event1 = Log4jLogEvent.newBuilder() //
+                
.setLoggerName(this.getClass().getName()).setLoggerFqcn("org.apache.logging.log4j.core.layout.PatternSelectorTest$FauxLogger")
+                .setMarker(MarkerManager.getMarker("FLOW"))
+                .setLevel(Level.TRACE) //
+                .setIncludeLocation(true)
+                .setMessage(new SimpleMessage("entry")).build();
+        final String result1 = new FauxLogger().formatEvent(event1, layout);
+        final String expectSuffix1 = String.format("====== 
PatternSelectorTest.testPatternSelector:53 entry ======%n");
+        assertTrue("Unexpected result: " + result1, 
result1.endsWith(expectSuffix1));
+        final LogEvent event2 = Log4jLogEvent.newBuilder() //
+                
.setLoggerName(this.getClass().getName()).setLoggerFqcn("org.apache.logging.log4j.core.Logger")
 //
+                .setLevel(Level.INFO) //
+                .setMessage(new SimpleMessage("Hello, world 1!")).build();
+        final String result2 = new String(layout.toByteArray(event2));
+        final String expectSuffix2 = String.format("Hello, world 1!%n");
+        assertTrue("Unexpected result: " + result2, 
result2.endsWith(expectSuffix2));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e72d2dc7/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/EqualsReplacementConverterTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/EqualsReplacementConverterTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/EqualsReplacementConverterTest.java
new file mode 100644
index 0000000..5534662
--- /dev/null
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/EqualsReplacementConverterTest.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.pattern;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.impl.Log4jLogEvent;
+import org.apache.logging.log4j.message.SimpleMessage;
+import org.apache.logging.log4j.util.Strings;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class EqualsReplacementConverterTest {
+
+    @Test
+    public void testMarkerReplacement() {
+        testReplacement("%marker", Strings.EMPTY);
+    }
+
+    @Test
+    public void testMarkerSimpleNameReplacement() {
+        testReplacement("%markerSimpleName", Strings.EMPTY);
+    }
+
+    @Test
+    public void testLoggerNameReplacement() {
+        testReplacement("%logger", "[" + 
EqualsReplacementConverterTest.class.getName() + "]");
+    }
+
+    private void testReplacement(String tag, String expectedValue) {
+        final LogEvent event = Log4jLogEvent.newBuilder() //
+                .setLoggerName(EqualsReplacementConverterTest.class.getName()) 
//
+                .setLevel(Level.DEBUG) //
+                .setMessage(new SimpleMessage("This is a test")) //
+                .build();
+        final StringBuilder sb = new StringBuilder();
+        final LoggerContext ctx = LoggerContext.getContext();
+        final String[] options = new String[] { "[" + tag + "]", "[]", 
expectedValue };
+        final EqualsReplacementConverter converter = 
EqualsReplacementConverter.newInstance(ctx.getConfiguration(),
+                options);
+        converter.format(event, sb);
+        assertEquals(expectedValue, sb.toString());
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e72d2dc7/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index ec10a83..db5fc73 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -27,6 +27,9 @@
       <action issue="LOG4J2-1129" dev="rgoers" type="add">
         Allow PatternLayout to select a pattern to use based on some selection 
criteria.
       </action>
+      <action issue="LOG4J2-1145" dev="ggregory" type="add">
+        Add %equals to PatternLayout to test and replace patterns with 
strings. 
+      </action>
       <action issue="LOG4J2-1020" dev="mikes" type="fix">
         Possibility to set shutdown timeout on AsyncAppender
       </action>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e72d2dc7/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 dd7a0fb..f05827a 100644
--- a/src/site/xdoc/manual/layouts.xml.vm
+++ b/src/site/xdoc/manual/layouts.xml.vm
@@ -618,7 +618,7 @@ WARN  [main]: Message 2</pre>
             <tr>
               <td align="center">
                 <b>enc</b>{pattern}<br />
-                <b>encode</b>{pattern}</b>
+                <b>encode</b>{pattern}
               </td>
               <td>
                 <p>
@@ -652,6 +652,19 @@ WARN  [main]: Message 2</pre>
             </tr>
             <tr>
               <td align="center">
+                <b>equals</b>{pattern}{test}{substitution}
+              </td>
+              <td>
+                <p>Replaces occurrences of 'test', a string, with its 
replacement 'substitution' in the
+                  string resulting from evaluation of the pattern. For 
example, "%equals{[%marker]}{[]}{}" will
+                  replace '[]' strings produces by events without markers with 
an empty string.
+                </p>
+                <p>The pattern can be arbitrarily complex and in particular 
can contain multiple conversion keywords.
+                </p>
+              </td>
+            </tr>
+            <tr>
+              <td align="center">
                 <b>ex</b>|<b>exception</b>|<b>throwable</b><br />
                 &nbsp;&nbsp;{["none"<br />
                 &nbsp;&nbsp;|"full"<br />

Reply via email to