Index: log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/MdcPatternConverterTest.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/MdcPatternConverterTest.java (date 1475431991000) +++ log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/MdcPatternConverterTest.java (revision ) @@ -78,6 +78,23 @@ assertEquals(expected, str); } + @Test + public void testConverterWithKeyAndDefault() { + final Message msg = new SimpleMessage("Hello"); + final String [] options = new String[] {"not_exist", "default_value"}; + final MdcPatternConverter converter = MdcPatternConverter.newInstance(options); + final LogEvent event = Log4jLogEvent.newBuilder() // + .setLoggerName("MyLogger") // + .setLevel(Level.DEBUG) // + .setMessage(msg) // + .build(); + final StringBuilder sb = new StringBuilder(); + converter.format(event, sb); + final String str = sb.toString(); + final String expected = "default_value"; + assertEquals(expected, str); + } + @Test public void testConverterWithKeys() { final Message msg = new SimpleMessage("Hello"); @@ -94,6 +111,23 @@ final String expected = "{object=Log4j, subject=I}"; assertEquals(expected, str); } + + @Test + public void testConverterWithKeysAndDefaults() { + final Message msg = new SimpleMessage("Hello"); + final String [] options = new String[] {"object_not_exist, subject_not_exist", "obj, sub"}; + final MdcPatternConverter converter = MdcPatternConverter.newInstance(options); + final LogEvent event = Log4jLogEvent.newBuilder() // + .setLoggerName("MyLogger") // + .setLevel(Level.DEBUG) // + .setMessage(msg) // + .build(); + final StringBuilder sb = new StringBuilder(); + converter.format(event, sb); + final String str = sb.toString(); + final String expected = "{object_not_exist=obj, subject_not_exist=sub}"; + assertEquals(expected, str); + } } Index: log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MdcPatternConverter.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/MdcPatternConverter.java (date 1475431991000) +++ log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MdcPatternConverter.java (revision ) @@ -16,12 +16,12 @@ */ package org.apache.logging.log4j.core.pattern; -import org.apache.logging.log4j.util.ReadOnlyStringMap; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.config.plugins.Plugin; import org.apache.logging.log4j.core.util.Constants; -import org.apache.logging.log4j.util.TriConsumer; +import org.apache.logging.log4j.util.ReadOnlyStringMap; import org.apache.logging.log4j.util.StringBuilders; +import org.apache.logging.log4j.util.TriConsumer; /** * Able to handle the contents of the LogEvent's MDC and either @@ -31,7 +31,7 @@ * when this pattern converter has the option set. */ @Plugin(name = "MdcPatternConverter", category = PatternConverter.CATEGORY) -@ConverterKeys({ "X", "mdc", "MDC" }) +@ConverterKeys({"X", "mdc", "MDC"}) public final class MdcPatternConverter extends LogEventPatternConverter { private static final ThreadLocal threadLocal = new ThreadLocal<>(); @@ -44,6 +44,7 @@ private final String key; private final String[] keys; private final boolean full; + private final String[] defaultValues; /** * Private constructor. @@ -64,10 +65,29 @@ keys = null; key = options[0]; } + if (options.length > 1) { + if (options[1].indexOf(',') > 0) { + defaultValues = options[1].split(","); + if (keys == null || keys.length != defaultValues.length){ + throw new IllegalArgumentException("number of default values is not EQUALS to number of keys."); + } + + for (int i = 0; i < defaultValues.length; i++) { + defaultValues[i] = defaultValues[i].trim(); + } + } else { + defaultValues = new String[1]; + defaultValues[0] = options[1]; + } + } else { + defaultValues = null; + } + } else { full = true; key = null; keys = null; + defaultValues = null; } } @@ -112,10 +132,15 @@ toAppendTo.append("{}"); return; } - appendSelectedKeys(keys, contextData, toAppendTo); - } else if (contextData != null){ + appendSelectedKeys(keys, defaultValues, contextData, toAppendTo); + } else if (contextData != null) { // otherwise they just want a single key output - final Object value = contextData.getValue(key); + Object value = contextData.getValue(key); + + if (value == null && defaultValues != null){ + value = defaultValues[0]; + } + if (value != null) { StringBuilders.appendValue(toAppendTo, value); } @@ -132,13 +157,18 @@ trimToMaxSize(sb); } - private static void appendSelectedKeys(final String[] keys, final ReadOnlyStringMap contextData, final StringBuilder toAppendTo) { + private static void appendSelectedKeys(final String[] keys, final String[] defaultValues, final ReadOnlyStringMap contextData, final StringBuilder toAppendTo) { // Print all the keys in the array that have a value. final StringBuilder sb = getStringBuilder(); sb.append("{"); for (int i = 0; i < keys.length; i++) { final String theKey = keys[i]; - final Object value = contextData.getValue(theKey); + Object value = contextData.getValue(theKey); + + if (value == null && defaultValues != null){ + value = defaultValues[i]; + } + if (value != null) { // !contextData.containskey(theKey) if (sb.length() > 1) { sb.append(", ");