April 16, 2015

Grails Goodness: Add Some Color to Our Logging

Grails 3 is based on Spring Boot. This means we can use a lot of the stuff that is available in Spring Boot now in our Grails application. If we look at the logging of a plain Spring Boot application we notice the logging has colors by default if our console supports ANSI. We can also configure our Grails logging so that we get colors.

First we need to change our logging configuration in the file grails-app/conf/logback.groovy:

// File: grails-app/conf/logback.groovy
import grails.util.BuildSettings
import grails.util.Environment
import org.springframework.boot.ApplicationPid

import java.nio.charset.Charset

// Get PID for Grails application.
// We use it in the logging output.
if (!System.getProperty("PID")) {
    System.setProperty("PID", (new ApplicationPid()).toString())

// Mimic Spring Boot logging configuration.
conversionRule 'clr', org.springframework.boot.logging.logback.ColorConverter
conversionRule 'wex', org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter

appender('STDOUT', ConsoleAppender) {
    encoder(PatternLayoutEncoder) {
        charset = Charset.forName('UTF-8')

        // Define pattern with clr converter to get colors.
        pattern =
                '%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} ' + // Date
                '%clr(%5p) ' + // Log level
                '%clr(%property{PID}){magenta} ' + // PID
                '%clr(---){faint} %clr([%15.15t]){faint} ' + // Thread
                '%clr(%-40.40logger{39}){cyan} %clr(:){faint} ' + // Logger
                '%m%n%wex' // Message

// Change root log level to INFO,
// so we get some more logging.
root(INFO, ['STDOUT'])

Normally when we would run our application Grails should check if the console support ANSI colors. If the console supports it the color logging is enabled, otherwise we still get non-colored logging. On my Mac OSX the check doesn't work correctly, but we can set an environment property spring.output.ansi.enabled to the value always to force colors in our logging output. The default value is detect to auto detect the support for colors. We can set this property in different ways. For example we could add it to our application configuration or we could add it as a Java system property to the JVM arguments of the bootRun task. In the following build file we use the JVM arguments for the bootRun task:

// File: build.gradle
bootRun {
    // If System.console() return non null instance,
    // we force ANSI color support with 'always', 
    // otherwise use default 'detect'.
    jvmArgs = ['-Dspring.output.ansi.enabled=' + (System.console() ? 'always' : 'detect')]

When we run the Grails application using bootRun we get for example the following output:

Written with Grails 3.0.1.