Skip to content

Commit 98707ab

Browse files
committed
Use Console charset for console logging when available
Prior to this commit, LogbackLoggingSystemProperties doesn't respect Console.charset(). It used Charset.getDefaultCharset() for logback and UTF-8 for log42j as defaults. This commit changes the behaviour of LogbackLoggingSystemProperties to use Console.charset() when available. If no console is present, the default charset is used instead. These changes bring consistency across logging implementations. See gh-43118 Signed-off-by: Dmytro Nosan <[email protected]>
1 parent f096707 commit 98707ab

File tree

4 files changed

+65
-15
lines changed

4 files changed

+65
-15
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/LoggingSystemProperties.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616

1717
package org.springframework.boot.logging;
1818

19+
import java.io.Console;
1920
import java.nio.charset.Charset;
20-
import java.nio.charset.StandardCharsets;
21+
import java.util.Optional;
2122
import java.util.function.BiConsumer;
2223
import java.util.function.Function;
2324

@@ -91,8 +92,12 @@ public LoggingSystemProperties(Environment environment, Function<String, String>
9192
this.setter = (setter != null) ? setter : systemPropertySetter;
9293
}
9394

95+
protected Console getConsole() {
96+
return System.console();
97+
}
98+
9499
protected Charset getDefaultCharset() {
95-
return StandardCharsets.UTF_8;
100+
return Charset.defaultCharset();
96101
}
97102

