When a flow involves many steps, long logs, and/or many branches, it can be hard for a developer receiving a failure email (for example) to quickly see what part of the build actually failed and why. I think it would be useful for the catchError step to do a DFS search on the Throwable and its cause chain through the FlowNode graph starting at the end of the catch step, looking for ErrorAction, and setting/appending an environment variable with the URL of the LogAction. Or provide a new step to do the same. Thus you could write

      def runStuff(param) {
        ...
      }
      try {
        parallel a: {runStuff 'a'}, b: {runStuff 'b'}
      } catch (e) {
        mail to: '...', subject: 'Failure!', body: "Build failed: ${errorUrl(e)}"
      }
      

      and get a link to http://jenkins/job/myflow/123/flowGraph/77/console or the like, according to the actual step in one of the branches that threw the error.

          [JENKINS-28119] Link to log of failed step

          hardi249 added a comment -

          Is this still in progress?

          hardi249 added a comment - Is this still in progress?

          Jesse Glick added a comment -

          Not really. I suppose I could revisit this, given the high vote count.

          Jesse Glick added a comment - Not really. I suppose I could revisit this, given the high vote count.

          David Riemens added a comment -

          just up-voted;
          Me too, I have similar usecase. In our testenvironment, we run many tools, each generating a separate logfile. We have one generic log shown in the console.
          If one test fails, we can see that it failed, and typically have an exception message shown in the console, but the actual (detailed) reason is hidden in one of
          the  detailed logs. For that reason we want to include a link to the workspace directory on the exception text, such that all the log-files are just one click away.
          For the pipeline jobs that link is not easy to derive; it is hidden in one of the pipeline steps. as also indicated by ringerc
          My feeling says that making sure that link, or the ID is available at runtime should be possible ... right ?

          David Riemens added a comment - just up-voted; Me too, I have similar usecase. In our testenvironment, we run many tools, each generating a separate logfile. We have one generic log shown in the console. If one test fails, we can see that it failed, and typically have an exception message shown in the console, but the actual (detailed) reason is hidden in one of the  detailed logs. For that reason we want to include a link to the workspace directory on the exception text, such that all the log-files are just one click away. For the pipeline jobs that link is not easy to derive; it is hidden in one of the pipeline steps. as also indicated by ringerc My feeling says that making sure that link, or the ID is available at runtime should be possible ... right ?

          Jan Heylen added a comment - - edited

          Is there already any way to get the link to 'blue/rest/organizations/jenkins/pipelines/<jobname>/runs/<build-id>/nodes/<PipelineNodeImpl-id>/log/ from within a pipeline parallel node?

          Jan Heylen added a comment - - edited Is there already any way to get the link to 'blue/rest/organizations/jenkins/pipelines/<jobname>/runs/<build-id>/nodes/<PipelineNodeImpl-id>/log/ from within a pipeline parallel node?

          Erik van Velzen added a comment - - edited

          Gonna be  harsh here, but rightfully so. I feel burned, I worked many days to set up docker containers, scripts and even fixing and compiling plugins, and I now find out that it's for naught.

          "run a command and produce a URL to the output" is basic functionality of a CI tool.

          There's no point in using Jenkins without it (for me).

          Erik van Velzen added a comment - - edited Gonna be  harsh here, but rightfully so. I feel burned, I worked many days to set up docker containers, scripts and even fixing and compiling plugins, and I now find out that it's for naught. "run a command and produce a URL to the output" is basic functionality of a CI tool. There's no point in using Jenkins without it (for me).

          Perhaps a workaround would be to pipe the output within the step to a file and publish it as an artifact.

          Erik van Velzen added a comment - Perhaps a workaround would be to pipe the output within the step to a file and publish it as an artifact.

          thang bui added a comment - - edited

          erikvv if you are using blue ocean, you can just have the link to the build and once the page open it will automatically scroll to the failed step.

          also another work around https://stackoverflow.com/questions/53444196/get-log-for-each-jenkins-pipeline-stage 

          thang bui added a comment - - edited erikvv if you are using blue ocean, you can just have the link to the build and once the page open it will automatically scroll to the failed step. also another work around  https://stackoverflow.com/questions/53444196/get-log-for-each-jenkins-pipeline-stage  

          Edgars Batna added a comment -

          +1 The advent of Blue Ocean came and went. Jenkins is still a powerful tool, but I feel weird seeing many functional improvements get so stale.

          Edgars Batna added a comment - +1 The advent of Blue Ocean came and went. Jenkins is still a powerful tool, but I feel weird seeing many functional improvements get so stale.

          Helder Magalhães added a comment - - edited

          Late in the game, but this is still not straightforward as it could be.

          Is there already any way to get the link to 'blue/rest/organizations/jenkins/pipelines/<jobname>/runs/<build-id>/nodes/<PipelineNodeImpl-id>/log/ from within a pipeline parallel node?

          Apparently it's possible but, unfortunately, not out-of-the-box:

          Seems that getting the link (out-of-the-box) is now closer with the RUN_DISPLAY_URL environment variable injected by the BlueOcean plugin but it would be very nice to have an environment variable set to the step ID available throughout the whole job (possibly as part of the pipeline plug-in?). Not only for linking but also for obtaining a unique identifier which maps to something and can be used for (temporary?) storage path, artifact filenames, for better diagnostic output, etc.

          Edit: correct link for "building a link"; added some arguments.

          Helder Magalhães added a comment - - edited Late in the game, but this is still not straightforward as it could be. Is there already any way to get the link to 'blue/rest/organizations/jenkins/pipelines/<jobname>/runs/<build-id>/nodes/<PipelineNodeImpl-id>/log/ from within a pipeline parallel node? Apparently it's possible but, unfortunately, not out-of-the-box: For getting the Pipeline implementation node ID, take a look at Unexpected exception when use getContext and sh together in the latest version of Jenkins . The example even works from non-library code! For building a link , check out Jenkins: Generating Blue Ocean URLs . The example even offers to choose between legacy or BlueOcean! Seems that getting the link (out-of-the-box) is now closer with the RUN_DISPLAY_URL environment variable injected by the BlueOcean plugin but it would be very nice to have an environment variable set to the step ID available throughout the whole job (possibly as part of the pipeline plug-in?). Not only for linking but also for obtaining a unique identifier which maps to something and can be used for (temporary?) storage path, artifact filenames, for better diagnostic output, etc. Edit : correct link for "building a link"; added some arguments.

          Denis added a comment - - edited

          +1 for this. 

          Currently we have to perform some tricks to print URL to the necessary BO pipeline node from the groovy job itself.

          First, RUN_DISPLAY_URL is not convenient if you want to add smth like "/pipeline/<node_id>" to it. The thing is that this var just adds /display/redirect to the classic URL, so we get smth like https://<jenkins_host>/<job_name>/<build_id>/display/redirect which is then redirected to  https://<jenkins_host>/blue/organizations/jenkins/<job_name>/<build_id>/pipeline

          So we first need to now the final URL (after redirections) - one can do this for example using [https://gist.github.com/sbglasius/3899754|this snippet]

          Next, we should find necessary node id for the current stage. This step looks ugly, we  just walk through the flow graph looking for a node with a needed name. It works for our pipelines consisting of many parallel jobs, suggestions are welcome for better and more universal code:

          Integer getFlowID() {
              FlowGraphWalker walker = new FlowGraphWalker(currentBuild.rawBuild.getExecution())
              for (FlowNode flowNode: walker) {
                  if (flowNode.getDisplayName() == "Branch: " + env.STAGE_NAME) {
                      return flowNode.getId()
                          }
                  }
              return 0
          }

           

          Definitely having a single variable for this would be a great solution.

          Denis added a comment - - edited +1 for this.  Currently we have to perform some tricks to print URL to the necessary BO pipeline node from the groovy job itself. First, RUN_DISPLAY_URL is not convenient if you want to add smth like "/pipeline/<node_id>" to it. The thing is that this var just adds /display/redirect to the classic URL, so we get smth like https://<jenkins_host>/<job_name>/<build_id>/display/redirect  which is then redirected to  https://<jenkins_host>/blue/organizations/jenkins/<job_name>/<build_id>/pipeline So we first need to now the final URL (after redirections) - one can do this for example using [https://gist.github.com/sbglasius/3899754|this snippet] Next, we should find necessary node id for the current stage. This step looks ugly, we  just walk through the flow graph looking for a node with a needed name. It works for our pipelines consisting of many parallel jobs, suggestions are welcome for better and more universal code: Integer getFlowID() {     FlowGraphWalker walker = new FlowGraphWalker(currentBuild.rawBuild.getExecution())     for (FlowNode flowNode: walker) {         if (flowNode.getDisplayName() == "Branch: " + env.STAGE_NAME) {             return flowNode.getId()                 }         }     return 0 }   Definitely having a single variable for this would be a great solution.

            jglick Jesse Glick
            jglick Jesse Glick
            Votes:
            50 Vote for this issue
            Watchers:
            67 Start watching this issue

              Created:
              Updated: