Index: log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutTest.java (revision 3d4fb63050aab105e3d960f449b4b2f45a5cca3b) +++ log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutTest.java (revision ) @@ -288,6 +288,28 @@ } @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(); Index: log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/EqualsReplacementConverterTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/EqualsReplacementConverterTest.java (revision 3d4fb63050aab105e3d960f449b4b2f45a5cca3b) +++ log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/EqualsReplacementConverterTest.java (revision ) @@ -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.util.Strings; import org.junit.Test; +import static org.junit.Assert.*; + /** * */ public class EqualsReplacementConverterTest { + private String testMessage = "This is a test"; + @Test public void testMarkerReplacement() { testReplacement("%marker", Strings.EMPTY); @@ -46,18 +48,61 @@ testReplacement("%logger", "[" + EqualsReplacementConverterTest.class.getName() + "]"); } + @Test + public void testMarkerReplacementWithMessage() { + testReplacement(testMessage, new String[]{"[%marker]", "[]", "%msg"}); + } + private void testReplacement(String tag, String expectedValue) { + final String[] options = new String[]{"[" + tag + "]", "[]", expectedValue}; + testReplacement(expectedValue, options); + } + + private void testReplacement(String expectedValue, String[] options) { final LogEvent event = Log4jLogEvent.newBuilder() // - .setLoggerName(EqualsReplacementConverterTest.class.getName()) // - .setLevel(Level.DEBUG) // + .setLoggerName(EqualsReplacementConverterTest.class.getName()) // + .setLevel(Level.DEBUG) // - .setMessage(new SimpleMessage("This is a test")) // + .setMessage(new SimpleMessage(testMessage)) // - .build(); + .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", testMessage); + } + + @Test + public void testParseSubstitutionWithoutPattern() { + String substitution = "test"; + testParseSubstitution(substitution, substitution); + } + + @Test + public void testParseSubstitutionEmpty() { + testParseSubstitution("", ""); + } + + @Test + public void testParseSubstitutionWithWhiteSpaces() { + testParseSubstitution(" ", " "); + } + + private void testParseSubstitution(String substitution, String expected) { + final LogEvent event = Log4jLogEvent.newBuilder() + .setLoggerName(EqualsReplacementConverterTest.class.getName()) + .setLevel(Level.DEBUG) + .setMessage(new SimpleMessage(testMessage)) + .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); } } Index: log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/EqualsReplacementConverter.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/EqualsReplacementConverter.java (revision 3d4fb63050aab105e3d960f449b4b2f45a5cca3b) +++ log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/EqualsReplacementConverter.java (revision ) @@ -27,16 +27,14 @@ * Equals pattern converter. */ @Plugin(name = "equals", category = PatternConverter.CATEGORY) -@ConverterKeys({ "equals" }) +@ConverterKeys({"equals"}) 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 @@ final String p = options[1]; final PatternParser parser = PatternLayout.createPatternParser(config); final List formatters = parser.parse(options[0]); - return new EqualsReplacementConverter(formatters, p, options[2]); + return new EqualsReplacementConverter(formatters, p, options[2], parser); } private final List formatters; @@ -68,22 +66,23 @@ 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 formatters The PatternFormatters to generate the text to manipulate. + * @param testString The test string. * @param substitution - * The substitution string. + * @param parser */ private EqualsReplacementConverter(final List 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,36 @@ formatter.format(event, buf); } final String string = buf.toString(); - toAppendTo.append(testString.equals(string) ? substitution : string); + + // if pattern equals test append substitution + if (testString.equals(string)) { + final String substitutionString = parseSubstitution(event); + toAppendTo.append(substitutionString); + } + // if pattern equals not test append pattern + else { + toAppendTo.append(string); + } + } + + /** + * Returns the parsed substitution test. + * + * @param event the current log event + * @return the parsed substitution test + */ + protected 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 substitutionFormatters = parser.parse(substitution); + for (final PatternFormatter formatter : substitutionFormatters) { + formatter.format(event, substitutionBuffer); + } + } else { + substitutionBuffer.append(substitution); + } + return substitutionBuffer.toString(); } }