diff --git a/README.md b/README.md index 8dda6f8..692cc37 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,36 @@ Default max stack trace size is `300`. It is recommended that you do not exceed lead to higher log event ingest costs. Max stack trace size can be configured by environment variable (`NEW_RELIC_LOG_EXTENSION_MAX_STACK_SIZE=integer`) or system property (`-Dnewrelic.log_extension.max_stack_size=integer`). +### Include full exception stack trace +Only supported on logback + +You can configure the logging extension to include in `error.stack` the full stack trace just like the downstream library does. +This includes the caused by chain. + +As an example, this snippet: +``` +Exception inner2 = new IllegalAccessException("test caused by 2"); +Exception inner1 = new RuntimeException("test caused by 1", inner2); +LOGGER.error("failed for test!", new RuntimeException("test exception", inner1)); +``` +Will set the `error.stack` as +``` +java.lang.RuntimeException: test exception + at (regular stacktrace) + at ... +Caused by: java.lang.RuntimeException: test caused by 1 + ... 49 common frames omitted +Caused by: java.lang.IllegalAccessException: test caused by 2 + ... 49 common frames omitted +``` + +Default is `false` for retro-compatibility. + +This setting can be enabled via environment variable (`NEW_RELIC_LOG_EXTENSION_INCLUDE_FULL_ERROR_STACK=true`) or system variable (`-Dnewrelic.log_extension.include_full_error_stack=true`). + +Be aware that enabling this setting will use the downstream library's stacktrace generation, not taking in consideration +the value of [Exception Stack Trace Size](#exception-stack-trace-size). + ## Support Should you need assistance with New Relic products, you are in good hands with several diagnostic tools and support channels. diff --git a/core/src/main/java/com/newrelic/logging/core/LogExtensionConfig.java b/core/src/main/java/com/newrelic/logging/core/LogExtensionConfig.java index 2c60f93..3e61816 100644 --- a/core/src/main/java/com/newrelic/logging/core/LogExtensionConfig.java +++ b/core/src/main/java/com/newrelic/logging/core/LogExtensionConfig.java @@ -13,6 +13,9 @@ public class LogExtensionConfig { public static final String MAX_STACK_SIZE_SYS_PROP = CONFIG_PREFIX_SYS_PROP + "max_stack_size"; public static final String ADD_MDC_ENV_VAR = CONFIG_PREFIX_ENV_VAR + "ADD_MDC"; public static final String ADD_MDC_SYS_PROP = CONFIG_PREFIX_SYS_PROP + "add_mdc"; + + public static final String INCLUDE_FULL_ERROR_STACK_ENV = CONFIG_PREFIX_ENV_VAR + "INCLUDE_FULL_ERROR_STACK"; + public static final String INCLUDE_FULL_ERROR_SYS_PROP = CONFIG_PREFIX_SYS_PROP + "include_full_error_stack"; public static final boolean ADD_MDC_DEFAULT = false; /** @@ -35,6 +38,24 @@ public static int getMaxStackSize() { } } + /** + * Get a boolean representing if error stack should include the full stacktrace, including the "caused by" chain + *
Default, for retro-compatibility, is {@code false}. + * @return boolean representing include full error stack configuration + */ + public static boolean getIncludeFullErrorStacktrace(){ + String envVar = System.getenv(INCLUDE_FULL_ERROR_STACK_ENV); + String sysProp = System.getProperty(INCLUDE_FULL_ERROR_SYS_PROP); + + if (envVar != null){ + return Boolean.parseBoolean(envVar); + } else if (sysProp != null) { + return Boolean.parseBoolean(sysProp); + } else { + return false; + } + } + /** * Get a boolean indicating if MDC should be added to logs *
diff --git a/logback/README.md b/logback/README.md
index 5c7b8cd..6d4f1ee 100644
--- a/logback/README.md
+++ b/logback/README.md
@@ -11,7 +11,8 @@
There are some changes to your application to use the New Relic
Logback Extension. All steps are required.
-**Optional**: [Configuration Options](..%2FREADME.md#configuration-options) for setting max stack size or collecting MDC.
+**Optional**: [Configuration Options](..%2FREADME.md#configuration-options) for setting max stack size (or to include
+the full stack trace in `error.stack`) or collecting MDC.
### 1. Include the dependency in your project.
diff --git a/logback/src/main/java/com/newrelic/logging/logback/NewRelicEncoder.java b/logback/src/main/java/com/newrelic/logging/logback/NewRelicEncoder.java
index b2422b9..d293588 100644
--- a/logback/src/main/java/com/newrelic/logging/logback/NewRelicEncoder.java
+++ b/logback/src/main/java/com/newrelic/logging/logback/NewRelicEncoder.java
@@ -12,6 +12,7 @@
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
+import static com.newrelic.logging.core.LogExtensionConfig.getIncludeFullErrorStacktrace;
import static com.newrelic.logging.core.LogExtensionConfig.getMaxStackSize;
/**
@@ -49,7 +50,7 @@ public byte[] encode(ILoggingEvent event) {
@Override
public void start() {
super.start();
- layout = new NewRelicJsonLayout(maxStackSize);
+ layout = new NewRelicJsonLayout(maxStackSize, getIncludeFullErrorStacktrace());
layout.start();
}
diff --git a/logback/src/main/java/com/newrelic/logging/logback/NewRelicJsonLayout.java b/logback/src/main/java/com/newrelic/logging/logback/NewRelicJsonLayout.java
index 40ae3cf..286c9b6 100644
--- a/logback/src/main/java/com/newrelic/logging/logback/NewRelicJsonLayout.java
+++ b/logback/src/main/java/com/newrelic/logging/logback/NewRelicJsonLayout.java
@@ -8,6 +8,7 @@
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.StackTraceElementProxy;
+import ch.qos.logback.classic.spi.ThrowableProxyUtil;
import ch.qos.logback.core.LayoutBase;
import com.fasterxml.jackson.core.JsonGenerator;
import com.newrelic.logging.core.ElementName;
@@ -21,18 +22,21 @@
import java.util.Map;
import static com.newrelic.logging.core.LogExtensionConfig.CONTEXT_PREFIX;
+import static com.newrelic.logging.core.LogExtensionConfig.getIncludeFullErrorStacktrace;
import static com.newrelic.logging.core.LogExtensionConfig.getMaxStackSize;
import static com.newrelic.logging.logback.NewRelicAsyncAppender.NEW_RELIC_PREFIX;
public class NewRelicJsonLayout extends LayoutBase