You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rp...@apache.org on 2016/08/28 15:11:59 UTC

[35/50] logging-log4j2 git commit: Option to exclude stack trace from some layouts

Option to exclude stack trace from some layouts


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/0e86947b
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/0e86947b
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/0e86947b

Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: 0e86947b0593d69818ee564b2b35fc3a266378de
Parents: c0cb21e
Author: Mikael St�ldal <mi...@staldal.nu>
Authored: Fri Aug 12 22:39:21 2016 +0200
Committer: Mikael St�ldal <mi...@staldal.nu>
Committed: Fri Aug 12 22:39:21 2016 +0200

----------------------------------------------------------------------
 .../log4j/core/jackson/Initializers.java        | 10 ++-
 .../log4j/core/jackson/Log4jJsonModule.java     |  9 ++-
 .../core/jackson/Log4jJsonObjectMapper.java     |  6 +-
 .../log4j/core/jackson/Log4jXmlModule.java      |  6 +-
 .../core/jackson/Log4jXmlObjectMapper.java      |  9 ++-
 .../log4j/core/jackson/Log4jYamlModule.java     |  9 ++-
 .../core/jackson/Log4jYamlObjectMapper.java     |  6 +-
 .../ThrowableProxyWithoutStacktraceMixIn.java   | 77 ++++++++++++++++++++
 .../log4j/core/layout/JacksonFactory.java       | 22 +++++-
 .../logging/log4j/core/layout/JsonLayout.java   | 14 ++--
 .../logging/log4j/core/layout/XmlLayout.java    | 15 ++--
 .../logging/log4j/core/layout/YamlLayout.java   | 13 ++--
 .../server/JsonInputStreamLogEventBridge.java   |  2 +-
 .../logging/log4j/MarkerMixInXmlTest.java       |  2 +-
 .../log4j/core/jackson/LevelMixInJsonTest.java  |  2 +-
 .../jackson/StackTraceElementMixInTest.java     |  2 +-
 .../log4j/core/layout/JsonLayoutTest.java       | 59 ++++++++++-----
 .../log4j/core/layout/LogEventFixtures.java     |  6 +-
 .../log4j/core/layout/XmlLayoutTest.java        | 59 ++++++++++-----
 .../log4j/core/layout/YamlLayoutTest.java       | 55 +++++++++-----
 .../net/server/AbstractSocketServerTest.java    |  4 +-
 src/changes/changes.xml                         |  3 +
 src/site/xdoc/manual/layouts.xml.vm             | 15 ++++
 23 files changed, 301 insertions(+), 104 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Initializers.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Initializers.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Initializers.java
