I am using a multibranch pipeline in jenkins and would like to record time taken by each pipeline stage and store it in DB. Any ideas on how to get the individual time durations for each build stage? I am just trying to get duration of each stage
If you go to the Jenkins page for any build job, there is a "Trend" link at the top of the list of builds on the left that tracks execution time for each build.
In order to use the timestamp information from Jenkins, you need to install the Build Timestamp Plugin and set the timestamp format in the Jenkins configuration (for example, to "yyyyMMdd-HHmm"). In every place where we use the Docker image, we need to add the tag suffix: ${BUILD_TIMESTAMP} .
Declarative versus Scripted Pipeline syntax Declarative and Scripted Pipelines are constructed fundamentally differently. Declarative Pipeline is a more recent feature of Jenkins Pipeline which: provides richer syntactical features over Scripted Pipeline syntax, and.
That is, the build, test, and deploy processes all come together in a stage. Generally, a stage block is used to visualize the Jenkins pipeline process. A step is nothing but a single task that executes a specific process at a defined time.
One can use Jenkins workflow API as well to get the data of each stage -
https://Jenkins_URL/job/${jobName}/wfapi/runs
This will return an array of JSON objects (last 10 runs by default)
This data can then be stored in a time-series DB like InfluxDB.
The answer of Patrice M. seems to be the most elegant at first, but there is a problem with nested stages and branches. The duration of nested nodes won't be accounted for, instead only the node's own duration will be reported.
Fortunately we can access the TimingAction
of the underlying FlowNode
that is wrapped by FlowNodeWrapper
to calculate the total duration, including nested nodes.
FlowNode
that represents the start of the branch or stage. Get the start time of this node by querying for its TimingAction
.FlowNode
that represents the end of the branch or stage. Get the start time of this node by querying for its TimingAction
.Finding the nodes of branches and stages is quite easy using PipelineNodeGraphVisitor
of Blue Ocean plugin API as I have shown in previous answers (for branches and for stages).
For getting the start time of a node, there is a handy static method TimingAction.getStartTime(node)
which returns the time in milliseconds.
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"
}
}
}
When running the above example code in sandbox, you will get errors due to use of "unsafe" Jenkins API. This won't happen when moving printStageDurations()
into a trusted shared library, as intended.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With