如何打印Groovy堆栈跟踪?

时间:2011-06-06 23:34:16

标签: groovy

如何打印Groovy堆栈跟踪? Java方法Thread.currentThread()。getStackTrace()产生一个巨大的堆栈跟踪,包括很多Groovy内部。我看到一个从StreamingMarkupBuilder中调用两次的函数看起来应该只调用一次,我想看看为什么Groovy认为应该调用它两次。

3 个答案:

答案 0 :(得分:14)

Google搜索会返回following information:

显然,org.codehaus.groovy.runtime.StackTraceUtils中有一种名为printSanitizedStackTrace的方法。该方法没有太多文档,但有一个名为sanitize的方法被描述为

  

删除所有显然groovy-internal   跟踪异常中的条目   实例这会修改原始内容   实例并返回它,但它没有   克隆

所以我会尝试org.codehaus.groovy.runtime.StackTraceUtils.printSanitizedStackTrace(Throwable t)(它是静态的) 并看看它是否适合你。

答案 1 :(得分:1)

我在搜索"spock print full stack trace"时发现了这个问题。

我的单元测试是用Groovy编写的,使用Spock测试框架,它们是在Gradle构建的上下文中运行的。

对我来说,修复就像在我的Gradle测试任务规范中添加exceptionFormat = 'full'一样简单:

test {
  testLogging {
    exceptionFormat = 'full'
  }
}

答案 2 :(得分:0)

我根据 NullPointerException 的人工模拟设计了这个用于堆栈跟踪打印的简单代码。 此代码在两种模式下产生相同的输出:来自 Jenkinsfile(管道)和来自命令行中的普通 .groovy 脚本。

def getStackTrace() {
    try {
        null.class.toString() // simulate NPE
    } catch (NullPointerException e) {
        return e.getStackTrace()
    }
    return null
}

def printStackTrace() {
    def stackTraceStr = ""
    def callingFuncFound = false
    for (StackTraceElement ste : getStackTrace()) {
        if (callingFuncFound) {
            stackTraceStr += ste.toString() + '\n'
        }
        if (!callingFuncFound && ste.toString().startsWith(this.class.name + '.printStackTrace(')) {
            callingFuncFound = true
        }
    }
    println(stackTraceStr)
}

一些解释:

  1. 将输出连接成一个字符串,以避免与 Jenkins Pipeline 的 println() 的“[Pipeline] echo”消息前缀混合。
  2. 与 NPE 相关的“不必要的”上层堆栈跟踪元素的数量在 Jenkinsfile 和普通命令行中是不同的。这就是为什么我计算 callingFuncFound 并且不使用像 e.getStackTrace()[2..-1] 这样的东西来跳过它们。