Index: ql/src/java/org/apache/hadoop/hive/ql/exec/JobDebugger.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/exec/JobDebugger.java (revision 1366480) +++ ql/src/java/org/apache/hadoop/hive/ql/exec/JobDebugger.java (working copy) @@ -190,12 +190,12 @@ // Also keep track of the total number of failures for that // task (typically, a task gets re-run up to 4 times if it fails. if (t.getTaskStatus() != TaskCompletionEvent.Status.SUCCEEDED) { + String[] diags = rj.getTaskDiagnostics(t.getTaskAttemptId()); + ti.setDiagnosticMesgs(diags); if (ti.getErrorCode() == 0) { - String[] diags = rj.getTaskDiagnostics(t.getTaskAttemptId()); ti.setErrorCode(extractErrorCode(diags)); - ti.setDiagnosticMesgs(diags); } - + Integer failAttempts = failures.get(taskId); if (failAttempts == null) { failAttempts = Integer.valueOf(0); @@ -226,6 +226,9 @@ @SuppressWarnings("deprecation") private void showJobFailDebugInfo() throws IOException { console.printError("Error during job, obtaining debugging information..."); + if (!rj.getTrackingURL().contains("localhost")) { // Show Tracking URL for remote jobs. + console.printError("Job Tracking URL: " + rj.getTrackingURL()); + } // Loop to get all task completion events because getTaskCompletionEvents // only returns a subset per call TaskInfoGrabber tlg = new TaskInfoGrabber(); @@ -257,14 +260,14 @@ console.printError("Unable to retrieve URL for Hadoop Task logs. " + e.getMessage()); } - + for (String task : failures.keySet()) { if (failures.get(task).intValue() == maxFailures) { TaskInfo ti = taskIdToInfo.get(task); String jobId = ti.getJobId(); - String taskUrl = (jtUrl == null) ? "Unavailable" : - jtUrl + "/taskdetails.jsp?jobid=" + jobId + "&tipid=" + task.toString(); - + String taskUrl = (jtUrl == null) ? null : + jtUrl + "/taskdetails.jsp?jobid=" + jobId + "&tipid=" + task.toString(); + TaskLogProcessor tlp = new TaskLogProcessor(conf); for (String logUrl : ti.getLogUrls()) { tlp.addTaskAttemptLogUrl(logUrl); @@ -290,8 +293,10 @@ sb.append("Task with the most failures(" + maxFailures + "): \n"); sb.append("-----\n"); sb.append("Task ID:\n " + task + "\n\n"); - sb.append("URL:\n " + taskUrl + "\n"); - + if (taskUrl != null) { + sb.append("URL:\n " + taskUrl + "\n"); + } + for (ErrorAndSolution e : errors) { sb.append("\n"); sb.append("Possible error:\n " + e.getError() + "\n\n"); Index: ql/src/java/org/apache/hadoop/hive/ql/exec/HadoopJobExecHelper.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/exec/HadoopJobExecHelper.java (revision 1366480) +++ ql/src/java/org/apache/hadoop/hive/ql/exec/HadoopJobExecHelper.java (working copy) @@ -26,10 +26,8 @@ import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -37,8 +35,6 @@ import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.ql.MapRedStats; import org.apache.hadoop.hive.ql.exec.Operator.ProgressCounter; -import org.apache.hadoop.hive.ql.exec.errors.ErrorAndSolution; -import org.apache.hadoop.hive.ql.exec.errors.TaskLogProcessor; import org.apache.hadoop.hive.ql.history.HiveHistory.Keys; import org.apache.hadoop.hive.ql.session.SessionState; import org.apache.hadoop.hive.ql.session.SessionState.LogHelper; @@ -471,161 +467,8 @@ } } - // Used for showJobFailDebugInfo - private static class TaskInfo { - String jobId; - HashSet logUrls; - public TaskInfo(String jobId) { - this.jobId = jobId; - logUrls = new HashSet(); - } - public void addLogUrl(String logUrl) { - logUrls.add(logUrl); - } - - public HashSet getLogUrls() { - return logUrls; - } - - public String getJobId() { - return jobId; - } - } - - @SuppressWarnings("deprecation") - private void showJobFailDebugInfo(JobConf conf, RunningJob rj) throws IOException { - // Mapping from task ID to the number of failures - Map failures = new HashMap(); - // Successful task ID's - Set successes = new HashSet(); - - Map taskIdToInfo = new HashMap(); - - int startIndex = 0; - - console.printError("Error during job, obtaining debugging information..."); - // Loop to get all task completion events because getTaskCompletionEvents - // only returns a subset per call - while (true) { - TaskCompletionEvent[] taskCompletions = rj.getTaskCompletionEvents(startIndex); - - if (taskCompletions == null || taskCompletions.length == 0) { - break; - } - - boolean more = true; - boolean firstError = true; - for (TaskCompletionEvent t : taskCompletions) { - // getTaskJobIDs returns Strings for compatibility with Hadoop versions - // without TaskID or TaskAttemptID - String[] taskJobIds = ShimLoader.getHadoopShims().getTaskJobIDs(t); - - if (taskJobIds == null) { - console.printError("Task attempt info is unavailable in this Hadoop version"); - more = false; - break; - } - - // For each task completion event, get the associated task id, job id - // and the logs - String taskId = taskJobIds[0]; - String jobId = taskJobIds[1]; - if (firstError) { - console.printError("Examining task ID: " + taskId + " (and more) from job " + jobId); - firstError = false; - } - - TaskInfo ti = taskIdToInfo.get(taskId); - if (ti == null) { - ti = new TaskInfo(jobId); - taskIdToInfo.put(taskId, ti); - } - // These tasks should have come from the same job. - assert (ti.getJobId() != null && ti.getJobId().equals(jobId)); - ti.getLogUrls().add(getTaskAttemptLogUrl(t.getTaskTrackerHttp(), t.getTaskId())); - - // If a task failed, then keep track of the total number of failures - // for that task (typically, a task gets re-run up to 4 times if it - // fails - - if (t.getTaskStatus() != TaskCompletionEvent.Status.SUCCEEDED) { - Integer failAttempts = failures.get(taskId); - if (failAttempts == null) { - failAttempts = Integer.valueOf(0); - } - failAttempts = Integer.valueOf(failAttempts.intValue() + 1); - failures.put(taskId, failAttempts); - } else { - successes.add(taskId); - } - } - if (!more) { - break; - } - startIndex += taskCompletions.length; - } - // Remove failures for tasks that succeeded - for (String task : successes) { - failures.remove(task); - } - - if (failures.keySet().size() == 0) { - return; - } - - // Find the highest failure count - int maxFailures = 0; - for (Integer failCount : failures.values()) { - if (maxFailures < failCount.intValue()) { - maxFailures = failCount.intValue(); - } - } - - // Display Error Message for tasks with the highest failure count - String jtUrl = JobTrackerURLResolver.getURL(conf); - - for (String task : failures.keySet()) { - if (failures.get(task).intValue() == maxFailures) { - TaskInfo ti = taskIdToInfo.get(task); - String jobId = ti.getJobId(); - String taskUrl = jtUrl + "/taskdetails.jsp?jobid=" + jobId + "&tipid=" + task.toString(); - - TaskLogProcessor tlp = new TaskLogProcessor(conf); - for (String logUrl : ti.getLogUrls()) { - tlp.addTaskAttemptLogUrl(logUrl); - } - - List errors = tlp.getErrors(); - - StringBuilder sb = new StringBuilder(); - // We use a StringBuilder and then call printError only once as - // printError will write to both stderr and the error log file. In - // situations where both the stderr and the log file output is - // simultaneously output to a single stream, this will look cleaner. - sb.append("\n"); - sb.append("Task with the most failures(" + maxFailures + "): \n"); - sb.append("-----\n"); - sb.append("Task ID:\n " + task + "\n\n"); - sb.append("URL:\n " + taskUrl + "\n"); - - for (ErrorAndSolution e : errors) { - sb.append("\n"); - sb.append("Possible error:\n " + e.getError() + "\n\n"); - sb.append("Solution:\n " + e.getSolution() + "\n"); - } - sb.append("-----\n"); - - console.printError(sb.toString()); - // Only print out one task because that's good enough for debugging. - break; - } - } - return; - - } - public void localJobDebugger(int exitVal, String taskId) { StringBuilder sb = new StringBuilder(); sb.append("\n");