dgorur
dgorur

Reputation: 1662

Configure logback from groovy script

I have a Java library, on top of which I have lightweight groovy scripts that function as terminal-based command-line utilities. So rather than asking my users to

java -cp ... com.foo.bar.package.SomeMainClass ...

They have access to a "standard" POSIX-like utility:

footool -a <arg> -b <another> -vfg <positional_arg>

I would like that -v argument to control logging level to a console appender. Now, I'm in a groovy script. Groovy has the most excellent CLIbuilder to make the argument parsing easy. Logback is configured using groovy programs. What I want to do should be easy. Right?

And yet it seems all but impossible to check the value of the -v flag, and accordingly set the Level for a threshold filter for an appender that's already specified in XML, or even to create the filter and appender from scratch and add to a logger.

Really? Seems like there must be a way without writing 30 lines of Java code for Joran. What do I have to do to get this (or something that's not 30 lines of Java code for Joran) to work from within my groovy script?

def cliBuilder = new CliBuilder...
def options = cli.parse(args)
def logLevel = options.v ? Level.DEBUG : Level.INFO

appender("CONSOLE", ConsoleAppender) {
  filter(ThresholdFilter) {
    level = logLevel
  }
  encoder(PatternLayoutEncoder) {
    pattern = "%-4relative [%thread] %-5level %logger{30} - %msg%n"
  }
}

Upvotes: 2

Views: 1435

Answers (1)

sfussenegger
sfussenegger

Reputation: 36096

You could simply use programmatic Groovy configuration without the logback.groovy magic:

import ch.qos.logback.classic.Logger
import static org.slf4j.LoggerFactory.getLogger
import static org.slf4j.Logger.ROOT_LOGGER_NAME as ROOT
import static ch.qos.logback.classic.Level.WARN

((Logger) getLogger(ROOT)).setLevel(WARN)

// one-liner
((ch.qos.logback.classic.Logger) org.slf4j.LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME)).setLevel(ch.qos.logback.classic.Level.WARN)

this is also useful to redirect logging to stderr:

import ch.qos.logback.classic.Logger
import ch.qos.logback.core.ConsoleAppender as Console
import static org.slf4j.LoggerFactory.getLogger
import static org.slf4j.Logger.ROOT_LOGGER_NAME as ROOT
import static ch.qos.logback.classic.Level.WARN

((Console) ((Logger) getLogger(ROOT)).getAppender("console")).setOutputStream(System.err)

// one-liner
((ch.qos.logback.core.ConsoleAppender) ((ch.qos.logback.classic.Logger) org.slf4j.LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME)).getAppender("console")).setOutputStream(System.err)

Upvotes: 2

Related Questions