Index: core/src/test/java/org/apache/logging/log4j/core/layout/RFC5424LayoutTest.java
===================================================================
--- core/src/test/java/org/apache/logging/log4j/core/layout/RFC5424LayoutTest.java	(revision 1514290)
+++ core/src/test/java/org/apache/logging/log4j/core/layout/RFC5424LayoutTest.java	(working copy)
@@ -32,15 +32,15 @@
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.junit.Assert;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Locale;
 
 import static org.junit.Assert.assertTrue;
 
-/**
- *
- */
 public class RFC5424LayoutTest {
     LoggerContext ctx = (LoggerContext) LogManager.getContext();
     Logger root = ctx.getLogger("");
@@ -51,11 +51,11 @@
     private static final String line3 = "ATM - - [RequestContext@3692 loginId=\"JohnDoe\"] filled mdc";
     private static final String line4 =
         "ATM - Audit [Transfer@18060 Amount=\"200.00\" FromAccount=\"123457\" ToAccount=\"123456\"]" +
-        "[RequestContext@18060 ipAddress=\"192.168.0.120\" loginId=\"JohnDoe\"] Transfer Complete";
+        "[RequestContext@3692 ipAddress=\"192.168.0.120\" loginId=\"JohnDoe\"] Transfer Complete";
     private static final String lineEscaped3 = "ATM - - [RequestContext@3692 escaped=\"Testing escaping #012 \\\" \\] \\\"\" loginId=\"JohnDoe\"] filled mdc";
     private static final String lineEscaped4 =
         "ATM - Audit [Transfer@18060 Amount=\"200.00\" FromAccount=\"123457\" ToAccount=\"123456\"]" +
-        "[RequestContext@18060 escaped=\"Testing escaping #012 \\\" \\] \\\"\" ipAddress=\"192.168.0.120\" loginId=\"JohnDoe\"] Transfer Complete";
+        "[RequestContext@3692 escaped=\"Testing escaping #012 \\\" \\] \\\"\" ipAddress=\"192.168.0.120\" loginId=\"JohnDoe\"] Transfer Complete";
 
     static ConfigurationFactory cf = new BasicConfigurationFactory();
 
@@ -247,9 +247,10 @@
             root.removeAppender(appender);
         }
 
-        final LoggerFields loggerFields = LoggerFields.createLoggerFields(new KeyValuePair[] {
-        		new KeyValuePair("source", "%C.%M")
-        });
+        final LoggerFields[] loggerFields = new LoggerFields[] {
+                LoggerFields.createLoggerFields(new KeyValuePair[] { new KeyValuePair("source", "%C.%M")}, null, null),
+                LoggerFields.createLoggerFields(new KeyValuePair[] { new KeyValuePair("source2", "%C.%M")}, null, null)
+        };
 
         // set up layout/appender
         final AbstractStringLayout layout = RFC5424Layout.createLayout("Local0", "Event", "3692", "true", "RequestContext",
@@ -278,4 +279,52 @@
             appender.stop();
         }
     }
+
+    @Test
+    public void testLoggerFields() {
+        List<String> expectedToContain = Arrays.asList(
+                "[BAZ@32473 baz=\"org.apache.logging.log4j.core.layout.RFC5424LayoutTest.testLoggerFields\"]"  +
+                "[RequestContext@3692 bar=\"org.apache.logging.log4j.core.layout.RFC5424LayoutTest.testLoggerFields\"]" +
+                "[SD-ID@32473 source=\"org.apache.logging.log4j.core.layout.RFC5424LayoutTest.testLoggerFields\"]"
+        );
+
+        for (final Appender appender : root.getAppenders().values()) {
+            root.removeAppender(appender);
+        }
+
+        final LoggerFields[] loggerFields = new LoggerFields[] {
+                LoggerFields.createLoggerFields(new KeyValuePair[] { new KeyValuePair("source", "%C.%M")}, "SD-ID",
+                        "32473"),
+                LoggerFields.createLoggerFields(new KeyValuePair[] { new KeyValuePair("baz", "%C.%M")}, "BAZ", "32473"),
+                LoggerFields.createLoggerFields(new KeyValuePair[] { new KeyValuePair("bar", "%C.%M")}, null, null)
+        };
+
+        final AbstractStringLayout layout = RFC5424Layout.createLayout("Local0", "Event", "3692", "true", "RequestContext",
+                null, null, "true", null, "ATM", null, "key1, key2, locale", null, null, null, loggerFields, null);
+        final ListAppender appender = new ListAppender("List", null, layout, true, false);
+        appender.start();
+
+        root.addAppender(appender);
+        root.setLevel(Level.DEBUG);
+
+        root.info("starting logger fields test");
+
+        try {
+
+            final List<String> list = appender.getMessages();
+            assertTrue("Not enough list entries", list.size() > 0);
+            String message =  list.get(0);
+            assertTrue("No class/method", message.contains("RFC5424LayoutTest.testLoggerFields"));
+            for (String value : expectedToContain) {
+                Assert.assertTrue("Not expected message received", message.contains(value));
+            }
+            appender.clear();
+        } finally {
+            root.removeAppender(appender);
+            ThreadContext.clear();
+
+            appender.stop();
+        }
+    }
+
 }
