Skip to content

Commit

Permalink
add support for finding the console's charset, LOGBACK-1642
Browse files Browse the repository at this point in the history
Signed-off-by: Ceki Gulcu <[email protected]>
  • Loading branch information
ceki committed Aug 12, 2024
1 parent 44fbe63 commit 7c29474
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 10 deletions.
38 changes: 38 additions & 0 deletions logback-classic/src/test/input/joran/consoleCharset.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
~ Logback: the reliable, generic, fast and flexible logging framework.
~ Copyright (C) 1999-2024, QOS.ch. All rights reserved.
~
~ This program and the accompanying materials are dual-licensed under
~ either the terms of the Eclipse Public License v1.0 as published by
~ the Eclipse Foundation
~
~ or (per the licensee's choosing)
~
~ under the terms of the GNU Lesser General Public License version 2.1
~ as published by the Free Software Foundation.
-->

<!DOCTYPE configuration>

<configuration>
<import class="ch.qos.logback.core.status.OnConsoleStatusListener"/>
<import class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"/>
<import class="ch.qos.logback.core.ConsoleAppender"/>
<import class="ch.qos.logback.core.property.ConsoleCharsetPropertyDefiner"/>

<define name="consoleCharset" class="ConsoleCharsetPropertyDefiner"/>

<appender name="CON" class="ConsoleAppender">
<encoder class="PatternLayoutEncoder">
<charset>${consoleCharset}</charset>
<pattern>TEST %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>

<root>
<level value="DEBUG"/>
<appender-ref ref="CON"/>
</root>
<statusListener class="OnConsoleStatusListener"/>
</configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.testUtil.StringListAppender;
import ch.qos.logback.core.util.CachingDateFormatter;
import ch.qos.logback.core.util.EnvUtil;
import ch.qos.logback.core.util.StatusPrinter;
import ch.qos.logback.core.util.StatusPrinter2;
import org.junit.jupiter.api.Disabled;
Expand Down Expand Up @@ -740,6 +741,18 @@ public void dateConverterWithLocale() throws JoranException {
//StatusPrinter.print(loggerContext);
}

@Test
public void consoleCharsetTest() throws JoranException {
if(EnvUtil.isJDK21OrHigher()) {
configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "consoleCharset.xml");
checker.assertContainsMatch(Status.INFO, "About to instantiate property definer of type \\[ch.qos.logback.core.property.ConsoleCharsetPropertyDefiner\\]");
checker.assertContainsMatch(Status.WARN, "System.console\\(\\) returned null. Cannot compute console's charset, returning");
checker.assertContainsMatch("Setting property consoleCharset=null in scope LOCAL" );
checker.assertContainsMatch("Converting the string \\\"null. as Charset.defaultCharset\\(\\)");
//StatusPrinter.print(loggerContext);
}
}

@Test
public void modelSerialization() throws JoranException, IOException, ClassNotFoundException {
String outputPath = OUTPUT_DIR_PREFIX+"minimal_"+diff+ MODEL_CONFIG_FILE_EXTENSION;
Expand Down
10 changes: 10 additions & 0 deletions logback-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,16 @@
<multiReleaseOutput>true</multiReleaseOutput>
</configuration>
</execution>

<execution>
<id>default-testCompile</id>
<phase>test-compile</phase>
<configuration>
<testExcludes>
<exclude>**/COWArrayListConcurrencyTest.java</exclude>
</testExcludes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class LayoutWrappingEncoder<E> extends EncoderBase<E> {
/**
* The charset to use when converting a String into bytes.
* <p>
* By default this property has the value {@code null} which corresponds to the
* By default, this property has the value {@code null} which corresponds to the
* system's default charset.
*/
private Charset charset;
Expand All @@ -51,7 +51,7 @@ public Charset getCharset() {
* Set the charset to use when converting the string returned by the layout into
* bytes.
* <p>
* By default this property has the value {@code null} which corresponds to the
* By default, this property has the value {@code null} which corresponds to the
* system's default charset.
*
* @param charset
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
*/
package ch.qos.logback.core.joran;

import ch.qos.logback.core.CoreConstants;

/**
*
* This class contains constants used by Joran components.
Expand All @@ -37,7 +39,8 @@ public abstract class JoranConstants {
public static final String ACTION_CLASS_ATTRIBUTE = "actionClass";

public static final String INHERITED = "INHERITED";
public static final String NULL = "NULL";
// all usages in the project are case-insensitive. Elsewhere this might not be the case hence the toUpperCase call
public static final String NULL = CoreConstants.NULL_STR.toUpperCase();
static final Class<?>[] ONE_STRING_PARAM = new Class[] { String.class };

public static final String APPENDER_BAG = "APPENDER_BAG";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,4 @@ public Class<?> getClassNameViaImplicitRules(String name, AggregationType aggreg
return aggregationAssessor.getClassNameViaImplicitRules(name, aggregationType, registry);
}





}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,27 @@
*/
package ch.qos.logback.core.joran.util;

import java.io.Console;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;

import ch.qos.logback.core.Context;
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.spi.ContextAware;
import ch.qos.logback.core.spi.ContextAwareBase;

import static ch.qos.logback.core.CoreConstants.CONSOLE;
import static ch.qos.logback.core.CoreConstants.NULL_STR;

/**
* Utility class which can convert string into objects.
*
* @author Ceki G&uuml;lc&uuml;
*
*/
public class StringToObjectConverter {
public class StringToObjectConverter {

private static final Class<?>[] STRING_CLASS_PARAMETER = new Class[] { String.class };

Expand All @@ -51,7 +57,7 @@ static public boolean canBeBuiltFromSimpleString(Class<?> parameterClass) {
* Convert <code>val</code> a String parameter to an object of a given type.
*/
@SuppressWarnings("unchecked")
public static Object convertArg(ContextAware ca, String val, Class<?> type) {
static public Object convertArg(ContextAware ca, String val, Class<?> type) {
if (val == null) {
return null;
}
Expand Down Expand Up @@ -88,6 +94,12 @@ static private boolean isOfTypeCharset(Class<?> type) {
}

static private Charset convertToCharset(ContextAware ca, String val) {

if (NULL_STR.equalsIgnoreCase(val)) {
ca.addInfo("Converting the string \"null\" as Charset.defaultCharset()");
return Charset.defaultCharset();
}

try {
return Charset.forName(val);
} catch (UnsupportedCharsetException e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Logback: the reliable, generic, fast and flexible logging framework.
* Copyright (C) 1999-2024, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/

package ch.qos.logback.core.property;

import ch.qos.logback.core.PropertyDefinerBase;
import static ch.qos.logback.core.CoreConstants.NULL_STR;

import java.io.Console;
import java.nio.charset.Charset;

/**
* Compute the console's charset.
*
* @since 1.5.7
*/
public class ConsoleCharsetPropertyDefiner extends PropertyDefinerBase {
@Override
public String getPropertyValue() {
// System.console().charset() requires Java 17
Console console = System.console();
if (console != null) {
Charset charset = console.charset();
if (charset != null) {
String charsetName = charset.name();
addInfo("Found value '" + charsetName + "' as returned by System.console().");
return charsetName;
} else {
addInfo("System.console() returned null charset. Returning \"NULL\" string as defined value.");
return NULL_STR;
}
} else {
addWarn("System.console() returned null. Cannot compute console's charset, returning the \"NULL\" string, i.e. the default JVM charset");
return NULL_STR;
}
}

}

0 comments on commit 7c29474

Please sign in to comment.