Output the console text of a Jenkins job that my Job is running

I tried looking here and here and here.

I am using the dsl flow. And I would like to be able to see the console log printed out of the job i’m building within the job I’m running. I tried looking around for examples and I couldn’t seem to find what I was looking for. I apologize if this question is not using the correct terminology or that it’s been asked in different ways. I just want to find the answer of how to do this.

  • CLOSED - Just install git but the console don't recognise the git commands
  • Start/Stop and Restart Jenkins service on Windows
  • Using git from Package Manager Console in Visual Studio
  • Format SVN diff as a side-by-side comparison
  • Restricting access to the remote on the client side. Is it possible?
  • How to color the Git console in Ubuntu?
  • A = build("Main Suites", SUITE: "qa_smoketests", OS: "mac")
    

    below I tried to do this but it didn’t seem to work

    OUTPUT = A.build.doConsoleText()
    out.println(OUTPUT)
    

    UPDATE:

    I tried the 2nd method to update it on the fly and I keep getting an issue with the url? strangely if I click the url link in the error it takes me to the appropriate page. I did have to modify things b/c the Job name has spaces in it. I also edited my error log for this post to say MYHOSTURL instead of my actual Jenkins host url.

    ERROR: Failed to run DSL Script
    java.util.concurrent.ExecutionException: org.codehaus.groovy.runtime.InvokerInvocationException: java.io.IOException: Server returned HTTP response code: 401 for URL: http://MYHOSTURL/job/Main%20Suites/159/consoleText
        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
        at java_util_concurrent_Future$get$7.call(Unknown Source)
        at com.cloudbees.plugins.flow.FlowDelegate$_parallel_closure6.doCall(FlowDSL.groovy:440)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:903)
        at groovy.lang.Closure.call(Closure.java:415)
        at groovy.lang.Closure.call(Closure.java:428)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:1379)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:1351)
        at org.codehaus.groovy.runtime.dgm$170.invoke(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:271)
        at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
        at com.cloudbees.plugins.flow.FlowDelegate.parallel(FlowDSL.groovy:438)
        at sun.reflect.GeneratedMethodAccessor10240.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1079)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:903)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:723)
        at com.cloudbees.plugins.flow.FlowDelegate.invokeMethod(FlowDSL.groovy)
        at hudson.util.spring.ClosureScript.invokeMethod(ClosureScript.java:83)
        at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:72)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:145)
        at Script1.run(Script1.groovy:12)
        at Script1$run.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
        at Script1$run.call(Unknown Source)
        at com.cloudbees.plugins.flow.FlowDSL.executeFlowScript(FlowDSL.groovy:84)
        at com.cloudbees.plugins.flow.FlowRun$FlyweightTaskRunnerImpl.run(FlowRun.java:219)
        at hudson.model.Run.execute(Run.java:1759)
        at com.cloudbees.plugins.flow.FlowRun.run(FlowRun.java:155)
        at hudson.model.ResourceController.execute(ResourceController.java:89)
        at hudson.model.Executor.run(Executor.java:240)
        at hudson.model.OneOffExecutor.run(OneOffExecutor.java:43)
    Caused by: org.codehaus.groovy.runtime.InvokerInvocationException: java.io.IOException: Server returned HTTP response code: 401 for URL: http://MYHOSTURL/job/Main%20Suites/159/consoleText
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:97)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:903)
        at groovy.lang.Closure.call(Closure.java:415)
        at groovy.lang.Closure.call(Closure.java:409)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)
    Caused by: java.io.IOException: Server returned HTTP response code: 401 for URL: http://MYHOSTURL/job/Main%20Suites/159/consoleText
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1627)
        at sun.net.www.protocol.http.HttpURLConnection$getInputStream.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
        at Script1.responseFrom(Script1.groovy:82)
        at Script1$responseFrom.callCurrent(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
        at Script1.printConsoleOutputTextChunksFrom(Script1.groovy:62)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:361)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:903)
        at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:66)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:149)
        at Script1$_run_closure2.doCall(Script1.groovy:20)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:903)
        at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:66)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
        at Script1$_run_closure2.doCall(Script1.groovy)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:903)
        at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:39)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
        at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:54)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
        at com.cloudbees.plugins.flow.FlowDelegate$_parallel_closure5_closure7.doCall(FlowDSL.groovy:427)
        at sun.reflect.GeneratedMethodAccessor8673.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:903)
        at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:66)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
        at com.cloudbees.plugins.flow.FlowDelegate$_parallel_closure5_closure7.doCall(FlowDSL.groovy)
        at sun.reflect.GeneratedMethodAccessor8672.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
        ... 9 more
    }
    Finished: FAILURE
    

    UPDATE 2:

    So I was able to get the first method working by modifying the responseFrom function to handle a page that needs authentication.

    InputStream responseFrom(String url)
      {
      // See Using java.net.URLConnection to fire and handle HTTP requests 
      //     https://stackoverflow.com/a/2793153/1744774
      URL myURL = new URL(url);
      HttpURLConnection connection = (HttpURLConnection)myURL.openConnection();
      String userCredentials = "username:password";
      String encoding = new sun.misc.BASE64Encoder().encode(userCredentials.getBytes());
      String basicAuth = "Basic " + encoding;
      connection.setRequestProperty("Authorization", basicAuth);
      connection.setRequestProperty("Accept-Charset", StandardCharsets.UTF_8.name());
      return connection.getInputStream();  
      }
    

    However I’m still having issues getting the 2nd method to work. I guess it’s with the function that is being used to get the build number from the downstream job.

    java.util.concurrent.ExecutionException:
    org.codehaus.groovy.runtime.InvokerInvocationException:
    groovy.lang.MissingMethodException: No signature of method: static
    java.lang.Integer.parseUnsignedInt() is applicable for argument types:
    (java.lang.String) values: [164]

  • Jenkins Git Publisher not working with Multiple SCM plugin
  • ERROR: Workspace has a .git repository, but it appears to be corrupt
  • Pre-configured Environment Variable in Jenkins
  • Missing WLInitializationPlugin when app is started worklight 6.2
  • How to upload an APK from Jenkins/Hudson to Play Store?
  • Change email address in Git
  • One Solution collect form web for “Output the console text of a Jenkins job that my Job is running”

    Interesting question. I can’t comprehend the downvote.

    • The first of your links describes how you should be able to do it: via “repeated GET requests”.
    • The second is about setting the result of an upstream job according to the content of a downstream job’s console output. This can be achieved easier by something else but parsing the console output.
    • The third is about the opposite direction: passing output from an upstream job to a downstream job.

    I’m going to try the first and will update this answer accordingly then.

    UPDATE 1

    The following updates the upstream’s log once the downstream build has finished.

    // From: Output the console text of a Jenkins job that my Job is running
    //       http://stackoverflow.com/a/31573477/1744774
    final String JENKINS_HOST = 'http://<your Jenkins host>'
    final String DOWNSTREAM_NAME = '<your downstream job's name>'
    
    final String SEPARATOR = new String(new char[8]).replace('\0', '-')
    final int DOWNSTREAM_BUILD_NO = build(DOWNSTREAM_NAME).getBuild().getNumber()
    
    println("${SEPARATOR} Begin console HTML output of ${DOWNSTREAM_NAME} #${DOWNSTREAM_BUILD_NO} ${SEPARATOR}")
    printConsoleOutputHtmlFrom(
        "${JENKINS_HOST}/job/${DOWNSTREAM_NAME}/${DOWNSTREAM_BUILD_NO}/console")
    
    println("${SEPARATOR} Begin console text output of ${DOWNSTREAM_NAME} #${DOWNSTREAM_BUILD_NO} ${SEPARATOR}")
    printConsoleOutputTextFrom(
        "${JENKINS_HOST}/job/${DOWNSTREAM_NAME}/${DOWNSTREAM_BUILD_NO}/consoleText")
    
    println("${SEPARATOR} End console output of ${DOWNSTREAM_NAME} ${SEPARATOR}")
    
    import org.xml.sax.InputSource
    
    void printConsoleOutputHtmlFrom(String consoleUrl)
      {
      println(xPathExpression('//pre[contains(@class, "console-output")]')
                  .evaluate(new InputSource(responseFrom(consoleUrl))))
      }
    
    import java.nio.charset.StandardCharsets
    
    void printConsoleOutputTextFrom(String consoleTextUrl)
      {
      BufferedReader log = new BufferedReader(
          new InputStreamReader(responseFrom(consoleTextUrl), StandardCharsets.UTF_8.name()));
      while ((line = log.readLine()) != null)
        {
        println(line)
        }
      }
    
    InputStream responseFrom(String url)
      {
      // See Using java.net.URLConnection to fire and handle HTTP requests 
      //     http://stackoverflow.com/a/2793153/1744774
      URLConnection connection = new URL(url).openConnection();
      connection.setRequestProperty("Accept-Charset", StandardCharsets.UTF_8.name());
      return connection.getInputStream();  
      }
    
    import javax.xml.xpath.XPath;
    import javax.xml.xpath.XPathExpression;
    import javax.xml.xpath.XPathFactory;
    
    XPathExpression xPathExpression(String expression)
      {
      // See How to read XML using XPath in Java
      //     http://stackoverflow.com/a/2811101/1744774
      XPathFactory xPathFactory = XPathFactory.newInstance();
      XPath xPath = xPathFactory.newXPath();
      return xPath.compile(expression);
      }
    

    References:

    • Build Flow Plugin
    • com.cloudbees.plugins.flow.JobInvocation (returned by build())
    • hudson.model.Run (returned by JobInvocation.getBuild())

    UPDATE 2

    The following updates the upstream’s log on the fly.

    // From: Output the console text of a Jenkins job that my Job is running
    //       http://stackoverflow.com/a/31573477/1744774
    final String JENKINS_HOST = 'http://<your Jenkins host>'
    final String DOWNSTREAM_NAME = '<your downstream job's name>'
    
    final String SEPARATOR = new String(new char[8]).replace('\0', '-')
    
    import java.util.concurrent.TimeUnit
    
    parallel(
      { build(DOWNSTREAM_NAME) },
      {
      final String THIS_BUILD_NAME = build.getProject().getName()
      final int THIS_BUILD_NO = build.getNumber()
      final int DOWNSTREAM_BUILD_NO = downstreamBuildNoFrom(
          "${JENKINS_HOST}/job/${THIS_BUILD_NAME}/${THIS_BUILD_NO}/consoleText") 
    
      println("${SEPARATOR} Begin console output of ${DOWNSTREAM_NAME} #${DOWNSTREAM_BUILD_NO} ${SEPARATOR}")
    
      printConsoleOutputTextChunksFrom(
          "${JENKINS_HOST}/job/${DOWNSTREAM_NAME}/${DOWNSTREAM_BUILD_NO}/consoleText", 3L, TimeUnit.SECONDS)
    
      println("${SEPARATOR} End console output of ${DOWNSTREAM_NAME} #${DOWNSTREAM_BUILD_NO} ${SEPARATOR}")
      })
    
    int downstreamBuildNoFrom(String thisBuildConsoleTextUrl)
      {
      int downstreamBuildNo = -1
      while (downstreamBuildNo <= 0)
        {
        TimeUnit.SECONDS.sleep(1L)
        BufferedReader log = new BufferedReader(
            new InputStreamReader(responseFrom(thisBuildConsoleTextUrl), StandardCharsets.UTF_8.name()));
        while ((line = log.readLine()) != null)
          {
          if (line.matches('.* Build .* started'))
            {
            final int buildNoIdx = line.indexOf('#') + 1
            downstreamBuildNo = Integer.parseUnsignedInt(
                line.substring(buildNoIdx, line.indexOf(' ', buildNoIdx)))
            break
            }
          /*if (log.lines().anyMatch(t -> t.matches(".* Build .* started")))
            {
            // in case of Java >=8
            }*/
          }
        }
      return downstreamBuildNo
      } // downstreamBuildNoFrom()
    
    import java.nio.charset.StandardCharsets
    
    void printConsoleOutputTextChunksFrom(String consoleTextUrl, long updateInterval, TimeUnit updateIntervalUnit)
      {
      final int LINE_BREAK_LENGTH = System.getProperty("line.separator").length()
      int charsPrintedSoFar = 0
      while (true) // effectively a do { ... }
        {
        int charsPrintedThisTime = 0
        BufferedReader chunk = new BufferedReader(
            new InputStreamReader(responseFrom(consoleTextUrl), StandardCharsets.UTF_8.name()))
        chunk.skip(charsPrintedSoFar)
        while ((line = chunk.readLine()) != null)
          {
          println(line)
          charsPrintedThisTime = line.length() + LINE_BREAK_LENGTH
          charsPrintedSoFar += charsPrintedThisTime
          }
        updateIntervalUnit.sleep(updateInterval)
        if (charsPrintedThisTime == 0)
          break
        } 
      } // printConsoleOutputTextChunksFrom()
    
    InputStream responseFrom(String url)
      {
      // See Using java.net.URLConnection to fire and handle HTTP requests 
      //     http://stackoverflow.com/a/2793153/1744774
      URLConnection connection = new URL(url).openConnection();
      connection.setRequestProperty("Accept-Charset", StandardCharsets.UTF_8.name());
      return connection.getInputStream();  
      }
    
    Git Baby is a git and github fan, let's start git clone.