Logback:仅在登录到真实终端时使用彩色输出

时间:2015-06-25 09:44:41

标签: logback ansi-colors

在我的Logback配置中,我有以下几行:

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
  <encoder>
    <pattern>%highlight(...) %msg%n</pattern>
  </encoder>
  <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
    <level>WARN</level>
  </filter>
</appender>

这使得警告和错误显示在终端中,有颜色,而主日志文件可以包含更多信息,例如INFO和DEBUG等级。

一般来说,这很好用。但是,当我从Emacs或任何其他人运行它时,不是真正的终端&#34;程序,着色命令显示为ASCII转义序列,例如, ^[[31m用于警告突出显示。是否有可能使Logback在连接到真实终端时仅使用ANSI着色?

2 个答案:

答案 0 :(得分:15)

这里有两个问题:

如何检测是否应该使用颜色

这不是微不足道的。正如this answer建议您可以使用JNI调用isatty来检测您是否已连接到终端,但是对于相当低优先级的功能而言,这是一项很多工作。

如何在logback中有条件地使用颜色

这实际上非常简单(official docs),请记住,您需要janino才能实现此目的:

<configuration>
    <appender name="COLOR" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%date] %highlight([%level]) [%logger{10} %file:%line] %msg%n</pattern>
            <!--             ^^^^^^^^^^ -->
        </encoder>
    </appender>
    <appender name="NOCOLOR" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%date] [%level] [%logger{10} %file:%line] %msg%n</pattern>
        </encoder>
    </appender>
    <root level="debug">
        <!-- to use enable this mode pass -Dcolor to jvm -->
        <if condition='isDefined("color")'>
            <then>
                    <appender-ref ref="COLOR"/>
            </then>
            <else>
                    <appender-ref ref="NOCOLOR"/>
            </else>
        </if>
    </root>
</configuration>

答案 1 :(得分:0)

就我而言,我通过创建自定义 PatternLayout 找到了解决方法。 它的工作是在终端不支持颜色时通过转换器替换默认颜色转换器。

作为:

  • 我也使用 Picocli
  • 根据我的经验,Picocli ANSI 颜色支持检测启发式方法非常好。

我用它来知道什么时候应该移除颜色转换器。 (但您可以使用任何其他启发式方法或使用 https://stackoverflow.com/a/36790201/5088764 中的环境变量,而无需依赖 janino)

代码如下:

/**
 * A Logback Pattern Layout which use Picocli ANSI color heuristic to apply ANSI color only on terminal which support
 * it.
 */
public class ColorAwarePatternLayout extends PatternLayout {

    static {
        if (!Ansi.AUTO.enabled()) { // Usage of Picocli heuristic
            defaultConverterMap.put("black", NoColorConverter.class.getName());
            defaultConverterMap.put("red", NoColorConverter.class.getName());
            defaultConverterMap.put("green", NoColorConverter.class.getName());
            defaultConverterMap.put("yellow", NoColorConverter.class.getName());
            defaultConverterMap.put("blue", NoColorConverter.class.getName());
            defaultConverterMap.put("magenta", NoColorConverter.class.getName());
            defaultConverterMap.put("cyan", NoColorConverter.class.getName());
            defaultConverterMap.put("white", NoColorConverter.class.getName());
            defaultConverterMap.put("gray", NoColorConverter.class.getName());
            defaultConverterMap.put("boldRed", NoColorConverter.class.getName());
            defaultConverterMap.put("boldGreen", NoColorConverter.class.getName());
            defaultConverterMap.put("boldYellow", NoColorConverter.class.getName());
            defaultConverterMap.put("boldBlue", NoColorConverter.class.getName());
            defaultConverterMap.put("boldMagenta", NoColorConverter.class.getName());
            defaultConverterMap.put("boldCyan", NoColorConverter.class.getName());
            defaultConverterMap.put("boldWhite", NoColorConverter.class.getName());
            defaultConverterMap.put("highlight", NoColorConverter.class.getName());
        }
    }
}
public class NoColorConverter<E> extends CompositeConverter<E> {

    @Override
    protected String transform(E event, String in) {
        return in;
    }
}
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="your.package.ColorAwarePatternLayout">
                <pattern>%gray(%30.30logger{0}) %gray(%d) [%highlight(%p)] %m%n</pattern>
            </layout>
        </encoder>
    </appender>

    <root level="WARN">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

(见https://github.com/eclipse/leshan/pull/1068

相关问题