Skip to content

Commit 3239342

Browse files
committed
Merge branch '3.4.x'
Closes gh-43707
2 parents 170ff4e + b6b9237 commit 3239342

File tree

5 files changed

+62
-4
lines changed

5 files changed

+62
-4
lines changed

spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/logging/ConfigureClasspathToPreferLog4j2.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
@Target(ElementType.TYPE)
3636
@Documented
3737
@ClassPathExclusions("log4j-to-slf4j-*.jar")
38-
@ClassPathOverrides({ "org.apache.logging.log4j:log4j-core:2.19.0",
39-
"org.apache.logging.log4j:log4j-slf4j-impl:2.19.0" })
38+
@ClassPathOverrides({ "org.apache.logging.log4j:log4j-core:2.24.3",
39+
"org.apache.logging.log4j:log4j-slf4j-impl:2.24.3" })
4040
public @interface ConfigureClasspathToPreferLog4j2 {
4141

4242
}

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -47,6 +47,7 @@
4747
import org.apache.logging.log4j.core.util.AuthorizationProvider;
4848
import org.apache.logging.log4j.core.util.NameUtil;
4949
import org.apache.logging.log4j.jul.Log4jBridgeHandler;
50+
import org.apache.logging.log4j.status.StatusLogger;
5051
import org.apache.logging.log4j.util.PropertiesUtil;
5152

5253
import org.springframework.boot.context.properties.bind.BindResult;
@@ -213,6 +214,7 @@ public void initialize(LoggingInitializationContext initializationContext, Strin
213214
if (isAlreadyInitialized(loggerContext)) {
214215
return;
215216
}
217+
resetFallbackListenerStream(StatusLogger.getLogger());
216218
Environment environment = initializationContext.getEnvironment();
217219
if (environment != null) {
218220
getLoggerContext().putObject(ENVIRONMENT_KEY, environment);
@@ -224,6 +226,21 @@ public void initialize(LoggingInitializationContext initializationContext, Strin
224226
markAsInitialized(loggerContext);
225227
}
226228

229+
/**
230+
* Reset the stream used by the fallback listener to the current system out. This
231+
* allows the fallback lister to work with any captured output streams in a similar
232+
* way to the {@code follow} attribute of the {@code literal Console} appender.
233+
* @param statusLogger the status logger to update
234+
*/
235+
private void resetFallbackListenerStream(StatusLogger statusLogger) {
236+
try {
237+
statusLogger.getFallbackListener().setStream(System.out);
238+
}
239+
catch (NoSuchMethodError ex) {
240+
// Ignore for older versions of Log4J
241+
}
242+
}
243+
227244
@Override
228245
protected void loadDefaults(LoggingInitializationContext initializationContext, LogFile logFile) {
229246
String location = getPackagedConfigFile((logFile != null) ? "log4j2-file.xml" : "log4j2.xml");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2012-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package smoketest.structuredlogging.log4j2;
18+
19+
import java.util.Objects;
20+
21+
import org.springframework.boot.json.JsonWriter.Members;
22+
import org.springframework.boot.logging.structured.StructuredLoggingJsonMembersCustomizer;
23+
24+
public class DuplicateJsonMembersCustomizer implements StructuredLoggingJsonMembersCustomizer<Object> {
25+
26+
@Override
27+
public void customize(Members<Object> members) {
28+
members.add("test").as(Objects::toString);
29+
members.add("test").as(Objects::toString);
30+
}
31+
32+
}

spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-structured-logging-log4j2/src/main/resources/application.properties

+3
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@ logging.structured.format.console=ecs
22
#---
33
spring.config.activate.on-profile=custom
44
logging.structured.format.console=smoketest.structuredlogging.log4j2.CustomStructuredLogFormatter
5+
#---
6+
spring.config.activate.on-profile=on-error
7+
logging.structured.json.customizer=smoketest.structuredlogging.log4j2.DuplicateJsonMembersCustomizer

spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-structured-logging-log4j2/src/test/java/smoketest/structuredlogging/log4j2/SampleLog4j2StructuredLoggingApplicationTests.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -62,4 +62,10 @@ void custom(CapturedOutput output) {
6262
assertThat(output).contains("epoch=").contains("msg=\"Starting SampleLog4j2StructuredLoggingApplication");
6363
}
6464

65+
@Test
66+
void shouldCaptureCustomizerError(CapturedOutput output) {
67+
SampleLog4j2StructuredLoggingApplication.main(new String[] { "--spring.profiles.active=on-error" });
68+
assertThat(output).contains("The name 'test' has already been written");
69+
}
70+
6571
}

0 commit comments

Comments
 (0)