Skip to content

Commit c5e28c9

Browse files
committed
Upgrade to Log4j2 2.25.2
Closes gh-46334
2 parents 5cec09d + c4cace3 commit c5e28c9

18 files changed

+98
-99
lines changed

config/checkstyle/checkstyle-suppressions.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,7 @@
7979
<suppress files="EntityManagerFactoryBuilder\.java" checks="NoWhitespaceBefore" message="'...' is preceded with whitespace"/>
8080
<suppress files="DockerApi\.java" checks="NoWhitespaceBefore" message="'...' is preceded with whitespace"/>
8181
<suppress files="InvocationContext\.java" checks="NoWhitespaceBefore" message="'...' is preceded with whitespace"/>
82+
<!-- https://github.com/apache/logging-log4j2/issues/2769#issuecomment-3049020222 -->
83+
<suppress files="SpringProfileArbiter\.java" checks="SpringMethodVisibility"/>
84+
<suppress files="StructuredLogLayout\.java" checks="SpringMethodVisibility"/>
8285
</suppressions>

core/spring-boot/build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,12 @@ tasks.named("checkFormatMain") {
8787
source(fileTree("src/main/javaTemplates"))
8888
}
8989

90+
tasks.named("compileJava") {
91+
// Provide the project coordinates to the `GraalVmProcessor`:
92+
options.compilerArgs << '-Alog4j.graalvm.groupId=org.springframework.boot'
93+
options.compilerArgs << '-Alog4j.graalvm.artifactId=spring-boot-log4j'
94+
}
95+
9096
plugins.withType(EclipsePlugin) {
9197
eclipse {
9298
synchronizationTasks syncJavaTemplates

core/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/ElasticCommonSchemaStructuredLogFormatter.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import org.apache.logging.log4j.Level;
2323
import org.apache.logging.log4j.Marker;
2424
import org.apache.logging.log4j.core.LogEvent;
25-
import org.apache.logging.log4j.core.impl.ThrowableProxy;
2625
import org.apache.logging.log4j.core.time.Instant;
2726
import org.apache.logging.log4j.util.ReadOnlyStringMap;
2827
import org.jspecify.annotations.Nullable;
@@ -70,13 +69,13 @@ private static void jsonMembers(Environment environment, @Nullable StackTracePri
7069
members.add("message", LogEvent::getMessage).as(StructuredMessage::get);
7170
members.from(LogEvent::getContextData)
7271
.usingPairs(contextPairs.nested(ElasticCommonSchemaStructuredLogFormatter::addContextDataPairs));
73-
members.from(LogEvent::getThrownProxy).whenNotNull().usingMembers((thrownProxyMembers) -> {
74-
thrownProxyMembers.add("error").usingMembers((error) -> {
75-
error.add("type", ThrowableProxy::getThrowable).whenNotNull().as(ObjectUtils::nullSafeClassName);
76-
error.add("message", ThrowableProxy::getMessage);
72+
members.from(LogEvent::getThrown)
73+
.whenNotNull()
74+
.usingMembers((thrownMembers) -> thrownMembers.add("error").usingMembers((error) -> {
75+
error.add("type", ObjectUtils::nullSafeClassName);
76+
error.add("message", Throwable::getMessage);
7777
error.add("stack_trace", extractor::stackTrace);
78-
});
79-
});
78+
}));
8079
members.add("tags", LogEvent::getMarker)
8180
.whenNotNull()
8281
.as(ElasticCommonSchemaStructuredLogFormatter::getMarkers)

core/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/ExtendedWhitespaceThrowablePatternConverter.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.apache.logging.log4j.core.config.plugins.Plugin;
2222
import org.apache.logging.log4j.core.pattern.ConverterKeys;
2323
import org.apache.logging.log4j.core.pattern.ExtendedThrowablePatternConverter;
24+
import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
2425
import org.apache.logging.log4j.core.pattern.PatternConverter;
2526
import org.apache.logging.log4j.core.pattern.ThrowablePatternConverter;
2627
import org.jspecify.annotations.Nullable;
@@ -35,24 +36,32 @@
3536
*/
3637
@Plugin(name = "ExtendedWhitespaceThrowablePatternConverter", category = PatternConverter.CATEGORY)
3738
@ConverterKeys({ "xwEx", "xwThrowable", "xwException" })
38-
public final class ExtendedWhitespaceThrowablePatternConverter extends ThrowablePatternConverter {
39+
public final class ExtendedWhitespaceThrowablePatternConverter extends LogEventPatternConverter {
3940

4041
private final ExtendedThrowablePatternConverter delegate;
4142

42-
private ExtendedWhitespaceThrowablePatternConverter(Configuration configuration, String @Nullable [] options) {
43-
super("WhitespaceExtendedThrowable", "throwable", options, configuration);
43+
private final String separator;
44+
45+
private ExtendedWhitespaceThrowablePatternConverter(Configuration configuration, @Nullable String[] options) {
46+
super("WhitespaceExtendedThrowable", "throwable");
4447
this.delegate = ExtendedThrowablePatternConverter.newInstance(configuration, options);
48+
this.separator = this.delegate.getOptions().getSeparator();
4549
}
4650

4751
@Override
4852
public void format(LogEvent event, StringBuilder buffer) {
4953
if (event.getThrown() != null) {
50-
buffer.append(this.options.getSeparator());
54+
buffer.append(this.separator);
5155
this.delegate.format(event, buffer);
52-
buffer.append(this.options.getSeparator());
56+
buffer.append(this.separator);
5357
}
5458
}
5559

60+
@Override
61+
public boolean handlesThrowable() {
62+
return true;
63+
}
64+
5665
/**
5766
* Creates a new instance of the class. Required by Log4J2.
5867
* @param configuration current configuration
@@ -61,7 +70,7 @@ public void format(LogEvent event, StringBuilder buffer) {
6170
* @return a new {@code WhitespaceThrowablePatternConverter}
6271
*/
6372
public static ExtendedWhitespaceThrowablePatternConverter newInstance(Configuration configuration,
64-
String @Nullable [] options) {
73+
@Nullable String[] options) {
6574
return new ExtendedWhitespaceThrowablePatternConverter(configuration, options);
6675
}
6776

core/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/Extractor.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@
1616

1717
package org.springframework.boot.logging.log4j2;
1818

19+
import java.io.PrintWriter;
20+
import java.io.StringWriter;
21+
1922
import org.apache.logging.log4j.core.LogEvent;
20-
import org.apache.logging.log4j.core.impl.ThrowableProxy;
2123
import org.jspecify.annotations.Nullable;
2224
import org.slf4j.event.LoggingEvent;
2325

2426
import org.springframework.boot.logging.StackTracePrinter;
25-
import org.springframework.util.Assert;
2627

2728
/**
2829
* Functions to extract items from {@link LoggingEvent}.
@@ -42,19 +43,23 @@ String messageAndStackTrace(LogEvent event) {
4243
}
4344

4445
@Nullable String stackTrace(LogEvent event) {
45-
return stackTrace(event.getThrownProxy());
46+
return stackTrace(event.getThrown());
4647
}
4748

48-
@Nullable String stackTrace(@Nullable ThrowableProxy throwableProxy) {
49-
if (throwableProxy == null) {
49+
@Nullable String stackTrace(@Nullable Throwable throwable) {
50+
if (throwable == null) {
5051
return null;
5152
}
5253
if (this.stackTracePrinter != null) {
53-
Throwable throwable = throwableProxy.getThrowable();
54-
Assert.state(throwable != null, "Proxy must return Throwable in order to print exception");
5554
return this.stackTracePrinter.printStackTraceToString(throwable);
5655
}
57-
return throwableProxy.getExtendedStackTraceAsString();
56+
return printStackTrace(throwable);
57+
}
58+
59+
private static String printStackTrace(Throwable throwable) {
60+
StringWriter stringWriter = new StringWriter();
61+
throwable.printStackTrace(new PrintWriter(stringWriter));
62+
return stringWriter.toString();
5863
}
5964

6065
}

core/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/GraylogExtendedLogFormatStructuredLogFormatter.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,11 @@ private static void jsonMembers(Environment environment, @Nullable StackTracePri
9898
.whenNot(mapIsEmpty)
9999
.usingPairs(contextPairs.flat(additionalFieldJoiner(),
100100
GraylogExtendedLogFormatStructuredLogFormatter::addContextDataPairs));
101-
Function<@Nullable LogEvent, @Nullable Object> getThrownProxy = (event) -> (event != null)
102-
? event.getThrownProxy() : null;
101+
Function<@Nullable LogEvent, @Nullable Object> getThrown = (event) -> (event != null) ? event.getThrown()
102+
: null;
103103
members.add()
104-
.whenNotNull(getThrownProxy)
105-
.usingMembers((thrownProxyMembers) -> throwableMembers(thrownProxyMembers, extractor));
104+
.whenNotNull(getThrown)
105+
.usingMembers((thrownMembers) -> throwableMembers(thrownMembers, extractor));
106106
}
107107

108108
private static String getMessageText(Message message) {
@@ -134,11 +134,9 @@ private static int convertLevel(LogEvent event) {
134134

135135
private static void throwableMembers(Members<LogEvent> members, Extractor extractor) {
136136
members.add("full_message", extractor::messageAndStackTrace);
137-
members.add("_error_type", (event) -> event.getThrownProxy().getThrowable())
138-
.whenNotNull()
139-
.as(ObjectUtils::nullSafeClassName);
137+
members.add("_error_type", LogEvent::getThrown).whenNotNull().as(ObjectUtils::nullSafeClassName);
140138
members.add("_error_stack_trace", extractor::stackTrace);
141-
members.add("_error_message", (event) -> event.getThrownProxy().getMessage());
139+
members.add("_error_message", (event) -> event.getThrown().getMessage());
142140
}
143141

144142
private static void addContextDataPairs(ContextPairs.Pairs<ReadOnlyStringMap> contextPairs) {

core/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/LogstashStructuredLogFormatter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ private static void jsonMembers(@Nullable StackTracePrinter stackTracePrinter, C
7171
.whenNotNull()
7272
.as(LogstashStructuredLogFormatter::getMarkers)
7373
.whenNot(collectionIsEmpty);
74-
members.add("stack_trace", LogEvent::getThrownProxy).whenNotNull().as(extractor::stackTrace);
74+
members.add("stack_trace", LogEvent::getThrown).whenNotNull().as(extractor::stackTrace);
7575
}
7676

7777
private static String asTimestamp(Instant instant) {

core/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/SpringProfileArbiter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ private Builder() {
9090
* @return this
9191
* @see Profiles#of(String...)
9292
*/
93-
Builder setName(String name) {
93+
public Builder setName(String name) {
9494
this.name = name;
9595
return this;
9696
}

core/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/StructuredLogLayout.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,12 @@ static final class Builder implements org.apache.logging.log4j.core.util.Builder
8787
@SuppressWarnings("NullAway.Init")
8888
private String charset = StandardCharsets.UTF_8.name();
8989

90-
Builder setFormat(String format) {
90+
public Builder setFormat(String format) {
9191
this.format = format;
9292
return this;
9393
}
9494

95-
Builder setCharset(String charset) {
95+
public Builder setCharset(String charset) {
9696
this.charset = charset;
9797
return this;
9898
}

core/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/WhitespaceThrowablePatternConverter.java

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@
1616

1717
package org.springframework.boot.logging.log4j2;
1818

19-
import org.apache.logging.log4j.core.LogEvent;
2019
import org.apache.logging.log4j.core.config.Configuration;
2120
import org.apache.logging.log4j.core.config.plugins.Plugin;
2221
import org.apache.logging.log4j.core.pattern.ConverterKeys;
22+
import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
2323
import org.apache.logging.log4j.core.pattern.PatternConverter;
2424
import org.apache.logging.log4j.core.pattern.ThrowablePatternConverter;
25+
import org.apache.logging.log4j.core.pattern.VariablesNotEmptyReplacementConverter;
2526
import org.jspecify.annotations.Nullable;
2627

2728
/**
@@ -33,31 +34,15 @@
3334
*/
3435
@Plugin(name = "WhitespaceThrowablePatternConverter", category = PatternConverter.CATEGORY)
3536
@ConverterKeys({ "wEx", "wThrowable", "wException" })
36-
public final class WhitespaceThrowablePatternConverter extends ThrowablePatternConverter {
37+
public final class WhitespaceThrowablePatternConverter {
3738

38-
private WhitespaceThrowablePatternConverter(Configuration configuration, String @Nullable [] options) {
39-
super("WhitespaceThrowable", "throwable", options, configuration);
39+
private WhitespaceThrowablePatternConverter() {
4040
}
4141

42-
@Override
43-
public void format(LogEvent event, StringBuilder buffer) {
44-
if (event.getThrown() != null) {
45-
buffer.append(this.options.getSeparator());
46-
super.format(event, buffer);
47-
buffer.append(this.options.getSeparator());
48-
}
49-
}
50-
51-
/**
52-
* Creates a new instance of the class. Required by Log4J2.
53-
* @param configuration current configuration
54-
* @param options pattern options, may be null. If first element is "short", only the
55-
* first line of the throwable will be formatted.
56-
* @return a new {@code WhitespaceThrowablePatternConverter}
57-
*/
58-
public static WhitespaceThrowablePatternConverter newInstance(Configuration configuration,
59-
String @Nullable [] options) {
60-
return new WhitespaceThrowablePatternConverter(configuration, options);
42+
public static LogEventPatternConverter newInstance(Configuration configuration, String @Nullable [] options) {
43+
final String nested = (options != null && options.length > 0) ? "{" + String.join("}{", options) + "}" : "";
44+
final String pattern = "%notEmpty{%n%ex" + nested + "%n}";
45+
return VariablesNotEmptyReplacementConverter.newInstance(configuration, new String[] { pattern });
6146
}
6247

6348
}

0 commit comments

Comments
 (0)