mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-09-17 12:09:16 +00:00
Switch Logback's file logging charset to UTF-8
This commit aligns the file charset between Log4j2 and Logback. Prior to this commit, there was an inconsistency between the two: Log4j2 used UTF-8, while Logback used Charset.defaultCharset(), which is platform-dependent. See gh-46846 Signed-off-by: Dmytro Nosan <dimanosan@gmail.com>
This commit is contained in:
committed by
Stéphane Nicoll
parent
4e425a9b4d
commit
26372e78c6
+13
-2
@@ -16,7 +16,9 @@
|
||||
|
||||
package org.springframework.boot.logging.logback;
|
||||
|
||||
import java.io.Console;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
|
||||
@@ -55,7 +57,7 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
class DefaultLogbackConfiguration {
|
||||
|
||||
private static final String DEFAULT_CHARSET = Charset.defaultCharset().name();
|
||||
private static final String DEFAULT_CHARSET = StandardCharsets.UTF_8.name();
|
||||
|
||||
private static final String NAME_AND_GROUP = "%esb(){APPLICATION_NAME}%esb{APPLICATION_GROUP}";
|
||||
|
||||
@@ -106,7 +108,7 @@ class DefaultLogbackConfiguration {
|
||||
config.conversionRule("wEx", ExtendedWhitespaceThrowableProxyConverter.class,
|
||||
ExtendedWhitespaceThrowableProxyConverter::new);
|
||||
putProperty(config, "CONSOLE_LOG_PATTERN", CONSOLE_LOG_PATTERN);
|
||||
putProperty(config, "CONSOLE_LOG_CHARSET", "${CONSOLE_LOG_CHARSET:-" + DEFAULT_CHARSET + "}");
|
||||
putProperty(config, "CONSOLE_LOG_CHARSET", "${CONSOLE_LOG_CHARSET:-" + getConsoleCharset() + "}");
|
||||
putProperty(config, "CONSOLE_LOG_THRESHOLD", "${CONSOLE_LOG_THRESHOLD:-TRACE}");
|
||||
putProperty(config, "CONSOLE_LOG_STRUCTURED_FORMAT", "${CONSOLE_LOG_STRUCTURED_FORMAT:-}");
|
||||
putProperty(config, "FILE_LOG_PATTERN", FILE_LOG_PATTERN);
|
||||
@@ -123,6 +125,15 @@ class DefaultLogbackConfiguration {
|
||||
config.logger("org.springframework.boot.actuate.endpoint.jmx", Level.WARN);
|
||||
}
|
||||
|
||||
private String getConsoleCharset() {
|
||||
Console console = getConsole();
|
||||
return (console != null) ? console.charset().name() : DEFAULT_CHARSET;
|
||||
}
|
||||
|
||||
@Nullable Console getConsole() {
|
||||
return System.console();
|
||||
}
|
||||
|
||||
void putProperty(LogbackConfigurator config, String name, String val) {
|
||||
config.getContext().putProperty(name, resolve(config, val));
|
||||
}
|
||||
|
||||
-6
@@ -17,7 +17,6 @@
|
||||
package org.springframework.boot.logging.logback;
|
||||
|
||||
import java.io.Console;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -78,11 +77,6 @@ public class LogbackLoggingSystemProperties extends LoggingSystemProperties {
|
||||
return super.getConsole();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Charset getDefaultFileCharset() {
|
||||
return Charset.defaultCharset();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void apply(@Nullable LogFile logFile, PropertyResolver resolver) {
|
||||
super.apply(logFile, resolver);
|
||||
|
||||
+68
@@ -16,14 +16,19 @@
|
||||
|
||||
package org.springframework.boot.logging.logback;
|
||||
|
||||
import java.io.Console;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
/**
|
||||
* Tests for {@link DefaultLogbackConfiguration}
|
||||
@@ -32,6 +37,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
class DefaultLogbackConfigurationTests {
|
||||
|
||||
private final LoggerContext loggerContext = new LoggerContext();
|
||||
|
||||
private final LogbackConfigurator logbackConfigurator = new LogbackConfigurator(this.loggerContext);
|
||||
|
||||
@Test
|
||||
void defaultLogbackXmlContainsConsoleLogPattern() throws Exception {
|
||||
assertThatDefaultXmlContains("CONSOLE_LOG_PATTERN", DefaultLogbackConfiguration.CONSOLE_LOG_PATTERN);
|
||||
@@ -42,6 +51,48 @@ class DefaultLogbackConfigurationTests {
|
||||
assertThatDefaultXmlContains("FILE_LOG_PATTERN", DefaultLogbackConfiguration.FILE_LOG_PATTERN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void consoleLogCharsetShouldUseConsoleCharsetIfConsoleAvailable() {
|
||||
DefaultLogbackConfiguration logbackConfiguration = spy(new DefaultLogbackConfiguration(null));
|
||||
Console console = mock(Console.class);
|
||||
given(console.charset()).willReturn(StandardCharsets.UTF_16);
|
||||
given(logbackConfiguration.getConsole()).willReturn(console);
|
||||
logbackConfiguration.apply(this.logbackConfigurator);
|
||||
assertThat(this.loggerContext.getProperty("CONSOLE_LOG_CHARSET")).isEqualTo(StandardCharsets.UTF_16.name());
|
||||
}
|
||||
|
||||
@Test
|
||||
void consoleLogCharsetShouldDefaultToUtf8WhenConsoleIsNull() {
|
||||
DefaultLogbackConfiguration logbackConfiguration = spy(new DefaultLogbackConfiguration(null));
|
||||
given(logbackConfiguration.getConsole()).willReturn(null);
|
||||
logbackConfiguration.apply(this.logbackConfigurator);
|
||||
assertThat(this.loggerContext.getProperty("CONSOLE_LOG_CHARSET")).isEqualTo(StandardCharsets.UTF_8.name());
|
||||
}
|
||||
|
||||
@Test
|
||||
void consoleLogCharsetShouldUseSystemPropertyIfSet() {
|
||||
withSystemProperty("CONSOLE_LOG_CHARSET", StandardCharsets.US_ASCII.name(), () -> {
|
||||
new DefaultLogbackConfiguration(null).apply(this.logbackConfigurator);
|
||||
assertThat(this.loggerContext.getProperty("CONSOLE_LOG_CHARSET"))
|
||||
.isEqualTo(StandardCharsets.US_ASCII.name());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void fileLogCharsetShouldUseSystemPropertyIfSet() {
|
||||
withSystemProperty("FILE_LOG_CHARSET", StandardCharsets.ISO_8859_1.name(), () -> {
|
||||
new DefaultLogbackConfiguration(null).apply(this.logbackConfigurator);
|
||||
assertThat(this.loggerContext.getProperty("FILE_LOG_CHARSET"))
|
||||
.isEqualTo(StandardCharsets.ISO_8859_1.name());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void fileLogCharsetShouldDefaultToUtf8() {
|
||||
new DefaultLogbackConfiguration(null).apply(this.logbackConfigurator);
|
||||
assertThat(this.loggerContext.getProperty("FILE_LOG_CHARSET")).isEqualTo(StandardCharsets.UTF_8.name());
|
||||
}
|
||||
|
||||
private void assertThatDefaultXmlContains(String name, String value) throws Exception {
|
||||
String expected = "<property name=\"%s\" value=\"%s\"/>".formatted(name, value);
|
||||
assertThat(defaultXmlContent()).contains(expected);
|
||||
@@ -51,4 +102,21 @@ class DefaultLogbackConfigurationTests {
|
||||
return StreamUtils.copyToString(getClass().getResourceAsStream("defaults.xml"), StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
private static void withSystemProperty(String name, String value, Runnable action) {
|
||||
String previous = System.getProperty(name);
|
||||
try {
|
||||
System.setProperty(name, value);
|
||||
action.run();
|
||||
}
|
||||
finally {
|
||||
if (previous != null) {
|
||||
System.setProperty(name, previous);
|
||||
}
|
||||
else {
|
||||
System.clearProperty(name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -131,10 +131,10 @@ class LogbackLoggingSystemPropertiesTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void fileCharsetWhenNoPropertyUsesDefault() {
|
||||
void fileCharsetWhenNoPropertyUsesUtf8() {
|
||||
new LoggingSystemProperties(new MockEnvironment()).apply(null);
|
||||
assertThat(System.getProperty(LoggingSystemProperty.FILE_CHARSET.getEnvironmentVariableName()))
|
||||
.isEqualTo(Charset.defaultCharset().name());
|
||||
.isEqualTo(StandardCharsets.UTF_8.name());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user