You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by vy...@apache.org on 2022/08/17 09:30:57 UTC
[logging-log4j2] 03/03: LOG4J2-3556 Rearrange stringified stack trace tests.
This is an automated email from the ASF dual-hosted git repository.
vy pushed a commit to branch LOG4J2-3556
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 100c6043d4476e8817e387e990d9ff457f850370
Author: Volkan Yazıcı <vo...@yazi.ci>
AuthorDate: Wed Aug 17 11:26:55 2022 +0200
LOG4J2-3556 Rearrange stringified stack trace tests.
---
.../template/json/JsonTemplateLayoutTest.java | 276 +--------------
.../resolver/StackTraceStringResolverTest.java | 374 ++++++++++++++++-----
2 files changed, 311 insertions(+), 339 deletions(-)
diff --git a/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutTest.java b/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutTest.java
index 2cd2518872..f0b8b86d3e 100644
--- a/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutTest.java
+++ b/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutTest.java
@@ -34,31 +34,14 @@ import org.apache.logging.log4j.core.lookup.MainMapLookup;
import org.apache.logging.log4j.core.net.Severity;
import org.apache.logging.log4j.core.time.MutableInstant;
import org.apache.logging.log4j.layout.template.json.JsonTemplateLayout.EventTemplateAdditionalField;
-import org.apache.logging.log4j.layout.template.json.resolver.EventResolver;
-import org.apache.logging.log4j.layout.template.json.resolver.EventResolverContext;
-import org.apache.logging.log4j.layout.template.json.resolver.EventResolverFactory;
-import org.apache.logging.log4j.layout.template.json.resolver.TemplateResolver;
-import org.apache.logging.log4j.layout.template.json.resolver.TemplateResolverConfig;
-import org.apache.logging.log4j.layout.template.json.resolver.TemplateResolverFactory;
+import org.apache.logging.log4j.layout.template.json.resolver.*;
import org.apache.logging.log4j.layout.template.json.util.JsonWriter;
-import org.apache.logging.log4j.message.Message;
-import org.apache.logging.log4j.message.MessageFactory;
-import org.apache.logging.log4j.message.ObjectMessage;
-import org.apache.logging.log4j.message.ParameterizedMessageFactory;
-import org.apache.logging.log4j.message.ReusableMessageFactory;
-import org.apache.logging.log4j.message.SimpleMessage;
-import org.apache.logging.log4j.message.StringMapMessage;
+import org.apache.logging.log4j.message.*;
import org.apache.logging.log4j.test.AvailablePortFinder;
import org.apache.logging.log4j.util.Strings;
-import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
-import java.io.ByteArrayOutputStream;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
+import java.io.*;
import java.math.BigDecimal;
import java.net.ServerSocket;
import java.net.Socket;
@@ -67,11 +50,7 @@ import java.nio.charset.Charset;
import java.time.Instant;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
@@ -81,6 +60,7 @@ import java.util.stream.IntStream;
import static org.apache.logging.log4j.layout.template.json.TestHelpers.*;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
@SuppressWarnings("DoubleBraceInitialization")
class JsonTemplateLayoutTest {
@@ -770,85 +750,17 @@ class JsonTemplateLayoutTest {
}
- private static final class NonAsciiUtf8MethodNameContainingException extends RuntimeException {
-
- public static final long serialVersionUID = 0;
-
- private static final String NON_ASCII_UTF8_TEXT = "அஆஇฬ๘";
-
- private static final NonAsciiUtf8MethodNameContainingException INSTANCE =
- createInstance();
-
- private static NonAsciiUtf8MethodNameContainingException createInstance() {
- try {
- throwException_அஆஇฬ๘();
- throw new IllegalStateException("should not have reached here");
- } catch (final NonAsciiUtf8MethodNameContainingException exception) {
- return exception;
- }
- }
-
- @SuppressWarnings("NonAsciiCharacters")
- private static void throwException_அஆஇฬ๘() {
- throw new NonAsciiUtf8MethodNameContainingException(
- "exception with non-ASCII UTF-8 method name");
- }
-
- private NonAsciiUtf8MethodNameContainingException(final String message) {
- super(message);
- }
-
- }
-
- @Test
- void test_exception_with_nonAscii_utf8_method_name() {
-
- // Create the log event.
- final SimpleMessage message = new SimpleMessage("Hello, World!");
- final RuntimeException exception = NonAsciiUtf8MethodNameContainingException.INSTANCE;
- final LogEvent logEvent = Log4jLogEvent
- .newBuilder()
- .setLoggerName(LOGGER_NAME)
- .setLevel(Level.ERROR)
- .setMessage(message)
- .setThrown(exception)
- .build();
-
- // Create the event template.
- final String eventTemplate = writeJson(asMap(
- "ex_stacktrace", asMap(
- "$resolver", "exception",
- "field", "stackTrace",
- "stringified", true)));
-
- // Create the layout.
- final JsonTemplateLayout layout = JsonTemplateLayout
- .newBuilder()
- .setConfiguration(CONFIGURATION)
- .setStackTraceEnabled(true)
- .setEventTemplate(eventTemplate)
- .build();
-
- // Check the serialized event.
- usingSerializedLogEventAccessor(layout, logEvent, accessor ->
- assertThat(accessor.getString("ex_stacktrace"))
- .contains(NonAsciiUtf8MethodNameContainingException.NON_ASCII_UTF8_TEXT));
-
- }
-
@Test
void test_event_template_additional_fields() {
// Create the log event.
final SimpleMessage message = new SimpleMessage("Hello, World!");
- final RuntimeException exception = NonAsciiUtf8MethodNameContainingException.INSTANCE;
final Level level = Level.ERROR;
final LogEvent logEvent = Log4jLogEvent
.newBuilder()
.setLoggerName(LOGGER_NAME)
.setLevel(level)
.setMessage(message)
- .setThrown(exception)
.build();
// Create the event template.
@@ -971,8 +883,7 @@ class JsonTemplateLayoutTest {
// Verify the test case.
usingSerializedLogEventAccessor(layout, logEvent, accessor ->
testCase.forEach((key, expectedValue) ->
- Assertions
- .assertThat(accessor.getObject(key))
+ assertThat(accessor.getObject(key))
.describedAs("key=%s", key)
.isEqualTo(expectedValue)));
@@ -1139,161 +1050,6 @@ class JsonTemplateLayoutTest {
}
- @Test
- void test_stringified_exception_resolver_with_maxStringLength() {
-
- // Create the event template.
- final String eventTemplate = writeJson(asMap(
- "stackTrace", asMap(
- "$resolver", "exception",
- "field", "stackTrace",
- "stringified", true)));
-
- // Create the layout.
- final int maxStringLength = eventTemplate.length();
- final JsonTemplateLayout layout = JsonTemplateLayout
- .newBuilder()
- .setConfiguration(CONFIGURATION)
- .setEventTemplate(eventTemplate)
- .setMaxStringLength(maxStringLength)
- .setStackTraceEnabled(true)
- .build();
-
- // Create the log event.
- final SimpleMessage message = new SimpleMessage("foo");
- final LogEvent logEvent = Log4jLogEvent
- .newBuilder()
- .setLoggerName(LOGGER_NAME)
- .setMessage(message)
- .setThrown(NonAsciiUtf8MethodNameContainingException.INSTANCE)
- .build();
-
- // Check the serialized event.
- usingSerializedLogEventAccessor(layout, logEvent, accessor -> {
- final int expectedLength = maxStringLength +
- JsonTemplateLayoutDefaults.getTruncatedStringSuffix().length();
- assertThat(accessor.getString("stackTrace").length()).isEqualTo(expectedLength);
- });
-
- }
-
- @Test
- void test_stack_trace_truncation() {
-
- // Create the exception to be logged.
- final Exception childError =
- new Exception("unique child exception message");
- final Exception parentError =
- new Exception("unique parent exception message", childError);
-
- // Create the event template.
- final String truncationSuffix = "~";
- final String eventTemplate = writeJson(asMap(
- // Raw exception.
- "ex", asMap(
- "$resolver", "exception",
- "field", "stackTrace",
- "stackTrace", asMap(
- "stringified", true)),
- // Exception matcher using strings.
- "stringMatchedEx", asMap(
- "$resolver", "exception",
- "field", "stackTrace",
- "stackTrace", asMap(
- "stringified", asMap(
- "truncation", asMap(
- "suffix", truncationSuffix,
- "pointMatcherStrings", Arrays.asList(
- "this string shouldn't match with anything",
- parentError.getMessage()))))),
- // Exception matcher using regexes.
- "regexMatchedEx", asMap(
- "$resolver", "exception",
- "field", "stackTrace",
- "stackTrace", asMap(
- "stringified", asMap(
- "truncation", asMap(
- "suffix", truncationSuffix,
- "pointMatcherRegexes", Arrays.asList(
- "this string shouldn't match with anything",
- parentError
- .getMessage()
- .replace("unique", "[xu]n.que")))))),
- // Raw exception root cause.
- "rootEx", asMap(
- "$resolver", "exceptionRootCause",
- "field", "stackTrace",
- "stackTrace", asMap(
- "stringified", true)),
- // Exception root cause matcher using strings.
- "stringMatchedRootEx", asMap(
- "$resolver", "exceptionRootCause",
- "field", "stackTrace",
- "stackTrace", asMap(
- "stringified", asMap(
- "truncation", asMap(
- "suffix", truncationSuffix,
- "pointMatcherStrings", Arrays.asList(
- "this string shouldn't match with anything",
- childError.getMessage()))))),
- // Exception root cause matcher using regexes.
- "regexMatchedRootEx", asMap(
- "$resolver", "exceptionRootCause",
- "field", "stackTrace",
- "stackTrace", asMap(
- "stringified", asMap(
- "truncation", asMap(
- "suffix", truncationSuffix,
- "pointMatcherRegexes", Arrays.asList(
- "this string shouldn't match with anything",
- childError
- .getMessage()
- .replace("unique", "[xu]n.que"))))))));
-
- // Create the layout.
- final JsonTemplateLayout layout = JsonTemplateLayout
- .newBuilder()
- .setConfiguration(CONFIGURATION)
- .setEventTemplate(eventTemplate)
- .setStackTraceEnabled(true)
- .build();
-
- // Create the log event.
- final LogEvent logEvent = Log4jLogEvent
- .newBuilder()
- .setLoggerName(LOGGER_NAME)
- .setThrown(parentError)
- .build();
-
- // Check the serialized event.
- final String expectedMatchedExEnd =
- parentError.getMessage() + truncationSuffix;
- final String expectedMatchedRootExEnd =
- childError.getMessage() + truncationSuffix;
- usingSerializedLogEventAccessor(layout, logEvent, accessor -> {
-
- // Check the serialized exception.
- assertThat(accessor.getString("ex"))
- .doesNotEndWith(expectedMatchedExEnd)
- .doesNotEndWith(expectedMatchedRootExEnd);
- assertThat(accessor.getString("stringMatchedEx"))
- .endsWith(expectedMatchedExEnd);
- assertThat(accessor.getString("regexMatchedEx"))
- .endsWith(expectedMatchedExEnd);
-
- // Check the serialized exception root cause.
- assertThat(accessor.getString("rootEx"))
- .doesNotEndWith(expectedMatchedExEnd)
- .doesNotEndWith(expectedMatchedRootExEnd);
- assertThat(accessor.getString("stringMatchedRootEx"))
- .endsWith(expectedMatchedRootExEnd);
- assertThat(accessor.getString("regexMatchedRootEx"))
- .endsWith(expectedMatchedRootExEnd);
-
- });
-
- }
-
@Test
void test_inline_stack_trace_element_template() {
@@ -1326,9 +1082,9 @@ class JsonTemplateLayoutTest {
// Check the serialized log event.
final String expectedClassName = JsonTemplateLayoutTest.class.getCanonicalName();
- usingSerializedLogEventAccessor(layout, logEvent, accessor -> Assertions
- .assertThat(accessor.getList("stackTrace", String.class))
- .contains(expectedClassName));
+ usingSerializedLogEventAccessor(layout, logEvent, accessor ->
+ assertThat(accessor.getList("stackTrace", String.class))
+ .contains(expectedClassName));
}
@@ -1355,9 +1111,9 @@ class JsonTemplateLayoutTest {
.build();
// Check the serialized log event.
- usingSerializedLogEventAccessor(layout, logEvent, accessor -> Assertions
- .assertThat(accessor.getString("customField"))
- .matches("CustomValue-[0-9]+"));
+ usingSerializedLogEventAccessor(layout, logEvent, accessor ->
+ assertThat(accessor.getString("customField"))
+ .matches("CustomValue-[0-9]+"));
}
@@ -1422,7 +1178,6 @@ class JsonTemplateLayoutTest {
.newBuilder()
.setLoggerName(LOGGER_NAME)
.setMessage(message)
- .setThrown(NonAsciiUtf8MethodNameContainingException.INSTANCE)
.build();
// Check the serialized event.
@@ -1814,9 +1569,7 @@ class JsonTemplateLayoutTest {
final String expectedSerializedLogEventJson =
"{}" + JsonTemplateLayoutDefaults.getEventDelimiter();
final String actualSerializedLogEventJson = layout.toSerializable(logEvent);
- Assertions
- .assertThat(actualSerializedLogEventJson)
- .isEqualTo(expectedSerializedLogEventJson);
+ assertThat(actualSerializedLogEventJson).isEqualTo(expectedSerializedLogEventJson);
}
@@ -1847,8 +1600,7 @@ class JsonTemplateLayoutTest {
.build();
// Check the serialized event.
- Assertions
- .assertThatThrownBy(() -> layout.toSerializable(logEvent))
+ assertThatThrownBy(() -> layout.toSerializable(logEvent))
.isInstanceOf(StackOverflowError.class);
}
diff --git a/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/StackTraceStringResolverTest.java b/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/StackTraceStringResolverTest.java
index c1aa485e21..6c93b1902f 100644
--- a/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/StackTraceStringResolverTest.java
+++ b/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/StackTraceStringResolverTest.java
@@ -19,8 +19,8 @@ package org.apache.logging.log4j.layout.template.json.resolver;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
import org.apache.logging.log4j.layout.template.json.JsonTemplateLayout;
+import org.apache.logging.log4j.layout.template.json.JsonTemplateLayoutDefaults;
import org.assertj.core.api.AbstractStringAssert;
-import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@@ -28,10 +28,12 @@ import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.math.BigDecimal;
import java.net.ServerSocket;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
+import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -47,7 +49,7 @@ class StackTraceStringResolverTest {
// Below we create arbitrary exceptions containing stack entries from non-Log4j packages.
// Non-Log4j package origin is needed to avoid the truncation (e.g., `... 58 more`) done by `Throwable#printStackTrace()`.
- private static final String EXCEPTION_REGEX_FLAGS = "(?m)(?s)"; // MULTILINE | DOTALL
+ private static final String EXCEPTION_REGEX_FLAGS = "(?s)"; // DOTALL
private static final String TRUNCATION_SUFFIX = "<truncated>";
@@ -110,9 +112,7 @@ class StackTraceStringResolverTest {
final Throwable error = exception1();
final String stackTrace = stackTrace(error);
final String regex = exception1Regex(false);
- Assertions
- .assertThat(stackTrace)
- .matches(EXCEPTION_REGEX_FLAGS + regex);
+ assertThat(stackTrace).matches(EXCEPTION_REGEX_FLAGS + regex);
}
@Test
@@ -120,9 +120,7 @@ class StackTraceStringResolverTest {
final Throwable error = exception2();
final String stackTrace = stackTrace(error);
final String regex = exception2Regex(false);
- Assertions
- .assertThat(stackTrace)
- .matches(EXCEPTION_REGEX_FLAGS + regex);
+ assertThat(stackTrace).matches(EXCEPTION_REGEX_FLAGS + regex);
}
@Test
@@ -130,9 +128,7 @@ class StackTraceStringResolverTest {
final Throwable error = exception3();
final String stackTrace = stackTrace(error);
final String regex = exception3Regex(false);
- Assertions
- .assertThat(stackTrace)
- .matches(EXCEPTION_REGEX_FLAGS + regex);
+ assertThat(stackTrace).matches(EXCEPTION_REGEX_FLAGS + regex);
}
private static String stackTrace(final Throwable throwable) {
@@ -309,6 +305,35 @@ class StackTraceStringResolverTest {
final Throwable exception,
final String regex);
+ private static void assertSerializedException(
+ final Map<String, ?> exceptionResolverTemplate,
+ final Throwable exception,
+ final Consumer<AbstractStringAssert<?>> serializedExceptionAsserter) {
+
+ // Create the event template.
+ final String eventTemplate = writeJson(asMap("output", exceptionResolverTemplate));
+
+ // Create the layout.
+ final JsonTemplateLayout layout = JsonTemplateLayout
+ .newBuilder()
+ .setConfiguration(CONFIGURATION)
+ .setEventTemplate(eventTemplate)
+ .build();
+
+ // Create the log event.
+ final LogEvent logEvent = Log4jLogEvent
+ .newBuilder()
+ .setThrown(exception)
+ .build();
+
+ // Check the serialized event.
+ usingSerializedLogEventAccessor(layout, logEvent, accessor -> {
+ AbstractStringAssert<?> serializedExceptionAssert = assertThat(accessor.getString("output"));
+ serializedExceptionAsserter.accept(serializedExceptionAssert);
+ });
+
+ }
+
}
////////////////////////////////////////////////////////////////////////////
@@ -327,23 +352,59 @@ class StackTraceStringResolverTest {
assertSerializedExceptionWithoutTruncation(exception, regex);
}
- }
+ private void assertSerializedExceptionWithoutTruncation(
+ final Throwable exception,
+ final String regex) {
- private static void assertSerializedExceptionWithoutTruncation(
- final Throwable exception,
- final String regex) {
+ // Create the event template.
+ final Map<String, ?> exceptionResolverTemplate = asMap(
+ "$resolver", "exception",
+ "field", "stackTrace",
+ "stackTrace", asMap("stringified", true));
- // Create the event template.
- final Map<String, ?> exceptionResolverTemplate = asMap(
- "$resolver", "exception",
- "field", "stackTrace",
- "stackTrace", asMap("stringified", true));
+ // Check the serialized event.
+ AbstractTestCases.assertSerializedException(
+ exceptionResolverTemplate,
+ exception,
+ serializedExceptionAssert -> serializedExceptionAssert.matches(regex));
- // Check the serialized event.
- assertSerializedException(
- exceptionResolverTemplate,
- exception,
- serializedExceptionAssert -> serializedExceptionAssert.matches(regex));
+ }
+
+ @Test
+ void JsonWriter_maxStringLength_should_work() {
+
+ // Create the event template.
+ final String eventTemplate = writeJson(asMap(
+ "ex", asMap(
+ "$resolver", "exception",
+ "field", "stackTrace",
+ "stringified", true)));
+
+ // Create the layout.
+ final int maxStringLength = eventTemplate.length();
+ final JsonTemplateLayout layout = JsonTemplateLayout
+ .newBuilder()
+ .setConfiguration(CONFIGURATION)
+ .setEventTemplate(eventTemplate)
+ .setMaxStringLength(maxStringLength)
+ .setStackTraceEnabled(true)
+ .build();
+
+ // Create the log event.
+ Throwable exception = exception1();
+ final LogEvent logEvent = Log4jLogEvent
+ .newBuilder()
+ .setThrown(exception)
+ .build();
+
+ // Check the serialized event.
+ usingSerializedLogEventAccessor(layout, logEvent, accessor -> {
+ final int expectedLength = maxStringLength +
+ JsonTemplateLayoutDefaults.getTruncatedStringSuffix().length();
+ assertThat(accessor.getString("ex").length()).isEqualTo(expectedLength);
+ });
+
+ }
}
@@ -352,9 +413,9 @@ class StackTraceStringResolverTest {
////////////////////////////////////////////////////////////////////////////
@Nested
- class WithStringTruncation extends AbstractTestCases {
+ class WithTruncation extends AbstractTestCases {
- WithStringTruncation() {
+ WithTruncation() {
super(true);
}
@@ -362,75 +423,234 @@ class StackTraceStringResolverTest {
void assertSerializedException(final Throwable exception, final String regex) {
assertSerializedExceptionWithStringTruncation(exception, regex);
}
-
- }
- private static void assertSerializedExceptionWithStringTruncation(
- final Throwable exception,
- final String regex) {
+ private void assertSerializedExceptionWithStringTruncation(
+ final Throwable exception,
+ final String regex) {
+
+ // Create the event template.
+ final List<String> pointMatcherStrings = pointMatcherStrings();
+ final Map<String, ?> exceptionResolverTemplate = asMap(
+ "$resolver", "exception",
+ "field", "stackTrace",
+ "stackTrace", asMap("stringified", asMap(
+ "truncation", asMap(
+ "suffix", TRUNCATION_SUFFIX,
+ "pointMatcherStrings", pointMatcherStrings))));
+
+ // Check the serialized event.
+ AbstractTestCases.assertSerializedException(
+ exceptionResolverTemplate,
+ exception,
+ serializedExceptionAssert -> serializedExceptionAssert.matches(regex));
- // Create the event template.
- final List<String> pointMatcherStrings = pointMatcherStrings();
- final Map<String, ?> exceptionResolverTemplate = asMap(
- "$resolver", "exception",
- "field", "stackTrace",
- "stackTrace", asMap("stringified", asMap(
- "truncation", asMap(
- "suffix", TRUNCATION_SUFFIX,
- "pointMatcherStrings", pointMatcherStrings))));
+ }
- // Check the serialized event.
- assertSerializedException(
- exceptionResolverTemplate,
- exception,
- serializedExceptionAssert -> serializedExceptionAssert.matches(regex));
+ private List<String> pointMatcherStrings() {
+ final Throwable exception1 = exception1();
+ final Throwable exception2 = exception2();
+ final Throwable exception3 = exception3();
+ return Stream
+ .of(exception1, exception2, exception3)
+ .map(this::pointMatcherString)
+ .collect(Collectors.toList());
+ }
- }
+ @Test
+ void point_matchers_should_work() {
+
+ // Create the exception to be logged.
+ final Throwable parentError = exception1();
+ final Throwable childError = exception3();
+ parentError.initCause(childError);
+
+ // Create the event template.
+ final String eventTemplate = writeJson(asMap(
+
+ // Raw exception
+ "ex", asMap(
+ "$resolver", "exception",
+ "field", "stackTrace",
+ "stackTrace", asMap(
+ "stringified", true)),
+
+ // Exception matcher using strings
+ "stringMatchedEx", asMap(
+ "$resolver", "exception",
+ "field", "stackTrace",
+ "stackTrace", asMap(
+ "stringified", asMap(
+ "truncation", asMap(
+ "suffix", TRUNCATION_SUFFIX,
+ "pointMatcherStrings", Arrays.asList(
+ "this string shouldn't match with anything",
+ pointMatcherString(parentError)))))),
+
+ // Exception matcher using regexes
+ "regexMatchedEx", asMap(
+ "$resolver", "exception",
+ "field", "stackTrace",
+ "stackTrace", asMap(
+ "stringified", asMap(
+ "truncation", asMap(
+ "suffix", TRUNCATION_SUFFIX,
+ "pointMatcherRegexes", Arrays.asList(
+ "this string shouldn't match with anything",
+ pointMatcherRegex(parentError)))))),
+
+ // Raw exception root cause
+ "rootEx", asMap(
+ "$resolver", "exceptionRootCause",
+ "field", "stackTrace",
+ "stackTrace", asMap(
+ "stringified", true)),
+
+ // Exception root cause matcher using strings
+ "stringMatchedRootEx", asMap(
+ "$resolver", "exceptionRootCause",
+ "field", "stackTrace",
+ "stackTrace", asMap(
+ "stringified", asMap(
+ "truncation", asMap(
+ "suffix", TRUNCATION_SUFFIX,
+ "pointMatcherStrings", Arrays.asList(
+ "this string shouldn't match with anything",
+ pointMatcherString(childError)))))),
+
+ // Exception root cause matcher using regexes
+ "regexMatchedRootEx", asMap(
+ "$resolver", "exceptionRootCause",
+ "field", "stackTrace",
+ "stackTrace", asMap(
+ "stringified", asMap(
+ "truncation", asMap(
+ "suffix", TRUNCATION_SUFFIX,
+ "pointMatcherRegexes", Arrays.asList(
+ "this string shouldn't match with anything",
+ pointMatcherRegex(childError))))))));
+
+ // Create the layout.
+ final JsonTemplateLayout layout = JsonTemplateLayout
+ .newBuilder()
+ .setConfiguration(CONFIGURATION)
+ .setEventTemplate(eventTemplate)
+ .build();
+
+ // Create the log event.
+ final LogEvent logEvent = Log4jLogEvent
+ .newBuilder()
+ .setThrown(parentError)
+ .build();
+
+ // Check the serialized event.
+ usingSerializedLogEventAccessor(layout, logEvent, accessor -> {
+
+ // Check the raw parent exception.
+ final String exPattern = EXCEPTION_REGEX_FLAGS +
+ exception1Regex(false) +
+ "\nCaused by: " + exception3Regex(false);
+ assertThat(accessor.getString("ex")).matches(exPattern);
+
+ // Check the matcher usage on parent exception.
+ final String matchedExPattern = EXCEPTION_REGEX_FLAGS +
+ exception1Regex(true) +
+ "\nCaused by: " + exception3Regex(false);
+ assertThat(accessor.getString("stringMatchedEx")).matches(matchedExPattern);
+ assertThat(accessor.getString("regexMatchedEx")).matches(matchedExPattern);
+
+ // Check the raw child exception.
+ final String rootExPattern = EXCEPTION_REGEX_FLAGS +
+ exception3Regex(false);
+ assertThat(accessor.getString("rootEx")).matches(rootExPattern);
+
+ // Check the matcher usage on child exception.
+ final String matchedRootExPattern = EXCEPTION_REGEX_FLAGS +
+ exception3Regex(true);
+ assertThat(accessor.getString("stringMatchedRootEx")).matches(matchedRootExPattern);
+ assertThat(accessor.getString("regexMatchedRootEx")).matches(matchedRootExPattern);
+
+ });
+
+ }
+
+ private String pointMatcherString(Throwable exception) {
+ final StackTraceElement stackTraceElement = exception.getStackTrace()[0];
+ final String className = stackTraceElement.getClassName();
+ return "at " + className;
+ }
+
+ private String pointMatcherRegex(Throwable exception) {
+ String string = pointMatcherString(exception);
+ return matchingRegex(string);
+ }
- private static List<String> pointMatcherStrings() {
- final Throwable exception1 = exception1();
- final Throwable exception2 = exception2();
- final Throwable exception3 = exception3();
- return Stream
- .of(exception1, exception2, exception3)
- .map(exception -> {
- final StackTraceElement stackTraceElement = exception.getStackTrace()[0];
- final String className = stackTraceElement.getClassName();
- return "at " + className;
- })
- .collect(Collectors.toList());
+ /**
+ * @return a regex matching the given input
+ */
+ private String matchingRegex(String string) {
+ return "[" + string.charAt(0) + "]" + Pattern.quote(string.substring(1));
+ }
+
}
- ////////////////////////////////////////////////////////////////////////////
- // utilities ///////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
+ @Test
+ void nonAscii_utf8_method_name_should_get_serialized() {
- private static void assertSerializedException(
- final Map<String, ?> exceptionResolverTemplate,
- final Throwable exception,
- final Consumer<AbstractStringAssert<?>> serializedExceptionAsserter) {
+ // Create the log event.
+ final LogEvent logEvent = Log4jLogEvent
+ .newBuilder()
+ .setThrown(NonAsciiUtf8MethodNameContainingException.INSTANCE)
+ .build();
// Create the event template.
- final String eventTemplate = writeJson(asMap("output", exceptionResolverTemplate));
+ final String eventTemplate = writeJson(asMap(
+ "ex_stacktrace", asMap(
+ "$resolver", "exception",
+ "field", "stackTrace",
+ "stringified", true)));
// Create the layout.
final JsonTemplateLayout layout = JsonTemplateLayout
.newBuilder()
.setConfiguration(CONFIGURATION)
+ .setStackTraceEnabled(true)
.setEventTemplate(eventTemplate)
.build();
- // Create the log event.
- final LogEvent logEvent = Log4jLogEvent
- .newBuilder()
- .setThrown(exception)
- .build();
-
// Check the serialized event.
- usingSerializedLogEventAccessor(layout, logEvent, accessor -> {
- AbstractStringAssert<?> serializedExceptionAssert = assertThat(accessor.getString("output"));
- serializedExceptionAsserter.accept(serializedExceptionAssert);
- });
+ usingSerializedLogEventAccessor(layout, logEvent, accessor ->
+ assertThat(accessor.getString("ex_stacktrace"))
+ .contains(NonAsciiUtf8MethodNameContainingException.NON_ASCII_UTF8_TEXT));
+
+ }
+
+ private static final class NonAsciiUtf8MethodNameContainingException extends RuntimeException {
+
+ public static final long serialVersionUID = 0;
+
+ private static final String NON_ASCII_UTF8_TEXT = "அஆஇฬ๘";
+
+ private static final NonAsciiUtf8MethodNameContainingException INSTANCE =
+ createInstance();
+
+ private static NonAsciiUtf8MethodNameContainingException createInstance() {
+ try {
+ throwException_அஆஇฬ๘();
+ throw new IllegalStateException("should not have reached here");
+ } catch (final NonAsciiUtf8MethodNameContainingException exception) {
+ return exception;
+ }
+ }
+
+ @SuppressWarnings("NonAsciiCharacters")
+ private static void throwException_அஆஇฬ๘() {
+ throw new NonAsciiUtf8MethodNameContainingException(
+ "exception with non-ASCII UTF-8 method name");
+ }
+
+ private NonAsciiUtf8MethodNameContainingException(final String message) {
+ super(message);
+ }
}