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-1010&LOG4J2-1447-injectable-contextdata&better-datastructure Commit: 0e86947b0593d69818ee564b2b35fc3a266378de Parents: c0cb21e Author: Mikael Ståldal <mik...@staldal.nu> Authored: Fri Aug 12 22:39:21 2016 +0200 Committer: Mikael Ståldal <mik...@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>