http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/JsonConstants.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/JsonConstants.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/JsonConstants.java
new file mode 100644
index 0000000..1db6f52
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/JsonConstants.java
@@ -0,0 +1,36 @@
+/*
+ * 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.jackson;
+
+/**
+ * Keeps constants separate from any class that may depend on third party jars.
+ */
+public final class JsonConstants {
+    public static final String ELT_CAUSE = "cause";
+    public static final String ELT_EVENT = "event";
+    public static final String ELT_CONTEXT_MAP = "contextMap";
+    public static final String ELT_CONTEXT_STACK = "contextStack";
+    public static final String ELT_MARKER = "marker";
+    public static final String ELT_PARENTS = "parents";
+    public static final String ELT_SOURCE = "source";
+    public static final String ELT_SUPPRESSED = "suppressed";
+    public static final String ELT_THROWN = "thrown";
+    public static final String ELT_MESSAGE = "message";
+    public static final String ELT_EXTENDED_STACK_TRACE = "extendedStackTrace";
+    public static final String ELT_NANO_TIME = "nanoTime";
+    public static final String ELT_INSTANT = "instant";
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/LevelMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/LevelMixIn.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/LevelMixIn.java
new file mode 100644
index 0000000..c11d22e
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/LevelMixIn.java
@@ -0,0 +1,44 @@
+/*
+ * 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.jackson;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+/**
+ * Jackson mix-in for {@link Level}.
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ * @see Marker
+ */
+@JsonIgnoreProperties({ "name", "declaringClass", "standardLevel" })
+public abstract class LevelMixIn {
+
+    @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
+    public static Level getLevel(final String name) {
+        return null;
+    }
+
+    @JsonValue
+    public abstract String name();
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ListOfMapEntryDeserializer.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ListOfMapEntryDeserializer.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ListOfMapEntryDeserializer.java
new file mode 100644
index 0000000..4a1199d
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ListOfMapEntryDeserializer.java
@@ -0,0 +1,55 @@
+/*
+ * 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.jackson;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+
+/**
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ */
+public class ListOfMapEntryDeserializer extends StdDeserializer<Map<String, 
String>> {
+
+    private static final long serialVersionUID = 1L;
+
+    ListOfMapEntryDeserializer() {
+        super(Map.class);
+    }
+
+    @Override
+    public Map<String, String> deserialize(final JsonParser jp, final 
DeserializationContext ctxt) throws IOException,
+            JsonProcessingException {
+        final List<MapEntry> list = jp.readValueAs(new 
TypeReference<List<MapEntry>>() {
+            // empty
+        });
+        final HashMap<String, String> map = new HashMap<>(list.size());
+        for (final MapEntry mapEntry : list) {
+            map.put(mapEntry.getKey(), mapEntry.getValue());
+        }
+        return map;
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ListOfMapEntrySerializer.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ListOfMapEntrySerializer.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ListOfMapEntrySerializer.java
new file mode 100644
index 0000000..48a9911
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ListOfMapEntrySerializer.java
@@ -0,0 +1,58 @@
+/*
+ * 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.jackson;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+
+/**
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ */
+public class ListOfMapEntrySerializer extends StdSerializer<Map<String, 
String>> {
+
+    private static final long serialVersionUID = 1L;
+
+    protected ListOfMapEntrySerializer() {
+        super(Map.class, false);
+    }
+
+    protected MapEntry[] createMapEntryArray(final Set<Entry<String, String>> 
entrySet) {
+        return new MapEntry[entrySet.size()];
+    }
+
+    @Override
+    public void serialize(final Map<String, String> map, final JsonGenerator 
jgen, final SerializerProvider provider)
+            throws IOException, JsonGenerationException {
+        final Set<Entry<String, String>> entrySet = map.entrySet();
+        final MapEntry[] pairs = createMapEntryArray(entrySet);
+        int i = 0;
+        for (final Entry<String, String> entry : entrySet) {
+            pairs[i++] = new MapEntry(entry.getKey(), entry.getValue());
+        }
+        jgen.writeObject(pairs);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/Log4jStackTraceElementDeserializer.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/Log4jStackTraceElementDeserializer.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/Log4jStackTraceElementDeserializer.java
new file mode 100644
index 0000000..7d03805
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/Log4jStackTraceElementDeserializer.java
@@ -0,0 +1,82 @@
+/*
+ * 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.jackson;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
+
+/**
+ * Copy and edit the Jackson (Apache License 2.0) class to use Log4j attribute 
names. Does not work as of Jackson 2.3.2.
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ */
+public final class Log4jStackTraceElementDeserializer extends 
StdScalarDeserializer<StackTraceElement> {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructs a new initialized instance.
+     */
+    public Log4jStackTraceElementDeserializer() {
+        super(StackTraceElement.class);
+    }
+
+    @Override
+    public StackTraceElement deserialize(final JsonParser jp, final 
DeserializationContext ctxt) throws IOException,
+            JsonProcessingException {
+        JsonToken t = jp.getCurrentToken();
+        // Must get an Object
+        if (t == JsonToken.START_OBJECT) {
+            String className = null, methodName = null, fileName = null;
+            int lineNumber = -1;
+
+            while ((t = jp.nextValue()) != JsonToken.END_OBJECT) {
+                final String propName = jp.getCurrentName();
+                if ("class".equals(propName)) {
+                    className = jp.getText();
+                } else if ("file".equals(propName)) {
+                    fileName = jp.getText();
+                } else if ("line".equals(propName)) {
+                    if (t.isNumeric()) {
+                        lineNumber = jp.getIntValue();
+                    } else {
+                        // An XML number always comes in a string since there 
is no syntax help as with JSON.
+                        try {
+                            lineNumber = Integer.parseInt(jp.getText().trim());
+                        } catch (final NumberFormatException e) {
+                            throw JsonMappingException.from(jp, "Non-numeric 
token (" + t + ") for property 'line'", e);
+                        }
+                    }
+                } else if ("method".equals(propName)) {
+                    methodName = jp.getText();
+                } else if ("nativeMethod".equals(propName)) {
+                    // no setter, not passed via constructor: ignore
+                } else {
+                    this.handleUnknownProperty(jp, ctxt, this._valueClass, 
propName);
+                }
+            }
+            return new StackTraceElement(className, methodName, fileName, 
lineNumber);
+        }
+        throw ctxt.mappingException(this._valueClass, t);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/LogEventJsonMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/LogEventJsonMixIn.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/LogEventJsonMixIn.java
new file mode 100644
index 0000000..e9607bd
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/LogEventJsonMixIn.java
@@ -0,0 +1,146 @@
+/*
+ * 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.jackson;
+
+import java.util.Map;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.ThreadContext.ContextStack;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.impl.ThrowableProxy;
+import org.apache.logging.log4j.core.time.Instant;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.util.ReadOnlyStringMap;
+
+import com.fasterxml.jackson.annotation.JsonFilter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.annotation.JsonRootName;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+@JsonRootName(JsonConstants.ELT_EVENT)
+@JsonFilter("org.apache.logging.log4j.core.impl.Log4jLogEvent")
+@JsonPropertyOrder({
+    // @formatter:off
+    "timeMillis",
+    JsonConstants.ELT_INSTANT,
+    "threadName",
+    "level",
+    "loggerName",
+    "marker",
+    "message",
+    "thrown",
+    JsonConstants.ELT_CONTEXT_MAP,
+    JsonConstants.ELT_CONTEXT_STACK,
+    "loggerFQCN",
+    "Source",
+    "endOfBatch" })
+    // @formatter:on
+/**
+ * As of Jackson 2.9.4, if we extend AbstractLogEventMixIn, then the {@link 
ObjectMessage} serializer
+ * {@code ObjectMessageSerializer} does not get invoked. Either a bug in 
Jackson or in our set up code.
+ */
+public abstract class LogEventJsonMixIn /* extends AbstractLogEventMixIn */ 
implements LogEvent {
+
+    private static final long serialVersionUID = 1L;
+
+    @JsonProperty(JsonConstants.ELT_CONTEXT_MAP)
+    @JsonSerialize(using = ContextDataSerializer.class)
+    @JsonDeserialize(using = ContextDataDeserializer.class)
+    @Override
+    public abstract ReadOnlyStringMap getContextData();
+
+    @Override
+    @JsonIgnore
+    public abstract Map<String, String> getContextMap();
+
+    @JsonProperty(JsonConstants.ELT_CONTEXT_STACK)
+    @Override
+    public abstract ContextStack getContextStack();
+
+    @JsonProperty(JsonConstants.ELT_INSTANT)
+    @Override
+    public abstract Instant getInstant();
+
+    @JsonProperty()
+    @Override
+    public abstract Level getLevel();
+
+    @JsonProperty()
+    @Override
+    public abstract String getLoggerFqcn();
+
+    @JsonProperty()
+    @Override
+    public abstract String getLoggerName();
+
+    @JsonProperty(JsonConstants.ELT_MARKER)
+    @Override
+    public abstract Marker getMarker();
+
+    @JsonProperty(JsonConstants.ELT_MESSAGE)
+    @JsonDeserialize(using = SimpleMessageDeserializer.class)
+    @Override
+    public abstract Message getMessage();
+
+    @JsonProperty(JsonConstants.ELT_SOURCE)
+    @JsonDeserialize(using = Log4jStackTraceElementDeserializer.class)
+    @Override
+    public abstract StackTraceElement getSource();
+
+    @Override
+    @JsonProperty("threadId")
+    public abstract long getThreadId();
+
+    @Override
+    @JsonProperty("thread")
+    public abstract String getThreadName();
+
+    @Override
+    @JsonProperty("threadPriority")
+    public abstract int getThreadPriority();
+
+    @JsonIgnore
+    @Override
+    public abstract Throwable getThrown();
+
+    @JsonProperty(JsonConstants.ELT_THROWN)
+    @Override
+    public abstract ThrowableProxy getThrownProxy();
+
+    @JsonIgnore // ignore from 2.11
+    @Override
+    public abstract long getTimeMillis();
+
+    @JsonProperty()
+    @Override
+    public abstract boolean isEndOfBatch();
+
+    @JsonIgnore
+    @Override
+    public abstract boolean isIncludeLocation();
+
+    @Override
+    public abstract void setEndOfBatch(boolean endOfBatch);
+
+    @Override
+    public abstract void setIncludeLocation(boolean locationRequired);
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/LogEventWithContextListMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/LogEventWithContextListMixIn.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/LogEventWithContextListMixIn.java
new file mode 100644
index 0000000..cd0639b
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/LogEventWithContextListMixIn.java
@@ -0,0 +1,130 @@
+/*
+ * 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.jackson;
+
+import java.util.Map;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.ThreadContext.ContextStack;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.impl.ThrowableProxy;
+import org.apache.logging.log4j.core.time.Instant;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.util.ReadOnlyStringMap;
+
+import com.fasterxml.jackson.annotation.JsonFilter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.annotation.JsonRootName;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+@JsonRootName(XmlConstants.ELT_EVENT)
+@JsonFilter("org.apache.logging.log4j.core.impl.Log4jLogEvent")
+@JsonPropertyOrder({ "timeMillis", XmlConstants.ELT_INSTANT, "threadName", 
"level", "loggerName", "marker", "message", "thrown", 
XmlConstants.ELT_CONTEXT_MAP,
+        JsonConstants.ELT_CONTEXT_STACK, "loggerFQCN", "Source", "endOfBatch" 
})
+abstract class LogEventWithContextListMixIn implements LogEvent {
+
+    private static final long serialVersionUID = 1L;
+
+    @JsonProperty(JsonConstants.ELT_CONTEXT_MAP)
+    @JsonSerialize(using = ContextDataAsEntryListSerializer.class)
+    @JsonDeserialize(using = ContextDataAsEntryListDeserializer.class)
+//    @JsonIgnore
+    @Override
+    public abstract ReadOnlyStringMap getContextData();
+
+    @Override
+    @JsonIgnore
+    public abstract Map<String, String> getContextMap();
+
+    @JsonProperty(JsonConstants.ELT_CONTEXT_STACK)
+    @Override
+    public abstract ContextStack getContextStack();
+
+    @JsonProperty(JsonConstants.ELT_INSTANT)
+    @Override
+    public abstract Instant getInstant();
+
+    @JsonProperty()
+    @Override
+    public abstract Level getLevel();
+
+    @JsonProperty()
+    @Override
+    public abstract String getLoggerFqcn();
+
+    @JsonProperty()
+    @Override
+    public abstract String getLoggerName();
+
+    @JsonProperty(JsonConstants.ELT_MARKER)
+    @Override
+    public abstract Marker getMarker();
+
+    @JsonProperty(JsonConstants.ELT_MESSAGE)
+    @JsonSerialize(using = MessageSerializer.class)
+    @JsonDeserialize(using = SimpleMessageDeserializer.class)
+    @Override
+    public abstract Message getMessage();
+
+    @JsonProperty(JsonConstants.ELT_SOURCE)
+    @JsonDeserialize(using = Log4jStackTraceElementDeserializer.class)
+    @Override
+    public abstract StackTraceElement getSource();
+
+    @Override
+    @JsonProperty("threadId")
+    public abstract long getThreadId();
+
+    @Override
+    @JsonProperty("thread")
+    public abstract String getThreadName();
+
+    @Override
+    @JsonProperty("threadPriority")
+    public abstract int getThreadPriority();
+
+    @JsonIgnore
+    @Override
+    public abstract Throwable getThrown();
+
+    @JsonProperty(JsonConstants.ELT_THROWN)
+    @Override
+    public abstract ThrowableProxy getThrownProxy();
+
+    @JsonIgnore // ignore from 2.11
+    @Override
+    public abstract long getTimeMillis();
+
+    @JsonProperty()
+    @Override
+    public abstract boolean isEndOfBatch();
+
+    @JsonIgnore
+    @Override
+    public abstract boolean isIncludeLocation();
+
+    @Override
+    public abstract void setEndOfBatch(boolean endOfBatch);
+
+    @Override
+    public abstract void setIncludeLocation(boolean locationRequired);
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/MapEntry.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/MapEntry.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/MapEntry.java
new file mode 100644
index 0000000..fc02180
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/MapEntry.java
@@ -0,0 +1,109 @@
+/*
+ * 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.jackson;
+
+import org.apache.logging.log4j.util.Strings;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+/**
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ * <p>
+ * Used to represent map entries in a generic fashion because the default 
Jackson behavior uses the key as the element
+ * tag. Using the key as an element/property name would mean that you cannot 
have a generic JSON/XML schema for all log
+ * event.
+ * </p>
+ */
+@JsonPropertyOrder({ "key", "value" })
+public class MapEntry {
+
+    @JsonProperty
+    private String key;
+
+    @JsonProperty
+    private String value;
+
+    @JsonCreator
+    public MapEntry(@JsonProperty("key") final String key, 
@JsonProperty("value") final String value) {
+        this.setKey(key);
+        this.setValue(value);
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof MapEntry)) {
+            return false;
+        }
+        final MapEntry other = (MapEntry) obj;
+        if (this.getKey() == null) {
+            if (other.getKey() != null) {
+                return false;
+            }
+        } else if (!this.getKey().equals(other.getKey())) {
+            return false;
+        }
+        if (this.getValue() == null) {
+            if (other.getValue() != null) {
+                return false;
+            }
+        } else if (!this.getValue().equals(other.getValue())) {
+            return false;
+        }
+        return true;
+    }
+
+    public String getKey() {
+        return this.key;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((this.getKey() == null) ? 0 : 
this.getKey().hashCode());
+        result = prime * result + ((this.getValue() == null) ? 0 : 
this.getValue().hashCode());
+        return result;
+    }
+
+    public void setKey(final String key) {
+        this.key = key;
+    }
+
+    public void setValue(final String value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return Strings.EMPTY + this.getKey() + "=" + this.getValue();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/MarkerMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/MarkerMixIn.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/MarkerMixIn.java
new file mode 100644
index 0000000..45bbcc3
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/MarkerMixIn.java
@@ -0,0 +1,71 @@
+/*
+ * 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.jackson;
+
+import org.apache.logging.log4j.Marker;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+
+/**
+ * Jackson mix-in for {@link Marker}.
+ * <p>
+ * If we want to deal with more than one {@link Marker} implementation then 
recode these annotations to include metadata.
+ * </p>
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ * <p>
+ * Example XML:
+ * </p>
+ * <pre>
+&lt;Marker name=&quot;Marker1&quot;&gt;
+    &lt;Parents&gt;
+        &lt;Marker name=&quot;ParentMarker1&quot;&gt;
+            &lt;Parents&gt;
+                &lt;Marker name=&quot;GrandMotherMarker&quot;/&gt;
+                &lt;Marker name=&quot;GrandFatherMarker&quot;/&gt;
+            &lt;/Parents&gt;
+        &lt;/Marker&gt;
+        &lt;Marker name=&quot;ParentMarker2&quot;/&gt;
+    &lt;/Parents&gt;
+&lt;/Marker&gt;
+ * </pre>
+ *
+ * @see Marker
+ */
+// Alternate for multiple Marker implementation.
+// @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = 
JsonTypeInfo.As.PROPERTY, property = "@class")
+@JsonDeserialize(as = org.apache.logging.log4j.MarkerManager.Log4jMarker.class)
+public abstract class MarkerMixIn implements Marker {
+    private static final long serialVersionUID = 1L;
+
+    @JsonCreator
+    public MarkerMixIn(@JsonProperty("name") final String name) {
+        // empty
+    }
+
+    @Override
+    @JsonProperty("name")
+    public abstract String getName();
+
+    @Override
+    @JsonProperty(JsonConstants.ELT_PARENTS)
+    public abstract Marker[] getParents();
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/MessageSerializer.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/MessageSerializer.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/MessageSerializer.java
new file mode 100644
index 0000000..faff2da
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/MessageSerializer.java
@@ -0,0 +1,47 @@
+/*
+ * 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.jackson;
+
+import java.io.IOException;
+
+import org.apache.logging.log4j.message.Message;
+
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
+
+/**
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ */
+public final class MessageSerializer extends StdScalarSerializer<Message> {
+
+    private static final long serialVersionUID = 1L;
+
+    public MessageSerializer() {
+        super(Message.class);
+    }
+
+    @Override
+    public void serialize(final Message value, final JsonGenerator jgen, final 
SerializerProvider provider) throws IOException,
+            JsonGenerationException {
+        jgen.writeString(value.getFormattedMessage());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/MutableThreadContextStackDeserializer.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/MutableThreadContextStackDeserializer.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/MutableThreadContextStackDeserializer.java
new file mode 100644
index 0000000..b98edb5
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/MutableThreadContextStackDeserializer.java
@@ -0,0 +1,51 @@
+/*
+ * 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.jackson;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.logging.log4j.spi.MutableThreadContextStack;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+
+/**
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ */
+final class MutableThreadContextStackDeserializer extends 
StdDeserializer<MutableThreadContextStack> {
+
+    private static final long serialVersionUID = 1L;
+
+    MutableThreadContextStackDeserializer() {
+        super(MutableThreadContextStack.class);
+    }
+
+    @Override
+    public MutableThreadContextStack deserialize(final JsonParser jp, final 
DeserializationContext ctxt) throws IOException,
+            JsonProcessingException {
+        final List<String> list = jp.readValueAs(new 
TypeReference<List<String>>() {
+            // empty
+        });
+        return new MutableThreadContextStack(list);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ObjectMessageSerializer.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ObjectMessageSerializer.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ObjectMessageSerializer.java
new file mode 100644
index 0000000..3cb9af2
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ObjectMessageSerializer.java
@@ -0,0 +1,47 @@
+/*
+ * 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.jackson;
+
+import java.io.IOException;
+
+import org.apache.logging.log4j.message.ObjectMessage;
+
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
+
+/**
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ */
+final class ObjectMessageSerializer extends StdScalarSerializer<ObjectMessage> 
{
+
+    private static final long serialVersionUID = 1L;
+
+    ObjectMessageSerializer() {
+        super(ObjectMessage.class);
+    }
+
+    @Override
+    public void serialize(final ObjectMessage value, final JsonGenerator 
jsonGenerator,
+            final SerializerProvider serializerProvider) throws IOException, 
JsonGenerationException {
+        jsonGenerator.writeObject(value.getParameter());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/SetupContextInitializer.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/SetupContextInitializer.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/SetupContextInitializer.java
new file mode 100644
index 0000000..3d73d93
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/SetupContextInitializer.java
@@ -0,0 +1,38 @@
+package org.apache.logging.log4j.jackson;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.impl.ExtendedStackTraceElement;
+import org.apache.logging.log4j.core.impl.ThrowableProxy;
+import org.apache.logging.log4j.core.time.Instant;
+
+import com.fasterxml.jackson.databind.Module.SetupContext;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+
+/**
+ * Used to set up {@link SetupContext} from different {@link SimpleModule}s.
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ */
+public class SetupContextInitializer {
+
+    public void setupModule(final SetupContext context, final boolean 
includeStacktrace,
+            final boolean stacktraceAsString) {
+        // JRE classes: we cannot edit those with Jackson annotations
+        context.setMixInAnnotations(StackTraceElement.class, 
StackTraceElementMixIn.class);
+        // Log4j API classes: we do not want to edit those with Jackson 
annotations because the API module should not
+        // depend on Jackson.
+        context.setMixInAnnotations(Marker.class, MarkerMixIn.class);
+        context.setMixInAnnotations(Level.class, LevelMixIn.class);
+        context.setMixInAnnotations(Instant.class, InstantMixIn.class);
+        context.setMixInAnnotations(LogEvent.class, 
LogEventWithContextListMixIn.class);
+        // Log4j Core classes: we do not want to bring in Jackson at runtime 
if we do not have to.
+        context.setMixInAnnotations(ExtendedStackTraceElement.class, 
ExtendedStackTraceElementMixIn.class);
+        context.setMixInAnnotations(ThrowableProxy.class, includeStacktrace
+                ? (stacktraceAsString ? 
ThrowableProxyWithStacktraceAsStringMixIn.class : ThrowableProxyMixIn.class)
+                : ThrowableProxyWithoutStacktraceMixIn.class);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/SimpleMessageDeserializer.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/SimpleMessageDeserializer.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/SimpleMessageDeserializer.java
new file mode 100644
index 0000000..2ab948c
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/SimpleMessageDeserializer.java
@@ -0,0 +1,47 @@
+/*
+ * 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.jackson;
+
+import java.io.IOException;
+
+import org.apache.logging.log4j.message.SimpleMessage;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
+
+/**
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ */
+public final class SimpleMessageDeserializer extends 
StdScalarDeserializer<SimpleMessage> {
+
+    private static final long serialVersionUID = 1L;
+
+    SimpleMessageDeserializer() {
+        super(SimpleMessage.class);
+    }
+
+    @Override
+    public SimpleMessage deserialize(final JsonParser jsonParser, final 
DeserializationContext deserializationContext)
+            throws IOException, JsonProcessingException {
+        return new SimpleMessage(jsonParser.getValueAsString());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/SimpleModuleInitializer.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/SimpleModuleInitializer.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/SimpleModuleInitializer.java
new file mode 100644
index 0000000..edae1bc
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/SimpleModuleInitializer.java
@@ -0,0 +1,26 @@
+package org.apache.logging.log4j.jackson;
+
+import org.apache.logging.log4j.ThreadContext.ContextStack;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.ObjectMessage;
+
+import com.fasterxml.jackson.databind.module.SimpleModule;
+
+/**
+ * Used to set up {@link SimpleModule} from different {@link SimpleModule} 
subclasses.
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ */
+public class SimpleModuleInitializer {
+    public void initialize(final SimpleModule simpleModule, final boolean 
objectMessageAsJsonObject) {
+        // Workaround because mix-ins do not work for classes that already 
have a built-in deserializer.
+        // See Jackson issue 429.
+        simpleModule.addDeserializer(StackTraceElement.class, new 
Log4jStackTraceElementDeserializer());
+        simpleModule.addDeserializer(ContextStack.class, new 
MutableThreadContextStackDeserializer());
+        if (objectMessageAsJsonObject) {
+            simpleModule.addSerializer(ObjectMessage.class, new 
ObjectMessageSerializer());
+        }
+        simpleModule.addSerializer(Message.class, new MessageSerializer());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/StackTraceElementConstants.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/StackTraceElementConstants.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/StackTraceElementConstants.java
new file mode 100644
index 0000000..0f0f025
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/StackTraceElementConstants.java
@@ -0,0 +1,30 @@
+/*
+ * 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.jackson;
+
+/**
+ * Defines constants use for naming stack trace elements.
+ */
+public class StackTraceElementConstants {
+
+    public static final String ATTR_CLASS = "class";
+    public static final String ATTR_FILE = "file";
+    public static final String ATTR_LINE = "line";
+    public static final String ATTR_METHOD = "method";
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/StackTraceElementMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/StackTraceElementMixIn.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/StackTraceElementMixIn.java
new file mode 100644
index 0000000..b3bff92
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/StackTraceElementMixIn.java
@@ -0,0 +1,59 @@
+/*
+ * 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.jackson;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Jackson mix-in for {@link StackTraceElement}.
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ *
+ * @see StackTraceElement
+ */
+@JsonIgnoreProperties("nativeMethod")
+public abstract class StackTraceElementMixIn {
+
+    @JsonCreator
+    protected StackTraceElementMixIn(
+    // @formatter:off
+            @JsonProperty(StackTraceElementConstants.ATTR_CLASS) final String 
declaringClass,
+            @JsonProperty(StackTraceElementConstants.ATTR_METHOD) final String 
methodName,
+            @JsonProperty(StackTraceElementConstants.ATTR_FILE) final String 
fileName,
+            @JsonProperty(StackTraceElementConstants.ATTR_LINE) final int 
lineNumber)
+    // @formatter:on
+    {
+        // empty
+    }
+
+    @JsonProperty(StackTraceElementConstants.ATTR_CLASS)
+    protected abstract String getClassName();
+
+    @JsonProperty(StackTraceElementConstants.ATTR_FILE)
+    protected abstract String getFileName();
+
+    @JsonProperty(StackTraceElementConstants.ATTR_LINE)
+    protected abstract int getLineNumber();
+
+    @JsonProperty(StackTraceElementConstants.ATTR_METHOD)
+    protected abstract String getMethodName();
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ThrowableProxyMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ThrowableProxyMixIn.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ThrowableProxyMixIn.java
new file mode 100644
index 0000000..7116c80
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ThrowableProxyMixIn.java
@@ -0,0 +1,70 @@
+/*
+ * 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.jackson;
+
+import org.apache.logging.log4j.core.impl.ExtendedStackTraceElement;
+import org.apache.logging.log4j.core.impl.ThrowableProxy;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Mix-in for {@link ThrowableProxy}.
+ */
+public abstract class ThrowableProxyMixIn {
+
+    @JsonProperty(JsonConstants.ELT_CAUSE)
+    private ThrowableProxyMixIn causeProxy;
+
+    @JsonProperty
+    private int commonElementCount;
+
+    @JsonProperty(JsonConstants.ELT_EXTENDED_STACK_TRACE)
+    private ExtendedStackTraceElement[] extendedStackTrace;
+
+    @JsonProperty
+    private String localizedMessage;
+
+    @JsonProperty
+    private String message;
+
+    @JsonProperty
+    private String name;
+
+    @JsonIgnore
+    private transient Throwable throwable;
+
+    @JsonIgnore
+    public abstract String getCauseStackTraceAsString();
+
+    @JsonIgnore
+    public abstract String getExtendedStackTraceAsString();
+
+    @JsonIgnore
+    public abstract StackTraceElement[] getStackTrace();
+
+    @JsonProperty(JsonConstants.ELT_SUPPRESSED)
+    public abstract ThrowableProxy[] getSuppressedProxies();
+
+    @JsonIgnore
+    public abstract String getSuppressedStackTrace();
+
+    @JsonIgnore
+    public abstract Throwable getThrowable();
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ThrowableProxyWithStacktraceAsStringMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ThrowableProxyWithStacktraceAsStringMixIn.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ThrowableProxyWithStacktraceAsStringMixIn.java
new file mode 100644
index 0000000..e73a108
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ThrowableProxyWithStacktraceAsStringMixIn.java
@@ -0,0 +1,70 @@
+/*
+ * 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.jackson;
+
+import org.apache.logging.log4j.core.impl.ExtendedStackTraceElement;
+import org.apache.logging.log4j.core.impl.ThrowableProxy;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Mix-in for {@link org.apache.logging.log4j.core.impl.ThrowableProxy}.
+ */
+public abstract class ThrowableProxyWithStacktraceAsStringMixIn {
+
+    @JsonProperty(JsonConstants.ELT_CAUSE)
+    private ThrowableProxyWithStacktraceAsStringMixIn causeProxy;
+
+    @JsonProperty
+    private int commonElementCount;
+
+    @JsonIgnore
+    private ExtendedStackTraceElement[] extendedStackTrace;
+
+    @JsonProperty
+    private String localizedMessage;
+
+    @JsonProperty
+    private String message;
+
+    @JsonProperty
+    private String name;
+
+    @JsonIgnore
+    private transient Throwable throwable;
+
+    @JsonIgnore
+    public abstract String getCauseStackTraceAsString();
+
+    @JsonProperty(JsonConstants.ELT_EXTENDED_STACK_TRACE)
+    public abstract String getExtendedStackTraceAsString();
+
+    @JsonIgnore
+    public abstract StackTraceElement[] getStackTrace();
+
+    @JsonProperty(JsonConstants.ELT_SUPPRESSED)
+    public abstract ThrowableProxy[] getSuppressedProxies();
+
+    @JsonIgnore
+    public abstract String getSuppressedStackTrace();
+
+    @JsonIgnore
+    public abstract Throwable getThrowable();
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ThrowableProxyWithoutStacktraceMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ThrowableProxyWithoutStacktraceMixIn.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ThrowableProxyWithoutStacktraceMixIn.java
new file mode 100644
index 0000000..b80c89c
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ThrowableProxyWithoutStacktraceMixIn.java
@@ -0,0 +1,69 @@
+/*
+ * 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.jackson;
+
+import org.apache.logging.log4j.core.impl.ExtendedStackTraceElement;
+import org.apache.logging.log4j.core.impl.ThrowableProxy;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Mix-in for {@link ThrowableProxy}.
+ */
+public abstract class ThrowableProxyWithoutStacktraceMixIn {
+
+    @JsonProperty(JsonConstants.ELT_CAUSE)
+    private ThrowableProxyWithoutStacktraceMixIn causeProxy;
+
+    @JsonProperty
+    private int commonElementCount;
+
+    @JsonIgnore
+    private ExtendedStackTraceElement[] extendedStackTrace;
+
+    @JsonProperty
+    private String localizedMessage;
+
+    @JsonProperty
+    private String message;
+
+    @JsonProperty
+    private String name;
+
+    @JsonIgnore
+    private transient Throwable throwable;
+
+    @JsonIgnore
+    public abstract String getCauseStackTraceAsString();
+
+    @JsonIgnore
+    public abstract String getExtendedStackTraceAsString();
+
+    @JsonIgnore
+    public abstract StackTraceElement[] getStackTrace();
+
+    @JsonProperty(JsonConstants.ELT_SUPPRESSED)
+    public abstract ThrowableProxy[] getSuppressedProxies();
+
+    @JsonIgnore
+    public abstract String getSuppressedStackTrace();
+
+    @JsonIgnore
+    public abstract Throwable getThrowable();
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/XmlConstants.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/XmlConstants.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/XmlConstants.java
new file mode 100644
index 0000000..10dc37d
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/XmlConstants.java
@@ -0,0 +1,39 @@
+/*
+ * 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.jackson;
+
+/**
+ * Keeps constants separate from any class that may depend on third party jars.
+ */
+public final class XmlConstants {
+    public static final String ELT_CAUSE = "Cause";
+    public static final String ELT_CONTEXT_MAP = "ContextMap";
+    public static final String ELT_CONTEXT_STACK = "ContextStack";
+    public static final String ELT_CONTEXT_STACK_ITEM = "ContextStackItem";
+    public static final String ELT_EVENT = "Event";
+    public static final String ELT_EXTENDED_STACK_TRACE = "ExtendedStackTrace";
+    public static final String ELT_EXTENDED_STACK_TRACE_ITEM = 
"ExtendedStackTraceItem";
+    public static final String ELT_INSTANT = "Instant";
+    public static final String ELT_MARKER = "Marker";
+    public static final String ELT_MESSAGE = "Message";
+    public static final String ELT_PARENTS = "Parents";
+    public static final String ELT_SOURCE = "Source";
+    public static final String ELT_SUPPRESSED = "Suppressed";
+    public static final String ELT_SUPPRESSED_ITEM = "SuppressedItem";
+    public static final String ELT_THROWN = "Thrown";
+    public static final String XML_NAMESPACE = 
"http://logging.apache.org/log4j/2.0/events";;
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/layout/AbstractJacksonLayout.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/layout/AbstractJacksonLayout.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/layout/AbstractJacksonLayout.java
new file mode 100644
index 0000000..a468c1e
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/layout/AbstractJacksonLayout.java
@@ -0,0 +1,378 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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.jackson.layout;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginElement;
+import org.apache.logging.log4j.core.impl.MutableLogEvent;
+import org.apache.logging.log4j.core.layout.AbstractStringLayout;
+import org.apache.logging.log4j.core.lookup.StrSubstitutor;
+import org.apache.logging.log4j.core.util.KeyValuePair;
+import org.apache.logging.log4j.core.util.StringBuilderWriter;
+import org.apache.logging.log4j.jackson.XmlConstants;
+import org.apache.logging.log4j.util.Strings;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonRootName;
+import com.fasterxml.jackson.annotation.JsonUnwrapped;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectWriter;
+
+abstract class AbstractJacksonLayout extends AbstractStringLayout {
+
+    public static abstract class Builder<B extends Builder<B>> extends 
AbstractStringLayout.Builder<B> {
+
+        @PluginBuilderAttribute
+        private boolean eventEol;
+
+        @PluginBuilderAttribute
+        private boolean compact;
+
+        @PluginBuilderAttribute
+        private boolean complete;
+
+        @PluginBuilderAttribute
+        private boolean locationInfo;
+
+        @PluginBuilderAttribute
+        private boolean properties;
+
+        @PluginBuilderAttribute
+        private boolean includeStacktrace = true;
+
+        @PluginBuilderAttribute
+        private boolean stacktraceAsString = false;
+
+        @PluginBuilderAttribute
+        private boolean includeNullDelimiter = false;
+
+        @PluginElement("AdditionalField")
+        private KeyValuePair[] additionalFields;
+
+        public KeyValuePair[] getAdditionalFields() {
+            return additionalFields;
+        }
+
+        public boolean getEventEol() {
+            return eventEol;
+        }
+
+        public boolean isCompact() {
+            return compact;
+        }
+
+        public boolean isComplete() {
+            return complete;
+        }
+
+        public boolean isIncludeNullDelimiter() {
+            return includeNullDelimiter;
+        }
+
+        /**
+         * If "true", includes the stacktrace of any Throwable in the 
generated data, defaults to "true".
+         *
+         * @return If "true", includes the stacktrace of any Throwable in the 
generated data, defaults to "true".
+         */
+        public boolean isIncludeStacktrace() {
+            return includeStacktrace;
+        }
+
+        public boolean isLocationInfo() {
+            return locationInfo;
+        }
+
+        public boolean isProperties() {
+            return properties;
+        }
+
+        public boolean isStacktraceAsString() {
+            return stacktraceAsString;
+        }
+
+        /**
+         * Additional fields to set on each log event.
+         *
+         * @return this builder
+         */
+        public B setAdditionalFields(final KeyValuePair[] additionalFields) {
+            this.additionalFields = additionalFields;
+            return asBuilder();
+        }
+
+        public B setCompact(final boolean compact) {
+            this.compact = compact;
+            return asBuilder();
+        }
+
+        public B setComplete(final boolean complete) {
+            this.complete = complete;
+            return asBuilder();
+        }
+
+        public B setEventEol(final boolean eventEol) {
+            this.eventEol = eventEol;
+            return asBuilder();
+        }
+
+        /**
+         * Whether to include NULL byte as delimiter after each event 
(optional, default to false).
+         *
+         * @return this builder
+         */
+        public B setIncludeNullDelimiter(final boolean includeNullDelimiter) {
+            this.includeNullDelimiter = includeNullDelimiter;
+            return asBuilder();
+        }
+
+        /**
+         * If "true", includes the stacktrace of any Throwable in the 
generated JSON, defaults to "true".
+         *
+         * @param includeStacktrace
+         *            If "true", includes the stacktrace of any Throwable in 
the generated JSON, defaults to "true".
+         * @return this builder
+         */
+        public B setIncludeStacktrace(final boolean includeStacktrace) {
+            this.includeStacktrace = includeStacktrace;
+            return asBuilder();
+        }
+
+        public B setLocationInfo(final boolean locationInfo) {
+            this.locationInfo = locationInfo;
+            return asBuilder();
+        }
+
+        public B setProperties(final boolean properties) {
+            this.properties = properties;
+            return asBuilder();
+        }
+
+        /**
+         * Whether to format the stacktrace as a string, and not a nested 
object (optional, defaults to false).
+         *
+         * @return this builder
+         */
+        public B setStacktraceAsString(final boolean stacktraceAsString) {
+            this.stacktraceAsString = stacktraceAsString;
+            return asBuilder();
+        }
+
+        protected String toStringOrNull(final byte[] header) {
+            return header == null ? null : new String(header, 
Charset.defaultCharset());
+        }
+    }
+    @JsonRootName(XmlConstants.ELT_EVENT)
+    public static class LogEventWrapperWithAdditionalFields {
+
+        private final Object logEvent;
+        private final Map<String, String> additionalFields;
+
+        public LogEventWrapperWithAdditionalFields(final Object logEvent, 
final Map<String, String> additionalFields) {
+            this.logEvent = logEvent;
+            this.additionalFields = additionalFields;
+        }
+
+        @JsonAnyGetter
+        @SuppressWarnings("unused")
+        public Map<String, String> getAdditionalFields() {
+            return additionalFields;
+        }
+
+        @JsonUnwrapped
+        public Object getLogEvent() {
+            return logEvent;
+        }
+    }
+
+    protected static class ResolvableKeyValuePair {
+
+        final String key;
+        final String value;
+        final boolean valueNeedsLookup;
+
+        ResolvableKeyValuePair(final KeyValuePair pair) {
+            this.key = pair.getKey();
+            this.value = pair.getValue();
+            this.valueNeedsLookup = 
AbstractJacksonLayout.valueNeedsLookup(this.value);
+        }
+    }
+
+    protected static final String DEFAULT_EOL = "\r\n";
+
+    protected static final String COMPACT_EOL = Strings.EMPTY;
+    private static LogEvent convertMutableToLog4jEvent(final LogEvent event) {
+        // TODO Jackson-based layouts have certain filters set up for 
Log4jLogEvent.
+        // TODO Need to set up the same filters for MutableLogEvent but don't 
know how...
+        // This is a workaround.
+        return event instanceof MutableLogEvent ? ((MutableLogEvent) 
event).createMemento() : event;
+    }
+    private static ResolvableKeyValuePair[] prepareAdditionalFields(final 
Configuration config,
+            final KeyValuePair[] additionalFields) {
+        if (additionalFields == null || additionalFields.length == 0) {
+            // No fields set
+            return new ResolvableKeyValuePair[0];
+        }
+
+        // Convert to specific class which already determines whether values 
needs lookup during serialization
+        final ResolvableKeyValuePair[] resolvableFields = new 
ResolvableKeyValuePair[additionalFields.length];
+
+        for (int i = 0; i < additionalFields.length; i++) {
+            final ResolvableKeyValuePair resolvable = resolvableFields[i] = 
new ResolvableKeyValuePair(additionalFields[i]);
+
+            // Validate
+            if (config == null && resolvable.valueNeedsLookup) {
+                throw new IllegalArgumentException(
+                        "configuration needs to be set when there are 
additional fields with variables");
+            }
+        }
+
+        return resolvableFields;
+    }
+    protected static boolean valueNeedsLookup(final String value) {
+        return value != null && value.contains("${");
+    }
+    protected final String eol;
+    protected final ObjectWriter objectWriter;
+
+    protected final boolean compact;
+
+    protected final boolean complete;
+
+    protected final boolean includeNullDelimiter;
+
+    protected final ResolvableKeyValuePair[] additionalFields;
+
+    @Deprecated
+    protected AbstractJacksonLayout(final Configuration config, final 
ObjectWriter objectWriter, final Charset charset,
+            final boolean compact, final boolean complete, final boolean 
eventEol, final Serializer headerSerializer,
+            final Serializer footerSerializer) {
+        this(config, objectWriter, charset, compact, complete, eventEol, 
headerSerializer, footerSerializer, false);
+    }
+
+    @Deprecated
+    protected AbstractJacksonLayout(final Configuration config, final 
ObjectWriter objectWriter, final Charset charset,
+            final boolean compact, final boolean complete, final boolean 
eventEol, final Serializer headerSerializer,
+            final Serializer footerSerializer, final boolean 
includeNullDelimiter) {
+        this(config, objectWriter, charset, compact, complete, eventEol, 
headerSerializer, footerSerializer,
+                includeNullDelimiter, null);
+    }
+
+    protected AbstractJacksonLayout(final Configuration config, final 
ObjectWriter objectWriter, final Charset charset,
+            final boolean compact, final boolean complete, final boolean 
eventEol, final Serializer headerSerializer,
+            final Serializer footerSerializer, final boolean 
includeNullDelimiter,
+            final KeyValuePair[] additionalFields) {
+        super(config, charset, headerSerializer, footerSerializer);
+        this.objectWriter = objectWriter;
+        this.compact = compact;
+        this.complete = complete;
+        this.eol = compact && !eventEol ? COMPACT_EOL : DEFAULT_EOL;
+        this.includeNullDelimiter = includeNullDelimiter;
+        this.additionalFields = prepareAdditionalFields(config, 
additionalFields);
+    }
+
+    protected LogEventWrapperWithAdditionalFields 
createLogEventWrapperWithAdditionalFields(final LogEvent event,
+            final Map<String, String> additionalFieldsMap) {
+        return new LogEventWrapperWithAdditionalFields(event, 
additionalFieldsMap);
+    }
+
+    private Map<String, String> resolveAdditionalFields(final LogEvent 
logEvent) {
+        // Note: LinkedHashMap retains order
+        final Map<String, String> additionalFieldsMap = new 
LinkedHashMap<>(additionalFields.length);
+        final StrSubstitutor strSubstitutor = 
configuration.getStrSubstitutor();
+
+        // Go over each field
+        for (final ResolvableKeyValuePair pair : additionalFields) {
+            if (pair.valueNeedsLookup) {
+                // Resolve value
+                additionalFieldsMap.put(pair.key, 
strSubstitutor.replace(logEvent, pair.value));
+            } else {
+                // Plain text value
+                additionalFieldsMap.put(pair.key, pair.value);
+            }
+        }
+
+        return additionalFieldsMap;
+    }
+
+    /**
+     * Formats a {@link org.apache.logging.log4j.core.LogEvent}.
+     *
+     * @param event
+     *            The LogEvent.
+     * @return The XML representation of the LogEvent.
+     */
+    @Override
+    public String toSerializable(final LogEvent event) {
+        final StringBuilderWriter writer = new StringBuilderWriter();
+        try {
+            toSerializable(event, writer);
+            return writer.toString();
+        } catch (final IOException e) {
+            // Should this be an ISE or IAE?
+            LOGGER.error(e);
+            return Strings.EMPTY;
+        }
+    }
+
+    public void toSerializable(final LogEvent event, final Writer writer)
+            throws JsonGenerationException, JsonMappingException, IOException {
+        objectWriter.writeValue(writer, 
wrapLogEvent(convertMutableToLog4jEvent(event)));
+        writer.write(eol);
+        if (includeNullDelimiter) {
+            writer.write('\0');
+        }
+        markEvent();
+    }
+
+    protected Object wrapLogEvent(final LogEvent event) {
+        if (additionalFields.length > 0) {
+            // Construct map for serialization - note that we are 
intentionally using original LogEvent
+            final Map<String, String> additionalFieldsMap = 
resolveAdditionalFields(event);
+            // This class combines LogEvent with AdditionalFields during 
serialization
+            return createLogEventWrapperWithAdditionalFields(event, 
additionalFieldsMap);
+        }
+        // No additional fields, return original object
+        return event;
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/package-info.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/package-info.java
 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/package-info.java
new file mode 100644
index 0000000..3b5c435
--- /dev/null
+++ 
b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+/**
+ * Classes and interfaces for serializing and deserializing Log4j 2 log events 
to XML and JSON using the Jackson
+ * library.
+ */
+package org.apache.logging.log4j.jackson;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/site/manual/index.md
----------------------------------------------------------------------
diff --git a/log4j-layout-jackson/src/site/manual/index.md 
b/log4j-layout-jackson/src/site/manual/index.md
new file mode 100644
index 0000000..b1d22b6
--- /dev/null
+++ b/log4j-layout-jackson/src/site/manual/index.md
@@ -0,0 +1,33 @@
+<!-- vim: set syn=markdown : -->
+<!--
+    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.
+-->
+
+# Apache Log4j Layout for Jackson module
+
+As of Log4j 3.0.0, common code for layouts based on Jackson have moved from 
the existing module logj-core to the new modules log4j-layout-jackson.
+
+## Requirements
+
+This module was introduced in Log4j 2.11.0 and requires Jackson.
+
+Some features may require optional
+[dependencies](../runtime-dependencies.html). These dependencies are specified 
in the
+documentation for those features.
+
+Some Log4j features require external dependencies.
+See the [Dependency Tree](dependencies.html#Dependency_Tree)
+for the exact list of JAR files needed for these features.

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/site/site.xml
----------------------------------------------------------------------
diff --git a/log4j-layout-jackson/src/site/site.xml 
b/log4j-layout-jackson/src/site/site.xml
new file mode 100644
index 0000000..6d4cddc
--- /dev/null
+++ b/log4j-layout-jackson/src/site/site.xml
@@ -0,0 +1,52 @@
+<!--
+ 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.
+
+-->
+<project name="Log4j Core"
+         xmlns="http://maven.apache.org/DECORATION/1.4.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/DECORATION/1.4.0 
http://maven.apache.org/xsd/decoration-1.4.0.xsd";>
+  <body>
+    <links>
+      <item name="Apache" href="http://www.apache.org/"; />
+      <item name="Logging Services" href="http://logging.apache.org/"/>
+      <item name="Log4j" href="../index.html"/>
+    </links>
+
+    <!-- Component-specific reports -->
+    <menu ref="reports"/>
+
+       <!-- Overall Project Info -->
+    <menu name="Log4j Project Information" img="icon-info-sign">
+      <item name="Dependencies" href="../dependencies.html" />
+      <item name="Dependency Convergence" 
href="../dependency-convergence.html" />
+      <item name="Dependency Management" href="../dependency-management.html" 
/>
+      <item name="Project Team" href="../team-list.html" />
+      <item name="Mailing Lists" href="../mail-lists.html" />
+      <item name="Issue Tracking" href="../issue-tracking.html" />
+      <item name="Project License" href="../license.html" />
+      <item name="Source Repository" href="../source-repository.html" />
+      <item name="Project Summary" href="../project-summary.html" />
+    </menu>
+
+    <menu name="Log4j Project Reports" img="icon-cog">
+      <item name="Changes Report" href="../changes-report.html" />
+      <item name="JIRA Report" href="../jira-report.html" />
+      <item name="Surefire Report" href="../surefire-report.html" />
+      <item name="RAT Report" href="../rat-report.html" />
+    </menu>
+  </body>
+</project>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson/src/test/java/org/apache/logging/log4j/jackson/AbstractMarkerMixInTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson/src/test/java/org/apache/logging/log4j/jackson/AbstractMarkerMixInTest.java
 
b/log4j-layout-jackson/src/test/java/org/apache/logging/log4j/jackson/AbstractMarkerMixInTest.java
new file mode 100644
index 0000000..acfae96
--- /dev/null
+++ 
b/log4j-layout-jackson/src/test/java/org/apache/logging/log4j/jackson/AbstractMarkerMixInTest.java
@@ -0,0 +1,97 @@
+/*
+* 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.jackson;
+
+import java.io.IOException;
+
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.MarkerManager;
+import org.apache.logging.log4j.MarkerManager.Log4jMarker;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectReader;
+import com.fasterxml.jackson.databind.ObjectWriter;
+
+/**
+ * Tests {@link MarkerMixIn}.
+ *
+ * This class is in this package to let {@link Log4jMarker} have the least 
visibility.
+ */
+public abstract class AbstractMarkerMixInTest {
+
+    private ObjectReader reader;
+    private ObjectWriter writer;
+
+    protected abstract ObjectMapper newObjectMapper();
+
+    @Before
+    public void setUp() {
+        final ObjectMapper log4jObjectMapper = newObjectMapper();
+        writer = log4jObjectMapper.writer();
+        reader = log4jObjectMapper.readerFor(Log4jMarker.class);
+        MarkerManager.clear();
+    }
+
+    @Test
+    public void testNameOnly() throws IOException {
+        final Marker expected = MarkerManager.getMarker("A");
+        final String str = writeValueAsString(expected);
+        Assert.assertFalse(str.contains("parents"));
+        final Marker actual = reader.readValue(str);
+        Assert.assertEquals(expected, actual);
+    }
+
+    @Test
+    public void testOneParent() throws IOException {
+        final Marker expected = MarkerManager.getMarker("A");
+        final Marker parent = MarkerManager.getMarker("PARENT_MARKER");
+        expected.addParents(parent);
+        final String str = writeValueAsString(expected);
+        Assert.assertTrue(str.contains("PARENT_MARKER"));
+        final Marker actual = reader.readValue(str);
+        Assert.assertEquals(expected, actual);
+    }
+
+    @Test
+    public void testTwoParents() throws IOException {
+        final Marker expected = MarkerManager.getMarker("A");
+        final Marker parent1 = MarkerManager.getMarker("PARENT_MARKER1");
+        final Marker parent2 = MarkerManager.getMarker("PARENT_MARKER2");
+        expected.addParents(parent1);
+        expected.addParents(parent2);
+        final String str = writeValueAsString(expected);
+        Assert.assertTrue(str.contains("PARENT_MARKER1"));
+        Assert.assertTrue(str.contains("PARENT_MARKER2"));
+        final Marker actual = reader.readValue(str);
+        Assert.assertEquals(expected, actual);
+    }
+
+    /**
+     * @param expected
+     * @return
+     * @throws JsonProcessingException
+     */
+    private String writeValueAsString(final Marker expected) throws 
JsonProcessingException {
+        final String str = writer.writeValueAsString(expected);
+        // System.out.println(str);
+        return str;
+    }
+}

Reply via email to