LOG4J2-1169 - PatternLayout: Possible variable substitution in equals substitution parameter
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/e2a86526 Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/e2a86526 Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/e2a86526 Branch: refs/heads/LOG4J2-1278-gc-free-logger Commit: e2a8652691143b5713e0b6872210da1d049a20a3 Parents: 1ecc28b Author: Matt Sicker <[email protected]> Authored: Wed Mar 9 14:14:26 2016 -0600 Committer: Matt Sicker <[email protected]> Committed: Wed Mar 9 14:14:35 2016 -0600 ---------------------------------------------------------------------- .../pattern/EqualsReplacementConverter.java | 48 ++++++++++----- .../log4j/core/layout/PatternLayoutTest.java | 22 +++++++ .../pattern/EqualsReplacementConverterTest.java | 63 +++++++++++++++++--- src/changes/changes.xml | 3 + 4 files changed, 113 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e2a86526/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 index 2534b5d..bb8464c 100644 --- 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 @@ -33,10 +33,8 @@ public final class EqualsReplacementConverter extends LogEventPatternConverter { /** * Gets an instance of the class. * - * @param config - * The current Configuration. - * @param options - * pattern options, an array of three elements: pattern, testString, and substitution. + * @param config The current Configuration. + * @param options pattern options, an array of three elements: pattern, testString, and substitution. * @return instance of class. */ public static EqualsReplacementConverter newInstance(final Configuration config, final String[] options) { @@ -59,7 +57,7 @@ public final class EqualsReplacementConverter extends LogEventPatternConverter { 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]); + return new EqualsReplacementConverter(formatters, p, options[2], parser); } private final List<PatternFormatter> formatters; @@ -68,22 +66,23 @@ public final class EqualsReplacementConverter extends LogEventPatternConverter { private final String testString; + private final PatternParser parser; + /** * Construct the converter. - * - * @param formatters - * The PatternFormatters to generate the text to manipulate. - * @param testString - * The test string. - * @param substitution - * The substitution string. + * + * @param formatters The PatternFormatters to generate the text to manipulate. + * @param testString The test string. + * @param substitution The substitution string. + * @param parser The PatternParser. */ private EqualsReplacementConverter(final List<PatternFormatter> formatters, final String testString, - final String substitution) { + final String substitution, PatternParser parser) { super("equals", "equals"); this.testString = testString; this.substitution = substitution; this.formatters = formatters; + this.parser = parser; } /** @@ -96,6 +95,27 @@ public final class EqualsReplacementConverter extends LogEventPatternConverter { formatter.format(event, buf); } final String string = buf.toString(); - toAppendTo.append(testString.equals(string) ? substitution : string); + toAppendTo.append(testString.equals(string) ? parseSubstitution(event) : string); + } + + /** + * Returns the parsed substitution text. + * + * @param event the current log event + * @return the parsed substitution text + */ + String parseSubstitution(final LogEvent event) { + final StringBuilder substitutionBuffer = new StringBuilder(); + // check if substitution needs to be parsed + if (substitution.contains("%")) { + // parse substitution pattern + final List<PatternFormatter> substitutionFormatters = parser.parse(substitution); + for (final PatternFormatter formatter : substitutionFormatters) { + formatter.format(event, substitutionBuffer); + } + } else { + substitutionBuffer.append(substitution); + } + return substitutionBuffer.toString(); } } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e2a86526/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 2184599..988b42b 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 @@ -288,6 +288,28 @@ public class PatternLayoutTest { } @Test + public void testEqualsMarkerWithMessageSubstitution() 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]", 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(); http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e2a86526/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 index 5534662..642ed16 100644 --- 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 @@ -16,8 +16,6 @@ */ 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; @@ -26,11 +24,15 @@ import org.apache.logging.log4j.message.SimpleMessage; import org.apache.logging.log4j.util.Strings; import org.junit.Test; +import static org.junit.Assert.*; + /** * */ public class EqualsReplacementConverterTest { + private static final String TEST_MESSAGE = "This is a test"; + @Test public void testMarkerReplacement() { testReplacement("%marker", Strings.EMPTY); @@ -46,18 +48,61 @@ public class EqualsReplacementConverterTest { testReplacement("%logger", "[" + EqualsReplacementConverterTest.class.getName() + "]"); } - private void testReplacement(String tag, String expectedValue) { + @Test + public void testMarkerReplacementWithMessage() { + testReplacement(TEST_MESSAGE, new String[]{"[%marker]", "[]", "%msg"}); + } + + private void testReplacement(final String tag, final String expectedValue) { + final String[] options = new String[]{"[" + tag + "]", "[]", expectedValue}; + testReplacement(expectedValue, options); + } + + private void testReplacement(final String expectedValue, final String[] options) { final LogEvent event = Log4jLogEvent.newBuilder() // - .setLoggerName(EqualsReplacementConverterTest.class.getName()) // - .setLevel(Level.DEBUG) // - .setMessage(new SimpleMessage("This is a test")) // - .build(); + .setLoggerName(EqualsReplacementConverterTest.class.getName()) // + .setLevel(Level.DEBUG) // + .setMessage(new SimpleMessage(TEST_MESSAGE)) // + .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); + options); converter.format(event, sb); assertEquals(expectedValue, sb.toString()); } + + @Test + public void testParseSubstitutionWithPattern() { + testParseSubstitution("%msg", TEST_MESSAGE); + } + + @Test + public void testParseSubstitutionWithoutPattern() { + String substitution = "test"; + testParseSubstitution(substitution, substitution); + } + + @Test + public void testParseSubstitutionEmpty() { + testParseSubstitution("", ""); + } + + @Test + public void testParseSubstitutionWithWhiteSpaces() { + testParseSubstitution(" ", " "); + } + + private void testParseSubstitution(final String substitution, final String expected) { + final LogEvent event = Log4jLogEvent.newBuilder() + .setLoggerName(EqualsReplacementConverterTest.class.getName()) + .setLevel(Level.DEBUG) + .setMessage(new SimpleMessage(TEST_MESSAGE)) + .build(); + final LoggerContext ctx = LoggerContext.getContext(); + final EqualsReplacementConverter converter = EqualsReplacementConverter.newInstance(ctx.getConfiguration(), + new String[]{"[%marker]", "[]", substitution}); + final String actual = converter.parseSubstitution(event); + assertEquals(expected, actual); + } } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e2a86526/src/changes/changes.xml ---------------------------------------------------------------------- diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 68e3ec8..686cc37 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -214,6 +214,9 @@ <action issue="LOG4J2-248" dev="mattsicker" type="fix"> Log4jWebInitializerImpl: Use Thread instead of Class for fallback classloader. </action> + <action issue="LOG4J2-1169" dev="mattsicker" type="add" due-to="Gerald Kritzinger"> + PatternLayout: Possible variable substitution in equals substitution parameter. + </action> </release> <release version="2.5" date="2015-12-06" description="GA Release 2.5"> <action issue="LOG4J2-324" dev="rpopma" type="fix">