index d0cbe2d..fd4e10d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Initializers.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Initializers.java
@@ -39,7 +39,7 @@ class Initializers {
      */
     static class SetupContextInitializer {
 
-        void setupModule(final SetupContext context) {
+        void setupModule(final SetupContext context, final boolean includeStacktrace) {
             // 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.
@@ -48,7 +48,8 @@ class Initializers {
             context.setMixInAnnotations(LogEvent.class, LogEventMixIn.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, ThrowableProxyMixIn.class);
+            context.setMixInAnnotations(ThrowableProxy.class,
+                    includeStacktrace ? ThrowableProxyMixIn.class : ThrowableProxyWithoutStacktraceMixIn.class);
         }
     }
 
@@ -59,7 +60,7 @@ class Initializers {
      */
     static class SetupContextJsonInitializer {
 
-        void setupModule(final SetupContext context) {
+        void setupModule(final SetupContext context, final boolean includeStacktrace) {
             // 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.
@@ -68,7 +69,8 @@ class Initializers {
             context.setMixInAnnotations(LogEvent.class, LogEventJsonMixIn.class); // different ThreadContext handling
             // 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, ThrowableProxyMixIn.class);
+            context.setMixInAnnotations(ThrowableProxy.class,
+                    includeStacktrace ? ThrowableProxyMixIn.class : ThrowableProxyWithoutStacktraceMixIn.class);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jJsonModule.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jJsonModule.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jJsonModule.java
index 87f7eb6..48bd137 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jJsonModule.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jJsonModule.java
@@ -17,6 +17,7 @@
 package org.apache.logging.log4j.core.jackson;
 
 import org.apache.logging.log4j.core.jackson.Initializers.SetupContextInitializer;
+import org.apache.logging.log4j.core.jackson.Initializers.SetupContextJsonInitializer;
 import org.apache.logging.log4j.core.jackson.Initializers.SimpleModuleInitializer;
 
 import com.fasterxml.jackson.core.Version;
@@ -31,10 +32,12 @@ class Log4jJsonModule extends SimpleModule {
 
     private static final long serialVersionUID = 1L;
     private final boolean encodeThreadContextAsList;
+    private final boolean includeStacktrace;
 
-    Log4jJsonModule(final boolean encodeThreadContextAsList) {
+    Log4jJsonModule(final boolean encodeThreadContextAsList, final boolean includeStacktrace) {
         super(Log4jJsonModule.class.getName(), new Version(2, 0, 0, null, null, null));
         this.encodeThreadContextAsList = encodeThreadContextAsList;
+        this.includeStacktrace = includeStacktrace;
         // MUST init here.
         // Calling this from setupModule is too late!
         //noinspection ThisEscapedInObjectConstruction
@@ -46,9 +49,9 @@ class Log4jJsonModule extends SimpleModule {
         // Calling super is a MUST!
         super.setupModule(context);
         if (encodeThreadContextAsList) {
-            new SetupContextInitializer().setupModule(context);
+            new SetupContextInitializer().setupModule(context, includeStacktrace);
         } else {
-            new Initializers.SetupContextJsonInitializer().setupModule(context);
+            new SetupContextJsonInitializer().setupModule(context, includeStacktrace);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jJsonObjectMapper.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jJsonObjectMapper.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jJsonObjectMapper.java
index ebb8dbd..36b130d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jJsonObjectMapper.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jJsonObjectMapper.java
@@ -33,14 +33,14 @@ public class Log4jJsonObjectMapper extends ObjectMapper {
      * Create a new instance using the {@link Log4jJsonModule}.
      */
     public Log4jJsonObjectMapper() {
-        this(false);
+        this(false, true);
     }
 
     /**
      * Create a new instance using the {@link Log4jJsonModule}.
      */
-    public Log4jJsonObjectMapper(final boolean encodeThreadContextAsList) {
-        this.registerModule(new Log4jJsonModule(encodeThreadContextAsList));
+    public Log4jJsonObjectMapper(final boolean encodeThreadContextAsList, final boolean includeStacktrace) {
+        this.registerModule(new Log4jJsonModule(encodeThreadContextAsList, includeStacktrace));
         this.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
     }
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jXmlModule.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jXmlModule.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jXmlModule.java
index 60a00c4..449e001 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jXmlModule.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jXmlModule.java
@@ -29,9 +29,11 @@ import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule;
 final class Log4jXmlModule extends JacksonXmlModule {
 
     private static final long serialVersionUID = 1L;
+    private final boolean includeStacktrace;
 
-    Log4jXmlModule() {
+    Log4jXmlModule(final boolean includeStacktrace) {
         super();
+        this.includeStacktrace = includeStacktrace;
         // MUST init here.
         // Calling this from setupModule is too late!
         new SimpleModuleInitializer().initialize(this);
@@ -41,6 +43,6 @@ final class Log4jXmlModule extends JacksonXmlModule {
     public void setupModule(final SetupContext context) {
         // Calling super is a MUST!
         super.setupModule(context);
-        new SetupContextInitializer().setupModule(context);
+        new SetupContextInitializer().setupModule(context, includeStacktrace);
     }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jXmlObjectMapper.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jXmlObjectMapper.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jXmlObjectMapper.java
index 7077ffd..77d8ce4 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jXmlObjectMapper.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jXmlObjectMapper.java
@@ -34,7 +34,14 @@ public class Log4jXmlObjectMapper extends XmlMapper {
      * Create a new instance using the {@link Log4jXmlModule}.
      */
     public Log4jXmlObjectMapper() {
-        super(new Log4jXmlModule());
+        this(true);
+    }
+
+    /**
+     * Create a new instance using the {@link Log4jXmlModule}.
+     */
+    public Log4jXmlObjectMapper(final boolean includeStacktrace) {
+        super(new Log4jXmlModule(includeStacktrace));
         this.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
     }
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jYamlModule.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jYamlModule.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jYamlModule.java
index 106942f..2623ade 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jYamlModule.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jYamlModule.java
@@ -17,6 +17,7 @@
 package org.apache.logging.log4j.core.jackson;
 
 import org.apache.logging.log4j.core.jackson.Initializers.SetupContextInitializer;
+import org.apache.logging.log4j.core.jackson.Initializers.SetupContextJsonInitializer;
 import org.apache.logging.log4j.core.jackson.Initializers.SimpleModuleInitializer;
 
 import com.fasterxml.jackson.core.Version;
@@ -31,10 +32,12 @@ final class Log4jYamlModule extends SimpleModule {
 
     private static final long serialVersionUID = 1L;
     private final boolean encodeThreadContextAsList;
+    private final boolean includeStacktrace;
 
-    Log4jYamlModule(final boolean encodeThreadContextAsList) {
+    Log4jYamlModule(final boolean encodeThreadContextAsList, final boolean includeStacktrace) {
         super(Log4jYamlModule.class.getName(), new Version(2, 0, 0, null, null, null));
         this.encodeThreadContextAsList = encodeThreadContextAsList;
+        this.includeStacktrace = includeStacktrace;
         // MUST init here.
         // Calling this from setupModule is too late!
         //noinspection ThisEscapedInObjectConstruction
@@ -46,9 +49,9 @@ final class Log4jYamlModule extends SimpleModule {
         // Calling super is a MUST!
         super.setupModule(context);
         if (encodeThreadContextAsList) {
-            new SetupContextInitializer().setupModule(context);
+            new SetupContextInitializer().setupModule(context, includeStacktrace);
         } else {
-            new Initializers.SetupContextJsonInitializer().setupModule(context);
+            new SetupContextJsonInitializer().setupModule(context, includeStacktrace);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jYamlObjectMapper.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jYamlObjectMapper.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jYamlObjectMapper.java
index 2e6ce1a..2ccb567 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jYamlObjectMapper.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/Log4jYamlObjectMapper.java
@@ -34,14 +34,14 @@ public class Log4jYamlObjectMapper extends YAMLMapper {
      * Create a new instance using the {@link Log4jYamlModule}.
      */
     public Log4jYamlObjectMapper() {
-        this(false);
+        this(false, true);
     }
 
     /**
      * Create a new instance using the {@link Log4jYamlModule}.
      */
-    public Log4jYamlObjectMapper(final boolean encodeThreadContextAsList) {
-        this.registerModule(new Log4jYamlModule(encodeThreadContextAsList));
+    public Log4jYamlObjectMapper(final boolean encodeThreadContextAsList, final boolean includeStacktrace) {
+        this.registerModule(new Log4jYamlModule(encodeThreadContextAsList, includeStacktrace));
         this.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
     }
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ThrowableProxyWithoutStacktraceMixIn.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ThrowableProxyWithoutStacktraceMixIn.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ThrowableProxyWithoutStacktraceMixIn.java
new file mode 100644
index 0000000..264bef8
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ThrowableProxyWithoutStacktraceMixIn.java
@@ -0,0 +1,77 @@
+/*
+ * 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.core.jackson;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import org.apache.logging.log4j.core.impl.ExtendedStackTraceElement;
+import org.apache.logging.log4j.core.impl.ThrowableProxy;
+
+/**
+ * Mix-in for {@link ThrowableProxy}.
+ */
+abstract class ThrowableProxyWithoutStacktraceMixIn {
+
+    @JsonProperty(JsonConstants.ELT_CAUSE)
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = XmlConstants.ELT_CAUSE)
+    private ThrowableProxyWithoutStacktraceMixIn causeProxy;
+
+    @JsonProperty
+    @JacksonXmlProperty(isAttribute = true)
+    private int commonElementCount;
+
+    @JsonIgnore
+    private ExtendedStackTraceElement[] extendedStackTrace;
+
+    @JsonProperty
+    @JacksonXmlProperty(isAttribute = true)
+    private String localizedMessage;
+
+    @JsonProperty
+    @JacksonXmlProperty(isAttribute = true)
+    private String message;
+
+    @JsonProperty
+    @JacksonXmlProperty(isAttribute = true)
+    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)
+    @JacksonXmlElementWrapper(namespace = XmlConstants.XML_NAMESPACE, localName = XmlConstants.ELT_SUPPRESSED)
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = XmlConstants.ELT_SUPPRESSED_ITEM)
+    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/0e86947b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JacksonFactory.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JacksonFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JacksonFactory.java
index e230119..a62bf94 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JacksonFactory.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JacksonFactory.java
@@ -43,9 +43,11 @@ abstract class JacksonFactory {
     static class JSON extends JacksonFactory {
 
         private final boolean encodeThreadContextAsList;
+        private final boolean includeStacktrace;
 
-        public JSON(final boolean encodeThreadContextAsList) {
+        public JSON(final boolean encodeThreadContextAsList, final boolean includeStacktrace) {
             this.encodeThreadContextAsList = encodeThreadContextAsList;
+            this.includeStacktrace = includeStacktrace;
         }
 
         @Override
@@ -70,7 +72,7 @@ abstract class JacksonFactory {
 
         @Override
         protected ObjectMapper newObjectMapper() {
-            return new Log4jJsonObjectMapper(encodeThreadContextAsList);
+            return new Log4jJsonObjectMapper(encodeThreadContextAsList, includeStacktrace);
         }
 
         @Override
@@ -83,6 +85,12 @@ abstract class JacksonFactory {
 
         static final int DEFAULT_INDENT = 1;
 
+        private final boolean includeStacktrace;
+
+        public XML(final boolean includeStacktrace) {
+            this.includeStacktrace = includeStacktrace;
+        }
+
         @Override
         protected String getPropertNameForContextMap() {
             return XmlConstants.ELT_CONTEXT_MAP;
@@ -106,7 +114,7 @@ abstract class JacksonFactory {
 
         @Override
         protected ObjectMapper newObjectMapper() {
-            return new Log4jXmlObjectMapper();
+            return new Log4jXmlObjectMapper(includeStacktrace);
         }
 
         @Override
@@ -117,6 +125,12 @@ abstract class JacksonFactory {
 
     static class YAML extends JacksonFactory {
 
+        private final boolean includeStacktrace;
+
+        public YAML(final boolean includeStacktrace) {
+            this.includeStacktrace = includeStacktrace;
+        }
+
         @Override
         protected String getPropertNameForContextMap() {
             return JsonConstants.ELT_CONTEXT_MAP;
@@ -139,7 +153,7 @@ abstract class JacksonFactory {
 
         @Override
         protected ObjectMapper newObjectMapper() {
-            return new Log4jYamlObjectMapper(false);
+            return new Log4jYamlObjectMapper(false, includeStacktrace);
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JsonLayout.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JsonLayout.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JsonLayout.java
index e9d87ae..df1d4ea 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JsonLayout.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JsonLayout.java
@@ -810,8 +810,9 @@ public final class JsonLayout extends AbstractJacksonLayout {
     protected JsonLayout(final Configuration config, final boolean locationInfo, final boolean properties,
             final boolean encodeThreadContextAsList,
             final boolean complete, final boolean compact, final boolean eventEol, final String headerPattern,
-            final String footerPattern, final Charset charset) {
-        super(config, new JacksonFactory.JSON(encodeThreadContextAsList).newWriter(locationInfo, properties, compact),
+            final String footerPattern, final Charset charset, final boolean includeStacktrace) {
+        super(config, new JacksonFactory.JSON(encodeThreadContextAsList, includeStacktrace).newWriter(
+                    locationInfo, properties, compact),
                 charset, compact, complete, eventEol,
                 PatternLayout.createSerializer(config, null, headerPattern, DEFAULT_HEADER, null, false, false),
                 PatternLayout.createSerializer(config, null, footerPattern, DEFAULT_FOOTER, null, false, false));
@@ -897,6 +898,8 @@ public final class JsonLayout extends AbstractJacksonLayout {
      *            The header pattern, defaults to {@code "]"} if null.
      * @param charset
      *            The character set to use, if {@code null}, uses "UTF-8".
+     * @param includeStacktrace
+     *            If "true", includes the stacktrace of any Throwable in the generated JSON, defaults to "true".
      * @return A JSON Layout.
      */
     @PluginFactory
@@ -911,12 +914,13 @@ public final class JsonLayout extends AbstractJacksonLayout {
             @PluginAttribute(value = "eventEol", defaultBoolean = false) final boolean eventEol,
             @PluginAttribute(value = "header", defaultString = DEFAULT_HEADER) final String headerPattern,
             @PluginAttribute(value = "footer", defaultString = DEFAULT_FOOTER) final String footerPattern,
-            @PluginAttribute(value = "charset", defaultString = "UTF-8") final Charset charset
+            @PluginAttribute(value = "charset", defaultString = "UTF-8") final Charset charset,
+            @PluginAttribute(value = "includeStacktrace", defaultBoolean = true) final boolean includeStacktrace
             // @formatter:on
     ) {
         final boolean encodeThreadContextAsList = properties && propertiesAsList;
         return new JsonLayout(config, locationInfo, properties, encodeThreadContextAsList, complete, compact, eventEol,
-                headerPattern, footerPattern, charset);
+                headerPattern, footerPattern, charset, includeStacktrace);
     }
 
     /**
@@ -926,7 +930,7 @@ public final class JsonLayout extends AbstractJacksonLayout {
      */
     public static JsonLayout createDefaultLayout() {
         return new JsonLayout(new DefaultConfiguration(), false, false, false, false, false, false,
-                DEFAULT_HEADER, DEFAULT_FOOTER, StandardCharsets.UTF_8);
+                DEFAULT_HEADER, DEFAULT_FOOTER, StandardCharsets.UTF_8, true);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/XmlLayout.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/XmlLayout.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/XmlLayout.java
index afa6db7..d83e814 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/XmlLayout.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/XmlLayout.java
@@ -194,8 +194,10 @@ public final class XmlLayout extends AbstractJacksonLayout {
 
     private static final String ROOT_TAG = "Events";
 
-    protected XmlLayout(final boolean locationInfo, final boolean properties, final boolean complete, final boolean compact, final Charset charset) {
-        super(null, new JacksonFactory.XML().newWriter(locationInfo, properties, compact), charset, compact, complete, false, null, null);
+    protected XmlLayout(final boolean locationInfo, final boolean properties, final boolean complete,
+                        final boolean compact, final Charset charset, final boolean includeStacktrace) {
+        super(null, new JacksonFactory.XML(includeStacktrace).newWriter(
+                locationInfo, properties, compact), charset, compact, complete, false, null, null);
     }
 
     /**
@@ -272,6 +274,8 @@ public final class XmlLayout extends AbstractJacksonLayout {
      * @param complete If "true", includes the XML header and footer, defaults to "false".
      * @param compact If "true", does not use end-of-lines and indentation, defaults to "false".
      * @param charset The character set to use, if {@code null}, uses "UTF-8".
+     * @param includeStacktrace
+     *            If "true", includes the stacktrace of any Throwable in the generated XML, defaults to "true".
      * @return An XML Layout.
      */
     @PluginFactory
@@ -281,10 +285,11 @@ public final class XmlLayout extends AbstractJacksonLayout {
             @PluginAttribute(value = "properties", defaultBoolean = false) final boolean properties,
             @PluginAttribute(value = "complete", defaultBoolean = false) final boolean complete,
             @PluginAttribute(value = "compact", defaultBoolean = false) final boolean compact,
-            @PluginAttribute(value = "charset", defaultString = "UTF-8") final Charset charset)
+            @PluginAttribute(value = "charset", defaultString = "UTF-8") final Charset charset,
+            @PluginAttribute(value = "includeStacktrace", defaultBoolean = true) final boolean includeStacktrace)
             // @formatter:on
     {
-        return new XmlLayout(locationInfo, properties, complete, compact, charset);
+        return new XmlLayout(locationInfo, properties, complete, compact, charset, includeStacktrace);
     }
 
     /**
@@ -293,6 +298,6 @@ public final class XmlLayout extends AbstractJacksonLayout {
      * @return an XML Layout.
      */
     public static XmlLayout createDefaultLayout() {
-        return new XmlLayout(false, false, false, false, StandardCharsets.UTF_8);
+        return new XmlLayout(false, false, false, false, StandardCharsets.UTF_8, true);
     }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/YamlLayout.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/YamlLayout.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/YamlLayout.java
index 6f3e103..52837c8 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/YamlLayout.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/YamlLayout.java
@@ -710,8 +710,8 @@ public final class YamlLayout extends AbstractJacksonLayout {
 
     protected YamlLayout(final Configuration config, final boolean locationInfo, final boolean properties,
             final boolean complete, final boolean compact, final boolean eventEol, final String headerPattern,
-            final String footerPattern, final Charset charset) {
-        super(config, new JacksonFactory.YAML().newWriter(locationInfo, properties, compact), charset, compact,
+            final String footerPattern, final Charset charset, final boolean includeStacktrace) {
+        super(config, new JacksonFactory.YAML(includeStacktrace).newWriter(locationInfo, properties, compact), charset, compact,
                 complete, eventEol,
                 PatternLayout.createSerializer(config, null, headerPattern, DEFAULT_HEADER, null, false, false),
                 PatternLayout.createSerializer(config, null, footerPattern, DEFAULT_FOOTER, null, false, false));
@@ -786,6 +786,8 @@ public final class YamlLayout extends AbstractJacksonLayout {
      *            The header pattern, defaults to {@code ""} if null.
      * @param charset
      *            The character set to use, if {@code null}, uses "UTF-8".
+     * @param includeStacktrace
+     *            If "true", includes the stacktrace of any Throwable in the generated YAML, defaults to "true".
      * @return A YAML Layout.
      */
     @PluginFactory
@@ -796,11 +798,12 @@ public final class YamlLayout extends AbstractJacksonLayout {
             @PluginAttribute(value = "properties", defaultBoolean = false) final boolean properties,
             @PluginAttribute(value = "header", defaultString = DEFAULT_HEADER) final String headerPattern,
             @PluginAttribute(value = "footer", defaultString = DEFAULT_FOOTER) final String footerPattern,
-            @PluginAttribute(value = "charset", defaultString = "UTF-8") final Charset charset
+            @PluginAttribute(value = "charset", defaultString = "UTF-8") final Charset charset,
+            @PluginAttribute(value = "includeStacktrace", defaultBoolean = true) final boolean includeStacktrace
             // @formatter:on
     ) {
         return new YamlLayout(config, locationInfo, properties, false, false, true, headerPattern, footerPattern,
-                charset);
+                charset, includeStacktrace);
     }
 
     /**
@@ -810,7 +813,7 @@ public final class YamlLayout extends AbstractJacksonLayout {
      */
     public static AbstractJacksonLayout createDefaultLayout() {
         return new YamlLayout(new DefaultConfiguration(), false, false, false, false, false, DEFAULT_HEADER,
-                DEFAULT_FOOTER, StandardCharsets.UTF_8);
+                DEFAULT_FOOTER, StandardCharsets.UTF_8, true);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/JsonInputStreamLogEventBridge.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/JsonInputStreamLogEventBridge.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/JsonInputStreamLogEventBridge.java
index cf89b5a..a0e4fdb 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/JsonInputStreamLogEventBridge.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/JsonInputStreamLogEventBridge.java
@@ -40,7 +40,7 @@ public class JsonInputStreamLogEventBridge extends InputStreamLogEventBridge {
     }
 
     public JsonInputStreamLogEventBridge(final int bufferSize, final Charset charset) {
-        super(new Log4jJsonObjectMapper(THREAD_CONTEXT_MAP_AS_LIST), bufferSize, charset,
+        super(new Log4jJsonObjectMapper(THREAD_CONTEXT_MAP_AS_LIST, true), bufferSize, charset,
                 String.valueOf(EVENT_END_MARKER));
     }
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/test/java/org/apache/logging/log4j/MarkerMixInXmlTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/MarkerMixInXmlTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/MarkerMixInXmlTest.java
index 8c63560..45c0bac 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/MarkerMixInXmlTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/MarkerMixInXmlTest.java
@@ -25,7 +25,7 @@ public class MarkerMixInXmlTest extends MarkerMixInTest {
 
     @Override
     protected ObjectMapper newObjectMapper() {
-        return new Log4jXmlObjectMapper();
+        return new Log4jXmlObjectMapper(true);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/test/java/org/apache/logging/log4j/core/jackson/LevelMixInJsonTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/jackson/LevelMixInJsonTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/jackson/LevelMixInJsonTest.java
index da77aa0..4d65b8d 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/jackson/LevelMixInJsonTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/jackson/LevelMixInJsonTest.java
@@ -23,7 +23,7 @@ public class LevelMixInJsonTest extends LevelMixInTest {
 
     @Override
     protected ObjectMapper newObjectMapper() {
-        return new Log4jJsonObjectMapper(false);
+        return new Log4jJsonObjectMapper(false, true);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/test/java/org/apache/logging/log4j/core/jackson/StackTraceElementMixInTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/jackson/StackTraceElementMixInTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/jackson/StackTraceElementMixInTest.java
index 3be145c..8050a68 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/jackson/StackTraceElementMixInTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/jackson/StackTraceElementMixInTest.java
@@ -78,7 +78,7 @@ public class StackTraceElementMixInTest {
     public void testFromJsonWithLog4jModule() throws Exception {
         final ObjectMapper mapper = new ObjectMapper();
         final boolean encodeThreadContextAsList = false;
-        final SimpleModule module = new Log4jJsonModule(encodeThreadContextAsList);
+        final SimpleModule module = new Log4jJsonModule(encodeThreadContextAsList, true);
         module.addDeserializer(StackTraceElement.class, new Log4jStackTraceElementDeserializer());
         mapper.registerModule(module);
         final StackTraceElement expected = new StackTraceElement("package.SomeClass", "someMethod", "SomeClass.java", 123);

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/JsonLayoutTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/JsonLayoutTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/JsonLayoutTest.java
index 0c2fbca..a6cdf43 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/JsonLayoutTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/JsonLayoutTest.java
@@ -17,6 +17,7 @@
 package org.apache.logging.log4j.core.layout;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
@@ -110,12 +111,17 @@ public class JsonLayoutTest {
         assertTrue(str, str.contains(DQUOTE + name + DQUOTE + propSep));
     }
 
+    private void checkPropertyNameAbsent(final String name, final boolean compact, final String str) {
+        final String propSep = this.toPropertySeparator(compact);
+        assertFalse(str, str.contains(DQUOTE + name + DQUOTE + propSep));
+    }
+
     private void testAllFeatures(final boolean includeSource, final boolean compact, final boolean eventEol,
-            final boolean includeContext, final boolean contextMapAslist)
+            final boolean includeContext, final boolean contextMapAslist, final boolean includeStacktace)
             throws Exception {
         final Log4jLogEvent expected = LogEventFixtures.createLogEvent();
         final AbstractJacksonLayout layout = JsonLayout.createLayout(null, includeSource,
-                includeContext, contextMapAslist, false, compact, eventEol, null, null, StandardCharsets.UTF_8);
+                includeContext, contextMapAslist, false, compact, eventEol, null, null, StandardCharsets.UTF_8, includeStacktace);
         final String str = layout.toSerializable(expected);
         // System.out.println(str);
         final String propSep = this.toPropertySeparator(compact);
@@ -123,8 +129,8 @@ public class JsonLayoutTest {
         assertEquals(str, !compact || eventEol, str.contains("\n"));
         assertEquals(str, includeSource, str.contains("source"));
         assertEquals(str, includeContext, str.contains("contextMap"));
-        final Log4jLogEvent actual = new Log4jJsonObjectMapper(contextMapAslist).readValue(str, Log4jLogEvent.class);
-        LogEventFixtures.assertEqualLogEvents(expected, actual, includeSource, includeContext);
+        final Log4jLogEvent actual = new Log4jJsonObjectMapper(contextMapAslist, includeStacktace).readValue(str, Log4jLogEvent.class);
+        LogEventFixtures.assertEqualLogEvents(expected, actual, includeSource, includeContext, includeStacktace);
         if (includeContext) {
             this.checkMapEntry("MDC.A", "A_Value", compact, str, contextMapAslist);
             this.checkMapEntry("MDC.B", "B_Value", compact, str, contextMapAslist);
@@ -142,25 +148,33 @@ public class JsonLayoutTest {
         this.checkPropertyName("message", compact, str);
         this.checkPropertyName("thrown", compact, str);
         this.checkPropertyName("cause", compact, str);
-        this.checkPropertyName("class", compact, str);
-        this.checkPropertyName("method", compact, str);
-        this.checkPropertyName("file", compact, str);
-        this.checkPropertyName("line", compact, str);
-        this.checkPropertyName("exact", compact, str);
-        this.checkPropertyName("location", compact, str);
-        this.checkPropertyName("version", compact, str);
         this.checkPropertyName("commonElementCount", compact, str);
         this.checkPropertyName("localizedMessage", compact, str);
-        this.checkPropertyName("extendedStackTrace", compact, str);
+        if (includeStacktace) {
+            this.checkPropertyName("extendedStackTrace", compact, str);
+            this.checkPropertyName("class", compact, str);
+            this.checkPropertyName("method", compact, str);
+            this.checkPropertyName("file", compact, str);
+            this.checkPropertyName("line", compact, str);
+            this.checkPropertyName("exact", compact, str);
+            this.checkPropertyName("location", compact, str);
+            this.checkPropertyName("version", compact, str);
+        } else {
+            this.checkPropertyNameAbsent("extendedStackTrace", compact, str);
+        }
         this.checkPropertyName("suppressed", compact, str);
         this.checkPropertyName("loggerFqcn", compact, str);
         this.checkPropertyName("endOfBatch", compact, str);
         if (includeContext) {
             this.checkPropertyName("contextMap", compact, str);
+        } else {
+            this.checkPropertyNameAbsent("contextMap", compact, str);
         }
         this.checkPropertyName("contextStack", compact, str);
         if (includeSource) {
             this.checkPropertyName("source", compact, str);
+        } else {
+            this.checkPropertyNameAbsent("source", compact, str);
         }
         // check some attrs
         this.checkProperty("loggerFqcn", "f.q.c.n", compact, str);
@@ -189,7 +203,7 @@ public class JsonLayoutTest {
         // set up appender
         final boolean propertiesAsList = false;
         final AbstractJacksonLayout layout = JsonLayout.createLayout(configuration, true, true, propertiesAsList,
-                true, false, false, null, null, null);
+                true, false, false, null, null, null, true);
         final ListAppender appender = new ListAppender("List", null, layout, true, false);
         appender.start();
 
@@ -228,7 +242,7 @@ public class JsonLayoutTest {
         // Use [[ and ]] to test header and footer (instead of [ and ])
         final boolean propertiesAsList = false;
         final AbstractJacksonLayout layout = JsonLayout.createLayout(configuration, true, true, propertiesAsList,
-                true, false, false, "[[", "]]", null);
+                true, false, false, "[[", "]]", null, true);
         final ListAppender appender = new ListAppender("List", null, layout, true, false);
         appender.start();
 
@@ -269,7 +283,7 @@ public class JsonLayoutTest {
     public void testLayoutLoggerName() throws Exception {
         final boolean propertiesAsList = false;
         final AbstractJacksonLayout layout = JsonLayout.createLayout(null, false, false, propertiesAsList,
-                false, true, false, null, null, StandardCharsets.UTF_8);
+                false, true, false, null, null, StandardCharsets.UTF_8, true);
         final Log4jLogEvent expected = Log4jLogEvent.newBuilder() //
                 .setLoggerName("a.B") //
                 .setLoggerFqcn("f.q.c.n") //
@@ -279,29 +293,34 @@ public class JsonLayoutTest {
                 .setTimeMillis(1).build();
         final String str = layout.toSerializable(expected);
         assertTrue(str, str.contains("\"loggerName\":\"a.B\""));
-        final Log4jLogEvent actual = new Log4jJsonObjectMapper(propertiesAsList).readValue(str, Log4jLogEvent.class);
+        final Log4jLogEvent actual = new Log4jJsonObjectMapper(propertiesAsList, true).readValue(str, Log4jLogEvent.class);
         assertEquals(expected.getLoggerName(), actual.getLoggerName());
         assertEquals(expected, actual);
     }
 
     @Test
     public void testLocationOffCompactOffMdcOff() throws Exception {
-        this.testAllFeatures(false, false, false, false, false);
+        this.testAllFeatures(false, false, false, false, false, true);
     }
 
     @Test
     public void testLocationOnCompactOnMdcOn() throws Exception {
-        this.testAllFeatures(true, true, false, true, false);
+        this.testAllFeatures(true, true, false, true, false, true);
     }
 
     @Test
     public void testLocationOnCompactOnEventEolOnMdcOn() throws Exception {
-        this.testAllFeatures(true, true, true, true, false);
+        this.testAllFeatures(true, true, true, true, false, true);
     }
 
     @Test
     public void testLocationOnCompactOnEventEolOnMdcOnMdcAsList() throws Exception {
-        this.testAllFeatures(true, true, true, true, true);
+        this.testAllFeatures(true, true, true, true, true, true);
+    }
+
+    @Test
+    public void testExcludeStacktrace() throws Exception {
+        this.testAllFeatures(false, false, false, false, false, false);
     }
 
     private String toPropertySeparator(final boolean compact) {

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/LogEventFixtures.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/LogEventFixtures.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/LogEventFixtures.java
index eb1a6c2..980ba37 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/LogEventFixtures.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/LogEventFixtures.java
@@ -81,7 +81,7 @@ class LogEventFixtures {
     }
 
     static void assertEqualLogEvents(final LogEvent expected, final LogEvent actual, final boolean includeSource, 
-            final boolean includeContext) {
+            final boolean includeContext, final boolean includeStacktrace) {
         assertEquals(expected.getClass(), actual.getClass());
         assertEquals(includeContext ? expected.getContextMap() : Collections.EMPTY_MAP, actual.getContextMap());
         assertEquals(expected.getContextStack(), actual.getContextStack());
@@ -95,7 +95,9 @@ class LogEventFixtures {
         assertEquals(expected.getThreadName(), actual.getThreadName());
         assertNotNull("original should have an exception", expected.getThrown());
         assertNull("exception should not be serialized", actual.getThrown());
-        assertEquals(expected.getThrownProxy(), actual.getThrownProxy());
+        if (includeStacktrace) { // TODO should compare the rest of the ThrowableProxy
+            assertEquals(expected.getThrownProxy(), actual.getThrownProxy());
+        }
         assertEquals(expected.isEndOfBatch(), actual.isEndOfBatch());
         assertEquals(expected.isIncludeLocation(), actual.isIncludeLocation());
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/XmlLayoutTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/XmlLayoutTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/XmlLayoutTest.java
index 2e87a94..f3cc559 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/XmlLayoutTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/XmlLayoutTest.java
@@ -107,6 +107,10 @@ public class XmlLayoutTest {
         Assert.assertTrue(str, endPos >= 0);
     }
 
+    private void checkElementNameAbsent(final String name, final boolean compact, final String str) {
+        Assert.assertFalse(str.contains("<" + name));
+    }
+
     /**
      * @param includeSource TODO
      * @param compact
@@ -115,17 +119,17 @@ public class XmlLayoutTest {
      * @throws JsonParseException
      * @throws JsonMappingException
      */
-    private void testAllFeatures(final boolean includeSource, final boolean compact, final boolean includeContext) throws IOException,
+    private void testAllFeatures(final boolean includeSource, final boolean compact, final boolean includeContext, final boolean includeStacktrace) throws IOException,
             JsonParseException, JsonMappingException {
         final Log4jLogEvent expected = LogEventFixtures.createLogEvent();
-        final XmlLayout layout = XmlLayout.createLayout(includeSource, includeContext, false, compact, StandardCharsets.UTF_8);
+        final XmlLayout layout = XmlLayout.createLayout(includeSource, includeContext, false, compact, StandardCharsets.UTF_8, includeStacktrace);
         final String str = layout.toSerializable(expected);
         // System.out.println(str);
         assertEquals(str, !compact, str.contains("\n"));
         assertEquals(str, includeSource, str.contains("Source"));
         assertEquals(str, includeContext, str.contains("ContextMap"));
         final Log4jLogEvent actual = new Log4jXmlObjectMapper().readValue(str, Log4jLogEvent.class);
-        LogEventFixtures.assertEqualLogEvents(expected, actual, includeSource, includeContext);
+        LogEventFixtures.assertEqualLogEvents(expected, actual, includeSource, includeContext, includeStacktrace);
         if (includeContext) {
             this.checkElement("MDC.A", "A_Value", compact, str);
             this.checkElement("MDC.B", "B_Value", compact, str);
@@ -138,10 +142,12 @@ public class XmlLayoutTest {
         assertTrue(str, str.contains("loggerName=\"a.B\""));
         // make sure short names are used
         assertTrue(str, str.contains("<Event "));
-        assertTrue(str, str.contains("class="));
-        assertTrue(str, str.contains("method="));
-        assertTrue(str, str.contains("file="));
-        assertTrue(str, str.contains("line="));
+        if (includeStacktrace) {
+            assertTrue(str, str.contains("class="));
+            assertTrue(str, str.contains("method="));
+            assertTrue(str, str.contains("file="));
+            assertTrue(str, str.contains("line="));
+        }
         //
         // make sure the names we want are used
         this.checkAttributeName("timeMillis", compact, str);
@@ -153,27 +159,35 @@ public class XmlLayoutTest {
         this.checkElementName("Parents", compact, str, false, true);
         this.checkElementName("Message", compact, str, false, true);
         this.checkElementName("Thrown", compact, str, true, true);
-        this.checkElementName("Cause", compact, str, true, true);
-        this.checkAttributeName("class", compact, str);
-        this.checkAttributeName("method", compact, str);
-        this.checkAttributeName("file", compact, str);
-        this.checkAttributeName("line", compact, str);
-        this.checkAttributeName("exact", compact, str);
-        this.checkAttributeName("location", compact, str);
-        this.checkAttributeName("version", compact, str);
+        this.checkElementName("Cause", compact, str, true, includeStacktrace);
         this.checkAttributeName("commonElementCount", compact, str);
         this.checkAttributeName("message", compact, str);
         this.checkAttributeName("localizedMessage", compact, str);
-        this.checkElementName("ExtendedStackTrace", compact, str, false, true);
+        if (includeStacktrace) {
+            this.checkElementName("ExtendedStackTrace", compact, str, false, true);
+            this.checkAttributeName("class", compact, str);
+            this.checkAttributeName("method", compact, str);
+            this.checkAttributeName("file", compact, str);
+            this.checkAttributeName("line", compact, str);
+            this.checkAttributeName("exact", compact, str);
+            this.checkAttributeName("location", compact, str);
+            this.checkAttributeName("version", compact, str);
+        } else {
+            this.checkElementNameAbsent("ExtendedStackTrace", compact, str);
+        }
         this.checkElementName("Suppressed", compact, str, false, true);
         this.checkAttributeName("loggerFqcn", compact, str);
         this.checkAttributeName("endOfBatch", compact, str);
         if (includeContext) {
             this.checkElementName("ContextMap", compact, str, false, true);
+        } else {
+            this.checkElementNameAbsent("ContextMap", compact, str);
         }
         this.checkElementName("ContextStack", compact, str, false, true);
         if (includeSource) {
             this.checkElementName("Source", compact, str, true, false);
+        } else {
+            this.checkElementNameAbsent("Source", compact, str);
         }
         // check some attrs
         this.checkAttribute("loggerFqcn", "f.q.c.n", compact, str);
@@ -202,7 +216,7 @@ public class XmlLayoutTest {
             this.rootLogger.removeAppender(appender);
         }
         // set up appender
-        final XmlLayout layout = XmlLayout.createLayout(true, true, true, false, null);
+        final XmlLayout layout = XmlLayout.createLayout(true, true, true, false, null, true);
         final ListAppender appender = new ListAppender("List", null, layout, true, false);
         appender.start();
 
@@ -251,7 +265,7 @@ public class XmlLayoutTest {
 
     @Test
     public void testLayoutLoggerName() {
-        final XmlLayout layout = XmlLayout.createLayout(false, true, true, false, null);
+        final XmlLayout layout = XmlLayout.createLayout(false, true, true, false, null, true);
         final Log4jLogEvent event = Log4jLogEvent.newBuilder() //
                 .setLoggerName("a.B") //
                 .setLoggerFqcn("f.q.c.n") //
@@ -265,11 +279,16 @@ public class XmlLayoutTest {
 
     @Test
     public void testLocationOffCompactOffMdcOff() throws Exception {
-        this.testAllFeatures(false, false, false);
+        this.testAllFeatures(false, false, false, true);
     }
 
     @Test
     public void testLocationOnCompactOnMdcOn() throws Exception {
-        this.testAllFeatures(true, true, true);
+        this.testAllFeatures(true, true, true, true);
+    }
+
+    @Test
+    public void testExcludeStacktrace() throws Exception {
+        this.testAllFeatures(false, false, false, false);
     }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/YamlLayoutTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/YamlLayoutTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/YamlLayoutTest.java
index 5bcb152..a553539 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/YamlLayoutTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/YamlLayoutTest.java
@@ -17,6 +17,7 @@
 package org.apache.logging.log4j.core.layout;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
@@ -103,19 +104,24 @@ public class YamlLayoutTest {
         assertTrue(str, str.contains(name + propSep));
     }
 
+    private void checkPropertyNameAbsent(final String name, final boolean compact, final String str, final boolean isValue) {
+        final String propSep = this.toPropertySeparator(compact, isValue);
+        assertFalse(str, str.contains(name + propSep));
+    }
+
     private void testAllFeatures(final boolean includeSource, final boolean compact, final boolean eventEol,
-            final boolean includeContext, final boolean contextMapAslist) throws Exception {
+            final boolean includeContext, final boolean contextMapAslist, final boolean includeStacktrace) throws Exception {
         final Log4jLogEvent expected = LogEventFixtures.createLogEvent();
         final AbstractJacksonLayout layout = YamlLayout.createLayout(null, includeSource, includeContext, null, null,
-                StandardCharsets.UTF_8);
+                StandardCharsets.UTF_8, includeStacktrace);
         final String str = layout.toSerializable(expected);
         // System.out.println(str);
         // Just check for \n since \r might or might not be there.
         assertEquals(str, !compact || eventEol, str.contains("\n"));
         assertEquals(str, includeSource, str.contains("source"));
         assertEquals(str, includeContext, str.contains("contextMap"));
-        final Log4jLogEvent actual = new Log4jYamlObjectMapper(contextMapAslist).readValue(str, Log4jLogEvent.class);
-        LogEventFixtures.assertEqualLogEvents(expected, actual, includeSource, includeContext);
+        final Log4jLogEvent actual = new Log4jYamlObjectMapper(contextMapAslist, includeStacktrace).readValue(str, Log4jLogEvent.class);
+        LogEventFixtures.assertEqualLogEvents(expected, actual, includeSource, includeContext, includeStacktrace);
         if (includeContext) {
             this.checkMapEntry("MDC.A", "A_Value", compact, str);
             this.checkMapEntry("MDC.B", "B_Value", compact, str);
@@ -133,25 +139,33 @@ public class YamlLayoutTest {
         this.checkPropertyName("message", compact, str, true);
         this.checkPropertyName("thrown", compact, str, false);
         this.checkPropertyName("cause", compact, str, false);
-        this.checkPropertyName("class", compact, str, true);
-        this.checkPropertyName("method", compact, str, true);
-        this.checkPropertyName("file", compact, str, true);
-        this.checkPropertyName("line", compact, str, true);
-        this.checkPropertyName("exact", compact, str, true);
-        this.checkPropertyName("location", compact, str, true);
-        this.checkPropertyName("version", compact, str, true);
         this.checkPropertyName("commonElementCount", compact, str, true);
         this.checkPropertyName("localizedMessage", compact, str, true);
-        this.checkPropertyName("extendedStackTrace", compact, str, false);
+        if (includeStacktrace) {
+            this.checkPropertyName("extendedStackTrace", compact, str, false);
+            this.checkPropertyName("class", compact, str, true);
+            this.checkPropertyName("method", compact, str, true);
+            this.checkPropertyName("file", compact, str, true);
+            this.checkPropertyName("line", compact, str, true);
+            this.checkPropertyName("exact", compact, str, true);
+            this.checkPropertyName("location", compact, str, true);
+            this.checkPropertyName("version", compact, str, true);
+        } else {
+            this.checkPropertyNameAbsent("extendedStackTrace", compact, str, false);
+        }
         this.checkPropertyName("suppressed", compact, str, false);
         this.checkPropertyName("loggerFqcn", compact, str, true);
         this.checkPropertyName("endOfBatch", compact, str, true);
         if (includeContext) {
             this.checkPropertyName("contextMap", compact, str, false);
+        } else {
+            this.checkPropertyNameAbsent("contextMap", compact, str, false);
         }
         this.checkPropertyName("contextStack", compact, str, false);
         if (includeSource) {
             this.checkPropertyName("source", compact, str, false);
+        } else {
+            this.checkPropertyNameAbsent("source", compact, str, false);
         }
         // check some attrs
         this.checkProperty("loggerFqcn", "f.q.c.n", compact, str, true);
@@ -178,7 +192,7 @@ public class YamlLayoutTest {
         }
         final Configuration configuration = rootLogger.getContext().getConfiguration();
         // set up appender
-        final AbstractJacksonLayout layout = YamlLayout.createLayout(configuration, true, true, null, null, null);
+        final AbstractJacksonLayout layout = YamlLayout.createLayout(configuration, true, true, null, null, null, true);
         final ListAppender appender = new ListAppender("List", null, layout, true, false);
         appender.start();
 
@@ -214,7 +228,7 @@ public class YamlLayoutTest {
         final Configuration configuration = rootLogger.getContext().getConfiguration();
         // set up appender
         // Use [[ and ]] to test header and footer (instead of [ and ])
-        final AbstractJacksonLayout layout = YamlLayout.createLayout(configuration, true, true, "[[", "]]", null);
+        final AbstractJacksonLayout layout = YamlLayout.createLayout(configuration, true, true, "[[", "]]", null, true);
         final ListAppender appender = new ListAppender("List", null, layout, true, false);
         appender.start();
 
@@ -253,7 +267,7 @@ public class YamlLayoutTest {
     @Test
     public void testLayoutLoggerName() throws Exception {
         final AbstractJacksonLayout layout = YamlLayout.createLayout(null, false, false, null, null,
-                StandardCharsets.UTF_8);
+                StandardCharsets.UTF_8, true);
         final Log4jLogEvent expected = Log4jLogEvent.newBuilder() //
                 .setLoggerName("a.B") //
                 .setLoggerFqcn("f.q.c.n") //
@@ -263,19 +277,24 @@ public class YamlLayoutTest {
                 .setTimeMillis(1).build();
         final String str = layout.toSerializable(expected);
         assertTrue(str, str.contains("loggerName: \"a.B\""));
-        final Log4jLogEvent actual = new Log4jYamlObjectMapper(false).readValue(str, Log4jLogEvent.class);
+        final Log4jLogEvent actual = new Log4jYamlObjectMapper(false, true).readValue(str, Log4jLogEvent.class);
         assertEquals(expected.getLoggerName(), actual.getLoggerName());
         assertEquals(expected, actual);
     }
 
     @Test
     public void testLocationOffCompactOffMdcOff() throws Exception {
-        this.testAllFeatures(false, false, false, false, false);
+        this.testAllFeatures(false, false, false, false, false, true);
     }
 
     @Test
     public void testLocationOnCompactOffEventEolOffMdcOn() throws Exception {
-        this.testAllFeatures(true, false, false, true, false);
+        this.testAllFeatures(true, false, false, true, false, true);
+    }
+
+    @Test
+    public void testExcludeStacktrace() throws Exception {
+        this.testAllFeatures(false, false, false, false, false, false);
     }
 
     private String toPropertySeparator(final boolean compact, final boolean value) {

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/server/AbstractSocketServerTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/server/AbstractSocketServerTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/server/AbstractSocketServerTest.java
index 9000698..0461eeb 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/server/AbstractSocketServerTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/server/AbstractSocketServerTest.java
@@ -78,7 +78,7 @@ public abstract class AbstractSocketServerTest {
     }
 
     protected Layout<String> createJsonLayout() {
-        return JsonLayout.createLayout(null, true, true, false, false, false, false, null, null, null);
+        return JsonLayout.createLayout(null, true, true, false, false, false, false, null, null, null, true);
     }
 
     protected abstract Layout<? extends Serializable> createLayout();
@@ -88,7 +88,7 @@ public abstract class AbstractSocketServerTest {
     }
 
     protected Layout<String> createXmlLayout() {
-        return XmlLayout.createLayout(true, true, false, false, null);
+        return XmlLayout.createLayout(true, true, false, false, null, true);
     }
 
     @After

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index a4fac9e..4937e63 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -24,6 +24,9 @@
   </properties>
   <body>
     <release version="2.7" date="2016-MM-DD" description="GA Release 2.7">
+      <action issue="LOG4J2-1512" dev="mikes" type="add">
+        Options to exclude stack trace from JSON, XML and YAML layouts.
+      </action>
       <action issue="LOG4J2-1448" dev="rpopma" type="fix" due-to="Keith Laban">
         Allow comma separated agents, host list to be passed to FlumeAppender.
       </action>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0e86947b/src/site/xdoc/manual/layouts.xml.vm
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/layouts.xml.vm b/src/site/xdoc/manual/layouts.xml.vm
index 8607604..04cc7fb 100644
--- a/src/site/xdoc/manual/layouts.xml.vm
+++ b/src/site/xdoc/manual/layouts.xml.vm
@@ -386,6 +386,11 @@ logger.debug("one={}, two={}, three={}", 1, 2, 3);
                 is an expensive operation and may impact performance. Use with caution.</p>
               </td>
             </tr>
+            <tr>
+              <td>includeStacktrace</td>
+              <td>boolean</td>
+              <td>If true, include full stacktrace of any logged #javadoc('java/lang', 'Throwable') (optional, default to true).</td>
+            </tr>
             <caption align="top">JSON Layout Parameters</caption>
           </table>
         </subsection>
@@ -1971,6 +1976,11 @@ at org.apache.logging.log4j.core.pattern.ExtendedThrowableTest.testException(Ext
                 is an expensive operation and may impact performance. Use with caution.</p>
               </td>
             </tr>
+            <tr>
+              <td>includeStacktrace</td>
+              <td>boolean</td>
+              <td>If true, include full stacktrace of any logged #javadoc('java/lang', 'Throwable') (optional, default to true).</td>
+            </tr>
             <caption align="top">XML Layout Parameters</caption>
           </table>
         </subsection>
@@ -2140,6 +2150,11 @@ source:
                 is an expensive operation and may impact performance. Use with caution.</p>
               </td>
             </tr>
+            <tr>
+              <td>includeStacktrace</td>
+              <td>boolean</td>
+              <td>If true, include full stacktrace of any logged #javadoc('java/lang', 'Throwable') (optional, default to true).</td>
+            </tr>
             <caption align="top">YAML Layout Parameters</caption>
           </table>
         </subsection>