Index: core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java
===================================================================
--- core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java	(revision 1514290)
+++ core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java	(working copy)
@@ -114,7 +114,7 @@
                                                 @PluginConfiguration final Configuration config,
                                                 @PluginAttr("charset") final String charsetName,
                                                 @PluginAttr("exceptionPattern") final String exceptionPattern,
-                                                @PluginElement("LoggerFields") final LoggerFields loggerFields,
+                                                @PluginElement("LoggerFields") final LoggerFields[] loggerFields,
                                                 @PluginAttr("advertise") final String advertise) {
 
         final boolean isFlush = Booleans.parseBoolean(immediateFlush, true);
Index: core/src/main/java/org/apache/logging/log4j/core/layout/LoggerFields.java
===================================================================
--- core/src/main/java/org/apache/logging/log4j/core/layout/LoggerFields.java	(revision 1514290)
+++ core/src/main/java/org/apache/logging/log4j/core/layout/LoggerFields.java	(working copy)
@@ -21,9 +21,11 @@
 import java.util.Map;
 
 import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttr;
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
 import org.apache.logging.log4j.core.helpers.KeyValuePair;
+import org.apache.logging.log4j.message.StructuredDataId;
 
 /**
  * A LoggerFields container.
@@ -32,8 +34,12 @@
 public final class LoggerFields {
 
     private final Map<String, String> map;
+    private String sdId;
+    private String enterpriseId;
 
-    private LoggerFields(final Map<String, String> map) {
+    private LoggerFields(final Map<String, String> map, String sdId, String enterpriseId) {
+        this.sdId = sdId;
+        this.enterpriseId = enterpriseId;
         this.map = Collections.unmodifiableMap(map);
     }
 
@@ -49,12 +55,16 @@
     /**
      * Create a LoggerFields from KeyValuePairs.
      *
+     * @param sdId The SD-ID in an SD-ELEMENT
+     * @param enterpriseId The IANA assigned enterprise number
      * @param keyValuePairs An array of KeyValuePairs.
      * @return A LoggerFields instance containing a Map<String, String>.
      */
     @PluginFactory
     public static LoggerFields createLoggerFields(
-        @PluginElement("LoggerFields") final KeyValuePair[] keyValuePairs) {
+        @PluginElement("LoggerFields") final KeyValuePair[] keyValuePairs,
+        @PluginAttr("sdId") final String sdId,
+        @PluginAttr("enterpriseId") String enterpriseId) {
         final Map<String, String> map =
             new HashMap<String, String>();
 
@@ -62,6 +72,16 @@
             map.put(keyValuePair.getKey(), keyValuePair.getValue());
         }
 
-        return new LoggerFields(map);
+        return new LoggerFields(map, sdId, enterpriseId);
     }
+
+    public StructuredDataId getSdId() {
+        if (enterpriseId == null || sdId == null)  {
+            return null;
+        }
+        else {
+            int eId = Integer.valueOf(enterpriseId);
+            return new StructuredDataId(sdId, eId, null, null);
+        }
+    }
 }
Index: core/src/main/java/org/apache/logging/log4j/core/layout/RFC5424Layout.java
===================================================================
--- core/src/main/java/org/apache/logging/log4j/core/layout/RFC5424Layout.java	(revision 1514290)
+++ core/src/main/java/org/apache/logging/log4j/core/layout/RFC5424Layout.java	(working copy)
@@ -28,6 +28,7 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.LoggingException;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.Configuration;
@@ -90,6 +91,7 @@
     private final Integer enterpriseNumber;
     private final boolean includeMDC;
     private final String mdcId;
+    private final StructuredDataId mdcSDID;
     private final String localHostName;
     private final String appName;
     private final String messageId;
@@ -100,7 +102,7 @@
     private final List<String> mdcIncludes;
     private final List<String> mdcRequired;
     private final ListChecker checker;
