Jenkins管道:如何在超时时打印挂起进程的堆栈跟踪?
在我的测试中,管道超时步骤将在挂起的进程到达catch块之前杀死它,因此似乎无法运行“jstack”(例如),因为太晚了:Jenkins管道:如何在超时时打印挂起进程的堆栈跟踪?,jenkins,groovy,jenkins-pipeline,Jenkins,Groovy,Jenkins Pipeline,在我的测试中,管道超时步骤将在挂起的进程到达catch块之前杀死它,因此似乎无法运行“jstack”(例如),因为太晚了: try{ timeout(time: 3, unit: 'SECONDS') { sh "some slow/hanging java process" } } catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e) { //check that the caus
try{
timeout(time: 3, unit: 'SECONDS') {
sh "some slow/hanging java process"
}
} catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e) {
//check that the cause is org.jenkinsci.plugins.workflow.steps.TimeoutStepExecution.ExceededTimeout
// then try to run jstack on all java processes on the machine.
// but that won't work because the offending process is already gone,
// "timeout" killed it...
}
概括地说,如何调试耗时太长的进程而不终止它?
我能想到的唯一解决办法是非常丑陋的,比如:
def ok = false
def alarmTime = System.currentTimeMillis() + 50000 //just before timeout
parallel main: {
timeout(60000) {
//run java
ok = true
}
}, watcher: {
waitUntil {
ok || System.currentTimeMillis() > alarmTime
}
if (!ok) {
//perform debugging just before timeout fires.
}
}
但这在代码和输出方面都很糟糕
更新:我打开了一个解决此问题的建议。您可以使用(coreutils的一部分)来完成此操作 例如:
timeout --preserve-status --kill-after=30m --signal=3 20m <command>
此代码是在您的文件中还是在共享库中?您能提供更多的上下文吗。@AndrewGray这是一个Jenkins文件,我相信它在共享库中也会以同样的方式工作。我想让您看看超时步骤是如何杀死某些东西的,它真的很难看。确实感觉应该在Jenkins管道内部执行一些操作,以跟踪长时间运行的步骤并记录调用堆栈,当通过超时或任何其他方式中止管道时可以获得调用堆栈。问题中的代码已在使用
超时
。这甚至不是试图回答这个问题。
timeout(time: 35, unit: 'MINUTES') {
sh "timeout --preserve-status --kill-after=30m --signal=3 20m sbt test"
}