diff --git a/core/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLogFormatterFactory.java b/core/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLogFormatterFactory.java index 750469dfb09..630e0f58ba7 100644 --- a/core/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLogFormatterFactory.java +++ b/core/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLogFormatterFactory.java @@ -93,7 +93,8 @@ public class StructuredLogFormatterFactory { 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 { 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) { diff --git a/core/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLoggingJsonProperties.java b/core/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLoggingJsonProperties.java index 6ff05dde52f..0b14d2b9e4c 100644 --- a/core/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLoggingJsonProperties.java +++ b/core/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLoggingJsonProperties.java @@ -102,7 +102,7 @@ record StructuredLoggingJsonProperties(Set include, Set 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 include, Set 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() { diff --git a/core/spring-boot/src/test/java/org/springframework/boot/logging/structured/StructuredLoggingJsonPropertiesTests.java b/core/spring-boot/src/test/java/org/springframework/boot/logging/structured/StructuredLoggingJsonPropertiesTests.java index 54bca909f75..a63306f300c 100644 --- a/core/spring-boot/src/test/java/org/springframework/boot/logging/structured/StructuredLoggingJsonPropertiesTests.java +++ b/core/spring-boot/src/test/java/org/springframework/boot/logging/structured/StructuredLoggingJsonPropertiesTests.java @@ -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()); }