-    private final ListChecker noopChecker = new NoopChecker();
+    private final NoopChecker noopChecker;
     private final boolean includeNewLine;
     private final String escapeNewLine;
 
@@ -108,14 +110,14 @@
     private String timestamppStr;
 
     private final List<PatternFormatter> exceptionFormatters;
-    private final Map<String, List<PatternFormatter>> fieldFormatters;
+    private final Map<String,  Map<String, List<PatternFormatter>>> fieldFormatters;
 
     private RFC5424Layout(final Configuration config, final Facility facility, final String id, final int ein,
                           final boolean includeMDC, final boolean includeNL, final String escapeNL, final String mdcId,
                           final String mdcPrefix, final String eventPrefix,
                           final String appName, final String messageId, final String excludes, final String includes,
                           final String required, final Charset charset, final String exceptionPattern,
-                          final Map<String, String> loggerFields) {
+                          final LoggerFields[] loggerFields) {
         super(charset);
         final PatternParser exceptionParser = createPatternParser(config, ThrowablePatternConverter.class);
         exceptionFormatters = exceptionPattern == null ? null : exceptionParser.parse(exceptionPattern, false);
@@ -126,6 +128,7 @@
         this.includeNewLine = includeNL;
         this.escapeNewLine = escapeNL == null ? null : Matcher.quoteReplacement(escapeNL);
         this.mdcId = mdcId;
+        this.mdcSDID = new StructuredDataId(mdcId, enterpriseNumber, null, null);
         this.mdcPrefix = mdcPrefix;
         this.eventPrefix = eventPrefix;
         this.appName = appName;
@@ -174,21 +177,33 @@
         } else {
             mdcRequired = null;
         }
+        this.noopChecker = new NoopChecker();
         this.checker = c != null ? c : noopChecker;
         final String name = config == null ? null : config.getName();
         configName = name != null && name.length() > 0 ? name : null;
-        if (loggerFields != null && !loggerFields.isEmpty()) {
-            final PatternParser fieldParser = createPatternParser(config, null);
+        this.fieldFormatters = createFieldFormatters(loggerFields, config);
+    }
 
