Browse Source

MAPREDUCE-6297. Task Id of the failed task in diagnostics should link to the task page. (Siqi Li via gera)

(cherry picked from commit 89ded89e86e5d9a634d92a5d8a7c889744d97f94)
Gera Shegalov 10 years ago
parent
commit
6f06e3b7ea

+ 3 - 0
hadoop-mapreduce-project/CHANGES.txt

@@ -95,6 +95,9 @@ Release 2.8.0 - UNRELEASED
     MAPREDUCE-6293. Set job classloader on uber-job's LocalContainerLauncher
     event thread. (Sangjin Lee via gera)
 
+    MAPREDUCE-6297. Task Id of the failed task in diagnostics should link to
+    the task page. (Siqi Li via gera)
+
 Release 2.7.1 - UNRELEASED
 
   INCOMPATIBLE CHANGES

+ 13 - 22
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/TaskID.java

@@ -25,6 +25,8 @@ import java.text.NumberFormat;
 import java.util.EnumMap;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.apache.hadoop.classification.InterfaceAudience;
 import org.apache.hadoop.classification.InterfaceStability;
@@ -58,6 +60,9 @@ import org.apache.hadoop.io.WritableUtils;
 public class TaskID extends org.apache.hadoop.mapred.ID {
   protected static final String TASK = "task";
   protected static final NumberFormat idFormat = NumberFormat.getInstance();
+  public static final String TASK_ID_REGEX = TASK + "_(\\d+)_(\\d+)_" +
+      CharTaskTypeMaps.allTaskTypes + "_(\\d+)";
+  public static final Pattern taskIdPattern = Pattern.compile(TASK_ID_REGEX);
   static {
     idFormat.setGroupingUsed(false);
     idFormat.setMinimumIntegerDigits(6);
@@ -207,29 +212,15 @@ public class TaskID extends org.apache.hadoop.mapred.ID {
     throws IllegalArgumentException {
     if(str == null)
       return null;
-    String exceptionMsg = null;
-    try {
-      String[] parts = str.split("_");
-      if(parts.length == 5) {
-        if(parts[0].equals(TASK)) {
-          String type = parts[3];
-          TaskType t = CharTaskTypeMaps.getTaskType(type.charAt(0));
-          if(t != null) {
-          
-            return new org.apache.hadoop.mapred.TaskID(parts[1], 
-                                                     Integer.parseInt(parts[2]),
-                                                     t, 
-                                                     Integer.parseInt(parts[4]));
-          } else
-            exceptionMsg = "Bad TaskType identifier. TaskId string : " + str
-                + " is not properly formed.";
-        }
-      }
-    }catch (Exception ex) {//fall below
-    }
-    if (exceptionMsg == null) {
-      exceptionMsg = "TaskId string : " + str + " is not properly formed";
+    Matcher m = taskIdPattern.matcher(str);
+    if (m.matches()) {
+      return new org.apache.hadoop.mapred.TaskID(m.group(1),
+          Integer.parseInt(m.group(2)),
+          CharTaskTypeMaps.getTaskType(m.group(3).charAt(0)),
+          Integer.parseInt(m.group(4)));
     }
+    String exceptionMsg = "TaskId string : " + str + " is not properly formed" +
+        "\nReason: " + m.toString();
     throw new IllegalArgumentException(exceptionMsg);
   }
   /**

+ 7 - 1
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/main/java/org/apache/hadoop/mapreduce/v2/hs/webapp/HsJobBlock.java

@@ -27,6 +27,7 @@ import static org.apache.hadoop.yarn.webapp.view.JQueryUI._TH;
 import java.util.Date;
 import java.util.List;
 
+import org.apache.hadoop.mapreduce.TaskID;
 import org.apache.hadoop.mapreduce.v2.api.records.AMInfo;
 import org.apache.hadoop.mapreduce.v2.api.records.JobId;
 import org.apache.hadoop.mapreduce.v2.app.AppContext;
@@ -98,7 +99,7 @@ public class HsJobBlock extends HtmlBlock {
     if(diagnostics != null && !diagnostics.isEmpty()) {
       StringBuffer b = new StringBuffer();
       for(String diag: diagnostics) {
-        b.append(diag);
+        b.append(addTaskLinks(diag));
       }
       infoBlock._("Diagnostics:", b.toString());
     }
@@ -203,4 +204,9 @@ public class HsJobBlock extends HtmlBlock {
        _().
      _();
   }
+
+  static String addTaskLinks(String text) {
+    return TaskID.taskIdPattern.matcher(text).replaceAll(
+        "<a href=\"/jobhistory/task/$0\">$0</a>");
+  }
 }

+ 19 - 1
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/test/java/org/apache/hadoop/mapreduce/v2/hs/webapp/TestBlocks.java

@@ -65,6 +65,7 @@ import org.apache.hadoop.yarn.webapp.log.AggregatedLogsPage;
 import org.apache.hadoop.yarn.webapp.view.BlockForTest;
 import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
 import org.apache.hadoop.yarn.webapp.view.HtmlBlock.Block;
+import org.junit.Assert;
 import org.junit.Test;
 
 import static org.junit.Assert.*;
@@ -78,6 +79,23 @@ import static org.mockito.Mockito.*;
 public class TestBlocks {
   private ByteArrayOutputStream data = new ByteArrayOutputStream();
 
+  @Test
+  public void testPullTaskLink(){
+    Task task = getTask(0);
+    String taskId = task.getID().toString();
+
+    Assert.assertEquals("pull links doesn't work correctly",
+        "Task failed <a href=\"/jobhistory/task/" + taskId + "\">" +
+        taskId + "</a>"
+        , HsJobBlock.addTaskLinks("Task failed " + taskId));
+
+    Assert.assertEquals("pull links doesn't work correctly",
+        "Task failed <a href=\"/jobhistory/task/" + taskId + "\">" +
+        taskId + "</a>\n Job failed as tasks failed. failedMaps:1 failedReduces:0"
+        , HsJobBlock.addTaskLinks("Task failed " + taskId + "\n " +
+        "Job failed as tasks failed. failedMaps:1 failedReduces:0"));
+  }
+
   /**
    * test HsTasksBlock's rendering.
    */
@@ -241,7 +259,7 @@ public class TestBlocks {
     assertEquals(HsAttemptsPage.class, controller.attemptsPage());
 
     controller.set(AMParams.JOB_ID, "job_01_01");
-    controller.set(AMParams.TASK_ID, "task_01_01_m01_01");
+    controller.set(AMParams.TASK_ID, "task_01_01_m_01");
     controller.set(AMParams.TASK_TYPE, "m");
     controller.set(AMParams.ATTEMPT_STATE, "State");
 

+ 18 - 9
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/test/java/org/apache/hadoop/mapreduce/v2/hs/webapp/TestHsWebServicesTasks.java

@@ -33,6 +33,7 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.mapreduce.TaskID;
 import org.apache.hadoop.mapreduce.v2.api.records.JobId;
 import org.apache.hadoop.mapreduce.v2.api.records.TaskId;
 import org.apache.hadoop.mapreduce.v2.api.records.TaskReport;
@@ -368,9 +369,11 @@ public class TestHsWebServicesTasks extends JerseyTest {
         String message = exception.getString("message");
         String type = exception.getString("exception");
         String classname = exception.getString("javaClassName");
-        WebServicesTestUtils.checkStringMatch("exception message",
+        WebServicesTestUtils.checkStringEqual("exception message",
             "java.lang.Exception: TaskId string : "
-                + "bogustaskid is not properly formed", message);
+                + "bogustaskid is not properly formed"
+                + "\nReason: java.util.regex.Matcher[pattern=" +
+                TaskID.TASK_ID_REGEX + " region=0,11 lastmatch=]", message);
         WebServicesTestUtils.checkStringMatch("exception type",
             "NotFoundException", type);
         WebServicesTestUtils.checkStringMatch("exception classname",
@@ -432,9 +435,11 @@ public class TestHsWebServicesTasks extends JerseyTest {
         String message = exception.getString("message");
         String type = exception.getString("exception");
         String classname = exception.getString("javaClassName");
-        WebServicesTestUtils.checkStringMatch("exception message",
-            "java.lang.Exception: Bad TaskType identifier. TaskId string : "
-                + "task_0_0000_d_000000 is not properly formed.", message);
+        WebServicesTestUtils.checkStringEqual("exception message",
+            "java.lang.Exception: TaskId string : "
+                + "task_0_0000_d_000000 is not properly formed" +
+                "\nReason: java.util.regex.Matcher[pattern=" +
+                TaskID.TASK_ID_REGEX + " region=0,20 lastmatch=]", message);
         WebServicesTestUtils.checkStringMatch("exception type",
             "NotFoundException", type);
         WebServicesTestUtils.checkStringMatch("exception classname",
@@ -464,9 +469,11 @@ public class TestHsWebServicesTasks extends JerseyTest {
         String message = exception.getString("message");
         String type = exception.getString("exception");
         String classname = exception.getString("javaClassName");
-        WebServicesTestUtils.checkStringMatch("exception message",
+        WebServicesTestUtils.checkStringEqual("exception message",
             "java.lang.Exception: TaskId string : "
-                + "task_0000_m_000000 is not properly formed", message);
+                + "task_0000_m_000000 is not properly formed" +
+                "\nReason: java.util.regex.Matcher[pattern=" +
+                TaskID.TASK_ID_REGEX + " region=0,18 lastmatch=]", message);
         WebServicesTestUtils.checkStringMatch("exception type",
             "NotFoundException", type);
         WebServicesTestUtils.checkStringMatch("exception classname",
@@ -496,9 +503,11 @@ public class TestHsWebServicesTasks extends JerseyTest {
         String message = exception.getString("message");
         String type = exception.getString("exception");
         String classname = exception.getString("javaClassName");
-        WebServicesTestUtils.checkStringMatch("exception message",
+        WebServicesTestUtils.checkStringEqual("exception message",
             "java.lang.Exception: TaskId string : "
-                + "task_0_0000_m is not properly formed", message);
+                + "task_0_0000_m is not properly formed" +
+                "\nReason: java.util.regex.Matcher[pattern=" +
+                TaskID.TASK_ID_REGEX + " region=0,13 lastmatch=]", message);
         WebServicesTestUtils.checkStringMatch("exception type",
             "NotFoundException", type);
         WebServicesTestUtils.checkStringMatch("exception classname",