Merge branch '4.0.x'

Closes gh-50414
This commit is contained in:
Phillip Webb
2026-05-12 13:08:05 -07:00
3 changed files with 27 additions and 19 deletions
@@ -93,7 +93,8 @@ public class StructuredLogFormatterFactory<E> {
new JsonMembersCustomizerBuilder(properties).build());
allAvailableParameters.add(StructuredLoggingJsonMembersCustomizer.Builder.class,
new JsonMembersCustomizerBuilder(properties));
allAvailableParameters.add(StackTracePrinter.class, (type) -> getStackTracePrinter(properties));
allAvailableParameters.add(StackTracePrinter.class,
(type) -> getStackTracePrinter(properties, environment));
allAvailableParameters.add(ContextPairs.class, (type) -> getContextPairs(properties));
if (availableParameters != null) {
availableParameters.accept(allAvailableParameters);
@@ -103,8 +104,10 @@ public class StructuredLogFormatterFactory<E> {
commonFormatters.accept(this.commonFormatters);
}
private @Nullable StackTracePrinter getStackTracePrinter(@Nullable StructuredLoggingJsonProperties properties) {
return (properties != null && properties.stackTrace() != null) ? properties.stackTrace().createPrinter() : null;
private @Nullable StackTracePrinter getStackTracePrinter(@Nullable StructuredLoggingJsonProperties properties,
Environment environment) {
return (properties != null && properties.stackTrace() != null)
? properties.stackTrace().createPrinter(environment) : null;
}
private ContextPairs getContextPairs(@Nullable StructuredLoggingJsonProperties properties) {
@@ -102,7 +102,7 @@ record StructuredLoggingJsonProperties(Set<String> include, Set<String> exclude,
@Nullable Integer maxThrowableDepth, @Nullable Boolean includeCommonFrames,
@Nullable Boolean includeHashes) {
@Nullable StackTracePrinter createPrinter() {
@Nullable StackTracePrinter createPrinter(Environment environment) {
String name = sanitizePrinter();
if ("loggingsystem".equals(name) || (name.isEmpty() && !hasAnyOtherProperty())) {
return null;
@@ -112,9 +112,10 @@ record StructuredLoggingJsonProperties(Set<String> include, Set<String> exclude,
return standardPrinter;
}
Assert.state(printer() != null, "'printer' must not be null");
return (StackTracePrinter) new Instantiator<>(StackTracePrinter.class,
(parameters) -> parameters.add(StandardStackTracePrinter.class, standardPrinter))
.instantiate(printer());
return (StackTracePrinter) new Instantiator<>(StackTracePrinter.class, (parameters) -> {
parameters.add(StandardStackTracePrinter.class, standardPrinter);
parameters.add(Environment.class, environment);
}).instantiate(printer());
}
boolean hasCustomPrinter() {
@@ -35,6 +35,7 @@ import org.springframework.boot.logging.structured.StructuredLoggingJsonProperti
import org.springframework.boot.logging.structured.StructuredLoggingJsonProperties.StackTrace;
import org.springframework.boot.logging.structured.StructuredLoggingJsonProperties.StackTrace.Root;
import org.springframework.boot.logging.structured.StructuredLoggingJsonProperties.StructuredLoggingJsonPropertiesRuntimeHints;
import org.springframework.core.env.Environment;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.util.ClassUtils;
@@ -116,44 +117,45 @@ class StructuredLoggingJsonPropertiesTests {
@Test
void createPrinterWhenEmptyReturnsNull() {
StackTrace properties = new StackTrace(null, null, null, null, null, null);
assertThat(properties.createPrinter()).isNull();
assertThat(properties.createPrinter(new MockEnvironment())).isNull();
}
@Test
void createPrinterWhenNoPrinterAndNotEmptyReturnsStandard() {
StackTrace properties = new StackTrace(null, Root.LAST, null, null, null, null);
assertThat(properties.createPrinter()).isInstanceOf(StandardStackTracePrinter.class);
assertThat(properties.createPrinter(new MockEnvironment())).isInstanceOf(StandardStackTracePrinter.class);
}
@Test
void createPrinterWhenLoggingSystemReturnsNull() {
StackTrace properties = new StackTrace("logging-system", null, null, null, null, null);
assertThat(properties.createPrinter()).isNull();
assertThat(properties.createPrinter(new MockEnvironment())).isNull();
}
@Test
void createPrinterWhenLoggingSystemRelaxedReturnsNull() {
StackTrace properties = new StackTrace("LoggingSystem", null, null, null, null, null);
assertThat(properties.createPrinter()).isNull();
assertThat(properties.createPrinter(new MockEnvironment())).isNull();
}
@Test
void createPrinterWhenStandardReturnsStandardPrinter() {
StackTrace properties = new StackTrace("standard", null, null, null, null, null);
assertThat(properties.createPrinter()).isInstanceOf(StandardStackTracePrinter.class);
assertThat(properties.createPrinter(new MockEnvironment())).isInstanceOf(StandardStackTracePrinter.class);
}
@Test
void createPrinterWhenStandardRelaxedReturnsStandardPrinter() {
StackTrace properties = new StackTrace("STANDARD", null, null, null, null, null);
assertThat(properties.createPrinter()).isInstanceOf(StandardStackTracePrinter.class);
assertThat(properties.createPrinter(new MockEnvironment())).isInstanceOf(StandardStackTracePrinter.class);
}
@Test
void createPrinterWhenStandardAppliesCustomizations() {
Exception exception = TestException.create();
StackTrace properties = new StackTrace(null, Root.FIRST, 300, 2, true, false);
StandardStackTracePrinter printer = (StandardStackTracePrinter) properties.createPrinter();
StandardStackTracePrinter printer = (StandardStackTracePrinter) properties
.createPrinter(new MockEnvironment());
assertThat(printer).isNotNull();
printer = printer.withLineSeparator("\n");
String actual = TestException.withoutLineNumbers(printer.printStackTraceToString(exception));
@@ -169,7 +171,7 @@ class StructuredLoggingJsonPropertiesTests {
void createPrinterWhenStandardWithHashesPrintsHash() {
Exception exception = TestException.create();
StackTrace properties = new StackTrace(null, null, null, null, null, true);
StackTracePrinter printer = properties.createPrinter();
StackTracePrinter printer = properties.createPrinter(new MockEnvironment());
assertThat(printer).isNotNull();
String actual = printer.printStackTraceToString(exception);
assertThat(actual).containsPattern("<#[0-9a-z]{8}>");
@@ -179,7 +181,7 @@ class StructuredLoggingJsonPropertiesTests {
void createPrinterWhenClassNameCreatesPrinter() {
Exception exception = TestException.create();
StackTrace properties = new StackTrace(TestStackTracePrinter.class.getName(), null, null, null, true, null);
StackTracePrinter printer = properties.createPrinter();
StackTracePrinter printer = properties.createPrinter(new MockEnvironment());
assertThat(printer).isNotNull();
assertThat(printer.printStackTraceToString(exception)).isEqualTo("java.lang.RuntimeException: exception");
}
@@ -187,9 +189,11 @@ class StructuredLoggingJsonPropertiesTests {
@Test
void createPrinterWhenClassNameInjectsConfiguredPrinter() {
Exception exception = TestException.create();
MockEnvironment environment = new MockEnvironment();
environment.setProperty("stracktracelineseparator", "!");
StackTrace properties = new StackTrace(TestStackTracePrinterCustomized.class.getName(), Root.FIRST, 300, 2,
true, null);
StackTracePrinter printer = properties.createPrinter();
StackTracePrinter printer = properties.createPrinter(environment);
assertThat(printer).isNotNull();
String actual = TestException.withoutLineNumbers(printer.printStackTraceToString(exception));
assertThat(actual).isEqualTo("RuntimeExceptionroot! at org.springfr...");
@@ -242,9 +246,9 @@ class StructuredLoggingJsonPropertiesTests {
private final StandardStackTracePrinter printer;
TestStackTracePrinterCustomized(StandardStackTracePrinter printer) {
TestStackTracePrinterCustomized(StandardStackTracePrinter printer, Environment environment) {
this.printer = printer.withMaximumLength(40)
.withLineSeparator("!")
.withLineSeparator(environment.getProperty("stracktracelineseparator", "\n"))
.withFormatter((throwable) -> ClassUtils.getShortName(throwable.getClass()) + throwable.getMessage());
}