-            final Map<String, List<PatternFormatter>> map = new HashMap<String, List<PatternFormatter>>();
-            for (final Map.Entry<String, String> entry : loggerFields.entrySet()) {
-                final List<PatternFormatter> formatters = fieldParser.parse(entry.getValue(), false);
-                map.put(entry.getKey(), formatters);
+    private Map<String,  Map<String, List<PatternFormatter>>> createFieldFormatters(final LoggerFields[] loggerFields, final Configuration config) {
+        final Map<String,  Map<String, List<PatternFormatter>>> sdIdMap = new HashMap<String,  Map<String, List<PatternFormatter>>>();
+
+        if (loggerFields != null) {
+            for (final LoggerFields lField: loggerFields) {
+                StructuredDataId key = lField.getSdId() == null ? mdcSDID : lField.getSdId();
+                Map<String, List<PatternFormatter>> sdParams = new HashMap<String, List<PatternFormatter>>();
+                Map<String, String> fields = lField.getMap();
+                if (!fields.isEmpty()) {
+                    final PatternParser fieldParser = createPatternParser(config, null);
+
+                    for (final Map.Entry<String, String> entry : fields.entrySet()) {
+                        final List<PatternFormatter> formatters = fieldParser.parse(entry.getValue(), false);
+                        sdParams.put(entry.getKey(), formatters);
+                    }
+                    sdIdMap.put(key.toString(), sdParams);
+                }
             }
-            this.fieldFormatters = map;
-        } else {
-            this.fieldFormatters = null;
         }
+        return sdIdMap.size() > 0 ? sdIdMap : null;
     }
 
     /**
@@ -235,88 +250,149 @@
      */
     @Override
     public String toSerializable(final LogEvent event) {
-        final Message msg = event.getMessage();
-        final boolean isStructured = msg instanceof StructuredDataMessage;
         final StringBuilder buf = new StringBuilder();
 
-        buf.append("<");
-        buf.append(Priority.getPriority(facility, event.getLevel()));
-        buf.append(">1 ");
-        buf.append(computeTimeStampString(event.getMillis()));
-        buf.append(' ');
-        buf.append(localHostName);
-        buf.append(' ');
+        appendPriority(buf, event.getLevel());
+        appendTimestamp(buf, event.getMillis());
+        appendSpace(buf);
+        appendHostName(buf);
+        appendSpace(buf);
+        appendAppName(buf);
+        appendSpace(buf);
+        appendProcessId(buf);
+        appendSpace(buf);
+        appendMessageId(buf, event.getMessage());
+        appendSpace(buf);
+        appendStructuredElements(buf, event);
+        appendMessage(buf, event);
+        return buf.toString();
+    }
+
+    private void appendPriority(final StringBuilder buffer, final Level logLevel) {
+        buffer.append("<");
+        buffer.append(Priority.getPriority(facility, logLevel));
+        buffer.append(">1 ");
+    }
+
+    private void appendTimestamp(final StringBuilder buffer, final long milliseconds)  {
+        buffer.append(computeTimeStampString(milliseconds));
+    }
+
+    private void appendSpace(final StringBuilder buffer) {
+        buffer.append(" ");
+    }
+
+    private void appendHostName(final StringBuilder buffer) {
+        buffer.append(localHostName);
+    }
+
+    private void appendAppName(final StringBuilder buffer) {
         if (appName != null) {
-            buf.append(appName);
+            buffer.append(appName);
         } else if (configName != null) {
-            buf.append(configName);
+            buffer.append(configName);
         } else {
-            buf.append("-");
+            buffer.append("-");
         }
-        buf.append(" ");
-        buf.append(getProcId());
-        buf.append(" ");
-        final String type = isStructured ? ((StructuredDataMessage) msg).getType() : null;
+    }
+
+    private void appendProcessId(final StringBuilder buffer) {
+        buffer.append(getProcId());
+    }
+
+    private void appendMessageId(final StringBuilder buffer, final Message message) {
+        final boolean isStructured = message instanceof StructuredDataMessage;
+        final String type = isStructured ? ((StructuredDataMessage) message).getType() : null;
         if (type != null) {
-            buf.append(type);
+            buffer.append(type);
         } else if (messageId != null) {
-            buf.append(messageId);
+            buffer.append(messageId);
         } else {
-            buf.append("-");
+            buffer.append("-");
         }
-        buf.append(" ");
-        if (isStructured || includeMDC) {
-            StructuredDataId id = null;
-            String text;
-            if (isStructured) {
-                final StructuredDataMessage data = (StructuredDataMessage) msg;
-                final Map<String, String> map = data.getData();
-                id = data.getId();
-                formatStructuredElement(id, eventPrefix, map, buf, noopChecker);
-                text = data.getFormat();
-            } else {
-                text = msg.getFormattedMessage();
-            }
-            if (includeMDC) {
-                Map<String, String> map = event.getContextMap();
-                if (mdcRequired != null) {
-                    checkRequired(map);
-                }
-                final int ein = id == null || id.getEnterpriseNumber() < 0 ?
-                    enterpriseNumber : id.getEnterpriseNumber();
-                final StructuredDataId mdcSDID = new StructuredDataId(mdcId, ein, null, null);
-                if (fieldFormatters != null) {
-                    map = new HashMap<String, String>(map);
-                    for (final Map.Entry<String, List<PatternFormatter>> entry : fieldFormatters.entrySet()) {
-                        final StringBuilder value = new StringBuilder();
-                        for (final PatternFormatter formatter : entry.getValue()) {
-                            formatter.format(event, value);
-                        }
-                        map.put(entry.getKey(), value.toString());
-                    }
-                }
-                formatStructuredElement(mdcSDID, mdcPrefix, map, buf, checker);
-            }
-            if (text != null && text.length() > 0) {
-                buf.append(" ").append(escapeNewlines(text, escapeNewLine));
-            }
-        } else {
-            buf.append("- ");
-            buf.append(escapeNewlines(msg.getFormattedMessage(), escapeNewLine));
+    }
+
+    private void appendMessage(final StringBuilder buffer, final LogEvent event) {
+        Message message = event.getMessage();
+        String text = message.getFormat();
+
+        if (text != null && text.length() > 0) {
+            buffer.append(" ").append(escapeNewlines(text, escapeNewLine));
         }
+
         if (exceptionFormatters != null && event.getThrown() != null) {
             final StringBuilder exception = new StringBuilder("\n");
             for (final PatternFormatter formatter : exceptionFormatters) {
                 formatter.format(event, exception);
             }
-            buf.append(escapeNewlines(exception.toString(), escapeNewLine));
+            buffer.append(escapeNewlines(exception.toString(), escapeNewLine));
         }
         if (includeNewLine) {
-            buf.append("\n");
+            buffer.append("\n");
         }
-        return buf.toString();
     }
 
+    private void appendStructuredElements(final StringBuilder buffer, final LogEvent event) {
+        final Message message = event.getMessage();
+        final boolean isStructured = message instanceof StructuredDataMessage;
+
+        if (!(isStructured || includeMDC || fieldFormatters.size() == 0)) {
+            buffer.append("- ");
+            return;
+        }
+
+        Map<String, Map<String, String>> sdElements = new HashMap<String, Map<String, String>>();
+        Map<String, String> contextMap = event.getContextMap();
+
+        if (mdcRequired != null) {
+            checkRequired(contextMap);
+        }
+
+        if (fieldFormatters != null) {
+            for (Map.Entry<String, Map<String, List<PatternFormatter>>> sdElement: fieldFormatters.entrySet()) {
+                String sdId = sdElement.getKey();
+
+                Map<String, String> map = new HashMap<String, String>();
+                for (final Map.Entry<String, List<PatternFormatter>> entry : sdElement.getValue().entrySet()) {
+                    final StringBuilder value = new StringBuilder();
+                    for (final PatternFormatter formatter : entry.getValue()) {
+                        formatter.format(event, value);
+                    }
+                    map.put(entry.getKey(), value.toString());
+                }
+                sdElements.put(sdId, map);
+            }
+        }
+
+        if (includeMDC && contextMap.size() > 0) {
+            if (sdElements.containsKey(mdcSDID.toString())) {
+                Map<String, String> union = sdElements.get(mdcSDID.toString());
+                union.putAll(contextMap);
+                sdElements.put(mdcSDID.toString(), union);
+            } else {
+                sdElements.put(mdcSDID.toString(), contextMap);
+            }
+        }
+
+        if (isStructured) {
+            final StructuredDataMessage data = (StructuredDataMessage) message;
+            final Map<String, String> map = data.getData();
+            StructuredDataId id = data.getId();
+
+            if (sdElements.containsKey(id.toString())) {
+                Map<String, String> union = sdElements.get(id.toString());
+                union.putAll(map);
+                sdElements.put(id.toString(), union);
+            } else {
+                sdElements.put(id.toString(), map);
+            }
+        }
+
+        for (Map.Entry<String, Map<String, String>> entry: sdElements.entrySet()) {
+            formatStructuredElement(entry.getKey(), mdcPrefix, entry.getValue(), buffer, checker);
+        }
+    }
+
     private String escapeNewlines(final String text, final String escapeNewLine) {
         if (null == escapeNewLine) {
             return text;
@@ -401,14 +477,18 @@
         buf.append(Integer.toString(val));
     }
 
-    private void formatStructuredElement(final StructuredDataId id, final String prefix, final Map<String, String> data,
+    private void formatStructuredElement(final String id, final String prefix, final Map<String, String> data,
                                          final StringBuilder sb, final ListChecker checker) {
         if (id == null && defaultId == null) {
             return;
         }
+
         sb.append("[");
-        sb.append(getId(id));
-        appendMap(prefix, data, sb, checker);
+        sb.append(id);
+        if (!mdcSDID.toString().equals(id))
+            appendMap(prefix, data, sb, noopChecker);
+        else
+            appendMap(prefix, data, sb, checker);
         sb.append("]");
     }
 
@@ -546,7 +626,7 @@
                                              @PluginAttr("mdcIncludes") String includes,
                                              @PluginAttr("mdcRequired") final String required,
                                              @PluginAttr("exceptionPattern") final String exceptionPattern,
-                                             @PluginElement("LoggerFields") final LoggerFields loggerFields,
+                                             @PluginElement("LoggerFields") final LoggerFields[] loggerFields,
                                              @PluginConfiguration final Configuration config) {
         final Charset charset = Charsets.UTF_8;
         if (includes != null && excludes != null) {
@@ -557,13 +637,12 @@
         final int enterpriseNumber = Integers.parseInt(ein, DEFAULT_ENTERPRISE_NUMBER);
         final boolean isMdc = Booleans.parseBoolean(includeMDC, true);
         final boolean includeNewLine = Boolean.parseBoolean(includeNL);
-        final Map<String, String> loggerFieldValues = loggerFields == null ? null : loggerFields.getMap();
         if (mdcId == null) {
             mdcId = DEFAULT_MDCID;
         }
 
         return new RFC5424Layout(config, f, id, enterpriseNumber, isMdc, includeNewLine, escapeNL, mdcId, mdcPrefix,
             eventPrefix, appName, msgId, excludes, includes, required, charset, exceptionPattern,
-            loggerFieldValues);
+            loggerFields);
     }
 }
