Call spring.factories customizers in the same way as one from props
Previously, customizers loaded from spring.factories were called using LambdaSafe. This resulted in customizers with a generic type more specific than Object being ignored. A customizer loaded from the logging.structured.json.customizer property was not affected as it was called directly rather than through LambdaSafe. This commit aligns the way in which customizers loaded from spring.factories are called with the way in which any customizer specified using the logging.structured.json.customizer property is called. Closes gh-43312
This commit is contained in:
parent
f9aedf5a43
commit
a1c1e32947
|
|
@ -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<E> {
|
|||
ArgumentResolver.from(this.instantiator::getArg));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private void invokeCustomizers(List<StructuredLoggingJsonMembersCustomizer<?>> customizers,
|
||||
Members<Object> members) {
|
||||
LambdaSafe.callbacks(StructuredLoggingJsonMembersCustomizer.class, customizers, members)
|
||||
.invoke((customizer) -> customizer.customize(members));
|
||||
for (StructuredLoggingJsonMembersCustomizer<?> customizer : customizers) {
|
||||
((StructuredLoggingJsonMembersCustomizer) customizer).customize(members);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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<LogEvent> 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<LogEvent> 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<String> {
|
||||
|
||||
@Override
|
||||
public void customize(Members<String> members) {
|
||||
members.applyingValueProcessor(ValueProcessor.of(String.class, String::toUpperCase));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class ObjectMembersStructuredLoggingJsonMembersCustomizer
|
||||
implements StructuredLoggingJsonMembersCustomizer<Object> {
|
||||
|
||||
@Override
|
||||
public void customize(Members<Object> members) {
|
||||
members.applyingValueProcessor(ValueProcessor.of(String.class, String::toUpperCase));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class LogEvent {
|
||||
|
||||
}
|
||||
|
|
@ -167,9 +199,9 @@ class StructuredLogFormatterFactoryTests {
|
|||
|
||||
}
|
||||
|
||||
static class CutomizedFormatter extends JsonWriterStructuredLogFormatter<LogEvent> {
|
||||
static class CustomizedFormatter extends JsonWriterStructuredLogFormatter<LogEvent> {
|
||||
|
||||
CutomizedFormatter(StructuredLoggingJsonMembersCustomizer<?> customizer) {
|
||||
CustomizedFormatter(StructuredLoggingJsonMembersCustomizer<?> customizer) {
|
||||
super((members) -> members.add("spring", "boot"), customizer);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue