22

I have a Jenkins job with 100+ builds. I need to search through all the builds of that job to find builds that have a certain string in the console output. Is there any plugin for that? How do I do that?

Dave Bacher
  • 15,652
  • 3
  • 63
  • 86
user1550159
  • 1,197
  • 3
  • 19
  • 36

8 Answers8

22

I often use the Jenkins Script Console for tasks like this. The Groovy plugin provides the Script Console, but if you're going to use the Script Console for periodic maintenance, you'll also want the Scriptler plugin which allows you to manage the scripts that you run.

From Manage Jenkins -> Script Console, you can write a groovy script that iterates through the job's builds looking for the matching string:

JOB_NAME = "My Job"
BUILD_STRING = "Hello, world"

def job = Jenkins.instance.items.find { it.name == JOB_NAME }
for (build in job.builds) {
  def log = build.log
  if (log.contains(BUILD_STRING)) {
    println "${job.name}: ${build.id}"
  }
}
Dave Bacher
  • 15,652
  • 3
  • 63
  • 86
  • 1
    FWIW, to search through all jobs use `def job = Jenkins.instance.items.find {true}` – Alexander Klimetschek Nov 16 '16 at 00:29
  • This does not work our CI setup. Can you confirm if this search for the console logs of the currently running jobs or even the completed jobs ? How can I do search for all the jobs which are both running and completed (failed/unstable/successful) ? – askb Feb 10 '17 at 08:15
  • 2
    @dave bacher I get: groovy.lang.MissingPropertyException: No such property: builds for class: java.lang.Boolean Any idea? – DenCowboy Dec 05 '17 at 07:53
  • It's working in the script console but not when I call it as groovy scriptin my pipeline. – DenCowboy Dec 05 '17 at 09:54
  • 2
    I think this fails if your job is in a subfolder (I get the same error as @DenCowboy). – Chris Weiss Mar 05 '18 at 23:12
  • I can confirm this won't work for subfolders, but overall a good solution! – rcorre Nov 13 '18 at 15:57
  • 1
    @rcorre Fixed in an edit (should be visible after a peer review). TL;DR: use `allItems` instead of `items`. – sm4rk0 Nov 23 '18 at 10:58
  • 1
    My edit got rejected, so here's the improved version of script: `Jenkins.instance.allItems.find { job -> job.name == JOB_NAME }.builds.findAll { build -> build.log.find(FIND_REGEX) }` – sm4rk0 Nov 23 '18 at 13:44
  • This works only for Free-style projects and Doesn't work for Multi-branch pipeline. – bhr Dec 13 '19 at 07:53
11

If there is no additional requirements I would do it simply in the shell, e.g.:

find $JENKINS_HOME/jobs/haystack -name log -exec grep -l needle {} \; \
    | sed 's|.*/\(.*\)/log|\1|'
jil
  • 2,601
  • 12
  • 14
  • 9
    While this is a fine answer, I would be very scared if one of my developers asked for access our Jenkins server so they could run shell commands against the job directories. :) – Dave Bacher Mar 23 '16 at 23:48
  • 1
    You could create a Jenkins job then that runs this in a shell step if your are concerned about that, @Dave. And referring to your own answer, I don't think running Groovy scripts in console is any safer than granting the shell access :) – jil Mar 24 '16 at 09:54
  • @jil, thanks. I now run a parameterized build with NEEDLE for the search string; the bash script searches all logs (excepting the search job itself) and excludes the commit messages with this: `find $JENKINS_HOME/jobs -type f -name log | grep -v "$JOB_BASE_NAME" | xargs grep "$NEEDLE" | grep -v 'Commit message:'` – Generic Ratzlaugh Apr 08 '21 at 21:45
6

To search in logs of all jobs:

I enhanced @DaveBacher 's code to be run in the Jenkins script console. Helped me to locate a sporadic error happening in multiple jobs.

NEEDLE = "string_i_am_looking_for"

for (job in Jenkins.instance.getAllItems(Job.class)) {
  for (build in job.builds) {
    def log = build.log
    if (log.contains(NEEDLE)) {
      println "${job.name}: ${build.id}"
    }
  }
}
RS1980
  • 634
  • 8
  • 13
3

Thanks everyone for your valuable solutions. After a bit of additional research i found that there is a plugin in Jenkins to do this.

https://wiki.jenkins-ci.org/display/JENKINS/Lucene-Search

This will save the console output results and users can do search in search box.

user1550159
  • 1,197
  • 3
  • 19
  • 36
1

There is the Log Parser Plugin

highlighting lines of interest in the log (errors, warnings,information)

dividing the log into sections displaying a summary of number of errors, warnings and information lines within the log and its sections.

linking the summary of errors and warnings into the context of the full log, making it easy to find a line of interest in the log

showing a summary of errors and warnings on the build page

If it is old logs then @jil has the answer assuming you are on Linux.

Community
  • 1
  • 1
KeepCalmAndCarryOn
  • 8,817
  • 2
  • 32
  • 47
  • No need to assume Linux. Just _bash_, _find_, _grep_, and _sed_. They can be easily installed on Windows (e.g. from cygwin or mingw) and chances are that you already have them, i.e. if you are using Git. – jil Mar 24 '16 at 09:43
1

Just to throw another plugin out there, this blog post pointed me at the TextFinder plugin which allows you to search for text in either a workspace file or the console output, and override the build status as success/failure when the text is found.

The original poster doesn't say what should happen when the text is found, but it was searching for this functionality that brought me here.

foz
  • 3,121
  • 1
  • 27
  • 21
0

To search for a regular expression text in console output of all Jenkins builds, run the following script in https://{jenkins url}/manage/script. It will print the job and build number + The first matching line found:

def regex="any text or regular expression"

for (job in Jenkins.instance.items) {
  for (build in job.builds) {
    try {
      def log = build.log
      def match = log =~ "\n(.*${regex}.*)\n"
      if (match) {
        println "Job [${job.name}] - Build [${build.id}]: ${match[0][0]}"
      }
    }
    catch (Exception e) {
      println e
    }
  }
}

For example, searching in my builds with regex = "(TLS|Build).*timeout" I found:

Job [OSP-AWS] - Build [83]: Build timeout: dial tcp [::1]:6443: connect: connection refused

Job [OSP-GCP] - Build [21]: Unable to connect to the server: net/http: TLS handshake timeout

Noam Manos
  • 15,216
  • 3
  • 86
  • 85
-2

Just use Jenkins std search (top right corner) with keyword "console":

console:"whatever you are looking for"