How does the condition functionality work in Logback?

theomega picture theomega · Jun 13, 2012 · Viewed 16.7k times · Source

I use this logback configuration file:

<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%-10.-10thread] %-5level %-30logger{1} - %msg%n</pattern>
    </encoder>
  </appender>

<if condition='isDefined("fileout-dir")'><then>
  <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
     <discriminator  class="edu.kit.sdq.storagebenchmarkharness.logging.SBHThreadDiscriminator"/>
    <sift>
      <appender name="FILE-${thread}" class="ch.qos.logback.core.FileAppender">
        <file>${fileout-dir:-}${thread}.log</file>
        <append>true</append>
        <layout class="ch.qos.logback.classic.PatternLayout">
          <pattern>%d{HH:mm:ss.SSS} %-5level %-30logger{1} - %msg%n</pattern>
        </layout>
      </appender>
    </sift>
  </appender>
  <root>
    <appender-ref>SIFT</appender-ref>
  </root>
 </then> </if>

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

When running my application, I get the following error:

org.codehaus.commons.compiler.CompileException: Line 1, Column 45: A method named "isDefined" is not declared in any enclosing class nor any supertype, nor through a static import
    at org.codehaus.commons.compiler.CompileException: Line 1, Column 45: A method named "isDefined" is not declared in any enclosing class nor any supertype, nor through a static import
    at  at org.codehaus.janino.UnitCompiler.compileError(UnitCompiler.java:9014)
    at  at org.codehaus.janino.UnitCompiler.findIMethod(UnitCompiler.java:6549)
    at  at org.codehaus.janino.UnitCompiler.compileGet2(UnitCompiler.java:3429)
    at  at org.codehaus.janino.UnitCompiler.access$6300(UnitCompiler.java:104)
    at  at org.codehaus.janino.UnitCompiler$11.visitMethodInvocation(UnitCompiler.java:2869)
    at  at org.codehaus.janino.Java$MethodInvocation.accept(Java.java:2831)
    at  at org.codehaus.janino.UnitCompiler.compileGet(UnitCompiler.java:2890)
    at  at org.codehaus.janino.UnitCompiler.compileGetValue(UnitCompiler.java:3897)
    at  at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:1637)
    at  at org.codehaus.janino.UnitCompiler.access$1700(UnitCompiler.java:104)
    at  at org.codehaus.janino.UnitCompiler$5.visitReturnStatement(UnitCompiler.java:877)
    at  at org.codehaus.janino.Java$ReturnStatement.accept(Java.java:1803)
    at  at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:888)
    at  at org.codehaus.janino.UnitCompiler.compileStatements(UnitCompiler.java:914)
    at  at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:1999)
    at  at org.codehaus.janino.UnitCompiler.compileDeclaredMethods(UnitCompiler.java:789)
    at  at org.codehaus.janino.UnitCompiler.compileDeclaredMethods(UnitCompiler.java:770)
    at  at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:464)
    at  at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:357)
    at  at org.codehaus.janino.UnitCompiler$3.visitPackageMemberClassDeclaration(UnitCompiler.java:312)
    at  at org.codehaus.janino.Java$PackageMemberClassDeclaration.accept(Java.java:770)
    at  at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:319)
    at  at org.codehaus.janino.UnitCompiler.compileUnit(UnitCompiler.java:288)
    at  at org.codehaus.janino.SimpleCompiler.compileToClassLoader(SimpleCompiler.java:393)
    at  at org.codehaus.janino.ClassBodyEvaluator.compileToClass(ClassBodyEvaluator.java:311)
    at  at org.codehaus.janino.ClassBodyEvaluator.cook(ClassBodyEvaluator.java:224)
    at  at org.codehaus.janino.SimpleCompiler.cook(SimpleCompiler.java:194)
    at  at org.codehaus.commons.compiler.Cookable.cook(Cookable.java:80)
    at  at org.codehaus.commons.compiler.Cookable.cook(Cookable.java:72)
    at  at ch.qos.logback.core.joran.conditional.PropertyEvalScriptBuilder.build(PropertyEvalScriptBuilder.java:34)
    at  at ch.qos.logback.core.joran.conditional.IfAction.begin(IfAction.java:43)
    at  at ch.qos.logback.core.joran.spi.Interpreter.callBeginAction(Interpreter.java:273)
    at  at ch.qos.logback.core.joran.spi.Interpreter.startElement(Interpreter.java:145)
    at  at ch.qos.logback.core.joran.spi.Interpreter.startElement(Interpreter.java:127)
    at  at ch.qos.logback.core.joran.spi.EventPlayer.play(EventPlayer.java:40)
    at  at ch.qos.logback.core.joran.spi.Interpreter.play(Interpreter.java:332)
    at  at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:126)
    at  at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:93)
    at  at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:52)
    at  at ch.qos.logback.classic.util.ContextInitializer.configureByResource(ContextInitializer.java:60)
    at  at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:121)
    at  at org.slf4j.impl.StaticLoggerBinder.init(StaticLoggerBinder.java:85)
    at  at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:55)
    at  at org.slf4j.LoggerFactory.bind(LoggerFactory.java:121)
    at  at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:111)
    at  at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:268)
    at  at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:241)
    at  at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:254)
    at  at edu.kit.sdq.storagebenchmarkharness.Logger.getLogger(Logger.java:44)
    at  at edu.kit.sdq.storagebenchmarkharness.BenchmarkController.<clinit>(BenchmarkController.java:66)

Why is the method isDefined unkown? The logback docs state that it should exists, and at least one stack overflow thread seems to use it.

I included the most recent version of janino in my classpath because it is needed for the evalution of the expressions. The janino compiler gets loaded as you can see in the error message.

Answer

JBCP picture JBCP · Apr 9, 2013

Make sure you are using the latest version of logback. In addition, using conditionals in logback requires the Janino library.

Add this to your pom.xml file to get the dependency:

    <!-- The org.codehaus.janino:commons-compiler:2.6.1 dependency -->
    <!-- will be automatically pulled in by Maven's transitivity rules -->
    <dependency>
        <groupId>org.codehaus.janino</groupId>
        <artifactId>janino</artifactId>
        <version>2.6.1</version>
    </dependency>