使groovy @Log注释保护内部闭包

编辑: GROOVY-6932已记录,现已关闭 – 该问题在Groovy v2.4.8中标记为已修复.

我使用@ Slf4j注释向我的groovy类添加日志记录.

我喜欢它,因为AST转换将我的日志调用包装在“启用”检查中,记录在here

我发现,如果从闭包内调用log方法,则guard子句不起作用.

在Groovy 2.2.0上运行,此代码只记录一条消息,但打印“被叫”两次.

@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 with $p"
    return "blah: $p"
  }
}

我已经尝试将“this”,“owner”和“delegate”说明符添加到日志语句中但结果相同.

我发现这个上下文的时候是我在使用XmlSlurper解析XML时尝试使用XmlUtil.serialize记录某些节点.

我正在通过使用调用XmlUtil类的toString()方法将NodeChild对象包装在轻量级对象中来解决此问题.这个工作正常,额外的包装类的开销不值得担心.我更感兴趣的是找到一个解决这个问题的简单方法,以便我可以回过头来不必考虑记录消息的构建成本,无论如何它们都没有被记录.

我问的问题是:有没有办法让日志级别保护条款在闭包内正常工作,而不是自己添加“log.traceEnabled”调用

解决方法

只是一个快速的想法.你怎么知道log.traceEnabled在关闭执行时会是什么?查看修改后的示例…

@Grapes([
        @Grab(group='org.slf4j',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 with $p"
        return "blah: $p"
    }
}

现在在创建闭包时,log.traceEnabled为false,但是当执行闭包时,这已经改变了.

输出是:

called with 1
16:53:15.408 [main] INFO  TestCode - blah: 1
called with 3
16:53:15.414 [main] TRACE TestCode - blah: 3

注意第二个TRACE仍未打印:-)

相关文章

背景:    8月29日,凌晨4点左右,某服务告警,其中一个...
https://support.smartbear.comeadyapi/docs/soapui/steps/g...
有几个选项可用于执行自定义JMeter脚本并扩展基线JMeter功能...
Scala和Java为静态语言,Groovy为动态语言Scala:函数式编程,...
出处:https://www.jianshu.com/p/ce6f8a1f66f4一、一些内部...
在运行groovy的junit方法时,报了这个错误:java.lang.Excep...