17 June 2014

Recently, I needed to add a Logback configuration to an application that is deployed in Apache Tomcat. I wanted to ensure that my log files did not grow in an unbounded manner. To protect against this, I decided to use the RollingFileAppender provided by Logback. That is an obvious choice to solve this problem, but I wanted to ensure that when running the application in Apache Tomcat, the generated log files end up in ${catalina.base}/logs and when running locally via something like the Maven Apache Tomcat Plugin it chose an appropriate output directory. I arrive at the following Groovy-based Logback configuration file:

logback.groovy
import static ch.qos.logback.classic.Level.INFO

import ch.qos.logback.classic.encoder.PatternLayoutEncoder
import ch.qos.logback.core.rolling.FixedWindowRollingPolicy
import ch.qos.logback.core.rolling.RollingFileAppender
import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy
import ch.qos.logback.core.status.OnConsoleStatusListener

// Print out the Logback configuration information at startup.
statusListener OnConsoleStatusListener

def BASE_DIR = System.getProperty('catalina.base') ?: System.getProperty('user.dir')	(1)

appender("WEBAPP", RollingFileAppender) {
    file = "${BASE_DIR}/logs/application.log"
    encoder(PatternLayoutEncoder) {
        pattern = "%-50(%date{ISO8601} [%thread]) %-5level %logger{50} - %msg%n%rEx"
    }
    triggeringPolicy(SizeBasedTriggeringPolicy) {
        maxFileSize = '10MB'
    }
    rollingPolicy(FixedWindowRollingPolicy) {
        fileNamePattern = "${BASE_DIR}/logs/application-%d{yyyyMMdd_hhmmss}.%i.gz"
        maxIndex = 10
    }
}

root(INFO, ["WEBAPP"])
1 If the catalina.base property is present and not blank, use it. Otherwise, use the current user’s directory as the base for the log file.

The configuration above ensures that not only will the log files be rotated based on size, but that the files will be created in the appropriate location based on the inspection of the catalina.base and user.dir system properties. Because the configuration is written in Groovy, we can use any sort of logic we want to manipulate the Logback configuration at runtime to ensure the proper setup for the logging infrastructure in our application.

comments powered by Disqus