98103
public final void apply() {
@@ -116,12 +121,11 @@ private PropertyResolver getPropertyResolver() {
116121
}
117122

118123
protected void apply(LogFile logFile, PropertyResolver resolver) {
119-
String defaultCharsetName = getDefaultCharset().name();
120124
setSystemProperty(LoggingSystemProperty.APPLICATION_NAME, resolver);
121125
setSystemProperty(LoggingSystemProperty.APPLICATION_GROUP, resolver);
122126
setSystemProperty(LoggingSystemProperty.PID, new ApplicationPid().toString());
123-
setSystemProperty(LoggingSystemProperty.CONSOLE_CHARSET, resolver, defaultCharsetName);
124-
setSystemProperty(LoggingSystemProperty.FILE_CHARSET, resolver, defaultCharsetName);
127+
setSystemProperty(LoggingSystemProperty.CONSOLE_CHARSET, resolver, getConsoleCharset().name());
128+
setSystemProperty(LoggingSystemProperty.FILE_CHARSET, resolver, getDefaultCharset().name());
125129
setSystemProperty(LoggingSystemProperty.CONSOLE_THRESHOLD, resolver, this::thresholdMapper);
126130
setSystemProperty(LoggingSystemProperty.FILE_THRESHOLD, resolver, this::thresholdMapper);
127131
setSystemProperty(LoggingSystemProperty.EXCEPTION_CONVERSION_WORD, resolver);
@@ -137,6 +141,10 @@ protected void apply(LogFile logFile, PropertyResolver resolver) {
137141
}
138142
}
139143

144+
private Charset getConsoleCharset() {
145+
return Optional.ofNullable(getConsole()).map(Console::charset).orElseGet(this::getDefaultCharset);
146+
}
147+
140148
private void setSystemProperty(LoggingSystemProperty property, PropertyResolver resolver) {
141149
setSystemProperty(property, resolver, Function.identity());
142150
}

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/LogbackLoggingSystemProperties.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@
1616

1717
package org.springframework.boot.logging.logback;
1818

19-
import java.nio.charset.Charset;
19+
import java.io.Console;
2020
import java.util.function.BiConsumer;
2121
import java.util.function.Function;
2222

@@ -71,8 +71,8 @@ public LogbackLoggingSystemProperties(Environment environment, Function<String,
7171
}
7272

7373
@Override
74-
protected Charset getDefaultCharset() {
75-
return Charset.defaultCharset();
74+
protected Console getConsole() {
75+
return super.getConsole();
7676
}
7777

7878
@Override

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/LoggingSystemPropertiesTests.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,9 @@
1616

1717
package org.springframework.boot.logging;
1818

19+
import java.io.Console;
20+
import java.nio.charset.Charset;
21+
import java.nio.charset.StandardCharsets;
1922
import java.util.Collections;
2023
import java.util.HashSet;
2124
import java.util.Map;
@@ -31,6 +34,9 @@
3134
import org.springframework.mock.env.MockEnvironment;
3235

3336
import static org.assertj.core.api.Assertions.assertThat;
37+
import static org.mockito.BDDMockito.given;
38+
import static org.mockito.Mockito.mock;
39+
import static org.mockito.Mockito.spy;
3440

3541
/**
3642
* Tests for {@link LoggingSystemProperties}.
@@ -72,9 +78,22 @@ void consoleLogPatternIsSet() {
7278
}
7379

7480
@Test
75-
void consoleCharsetWhenNoPropertyUsesUtf8() {
76-
new LoggingSystemProperties(new MockEnvironment()).apply(null);
77-
assertThat(getSystemProperty(LoggingSystemProperty.CONSOLE_CHARSET)).isEqualTo("UTF-8");
81+
void consoleCharsetWhenNoPropertyUsesCharsetDefault() {
82+
LoggingSystemProperties loggingSystemProperties = spy(new LoggingSystemProperties(new MockEnvironment()));
83+
given(loggingSystemProperties.getConsole()).willReturn(null);
84+
loggingSystemProperties.apply(null);
85+
assertThat(getSystemProperty(LoggingSystemProperty.CONSOLE_CHARSET)).isEqualTo(Charset.defaultCharset().name());
86+
}
87+
88+
@Test
89+
void consoleCharsetWhenNoPropertyUsesSystemConsoleCharsetWhenAvailable() {
90+
LoggingSystemProperties loggingSystemProperties = spy(new LoggingSystemProperties(new MockEnvironment()));
91+
Console console = mock(Console.class);
92+
given(console.charset()).willReturn(StandardCharsets.UTF_16BE);
93+
given(loggingSystemProperties.getConsole()).willReturn(console);
94+
loggingSystemProperties.apply(null);
95+
assertThat(getSystemProperty(LoggingSystemProperty.CONSOLE_CHARSET))
96+
.isEqualTo(StandardCharsets.UTF_16BE.name());
7897
}
7998

8099
@Test

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/logback/LogbackLoggingSystemPropertiesTests.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,7 +16,9 @@
1616

1717
package org.springframework.boot.logging.logback;
1818

19+
import java.io.Console;
1920
import java.nio.charset.Charset;
21+
import java.nio.charset.StandardCharsets;
2022
import java.util.HashSet;
2123
import java.util.Set;
2224

@@ -31,6 +33,9 @@
3133
import org.springframework.mock.env.MockEnvironment;
3234

3335
import static org.assertj.core.api.Assertions.assertThat;
36+
import static org.mockito.BDDMockito.given;
37+
import static org.mockito.Mockito.mock;
38+
import static org.mockito.Mockito.spy;
3439

3540
/**
3641
* Tests for {@link LogbackLoggingSystemProperties}.
@@ -102,11 +107,29 @@ void applySetsLogbackSystemPropertiesFromDeprecated() {
102107

103108
@Test
104109
void consoleCharsetWhenNoPropertyUsesDefault() {
105-
new LoggingSystemProperties(new MockEnvironment()).apply(null);
110+
LogbackLoggingSystemProperties logbackLoggingSystemProperties = spy(
111+
new LogbackLoggingSystemProperties(new MockEnvironment(), null, null));
112+
given(logbackLoggingSystemProperties.getConsole()).willReturn(null);
113+
114+
logbackLoggingSystemProperties.apply(null);
106115
assertThat(System.getProperty(LoggingSystemProperty.CONSOLE_CHARSET.getEnvironmentVariableName()))
107116
.isEqualTo(Charset.defaultCharset().name());
108117
}
109118

119+
@Test
120+
void consoleCharsetWhenNoPropertyUsesSystemConsoleCharsetWhenAvailable() {
121+
LogbackLoggingSystemProperties logbackLoggingSystemProperties = spy(
122+
new LogbackLoggingSystemProperties(new MockEnvironment(), null, null));
123+
124+
Console console = mock(Console.class);
125+
given(console.charset()).willReturn(StandardCharsets.UTF_16BE);
126+
given(logbackLoggingSystemProperties.getConsole()).willReturn(console);
127+
128+
logbackLoggingSystemProperties.apply(null);
129+
assertThat(System.getProperty(LoggingSystemProperty.CONSOLE_CHARSET.getEnvironmentVariableName()))
130+
.isEqualTo(StandardCharsets.UTF_16BE.name());
131+
}
132+
110133
@Test
111134
void fileCharsetWhenNoPropertyUsesDefault() {
112135
new LoggingSystemProperties(new MockEnvironment()).apply(null);

0 commit comments

Comments
 (0)