Logback: use colored output only when logging to a real terminal

doublep picture doublep · Jun 25, 2015 · Viewed 20.5k times · Source

In my Logback configuration I have the following lines:

<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>

This makes warnings and errors show up in terminal, colored, while main log file can contain much more information, e.g. INFO and DEBUG levels.

Generally, this works fine. But, when I run it from Emacs or any other "not really a terminal" program, coloring commands show out as ASCII escape sequences, e.g. ^[[31m for warning highlighting. Is it somehow possible to make Logback only use ANSI coloring when connected to a real terminal?

Answer

joozek picture joozek · Apr 22, 2016

You have two problems here:

how to detect if you should use colors or not

This is not trivial. As this answer suggests you could use JNI call to isatty to detect if you're connected to a terminal, but it's a lot of work for fairly low-priority feature.

how to conditionally use colors in logback

That is actually quite easy (official docs), remember that you need janino for this to work:

<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>