diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLogFormatterFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLogFormatterFactory.java index e5fc4c3218d..22e3c6d872c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLogFormatterFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLogFormatterFactory.java @@ -27,7 +27,6 @@ import org.springframework.boot.json.JsonWriter.Members; import org.springframework.boot.util.Instantiator; import org.springframework.boot.util.Instantiator.AvailableParameters; import org.springframework.boot.util.Instantiator.FailureHandler; -import org.springframework.boot.util.LambdaSafe; import org.springframework.core.GenericTypeResolver; import org.springframework.core.env.Environment; import org.springframework.core.io.support.SpringFactoriesLoader; @@ -108,11 +107,12 @@ public class StructuredLogFormatterFactory { ArgumentResolver.from(this.instantiator::getArg)); } - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "rawtypes" }) private void invokeCustomizers(List> customizers, Members members) { - LambdaSafe.callbacks(StructuredLoggingJsonMembersCustomizer.class, customizers, members) - .invoke((customizer) -> customizer.customize(members)); + for (StructuredLoggingJsonMembersCustomizer customizer : customizers) { + ((StructuredLoggingJsonMembersCustomizer) customizer).customize(members); + } } /** diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/structured/StructuredLogFormatterFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/structured/StructuredLogFormatterFactoryTests.java index c91a75f0acd..cc0bbc8d043 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/structured/StructuredLogFormatterFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/structured/StructuredLogFormatterFactoryTests.java @@ -20,6 +20,7 @@ import java.util.List; import org.junit.jupiter.api.Test; +import org.springframework.boot.json.JsonWriter.Members; import org.springframework.boot.json.JsonWriter.ValueProcessor; import org.springframework.boot.logging.structured.StructuredLogFormatterFactory.CommonFormatters; import org.springframework.boot.util.Instantiator.AvailableParameters; @@ -104,18 +105,49 @@ class StructuredLogFormatterFactoryTests { } @Test - void getInjectCustomizers() { + void getInjectStringMembersCustomizer() { this.environment.setProperty("logging.structured.json.rename.spring", "test"); SpringFactoriesLoader factoriesLoader = mock(SpringFactoriesLoader.class); - StructuredLoggingJsonMembersCustomizer customizer = (members) -> members - .applyingValueProcessor(ValueProcessor.of(String.class, String::toUpperCase)); - given(factoriesLoader.load(any(), any(ArgumentResolver.class))).willReturn(List.of(customizer)); + given(factoriesLoader.load(any(), any(ArgumentResolver.class))) + .willReturn(List.of(new StringMembersStructuredLoggingJsonMembersCustomizer())); StructuredLogFormatterFactory factory = new StructuredLogFormatterFactory<>(factoriesLoader, LogEvent.class, this.environment, this::addAvailableParameters, this::addCommonFormatters); - CutomizedFormatter formatter = (CutomizedFormatter) factory.get(CutomizedFormatter.class.getName()); + CustomizedFormatter formatter = (CustomizedFormatter) factory.get(CustomizedFormatter.class.getName()); assertThat(formatter.format(new LogEvent())).contains("\"test\":\"BOOT\""); } + @Test + void getInjectObjectMembersCustomizer() { + this.environment.setProperty("logging.structured.json.rename.spring", "test"); + SpringFactoriesLoader factoriesLoader = mock(SpringFactoriesLoader.class); + given(factoriesLoader.load(any(), any(ArgumentResolver.class))) + .willReturn(List.of(new ObjectMembersStructuredLoggingJsonMembersCustomizer())); + StructuredLogFormatterFactory factory = new StructuredLogFormatterFactory<>(factoriesLoader, + LogEvent.class, this.environment, this::addAvailableParameters, this::addCommonFormatters); + CustomizedFormatter formatter = (CustomizedFormatter) factory.get(CustomizedFormatter.class.getName()); + assertThat(formatter.format(new LogEvent())).contains("\"test\":\"BOOT\""); + } + + static class StringMembersStructuredLoggingJsonMembersCustomizer + implements StructuredLoggingJsonMembersCustomizer { + + @Override + public void customize(Members members) { + members.applyingValueProcessor(ValueProcessor.of(String.class, String::toUpperCase)); + } + + } + + static class ObjectMembersStructuredLoggingJsonMembersCustomizer + implements StructuredLoggingJsonMembersCustomizer { + + @Override + public void customize(Members members) { + members.applyingValueProcessor(ValueProcessor.of(String.class, String::toUpperCase)); + } + + } + static class LogEvent { } @@ -167,9 +199,9 @@ class StructuredLogFormatterFactoryTests { } - static class CutomizedFormatter extends JsonWriterStructuredLogFormatter { + static class CustomizedFormatter extends JsonWriterStructuredLogFormatter { - CutomizedFormatter(StructuredLoggingJsonMembersCustomizer customizer) { + CustomizedFormatter(StructuredLoggingJsonMembersCustomizer customizer) { super((members) -> members.add("spring", "boot"), customizer); }