private HadoopException analyzeJob(String jobId) {
    HadoopException jobLevelException = new HadoopException();
    List<HadoopException> childExceptions = new ArrayList<HadoopException>();

    _workflowClient.analyzeJob(jobId);

    // get the set of all the yarn jobs from workflowClient
    Set<String> yarnJobIds = _workflowClient.getYarnApplicationsFromJob(jobId);

    for (String mrJobId : yarnJobIds) {
      //To do: Check if mr job logs are there or not in job history server
      String rawMRJobLog = _mrClient.getMRJobLog(mrJobId);
      if (rawMRJobLog != null && !rawMRJobLog.isEmpty()) { // null for log not found and empty for successful mr jobs
        //To do: rawMRJob is empty for successful mr jobs but this is not a good way to figure out whether a job failed
        // or succeeded, do this using the state field in rest api
        HadoopException mrJobLevelException = analyzeMRJob(mrJobId, rawMRJobLog);
        childExceptions.add(mrJobLevelException);
      }
    }

    if (_workflowClient.getJobState(jobId) == JobState.MRFAIL) {
      jobLevelException.setType(HadoopException.HadoopExceptionType.MR);
      jobLevelException.setLoggingEvent(_workflowClient.getJobException(jobId));
      //LoggingEvent is set only for the case if mr logs could not be found in job history server and childException is
      // empty
      jobLevelException.setChildExceptions(childExceptions);
    } else if (_workflowClient.getJobState(jobId) == JobState.SCHEDULERFAIL) {
      jobLevelException.setType(HadoopException.HadoopExceptionType.SCHEDULER);
      jobLevelException.setLoggingEvent(_workflowClient.getJobException(jobId));
      jobLevelException.setChildExceptions(null);
    } else if (_workflowClient.getJobState(jobId) == JobState.SCRIPTFAIL) {
      jobLevelException.setType(HadoopException.HadoopExceptionType.SCRIPT);
      jobLevelException.setLoggingEvent(_workflowClient.getJobException(jobId));
      jobLevelException.setChildExceptions(null);
    } else if (_workflowClient.getJobState(jobId) == JobState.KILLED) {
      jobLevelException.setType(HadoopException.HadoopExceptionType.KILL);
      jobLevelException.setLoggingEvent(null);
      jobLevelException.setChildExceptions(null);
    }
    jobLevelException.setId(jobId);
    return jobLevelException;
  }
Given a failed Job, this method analyzes the job and returns a HadoopException object which captures all the exception in the given job.
@param jobId The job execution id/url, specific to the scheduler
@return HadoopException object which captures all the exceptions in the given job
app/com/linkedin/drelephant/exceptions/ExceptionFinder.java