a library to parse and filter logs
- implementation of https://stackoverflow.com/a/57351397
- workaround for https://issues.jenkins-ci.org/browse/JENKINS-54304
this library offer functions to retrieve logs as string or files (as run artifacts), and to parse the logs at the same time
it allows:
-
to add branch prefix [branchName] in front of each line of the logs belonging to a parallel branch
echo 'not in any branch' parallel ( branch1: { echo 'in branch1' }, branch2: { echo 'in branch2' } )
not in any branch
[branch1] in branch1
[branch2] in branch2 -
to filter logs by branchName
[branch1] in branch1
-
to show the name of parent branches (parent branch first) for nested branches
parallel branch2: { echo 'in branch2' parallel branch21: { echo 'in branch2.branch21' } }
[branch2] in branch2
[branch2] [branch21] in branch2.branch21 -
to archive logs in job artifacts (without having to allocate a node : same as ArchiveArtifacts but without
node()
scope) -
to hide or show VT100 markups from logs (which make raw log hard to read)
-
to hide or show Pipeline technical log lines (lines starting with [Pipeline] ) from logs
[Pipeline] Start of Pipeline
[Pipeline] echo
not in any branch
[Pipeline] parallel
[Pipeline] { (Branch: branch1)
[Pipeline] { (Branch: branch2)
[Pipeline] echo
[branch1] in branch1
[Pipeline] }
[Pipeline] echo
[branch2] in branch2
[Pipeline] }
[Pipeline] // parallel
[Pipeline] End of Pipeline
Finished: SUCCESS -
to access descriptors of log and branches internal ids
in Jenkinsfile import library like this
@Library('[email protected]') _
identifier "pipeline-logparser" is the name of the library set by jenkins administrator in instance configuration:
- it may be different on your instance
- see below Installation
-
the name of the package is logparser:
// get logs with branch prefix def mylog = logparser.getLogsWithBranchInfo()
-
see complete documentation here: logparser.txt
also available in $JOB_URL/pipeline-syntax/globals#logparser (visible only after the library has been imported once)
install the library as a "Global Pipeline Library" in "Manage jenkins > Configure System > Global Pipeline Library" (cf https://jenkins.io/doc/book/pipeline/shared-libraries/)
Note:
- it's also possible to copy the code in a Jenkinsfile and use functions from there
- but it would imply approving whatever needs to be in "Manage jenkins > In-process Script Approval" (including some unsafe API's)
- using this library as a "Global Pipeline Library" allows to avoid that (avoid getting access to unsafe API's)
-
parsing may fail (and cause job to fail) when log is too big (millions of lines, hundreds of MB of logs) because of a lack of heap space
-
when logparser functions are called the last lines of logs might not be flushed yet and shall not be in the resulting log workaround: before to call logparser add these 2 statements
// sleep 1s and use echo to flush logs before to call logparser sleep 1 echo ''
example:
@Library('[email protected]') _ parallel( branch1: { echo 'in branch1' }, branch2: { echo 'in branch2' } ) // sleep 1s and use echo to flush logs before to call logparser sleep 1 echo '' logparser.archiveLogsWithBranchInfo('console.txt')
NB: this might not always be enough
-
when hidePipeline is false, the output is not fully equivalent to what we had with job-workflow plugin v2.25 and earlier : example:
-
pipeline code
parallel( branch1: { echo 'in branch1' }, branch2: { echo 'in branch2' } )
-
job-workflow plugin v2.25 output:
[Pipeline] parallel
[Pipeline] [branch1] { (Branch: branch1)
[Pipeline] [branch2] { (Branch: branch2)
[Pipeline] [branch1] echo
[branch1] in branch1
[Pipeline] [branch1] }
[Pipeline] [branch2] echo
[branch2] in branch2
[Pipeline] [branch2] }
[Pipeline] // parallel
[Pipeline] End of Pipeline -
output using
logparser.getLogsWithBranchInfo()
:[Pipeline] Start of Pipeline
[Pipeline] parallel
[Pipeline] { (Branch: branch1)
[Pipeline] { (Branch: branch2)
[Pipeline] echo
[branch1] in branch1
[Pipeline] }
[Pipeline] echo
[branch2] in branch2So we lose a bit of information: the lines starting with
[Pipeline]
and which belonged to a specific branch like[Pipeline] [branch2] echo
It might not be the most important information but sometimes it is useful to know which branch it belongs to
-
-
1.0 (09/2019)
- API to get edited logs with branchName (with nested branches, without VT100 markups, etc ...)
- API to filter logs by branch name (get logs of a specific branch)
- API to parse logs and retrieve maps of id/offsets/branchname
-
1.0.1 (11/2019)
- fix parsing issues (when there is only one branch and when logs of 2 branches are mixed without pipeline technical logs in between)
-
1.1 (03/2020)
- ability to set branch name to filter using regular expression
- ability to filter more than one branch (API change : option filter is now a list)
- ability to filter main thread (using filter = [null])
- new option hidePipeline to filter Pipeline technical logs (default value true to hide them)
- fix parsing issues with old version of workflow-job plugin