捕获 jenkins 中每个管道阶段所花费的时间

use*_*rAk 7 jenkins

我在 jenkins 中使用多分支管道,并希望记录每个管道阶段所花费的时间并将其存储在数据库中。关于如何获得每个构建阶段的个人持续时间的任何想法?我只是想获得每个阶段的持续时间

Pan*_*ini 8

也可以使用 Jenkins 工作流 API 来获取每个阶段的数据 -

https://Jenkins_URL/job/${jobName}/wfapi/runs
Run Code Online (Sandbox Code Playgroud)

这将返回一个 JSON 对象数组(默认情况下最近 10 次运行)

然后可以将这些数据存储在像 InfluxDB 这样的时间序列数据库中。


zet*_*t42 8

Patrice M.的答案乍一看似乎是最优雅的,但是存在嵌套阶段和分支的问题。不会考虑嵌套节点的持续时间,而只会报告节点自身的持续时间。

幸运的是,我们可以访问被包装的TimingAction底层的来计算总持续时间,包括嵌套节点。FlowNodeFlowNodeWrapper

解决方案

  1. 找到FlowNode代表分支或阶段开始的 。通过查询该节点的 来获取该节点的开始时间TimingAction
  2. 找到FlowNode代表分支或阶段结束的 。通过查询该节点的 来获取该节点的开始时间TimingAction
  3. 计算这两个时间点之间的差异。

PipelineNodeGraphVisitor正如我在之前的答案中所示(对于分支和阶段),使用 Blue Ocean 插件 API 查找分支阶段的节点非常容易。

为了获取节点的启动时间,有一个方便的静态方法TimingAction.getStartTime(node),它返回以毫秒为单位的时间。

例子

import io.jenkins.blueocean.rest.impl.pipeline.PipelineNodeGraphVisitor
import io.jenkins.blueocean.rest.impl.pipeline.FlowNodeWrapper
import org.jenkinsci.plugins.workflow.actions.TimingAction

pipeline {
    agent any
    
    stages {
        stage('A') {
            stages {
                stage('A1') {
                    steps {
                        sleep 1
                    }
                }
                stage('A2') {
                    steps {
                        sleep 1
                    }
                }
            }
        }
    }
    post {
        always {
            printFinishedStageDurations()
        }
    }
}

void printFinishedStageDurations() {

    def visitor = new PipelineNodeGraphVisitor( currentBuild.rawBuild )

    // To find branches instead, replace NodeType.STAGE by NodeType.PARALLEL
    def stages = visitor.pipelineNodes.findAll{ it.type == FlowNodeWrapper.NodeType.STAGE }
    
    for( stage in stages ) {
        if( stage.node.endNode ) {   // only finished stages have endNode
            def startTime  = TimingAction.getStartTime( stage.node )
            def endTime    = TimingAction.getStartTime( stage.node.endNode )
            def duration   = endTime - startTime
        
            echo "Stage $stage.displayName duration: $duration ms" 
        }
    } 
}
Run Code Online (Sandbox Code Playgroud)

输出

管道蓝色海景

笔记

在沙盒中运行上述示例代码时,由于使用“不安全”的 Jenkins API,您将收到错误。printStageDurations()当按照预期转移到受信任的共享库时,这种情况不会发生。


Dom*_*art 0

只是为了记录,因为这在相当长的一段时间内没有得到答复,据我所知,还没有内置的方法来实现这一点(也许有一些插件?),但是 jenkins 管道脚本功能提供了自己添加此功能的灵活性,即添加命令它在阶段开始时记录一个时间戳,在阶段结束时记录另一个时间戳。

即检查有关获取时间戳值的信息,您可以自由地使用它进行计算并将其发送给某些数据库或其他使用者。