Making groovy @Log annotation safeguard calls inside closures -
edit: groovy-6932 logged , has been closed - problem marked fixed in groovy v2.4.8.
i use @slf4j annotation add logging groovy classes.
i because of ast transformation wraps log calls inside "enablement" check, documented here
what i've found though, guard clause doesn't work if log method called within closure.
running on groovy 2.2.0, code logs 1 message, prints "called" twice.
@grapes([ @grab(group='org.slf4j', module='slf4j-api', version='1.7+'), @grab(group='ch.qos.logback', module='logback-classic', version='1.+')]) import groovy.util.logging.slf4j new testcode().dosomethingthatlogs() @slf4j class testcode { void dosomethingthatlogs(){ log.info createlogstring(1) log.trace createlogstring(2) closure c = { log.trace createlogstring(3) } c() } string createlogstring(int p){ println "called $p" return "blah: $p" } }
i've tried adding "this", "owner" , "delegate" specifiers log statement same result.
the context found in when trying log nodes using xmlutil.serialize while parsing xml xmlslurper.
i'm working around problem wrapping nodechild object in lightweight object tostring() method calls xmlutil class. that'll work fine , overhead of wrapper classes not worth worrying about. i'm more interested in finding simple way around problem can go not having think cost of construction of logging messages when aren't being logged anyway.
the question i'm asking: there way have logging level guard clause work within closures, instead of having add "log.traceenabled" calls myself?
just quick thought. how know log.traceenabled
on closure execution? see modified example ...
@grapes([ @grab(group='org.slf4j', module='slf4j-api', version='1.7+'), @grab(group='ch.qos.logback', module='logback-classic', version='1.+')]) import groovy.util.logging.slf4j import jline.internal.log import org.slf4j.loggerfactory; import ch.qos.logback.classic.level; import ch.qos.logback.classic.logger; new testcode().dosomethingthatlogs() @slf4j class testcode { void dosomethingthatlogs(){ log.info createlogstring(1) log.trace createlogstring(2) closure c = { log.trace createlogstring(3) } logger root = (logger)loggerfactory.getlogger(logger.root_logger_name); root.setlevel(level.trace); c() } string createlogstring(int p){ println "called $p" return "blah: $p" } }
now @ time closure created log.traceenabled
false, when closure executed had changed.
the output is:
called 1 16:53:15.408 [main] info testcode - blah: 1 called 3 16:53:15.414 [main] trace testcode - blah: 3
note second trace
still not printed :-)
Comments
Post a Comment