Skip to content

Commit d46918c

Browse files
JongminChungvy
andauthored
Take Throwable#toString() into account while rendering stack traces in Pattern Layout (#4033)
Signed-off-by: Jongmin Chung <chungjm0711@gmail.com> Co-authored-by: Volkan Yazıcı <volkan@yazi.ci>
1 parent 8e7d897 commit d46918c

4 files changed

Lines changed: 51 additions & 13 deletions

File tree

log4j-core-test/src/test/java/org/apache/logging/log4j/core/EventParameterMemoryLeakTest.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,8 @@ void parameters_should_be_garbage_collected(final TestInfo testInfo) throws Thro
5959
assertThat(messages).hasSize(4);
6060
assertThat(messages.get(0)).isEqualTo("Message with parameter %s", parameter.value);
6161
assertThat(messages.get(1)).isEqualTo(parameter.value);
62-
assertThat(messages.get(2))
63-
.startsWith(String.format("test%n%s: %s", ObjectThrowable.class.getName(), parameter.value));
64-
assertThat(messages.get(3))
65-
.startsWith(
66-
String.format("test hello%n%s: %s", ObjectThrowable.class.getName(), parameter.value));
62+
assertThat(messages.get(2)).startsWith(String.format("test%n%s", new ObjectThrowable(parameter)));
63+
assertThat(messages.get(3)).startsWith(String.format("test hello%n%s", new ObjectThrowable(parameter)));
6764

6865
// Return the GC subject
6966
return parameter;

log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverterTest.java

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,23 @@ public String toString() {
7979
}
8080
}
8181

82+
/**
83+
* Test exception whose {@link #toString()} is intentionally overridden to return a fixed value.
84+
*/
85+
private static final class ToStringOverridingException extends RuntimeException {
86+
87+
private static final ToStringOverridingException INSTANCE = new ToStringOverridingException();
88+
89+
private ToStringOverridingException() {
90+
super(EXCEPTION);
91+
}
92+
93+
@Override
94+
public String toString() {
95+
return "foo";
96+
}
97+
}
98+
8299
static Stream<SeparatorTestCase> separatorTestCases() {
83100
final String level = LEVEL.toString();
84101
return Stream.of(
@@ -214,6 +231,14 @@ void full_output_should_match_Throwable_printStackTrace(final String pattern) {
214231
assertThat(actualStackTrace).as("pattern=`%s`", effectivePattern).isEqualTo(expectedStackTrace);
215232
}
216233

234+
@Test
235+
void full_output_should_use_custom_toString() {
236+
final Throwable exception = ToStringOverridingException.INSTANCE;
237+
final String expectedStackTrace = renderStackTraceUsingJava(exception);
238+
final String actualStackTrace = convert(patternPrefix, exception);
239+
assertThat(actualStackTrace).isEqualTo(expectedStackTrace);
240+
}
241+
217242
// This test does not provide `separator` and `suffix` options, since the reference output will be obtained from
218243
// `Throwable#printStackTrace()`, which doesn't take these into account.
219244
@ParameterizedTest
@@ -252,10 +277,14 @@ private String limitLines(final String text, final int maxLineCount) {
252277
}
253278

254279
private String renderStackTraceUsingJava() {
280+
return renderStackTraceUsingJava(EXCEPTION);
281+
}
282+
283+
private String renderStackTraceUsingJava(final Throwable throwable) {
255284
final Charset charset = StandardCharsets.UTF_8;
256285
try (final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
257286
final PrintStream printStream = new PrintStream(outputStream, false, charset.name())) {
258-
EXCEPTION.printStackTrace(printStream);
287+
throwable.printStackTrace(printStream);
259288
printStream.flush();
260289
return new String(outputStream.toByteArray(), charset);
261290
} catch (final Exception error) {
@@ -545,9 +574,13 @@ private static List<Exception> createExceptionsOfDifferentDepths() {
545574
}
546575

547576
static String convert(final String pattern) {
577+
return convert(pattern, EXCEPTION);
578+
}
579+
580+
private static String convert(final String pattern, final Throwable throwable) {
548581
final List<PatternFormatter> patternFormatters = PATTERN_PARSER.parse(pattern, false, true, true);
549582
final LogEvent logEvent =
550-
Log4jLogEvent.newBuilder().setThrown(EXCEPTION).setLevel(LEVEL).build();
583+
Log4jLogEvent.newBuilder().setThrown(throwable).setLevel(LEVEL).build();
551584
final StringBuilder buffer = new StringBuilder();
552585
for (final PatternFormatter patternFormatter : patternFormatters) {
553586
patternFormatter.format(logEvent, buffer);

log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowableStackTraceRenderer.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,7 @@ private void renderCause(
138138
}
139139

140140
static void renderThrowableMessage(final StringBuilder buffer, final Throwable throwable) {
141-
final String message = throwable.getLocalizedMessage();
142-
buffer.append(throwable.getClass().getName());
143-
if (message != null) {
144-
buffer.append(": ");
145-
buffer.append(message);
146-
}
141+
buffer.append(throwable);
147142
}
148143

149144
final void renderStackTraceElements(
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<entry xmlns="https://logging.apache.org/xml/ns"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="
5+
https://logging.apache.org/xml/ns
6+
https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
7+
type="changed">
8+
<issue id="3623" link="https://github.com/apache/logging-log4j2/issues/3623"/>
9+
<issue id="4033" link="https://github.com/apache/logging-log4j2/pull/4033"/>
10+
<description format="asciidoc">
11+
Take `Throwable#toString()` into account while rendering stack traces in Pattern Layout.
12+
</description>
13+
</entry>

0 commit comments

Comments
 (0)