Skip to content

Commit 79568db

Browse files
JongminChungvy
authored andcommitted
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 0881bc5 commit 79568db

File tree

4 files changed

+51
-13
lines changed

4 files changed

+51
-13
lines changed

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
@@ -69,6 +69,23 @@ public String toString() {
6969
}
7070
}
7171

72+
/**
73+
* Test exception whose {@link #toString()} is intentionally overridden to return a fixed value.
74+
*/
75+
private static final class ToStringOverridingException extends RuntimeException {
76+
77+
private static final ToStringOverridingException INSTANCE = new ToStringOverridingException();
78+
79+
private ToStringOverridingException() {
80+
super(EXCEPTION);
81+
}
82+
83+
@Override
84+
public String toString() {
85+
return "foo";
86+
}
87+
}
88+
7289
static Stream<SeparatorTestCase> separatorTestCases() {
7390
final String level = LEVEL.toString();
7491
return Stream.of(
@@ -204,6 +221,14 @@ void full_output_should_match_Throwable_printStackTrace(final String pattern) {
204221
assertThat(actualStackTrace).as("pattern=`%s`", effectivePattern).isEqualTo(expectedStackTrace);
205222
}
206223

224+
@Test
225+
void full_output_should_use_custom_toString() {
226+
final Throwable exception = ToStringOverridingException.INSTANCE;
227+
final String expectedStackTrace = renderStackTraceUsingJava(exception);
228+
final String actualStackTrace = convert(patternPrefix, exception);
229+
assertThat(actualStackTrace).isEqualTo(expectedStackTrace);
230+
}
231+
207232
// This test does not provide `separator` and `suffix` options, since the reference output will be obtained from
208233
// `Throwable#printStackTrace()`, which doesn't take these into account.
209234
@ParameterizedTest
@@ -242,10 +267,14 @@ private String limitLines(final String text, final int maxLineCount) {
242267
}
243268

244269
private String renderStackTraceUsingJava() {
270+
return renderStackTraceUsingJava(EXCEPTION);
271+
}
272+
273+
private String renderStackTraceUsingJava(final Throwable throwable) {
245274
final Charset charset = StandardCharsets.UTF_8;
246275
try (final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
247276
final PrintStream printStream = new PrintStream(outputStream, false, charset.name())) {
248-
EXCEPTION.printStackTrace(printStream);
277+
throwable.printStackTrace(printStream);
249278
printStream.flush();
250279
return new String(outputStream.toByteArray(), charset);
251280
} catch (final Exception error) {
@@ -438,9 +467,13 @@ private static String normalizeStackTrace(final String stackTrace, final String
438467
}
439468

440469
static String convert(final String pattern) {
470+
return convert(pattern, EXCEPTION);
471+
}
472+
473+
private static String convert(final String pattern, final Throwable throwable) {
441474
final List<PatternFormatter> patternFormatters = PATTERN_PARSER.parse(pattern, false, true, true);
442475
final LogEvent logEvent =
443-
Log4jLogEvent.newBuilder().setThrown(EXCEPTION).setLevel(LEVEL).build();
476+
Log4jLogEvent.newBuilder().setThrown(throwable).setLevel(LEVEL).build();
444477
final StringBuilder buffer = new StringBuilder();
445478
for (final PatternFormatter patternFormatter : patternFormatters) {
446479
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)