From b5416dc54f2fbc2e4d6ed4348cf2b27ed883ae1d Mon Sep 17 00:00:00 2001 From: Yanming Zhou Date: Wed, 4 Dec 2024 10:42:54 +0800 Subject: [PATCH] Let `logging.structured.json.customizer` accept multiple Customizers also See https://github.com/spring-projects/spring-boot/issues/43312#issuecomment-2509058761 --- .../StructuredLoggingJsonProperties.java | 4 ++- ...ngJsonPropertiesJsonMembersCustomizer.java | 6 ++-- ...nPropertiesJsonMembersCustomizerTests.java | 35 ++++++++++++++++++- .../StructuredLoggingJsonPropertiesTests.java | 3 +- 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLoggingJsonProperties.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLoggingJsonProperties.java index cf34cb1a7d10..7fce00110b94 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLoggingJsonProperties.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLoggingJsonProperties.java @@ -16,6 +16,7 @@ package org.springframework.boot.logging.structured; +import java.util.List; import java.util.Map; import java.util.Set; @@ -32,9 +33,10 @@ * @param customizer the fully qualified name of a * {@link StructuredLoggingJsonMembersCustomizer} * @author Phillip Webb + * @author Yanming Zhou */ record StructuredLoggingJsonProperties(Set include, Set exclude, Map rename, - Map add, Class> customizer) { + Map add, List>> customizer) { static StructuredLoggingJsonProperties get(Environment environment) { return Binder.get(environment) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLoggingJsonPropertiesJsonMembersCustomizer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLoggingJsonPropertiesJsonMembersCustomizer.java index a33f2ff9df6c..9350c02c5b11 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLoggingJsonPropertiesJsonMembersCustomizer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLoggingJsonPropertiesJsonMembersCustomizer.java @@ -16,6 +16,7 @@ package org.springframework.boot.logging.structured; +import java.util.List; import java.util.Map; import org.springframework.boot.json.JsonWriter.MemberPath; @@ -28,6 +29,7 @@ * {@link StructuredLoggingJsonProperties}. * * @author Phillip Webb + * @author Yanming Zhou */ class StructuredLoggingJsonPropertiesJsonMembersCustomizer implements StructuredLoggingJsonMembersCustomizer { @@ -49,9 +51,9 @@ public void customize(Members members) { if (!CollectionUtils.isEmpty(add)) { add.forEach(members::add); } - Class> customizer = this.properties.customizer(); + List>> customizer = this.properties.customizer(); if (customizer != null) { - createAndApplyCustomizer(members, customizer); + customizer.forEach((c) -> createAndApplyCustomizer(members, c)); } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/structured/StructuredLoggingJsonPropertiesJsonMembersCustomizerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/structured/StructuredLoggingJsonPropertiesJsonMembersCustomizerTests.java index 9ba25407f16f..30967d9c63cb 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/structured/StructuredLoggingJsonPropertiesJsonMembersCustomizerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/structured/StructuredLoggingJsonPropertiesJsonMembersCustomizerTests.java @@ -17,6 +17,7 @@ package org.springframework.boot.logging.structured; import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.Set; @@ -37,6 +38,7 @@ * Tests for {@link StructuredLoggingJsonPropertiesJsonMembersCustomizer}. * * @author Phillip Webb + * @author Yanming Zhou */ @ExtendWith(MockitoExtension.class) class StructuredLoggingJsonPropertiesJsonMembersCustomizerTests { @@ -102,12 +104,25 @@ void customizeWhenHasCustomizerCustomizesMember() { .applyingNameProcessor(NameProcessor.of(String::toUpperCase)); given(((Instantiator) this.instantiator).instantiateType(TestCustomizer.class)).willReturn(uppercaseCustomizer); StructuredLoggingJsonProperties properties = new StructuredLoggingJsonProperties(Collections.emptySet(), - Collections.emptySet(), Collections.emptyMap(), Collections.emptyMap(), TestCustomizer.class); + Collections.emptySet(), Collections.emptyMap(), Collections.emptyMap(), List.of(TestCustomizer.class)); StructuredLoggingJsonPropertiesJsonMembersCustomizer customizer = new StructuredLoggingJsonPropertiesJsonMembersCustomizer( this.instantiator, properties); assertThat(writeSampleJson(customizer)).contains("\"A\":\"a\""); } + @Test + @SuppressWarnings({ "rawtypes", "unchecked" }) + void multipleCustomizers() { + given(((Instantiator) this.instantiator).instantiateType(FooCustomizer.class)).willReturn(new FooCustomizer()); + given(((Instantiator) this.instantiator).instantiateType(BarCustomizer.class)).willReturn(new BarCustomizer()); + StructuredLoggingJsonProperties properties = new StructuredLoggingJsonProperties(Collections.emptySet(), + Collections.emptySet(), Collections.emptyMap(), Collections.emptyMap(), + List.of(FooCustomizer.class, BarCustomizer.class)); + StructuredLoggingJsonPropertiesJsonMembersCustomizer customizer = new StructuredLoggingJsonPropertiesJsonMembersCustomizer( + this.instantiator, properties); + assertThat(writeSampleJson(customizer)).contains("\"foo\":\"foo\"").contains("\"bar\":\"bar\""); + } + @SuppressWarnings({ "rawtypes", "unchecked" }) private String writeSampleJson(StructuredLoggingJsonMembersCustomizer customizer) { return JsonWriter.of((members) -> { @@ -126,4 +141,22 @@ public void customize(Members members) { } + static class FooCustomizer implements StructuredLoggingJsonMembersCustomizer { + + @Override + public void customize(Members members) { + members.add("foo", "foo"); + } + + } + + static class BarCustomizer implements StructuredLoggingJsonMembersCustomizer { + + @Override + public void customize(Members members) { + members.add("bar", "bar"); + } + + } + } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/structured/StructuredLoggingJsonPropertiesTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/structured/StructuredLoggingJsonPropertiesTests.java index 43b1510317ea..041eb877c661 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/structured/StructuredLoggingJsonPropertiesTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/structured/StructuredLoggingJsonPropertiesTests.java @@ -16,6 +16,7 @@ package org.springframework.boot.logging.structured; +import java.util.List; import java.util.Map; import java.util.Set; @@ -43,7 +44,7 @@ void getBindsFromEnvironment() { environment.setProperty("logging.structured.json.customizer", TestCustomizer.class.getName()); StructuredLoggingJsonProperties properties = StructuredLoggingJsonProperties.get(environment); assertThat(properties).isEqualTo(new StructuredLoggingJsonProperties(Set.of("a", "b"), Set.of("c", "d"), - Map.of("e", "f"), Map.of("g", "h"), TestCustomizer.class)); + Map.of("e", "f"), Map.of("g", "h"), List.of(TestCustomizer.class))); } @Test