Skip to content

Commit

Permalink
Use Console charset for console logging when available
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
nosan committed Feb 19, 2025
1 parent f096707 commit 98707ab
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@

package org.springframework.boot.logging;

import java.io.Console;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Function;

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

protected Console getConsole() {
return System.console();
}

protected Charset getDefaultCharset() {
return StandardCharsets.UTF_8;
return Charset.defaultCharset();
}

public final void apply() {
Expand All @@ -116,12 +121,11 @@ private PropertyResolver getPropertyResolver() {
}

protected void apply(LogFile logFile, PropertyResolver resolver) {
String defaultCharsetName = getDefaultCharset().name();
setSystemProperty(LoggingSystemProperty.APPLICATION_NAME, resolver);
setSystemProperty(LoggingSystemProperty.APPLICATION_GROUP, resolver);
setSystemProperty(LoggingSystemProperty.PID, new ApplicationPid().toString());
setSystemProperty(LoggingSystemProperty.CONSOLE_CHARSET, resolver, defaultCharsetName);
setSystemProperty(LoggingSystemProperty.FILE_CHARSET, resolver, defaultCharsetName);
setSystemProperty(LoggingSystemProperty.CONSOLE_CHARSET, resolver, getConsoleCharset().name());
setSystemProperty(LoggingSystemProperty.FILE_CHARSET, resolver, getDefaultCharset().name());
setSystemProperty(LoggingSystemProperty.CONSOLE_THRESHOLD, resolver, this::thresholdMapper);
setSystemProperty(LoggingSystemProperty.FILE_THRESHOLD, resolver, this::thresholdMapper);
setSystemProperty(LoggingSystemProperty.EXCEPTION_CONVERSION_WORD, resolver);
Expand All @@ -137,6 +141,10 @@ protected void apply(LogFile logFile, PropertyResolver resolver) {
}
}

private Charset getConsoleCharset() {
return Optional.ofNullable(getConsole()).map(Console::charset).orElseGet(this::getDefaultCharset);
}

private void setSystemProperty(LoggingSystemProperty property, PropertyResolver resolver) {
setSystemProperty(property, resolver, Function.identity());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,7 +16,7 @@

package org.springframework.boot.logging.logback;

import java.nio.charset.Charset;
import java.io.Console;
import java.util.function.BiConsumer;
import java.util.function.Function;

Expand Down Expand Up @@ -71,8 +71,8 @@ public LogbackLoggingSystemProperties(Environment environment, Function<String,
}

@Override
protected Charset getDefaultCharset() {
return Charset.defaultCharset();
protected Console getConsole() {
return super.getConsole();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,6 +16,9 @@

package org.springframework.boot.logging;

import java.io.Console;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
Expand All @@ -31,6 +34,9 @@
import org.springframework.mock.env.MockEnvironment;

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 LoggingSystemProperties}.
Expand Down Expand Up @@ -72,9 +78,22 @@ void consoleLogPatternIsSet() {
}

@Test
void consoleCharsetWhenNoPropertyUsesUtf8() {
new LoggingSystemProperties(new MockEnvironment()).apply(null);
assertThat(getSystemProperty(LoggingSystemProperty.CONSOLE_CHARSET)).isEqualTo("UTF-8");
void consoleCharsetWhenNoPropertyUsesCharsetDefault() {
LoggingSystemProperties loggingSystemProperties = spy(new LoggingSystemProperties(new MockEnvironment()));
given(loggingSystemProperties.getConsole()).willReturn(null);
loggingSystemProperties.apply(null);
assertThat(getSystemProperty(LoggingSystemProperty.CONSOLE_CHARSET)).isEqualTo(Charset.defaultCharset().name());
}

@Test
void consoleCharsetWhenNoPropertyUsesSystemConsoleCharsetWhenAvailable() {
LoggingSystemProperties loggingSystemProperties = spy(new LoggingSystemProperties(new MockEnvironment()));
Console console = mock(Console.class);
given(console.charset()).willReturn(StandardCharsets.UTF_16BE);
given(loggingSystemProperties.getConsole()).willReturn(console);
loggingSystemProperties.apply(null);
assertThat(getSystemProperty(LoggingSystemProperty.CONSOLE_CHARSET))
.isEqualTo(StandardCharsets.UTF_16BE.name());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -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 java.util.HashSet;
import java.util.Set;

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

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 LogbackLoggingSystemProperties}.
Expand Down Expand Up @@ -102,11 +107,29 @@ void applySetsLogbackSystemPropertiesFromDeprecated() {

@Test
void consoleCharsetWhenNoPropertyUsesDefault() {
new LoggingSystemProperties(new MockEnvironment()).apply(null);
LogbackLoggingSystemProperties logbackLoggingSystemProperties = spy(
new LogbackLoggingSystemProperties(new MockEnvironment(), null, null));
given(logbackLoggingSystemProperties.getConsole()).willReturn(null);

logbackLoggingSystemProperties.apply(null);
assertThat(System.getProperty(LoggingSystemProperty.CONSOLE_CHARSET.getEnvironmentVariableName()))
.isEqualTo(Charset.defaultCharset().name());
}

@Test
void consoleCharsetWhenNoPropertyUsesSystemConsoleCharsetWhenAvailable() {
LogbackLoggingSystemProperties logbackLoggingSystemProperties = spy(
new LogbackLoggingSystemProperties(new MockEnvironment(), null, null));

Console console = mock(Console.class);
given(console.charset()).willReturn(StandardCharsets.UTF_16BE);
given(logbackLoggingSystemProperties.getConsole()).willReturn(console);

logbackLoggingSystemProperties.apply(null);
assertThat(System.getProperty(LoggingSystemProperty.CONSOLE_CHARSET.getEnvironmentVariableName()))
.isEqualTo(StandardCharsets.UTF_16BE.name());
}

@Test
void fileCharsetWhenNoPropertyUsesDefault() {
new LoggingSystemProperties(new MockEnvironment()).apply(null);
Expand Down

0 comments on commit 98707ab

Please sign in to comment.