Merge pull request #43203 from izeye

* pr/43203:
  Replace "structure logging" with "structured logging"

Closes gh-43203
This commit is contained in:
Phillip Webb 2024-11-16 08:30:28 -08:00
commit 37927720b0
32 changed files with 66 additions and 65 deletions

View File

@ -609,7 +609,7 @@ logging:
corpname: mycorp corpname: mycorp
---- ----
TIP: For more advanced customizations, you can write your own class that implements the javadoc:org.springframework.boot.logging.structured.StructureLoggingJsonMembersCustomizer[] interface and declare it using the configprop:logging.structured.json.customizer[] property. TIP: For more advanced customizations, you can write your own class that implements the javadoc:org.springframework.boot.logging.structured.StructuredLoggingJsonMembersCustomizer[] interface and declare it using the configprop:logging.structured.json.customizer[] property.
You can also declare implementations by listing them in a `META-INF/spring.factories` file. You can also declare implementations by listing them in a `META-INF/spring.factories` file.

View File

@ -28,8 +28,8 @@ import org.springframework.boot.json.JsonWriter;
import org.springframework.boot.logging.structured.CommonStructuredLogFormat; import org.springframework.boot.logging.structured.CommonStructuredLogFormat;
import org.springframework.boot.logging.structured.ElasticCommonSchemaProperties; import org.springframework.boot.logging.structured.ElasticCommonSchemaProperties;
import org.springframework.boot.logging.structured.JsonWriterStructuredLogFormatter; import org.springframework.boot.logging.structured.JsonWriterStructuredLogFormatter;
import org.springframework.boot.logging.structured.StructureLoggingJsonMembersCustomizer;
import org.springframework.boot.logging.structured.StructuredLogFormatter; import org.springframework.boot.logging.structured.StructuredLogFormatter;
import org.springframework.boot.logging.structured.StructuredLoggingJsonMembersCustomizer;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
@ -43,7 +43,7 @@ import org.springframework.util.ObjectUtils;
class ElasticCommonSchemaStructuredLogFormatter extends JsonWriterStructuredLogFormatter<LogEvent> { class ElasticCommonSchemaStructuredLogFormatter extends JsonWriterStructuredLogFormatter<LogEvent> {
ElasticCommonSchemaStructuredLogFormatter(Environment environment, ElasticCommonSchemaStructuredLogFormatter(Environment environment,
StructureLoggingJsonMembersCustomizer<?> customizer) { StructuredLoggingJsonMembersCustomizer<?> customizer) {
super((members) -> jsonMembers(environment, members), customizer); super((members) -> jsonMembers(environment, members), customizer);
} }

View File

@ -37,8 +37,8 @@ import org.springframework.boot.json.WritableJson;
import org.springframework.boot.logging.structured.CommonStructuredLogFormat; import org.springframework.boot.logging.structured.CommonStructuredLogFormat;
import org.springframework.boot.logging.structured.GraylogExtendedLogFormatProperties; import org.springframework.boot.logging.structured.GraylogExtendedLogFormatProperties;
import org.springframework.boot.logging.structured.JsonWriterStructuredLogFormatter; import org.springframework.boot.logging.structured.JsonWriterStructuredLogFormatter;
import org.springframework.boot.logging.structured.StructureLoggingJsonMembersCustomizer;
import org.springframework.boot.logging.structured.StructuredLogFormatter; import org.springframework.boot.logging.structured.StructuredLogFormatter;
import org.springframework.boot.logging.structured.StructuredLoggingJsonMembersCustomizer;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.core.log.LogMessage; import org.springframework.core.log.LogMessage;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -70,7 +70,7 @@ class GraylogExtendedLogFormatStructuredLogFormatter extends JsonWriterStructure
private static final Set<String> ADDITIONAL_FIELD_ILLEGAL_KEYS = Set.of("id", "_id"); private static final Set<String> ADDITIONAL_FIELD_ILLEGAL_KEYS = Set.of("id", "_id");
GraylogExtendedLogFormatStructuredLogFormatter(Environment environment, GraylogExtendedLogFormatStructuredLogFormatter(Environment environment,
StructureLoggingJsonMembersCustomizer<?> customizer) { StructuredLoggingJsonMembersCustomizer<?> customizer) {
super((members) -> jsonMembers(environment, members), customizer); super((members) -> jsonMembers(environment, members), customizer);
} }

View File

@ -32,8 +32,8 @@ import org.apache.logging.log4j.util.ReadOnlyStringMap;
import org.springframework.boot.json.JsonWriter; import org.springframework.boot.json.JsonWriter;
import org.springframework.boot.logging.structured.CommonStructuredLogFormat; import org.springframework.boot.logging.structured.CommonStructuredLogFormat;
import org.springframework.boot.logging.structured.JsonWriterStructuredLogFormatter; import org.springframework.boot.logging.structured.JsonWriterStructuredLogFormatter;
import org.springframework.boot.logging.structured.StructureLoggingJsonMembersCustomizer;
import org.springframework.boot.logging.structured.StructuredLogFormatter; import org.springframework.boot.logging.structured.StructuredLogFormatter;
import org.springframework.boot.logging.structured.StructuredLoggingJsonMembersCustomizer;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
/** /**
@ -44,7 +44,7 @@ import org.springframework.util.CollectionUtils;
*/ */
class LogstashStructuredLogFormatter extends JsonWriterStructuredLogFormatter<LogEvent> { class LogstashStructuredLogFormatter extends JsonWriterStructuredLogFormatter<LogEvent> {
LogstashStructuredLogFormatter(StructureLoggingJsonMembersCustomizer<?> customizer) { LogstashStructuredLogFormatter(StructuredLoggingJsonMembersCustomizer<?> customizer) {
super(LogstashStructuredLogFormatter::jsonMembers, customizer); super(LogstashStructuredLogFormatter::jsonMembers, customizer);
} }

View File

@ -30,10 +30,10 @@ import org.apache.logging.log4j.core.config.plugins.PluginLoggerContext;
import org.apache.logging.log4j.core.layout.AbstractStringLayout; import org.apache.logging.log4j.core.layout.AbstractStringLayout;
import org.springframework.boot.logging.structured.CommonStructuredLogFormat; import org.springframework.boot.logging.structured.CommonStructuredLogFormat;
import org.springframework.boot.logging.structured.StructureLoggingJsonMembersCustomizer;
import org.springframework.boot.logging.structured.StructuredLogFormatter; import org.springframework.boot.logging.structured.StructuredLogFormatter;
import org.springframework.boot.logging.structured.StructuredLogFormatterFactory; import org.springframework.boot.logging.structured.StructuredLogFormatterFactory;
import org.springframework.boot.logging.structured.StructuredLogFormatterFactory.CommonFormatters; import org.springframework.boot.logging.structured.StructuredLogFormatterFactory.CommonFormatters;
import org.springframework.boot.logging.structured.StructuredLoggingJsonMembersCustomizer;
import org.springframework.boot.util.Instantiator; import org.springframework.boot.util.Instantiator;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -111,21 +111,21 @@ final class StructuredLogLayout extends AbstractStringLayout {
private ElasticCommonSchemaStructuredLogFormatter createEcsFormatter(Instantiator<?> instantiator) { private ElasticCommonSchemaStructuredLogFormatter createEcsFormatter(Instantiator<?> instantiator) {
Environment environment = instantiator.getArg(Environment.class); Environment environment = instantiator.getArg(Environment.class);
StructureLoggingJsonMembersCustomizer<?> jsonMembersCustomizer = instantiator StructuredLoggingJsonMembersCustomizer<?> jsonMembersCustomizer = instantiator
.getArg(StructureLoggingJsonMembersCustomizer.class); .getArg(StructuredLoggingJsonMembersCustomizer.class);
return new ElasticCommonSchemaStructuredLogFormatter(environment, jsonMembersCustomizer); return new ElasticCommonSchemaStructuredLogFormatter(environment, jsonMembersCustomizer);
} }
private GraylogExtendedLogFormatStructuredLogFormatter createGraylogFormatter(Instantiator<?> instantiator) { private GraylogExtendedLogFormatStructuredLogFormatter createGraylogFormatter(Instantiator<?> instantiator) {
Environment environment = instantiator.getArg(Environment.class); Environment environment = instantiator.getArg(Environment.class);
StructureLoggingJsonMembersCustomizer<?> jsonMembersCustomizer = instantiator StructuredLoggingJsonMembersCustomizer<?> jsonMembersCustomizer = instantiator
.getArg(StructureLoggingJsonMembersCustomizer.class); .getArg(StructuredLoggingJsonMembersCustomizer.class);
return new GraylogExtendedLogFormatStructuredLogFormatter(environment, jsonMembersCustomizer); return new GraylogExtendedLogFormatStructuredLogFormatter(environment, jsonMembersCustomizer);
} }
private LogstashStructuredLogFormatter createLogstashFormatter(Instantiator<?> instantiator) { private LogstashStructuredLogFormatter createLogstashFormatter(Instantiator<?> instantiator) {
StructureLoggingJsonMembersCustomizer<?> jsonMembersCustomizer = instantiator StructuredLoggingJsonMembersCustomizer<?> jsonMembersCustomizer = instantiator
.getArg(StructureLoggingJsonMembersCustomizer.class); .getArg(StructuredLoggingJsonMembersCustomizer.class);
return new LogstashStructuredLogFormatter(jsonMembersCustomizer); return new LogstashStructuredLogFormatter(jsonMembersCustomizer);
} }

View File

@ -28,8 +28,8 @@ import org.springframework.boot.json.JsonWriter.PairExtractor;
import org.springframework.boot.logging.structured.CommonStructuredLogFormat; import org.springframework.boot.logging.structured.CommonStructuredLogFormat;
import org.springframework.boot.logging.structured.ElasticCommonSchemaProperties; import org.springframework.boot.logging.structured.ElasticCommonSchemaProperties;
import org.springframework.boot.logging.structured.JsonWriterStructuredLogFormatter; import org.springframework.boot.logging.structured.JsonWriterStructuredLogFormatter;
import org.springframework.boot.logging.structured.StructureLoggingJsonMembersCustomizer;
import org.springframework.boot.logging.structured.StructuredLogFormatter; import org.springframework.boot.logging.structured.StructuredLogFormatter;
import org.springframework.boot.logging.structured.StructuredLoggingJsonMembersCustomizer;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
/** /**
@ -45,7 +45,7 @@ class ElasticCommonSchemaStructuredLogFormatter extends JsonWriterStructuredLogF
(pair) -> pair.value); (pair) -> pair.value);
ElasticCommonSchemaStructuredLogFormatter(Environment environment, ThrowableProxyConverter throwableProxyConverter, ElasticCommonSchemaStructuredLogFormatter(Environment environment, ThrowableProxyConverter throwableProxyConverter,
StructureLoggingJsonMembersCustomizer<?> customizer) { StructuredLoggingJsonMembersCustomizer<?> customizer) {
super((members) -> jsonMembers(environment, throwableProxyConverter, members), customizer); super((members) -> jsonMembers(environment, throwableProxyConverter, members), customizer);
} }

View File

@ -37,8 +37,8 @@ import org.springframework.boot.json.WritableJson;
import org.springframework.boot.logging.structured.CommonStructuredLogFormat; import org.springframework.boot.logging.structured.CommonStructuredLogFormat;
import org.springframework.boot.logging.structured.GraylogExtendedLogFormatProperties; import org.springframework.boot.logging.structured.GraylogExtendedLogFormatProperties;
import org.springframework.boot.logging.structured.JsonWriterStructuredLogFormatter; import org.springframework.boot.logging.structured.JsonWriterStructuredLogFormatter;
import org.springframework.boot.logging.structured.StructureLoggingJsonMembersCustomizer;
import org.springframework.boot.logging.structured.StructuredLogFormatter; import org.springframework.boot.logging.structured.StructuredLogFormatter;
import org.springframework.boot.logging.structured.StructuredLoggingJsonMembersCustomizer;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.core.log.LogMessage; import org.springframework.core.log.LogMessage;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -70,7 +70,7 @@ class GraylogExtendedLogFormatStructuredLogFormatter extends JsonWriterStructure
private static final Set<String> ADDITIONAL_FIELD_ILLEGAL_KEYS = Set.of("id", "_id"); private static final Set<String> ADDITIONAL_FIELD_ILLEGAL_KEYS = Set.of("id", "_id");
GraylogExtendedLogFormatStructuredLogFormatter(Environment environment, GraylogExtendedLogFormatStructuredLogFormatter(Environment environment,
ThrowableProxyConverter throwableProxyConverter, StructureLoggingJsonMembersCustomizer<?> customizer) { ThrowableProxyConverter throwableProxyConverter, StructuredLoggingJsonMembersCustomizer<?> customizer) {
super((members) -> jsonMembers(environment, throwableProxyConverter, members), customizer); super((members) -> jsonMembers(environment, throwableProxyConverter, members), customizer);
} }

View File

@ -35,8 +35,8 @@ import org.springframework.boot.json.JsonWriter;
import org.springframework.boot.json.JsonWriter.PairExtractor; import org.springframework.boot.json.JsonWriter.PairExtractor;
import org.springframework.boot.logging.structured.CommonStructuredLogFormat; import org.springframework.boot.logging.structured.CommonStructuredLogFormat;
import org.springframework.boot.logging.structured.JsonWriterStructuredLogFormatter; import org.springframework.boot.logging.structured.JsonWriterStructuredLogFormatter;
import org.springframework.boot.logging.structured.StructureLoggingJsonMembersCustomizer;
import org.springframework.boot.logging.structured.StructuredLogFormatter; import org.springframework.boot.logging.structured.StructuredLogFormatter;
import org.springframework.boot.logging.structured.StructuredLoggingJsonMembersCustomizer;
/** /**
* Logback {@link StructuredLogFormatter} for {@link CommonStructuredLogFormat#LOGSTASH}. * Logback {@link StructuredLogFormatter} for {@link CommonStructuredLogFormat#LOGSTASH}.
@ -50,7 +50,7 @@ class LogstashStructuredLogFormatter extends JsonWriterStructuredLogFormatter<IL
(pair) -> pair.value); (pair) -> pair.value);
LogstashStructuredLogFormatter(ThrowableProxyConverter throwableProxyConverter, LogstashStructuredLogFormatter(ThrowableProxyConverter throwableProxyConverter,
StructureLoggingJsonMembersCustomizer<?> customizer) { StructuredLoggingJsonMembersCustomizer<?> customizer) {
super((members) -> jsonMembers(throwableProxyConverter, members), customizer); super((members) -> jsonMembers(throwableProxyConverter, members), customizer);
} }

View File

@ -25,10 +25,10 @@ import ch.qos.logback.core.encoder.Encoder;
import ch.qos.logback.core.encoder.EncoderBase; import ch.qos.logback.core.encoder.EncoderBase;
import org.springframework.boot.logging.structured.CommonStructuredLogFormat; import org.springframework.boot.logging.structured.CommonStructuredLogFormat;
import org.springframework.boot.logging.structured.StructureLoggingJsonMembersCustomizer;
import org.springframework.boot.logging.structured.StructuredLogFormatter; import org.springframework.boot.logging.structured.StructuredLogFormatter;
import org.springframework.boot.logging.structured.StructuredLogFormatterFactory; import org.springframework.boot.logging.structured.StructuredLogFormatterFactory;
import org.springframework.boot.logging.structured.StructuredLogFormatterFactory.CommonFormatters; import org.springframework.boot.logging.structured.StructuredLogFormatterFactory.CommonFormatters;
import org.springframework.boot.logging.structured.StructuredLoggingJsonMembersCustomizer;
import org.springframework.boot.util.Instantiator; import org.springframework.boot.util.Instantiator;
import org.springframework.boot.util.Instantiator.AvailableParameters; import org.springframework.boot.util.Instantiator.AvailableParameters;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
@ -89,8 +89,8 @@ public class StructuredLogEncoder extends EncoderBase<ILoggingEvent> {
private StructuredLogFormatter<ILoggingEvent> createEcsFormatter(Instantiator<?> instantiator) { private StructuredLogFormatter<ILoggingEvent> createEcsFormatter(Instantiator<?> instantiator) {
Environment environment = instantiator.getArg(Environment.class); Environment environment = instantiator.getArg(Environment.class);
ThrowableProxyConverter throwableProxyConverter = instantiator.getArg(ThrowableProxyConverter.class); ThrowableProxyConverter throwableProxyConverter = instantiator.getArg(ThrowableProxyConverter.class);
StructureLoggingJsonMembersCustomizer<?> jsonMembersCustomizer = instantiator StructuredLoggingJsonMembersCustomizer<?> jsonMembersCustomizer = instantiator
.getArg(StructureLoggingJsonMembersCustomizer.class); .getArg(StructuredLoggingJsonMembersCustomizer.class);
return new ElasticCommonSchemaStructuredLogFormatter(environment, throwableProxyConverter, return new ElasticCommonSchemaStructuredLogFormatter(environment, throwableProxyConverter,
jsonMembersCustomizer); jsonMembersCustomizer);
} }
@ -98,16 +98,16 @@ public class StructuredLogEncoder extends EncoderBase<ILoggingEvent> {
private StructuredLogFormatter<ILoggingEvent> createGraylogFormatter(Instantiator<?> instantiator) { private StructuredLogFormatter<ILoggingEvent> createGraylogFormatter(Instantiator<?> instantiator) {
Environment environment = instantiator.getArg(Environment.class); Environment environment = instantiator.getArg(Environment.class);
ThrowableProxyConverter throwableProxyConverter = instantiator.getArg(ThrowableProxyConverter.class); ThrowableProxyConverter throwableProxyConverter = instantiator.getArg(ThrowableProxyConverter.class);
StructureLoggingJsonMembersCustomizer<?> jsonMembersCustomizer = instantiator StructuredLoggingJsonMembersCustomizer<?> jsonMembersCustomizer = instantiator
.getArg(StructureLoggingJsonMembersCustomizer.class); .getArg(StructuredLoggingJsonMembersCustomizer.class);
return new GraylogExtendedLogFormatStructuredLogFormatter(environment, throwableProxyConverter, return new GraylogExtendedLogFormatStructuredLogFormatter(environment, throwableProxyConverter,
jsonMembersCustomizer); jsonMembersCustomizer);
} }
private StructuredLogFormatter<ILoggingEvent> createLogstashFormatter(Instantiator<?> instantiator) { private StructuredLogFormatter<ILoggingEvent> createLogstashFormatter(Instantiator<?> instantiator) {
ThrowableProxyConverter throwableProxyConverter = instantiator.getArg(ThrowableProxyConverter.class); ThrowableProxyConverter throwableProxyConverter = instantiator.getArg(ThrowableProxyConverter.class);
StructureLoggingJsonMembersCustomizer<?> jsonMembersCustomizer = instantiator StructuredLoggingJsonMembersCustomizer<?> jsonMembersCustomizer = instantiator
.getArg(StructureLoggingJsonMembersCustomizer.class); .getArg(StructuredLoggingJsonMembersCustomizer.class);
return new LogstashStructuredLogFormatter(throwableProxyConverter, jsonMembersCustomizer); return new LogstashStructuredLogFormatter(throwableProxyConverter, jsonMembersCustomizer);
} }

View File

@ -42,18 +42,18 @@ public abstract class JsonWriterStructuredLogFormatter<E> implements StructuredL
* @param customizer an optional customizer to apply * @param customizer an optional customizer to apply
*/ */
protected JsonWriterStructuredLogFormatter(Consumer<Members<E>> members, protected JsonWriterStructuredLogFormatter(Consumer<Members<E>> members,
StructureLoggingJsonMembersCustomizer<?> customizer) { StructuredLoggingJsonMembersCustomizer<?> customizer) {
this(JsonWriter.of(customized(members, customizer)).withNewLineAtEnd()); this(JsonWriter.of(customized(members, customizer)).withNewLineAtEnd());
} }
private static <E> Consumer<Members<E>> customized(Consumer<Members<E>> members, private static <E> Consumer<Members<E>> customized(Consumer<Members<E>> members,
StructureLoggingJsonMembersCustomizer<?> customizer) { StructuredLoggingJsonMembersCustomizer<?> customizer) {
return (customizer != null) ? members.andThen(customizeWith(customizer)) : members; return (customizer != null) ? members.andThen(customizeWith(customizer)) : members;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static <E> Consumer<Members<E>> customizeWith(StructureLoggingJsonMembersCustomizer<?> customizer) { private static <E> Consumer<Members<E>> customizeWith(StructuredLoggingJsonMembersCustomizer<?> customizer) {
return (members) -> LambdaSafe.callback(StructureLoggingJsonMembersCustomizer.class, customizer, members) return (members) -> LambdaSafe.callback(StructuredLoggingJsonMembersCustomizer.class, customizer, members)
.invoke((instance) -> instance.customize(members)); .invoke((instance) -> instance.customize(members));
} }

View File

@ -28,7 +28,7 @@ import org.springframework.core.env.Environment;
* Implementing classes can declare the following parameter types in the constructor: * Implementing classes can declare the following parameter types in the constructor:
* <ul> * <ul>
* <li>{@link Environment}</li> * <li>{@link Environment}</li>
* <li>{@link StructureLoggingJsonMembersCustomizer}</li> * <li>{@link StructuredLoggingJsonMembersCustomizer}</li>
* </ul> * </ul>
* When using Logback, implementing classes can also use the following parameter types in * When using Logback, implementing classes can also use the following parameter types in
* the constructor: * the constructor:

View File

@ -82,8 +82,8 @@ public class StructuredLogFormatterFactory<E> {
this.logEventType = logEventType; this.logEventType = logEventType;
this.instantiator = new Instantiator<>(Object.class, (allAvailableParameters) -> { this.instantiator = new Instantiator<>(Object.class, (allAvailableParameters) -> {
allAvailableParameters.add(Environment.class, environment); allAvailableParameters.add(Environment.class, environment);
allAvailableParameters.add(StructureLoggingJsonMembersCustomizer.class, allAvailableParameters.add(StructuredLoggingJsonMembersCustomizer.class,
(type) -> getStructureLoggingJsonMembersCustomizer(environment)); (type) -> getStructuredLoggingJsonMembersCustomizer(environment));
if (availableParameters != null) { if (availableParameters != null) {
availableParameters.accept(allAvailableParameters); availableParameters.accept(allAvailableParameters);
} }
@ -92,26 +92,26 @@ public class StructuredLogFormatterFactory<E> {
commonFormatters.accept(this.commonFormatters); commonFormatters.accept(this.commonFormatters);
} }
StructureLoggingJsonMembersCustomizer<?> getStructureLoggingJsonMembersCustomizer(Environment environment) { StructuredLoggingJsonMembersCustomizer<?> getStructuredLoggingJsonMembersCustomizer(Environment environment) {
List<StructureLoggingJsonMembersCustomizer<?>> customizers = new ArrayList<>(); List<StructuredLoggingJsonMembersCustomizer<?>> customizers = new ArrayList<>();
StructuredLoggingJsonProperties properties = StructuredLoggingJsonProperties.get(environment); StructuredLoggingJsonProperties properties = StructuredLoggingJsonProperties.get(environment);
if (properties != null) { if (properties != null) {
customizers.add(new StructuredLoggingJsonPropertiesJsonMembersCustomizer(this.instantiator, properties)); customizers.add(new StructuredLoggingJsonPropertiesJsonMembersCustomizer(this.instantiator, properties));
} }
customizers.addAll(loadStructureLoggingJsonMembersCustomizers()); customizers.addAll(loadStructuredLoggingJsonMembersCustomizers());
return (members) -> invokeCustomizers(customizers, members); return (members) -> invokeCustomizers(customizers, members);
} }
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
private List<StructureLoggingJsonMembersCustomizer<?>> loadStructureLoggingJsonMembersCustomizers() { private List<StructuredLoggingJsonMembersCustomizer<?>> loadStructuredLoggingJsonMembersCustomizers() {
return (List) this.factoriesLoader.load(StructureLoggingJsonMembersCustomizer.class, return (List) this.factoriesLoader.load(StructuredLoggingJsonMembersCustomizer.class,
ArgumentResolver.from(this.instantiator::getArg)); ArgumentResolver.from(this.instantiator::getArg));
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void invokeCustomizers(List<StructureLoggingJsonMembersCustomizer<?>> customizers, private void invokeCustomizers(List<StructuredLoggingJsonMembersCustomizer<?>> customizers,
Members<Object> members) { Members<Object> members) {
LambdaSafe.callbacks(StructureLoggingJsonMembersCustomizer.class, customizers, members) LambdaSafe.callbacks(StructuredLoggingJsonMembersCustomizer.class, customizers, members)
.invoke((customizer) -> customizer.customize(members)); .invoke((customizer) -> customizer.customize(members));
} }

View File

@ -32,7 +32,7 @@ import org.springframework.boot.json.JsonWriter.Members;
* @see JsonWriterStructuredLogFormatter * @see JsonWriterStructuredLogFormatter
*/ */
@FunctionalInterface @FunctionalInterface
public interface StructureLoggingJsonMembersCustomizer<T> { public interface StructuredLoggingJsonMembersCustomizer<T> {
/** /**
* Customize the given {@link Members} instance. * Customize the given {@link Members} instance.

View File

@ -28,13 +28,13 @@ import org.springframework.core.env.Environment;
* @param include the paths that should be included. An empty set includes all names * @param include the paths that should be included. An empty set includes all names
* @param exclude the paths that should be excluded. An empty set excludes nothing * @param exclude the paths that should be excluded. An empty set excludes nothing
* @param rename a map of path to replacement names * @param rename a map of path to replacement names
* @param add a map of additional elements {@link StructureLoggingJsonMembersCustomizer} * @param add a map of additional elements {@link StructuredLoggingJsonMembersCustomizer}
* @param customizer the fully qualified name of a * @param customizer the fully qualified name of a
* {@link StructureLoggingJsonMembersCustomizer} * {@link StructuredLoggingJsonMembersCustomizer}
* @author Phillip Webb * @author Phillip Webb
*/ */
record StructuredLoggingJsonProperties(Set<String> include, Set<String> exclude, Map<String, String> rename, record StructuredLoggingJsonProperties(Set<String> include, Set<String> exclude, Map<String, String> rename,
Map<String, String> add, Class<? extends StructureLoggingJsonMembersCustomizer<?>> customizer) { Map<String, String> add, Class<? extends StructuredLoggingJsonMembersCustomizer<?>> customizer) {
static StructuredLoggingJsonProperties get(Environment environment) { static StructuredLoggingJsonProperties get(Environment environment) {
return Binder.get(environment) return Binder.get(environment)

View File

@ -24,12 +24,12 @@ import org.springframework.boot.util.Instantiator;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
/** /**
* {@link StructureLoggingJsonMembersCustomizer} to apply * {@link StructuredLoggingJsonMembersCustomizer} to apply
* {@link StructuredLoggingJsonProperties}. * {@link StructuredLoggingJsonProperties}.
* *
* @author Phillip Webb * @author Phillip Webb
*/ */
class StructuredLoggingJsonPropertiesJsonMembersCustomizer implements StructureLoggingJsonMembersCustomizer<Object> { class StructuredLoggingJsonPropertiesJsonMembersCustomizer implements StructuredLoggingJsonMembersCustomizer<Object> {
private final Instantiator<?> instantiator; private final Instantiator<?> instantiator;
@ -49,7 +49,7 @@ class StructuredLoggingJsonPropertiesJsonMembersCustomizer implements StructureL
if (!CollectionUtils.isEmpty(add)) { if (!CollectionUtils.isEmpty(add)) {
add.forEach(members::add); add.forEach(members::add);
} }
Class<? extends StructureLoggingJsonMembersCustomizer<?>> customizer = this.properties.customizer(); Class<? extends StructuredLoggingJsonMembersCustomizer<?>> customizer = this.properties.customizer();
if (customizer != null) { if (customizer != null) {
createAndApplyCustomizer(members, customizer); createAndApplyCustomizer(members, customizer);
} }
@ -71,8 +71,9 @@ class StructuredLoggingJsonPropertiesJsonMembersCustomizer implements StructureL
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
private void createAndApplyCustomizer(Members<Object> members, private void createAndApplyCustomizer(Members<Object> members,
Class<? extends StructureLoggingJsonMembersCustomizer<?>> customizerClass) { Class<? extends StructuredLoggingJsonMembersCustomizer<?>> customizerClass) {
((StructureLoggingJsonMembersCustomizer) this.instantiator.instantiateType(customizerClass)).customize(members); ((StructuredLoggingJsonMembersCustomizer) this.instantiator.instantiateType(customizerClass))
.customize(members);
} }
} }

View File

@ -269,7 +269,7 @@
{ {
"name": "logging.structured.json.customizer", "name": "logging.structured.json.customizer",
"type": "java.lang.String", "type": "java.lang.String",
"description": "The fully qualified class name of a StructureLoggingJsonMembersCustomizer" "description": "The fully qualified class name of a StructuredLoggingJsonMembersCustomizer"
}, },
{ {
"name": "logging.structured.json.exclude", "name": "logging.structured.json.exclude",

View File

@ -31,7 +31,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.boot.logging.structured.StructureLoggingJsonMembersCustomizer; import org.springframework.boot.logging.structured.StructuredLoggingJsonMembersCustomizer;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -48,7 +48,7 @@ abstract class AbstractStructuredLoggingTests {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Mock @Mock
StructureLoggingJsonMembersCustomizer<?> customizer; StructuredLoggingJsonMembersCustomizer<?> customizer;
protected Map<String, Object> map(Object... values) { protected Map<String, Object> map(Object... values) {
assertThat(values.length).isEven(); assertThat(values.length).isEven();

View File

@ -38,7 +38,7 @@ import org.slf4j.Marker;
import org.slf4j.event.KeyValuePair; import org.slf4j.event.KeyValuePair;
import org.slf4j.helpers.BasicMarkerFactory; import org.slf4j.helpers.BasicMarkerFactory;
import org.springframework.boot.logging.structured.StructureLoggingJsonMembersCustomizer; import org.springframework.boot.logging.structured.StructuredLoggingJsonMembersCustomizer;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -59,7 +59,7 @@ abstract class AbstractStructuredLoggingTests {
private BasicMarkerFactory markerFactory; private BasicMarkerFactory markerFactory;
@Mock @Mock
StructureLoggingJsonMembersCustomizer<?> customizer; StructuredLoggingJsonMembersCustomizer<?> customizer;
@BeforeEach @BeforeEach
void setUp() { void setUp() {

View File

@ -107,7 +107,7 @@ class StructuredLogFormatterFactoryTests {
void getInjectCustomizers() { void getInjectCustomizers() {
this.environment.setProperty("logging.structured.json.rename.spring", "test"); this.environment.setProperty("logging.structured.json.rename.spring", "test");
SpringFactoriesLoader factoriesLoader = mock(SpringFactoriesLoader.class); SpringFactoriesLoader factoriesLoader = mock(SpringFactoriesLoader.class);
StructureLoggingJsonMembersCustomizer<?> customizer = (members) -> members StructuredLoggingJsonMembersCustomizer<?> customizer = (members) -> members
.applyingValueProcessor(ValueProcessor.of(String.class, String::toUpperCase)); .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(customizer));
StructuredLogFormatterFactory<LogEvent> factory = new StructuredLogFormatterFactory<>(factoriesLoader, StructuredLogFormatterFactory<LogEvent> factory = new StructuredLogFormatterFactory<>(factoriesLoader,
@ -169,7 +169,7 @@ class StructuredLogFormatterFactoryTests {
static class CutomizedFormatter extends JsonWriterStructuredLogFormatter<LogEvent> { static class CutomizedFormatter extends JsonWriterStructuredLogFormatter<LogEvent> {
CutomizedFormatter(StructureLoggingJsonMembersCustomizer<?> customizer) { CutomizedFormatter(StructuredLoggingJsonMembersCustomizer<?> customizer) {
super((members) -> members.add("spring", "boot"), customizer); super((members) -> members.add("spring", "boot"), customizer);
} }

View File

@ -98,7 +98,7 @@ class StructuredLoggingJsonPropertiesJsonMembersCustomizerTests {
@Test @Test
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
void customizeWhenHasCustomizerCustomizesMember() { void customizeWhenHasCustomizerCustomizesMember() {
StructureLoggingJsonMembersCustomizer<?> uppercaseCustomizer = (members) -> members StructuredLoggingJsonMembersCustomizer<?> uppercaseCustomizer = (members) -> members
.applyingNameProcessor(NameProcessor.of(String::toUpperCase)); .applyingNameProcessor(NameProcessor.of(String::toUpperCase));
given(((Instantiator) this.instantiator).instantiateType(TestCustomizer.class)).willReturn(uppercaseCustomizer); given(((Instantiator) this.instantiator).instantiateType(TestCustomizer.class)).willReturn(uppercaseCustomizer);
StructuredLoggingJsonProperties properties = new StructuredLoggingJsonProperties(Collections.emptySet(), StructuredLoggingJsonProperties properties = new StructuredLoggingJsonProperties(Collections.emptySet(),
@ -109,7 +109,7 @@ class StructuredLoggingJsonPropertiesJsonMembersCustomizerTests {
} }
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
private String writeSampleJson(StructureLoggingJsonMembersCustomizer customizer) { private String writeSampleJson(StructuredLoggingJsonMembersCustomizer customizer) {
return JsonWriter.of((members) -> { return JsonWriter.of((members) -> {
members.add("a", "a"); members.add("a", "a");
members.add("b", "b"); members.add("b", "b");
@ -118,7 +118,7 @@ class StructuredLoggingJsonPropertiesJsonMembersCustomizerTests {
}).writeToString(new Object()); }).writeToString(new Object());
} }
static class TestCustomizer implements StructureLoggingJsonMembersCustomizer<String> { static class TestCustomizer implements StructuredLoggingJsonMembersCustomizer<String> {
@Override @Override
public void customize(Members<String> members) { public void customize(Members<String> members) {

View File

@ -52,7 +52,7 @@ class StructuredLoggingJsonPropertiesTests {
StructuredLoggingJsonProperties.get(environment); StructuredLoggingJsonProperties.get(environment);
} }
static class TestCustomizer implements StructureLoggingJsonMembersCustomizer<String> { static class TestCustomizer implements StructuredLoggingJsonMembersCustomizer<String> {
@Override @Override
public void customize(Members<String> members) { public void customize(Members<String> members) {

View File

@ -2,7 +2,7 @@ plugins {
id "java" id "java"
} }
description = "Spring Boot structure logging Log4j2 smoke test" description = "Spring Boot structured logging Log4j2 smoke test"
configurations.all { configurations.all {
exclude module: "spring-boot-starter-logging" exclude module: "spring-boot-starter-logging"

View File

@ -2,7 +2,7 @@ plugins {
id "java" id "java"
} }
description = "Spring Boot structure logging smoke test" description = "Spring Boot structured logging smoke test"
dependencies { dependencies {
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter"))

View File

@ -18,9 +18,9 @@ package smoketest.structuredlogging;
import org.springframework.boot.json.JsonWriter.Members; import org.springframework.boot.json.JsonWriter.Members;
import org.springframework.boot.json.JsonWriter.ValueProcessor; import org.springframework.boot.json.JsonWriter.ValueProcessor;
import org.springframework.boot.logging.structured.StructureLoggingJsonMembersCustomizer; import org.springframework.boot.logging.structured.StructuredLoggingJsonMembersCustomizer;
public class SampleJsonMembersCustomizer implements StructureLoggingJsonMembersCustomizer<Object> { public class SampleJsonMembersCustomizer implements StructuredLoggingJsonMembersCustomizer<Object> {
@Override @Override
public void customize(Members<Object> members) { public void customize(Members<Object> members) {