You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by cu...@apache.org on 2006/05/12 23:07:09 UTC

svn commit: r405871 - in /lucene/hadoop/trunk: ./ src/java/org/apache/hadoop/mapred/ src/java/org/apache/hadoop/util/ src/webapps/mapred/

Author: cutting
Date: Fri May 12 14:07:07 2006
New Revision: 405871

URL: http://svn.apache.org/viewcvs?rev=405871&view=rev
Log:
HADOOP-208.  Enhance MapReduce web interface.  Contributed by Owen.

Added:
    lucene/hadoop/trunk/src/webapps/mapred/jobfailures.jsp
    lucene/hadoop/trunk/src/webapps/mapred/jobtasks.jsp
    lucene/hadoop/trunk/src/webapps/mapred/machines.jsp
Modified:
    lucene/hadoop/trunk/CHANGES.txt
    lucene/hadoop/trunk/src/java/org/apache/hadoop/mapred/JobInProgress.java
    lucene/hadoop/trunk/src/java/org/apache/hadoop/mapred/TaskInProgress.java
    lucene/hadoop/trunk/src/java/org/apache/hadoop/util/StringUtils.java
    lucene/hadoop/trunk/src/webapps/mapred/jobdetails.jsp
    lucene/hadoop/trunk/src/webapps/mapred/jobtracker.jsp
    lucene/hadoop/trunk/src/webapps/mapred/taskdetails.jsp

Modified: lucene/hadoop/trunk/CHANGES.txt
URL: http://svn.apache.org/viewcvs/lucene/hadoop/trunk/CHANGES.txt?rev=405871&r1=405870&r2=405871&view=diff
==============================================================================
--- lucene/hadoop/trunk/CHANGES.txt (original)
+++ lucene/hadoop/trunk/CHANGES.txt Fri May 12 14:07:07 2006
@@ -3,6 +3,12 @@
 
 Trunk (unreleased)
 
+ 1. HADOOP-208.  Enhance MapReduce web interface, adding new pages
+    for failed tasks, and tasktrackers.  (omalley via cutting)
+
+
+Release 0.2.1 - 2006-05-05
+
  1. HADOOP-199.  Fix reduce progress (broken by HADOOP-182).
     (omalley via cutting)
 

Modified: lucene/hadoop/trunk/src/java/org/apache/hadoop/mapred/JobInProgress.java
URL: http://svn.apache.org/viewcvs/lucene/hadoop/trunk/src/java/org/apache/hadoop/mapred/JobInProgress.java?rev=405871&r1=405870&r2=405871&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/java/org/apache/hadoop/mapred/JobInProgress.java (original)
+++ lucene/hadoop/trunk/src/java/org/apache/hadoop/mapred/JobInProgress.java Fri May 12 14:07:07 2006
@@ -222,6 +222,22 @@
     }
 
     /**
+     * Get the list of map tasks
+     * @return the raw array of maps for this job
+     */
+    TaskInProgress[] getMapTasks() {
+      return maps;
+    }
+    
+    /**
+     * Get the list of reduce tasks
+     * @return the raw array of reduce tasks for this job
+     */
+    TaskInProgress[] getReduceTasks() {
+      return reduces;
+    }
+    
+    /**
      * Return a treeset of completed TaskInProgress objects
      */
     public Vector reportTasksInProgress(boolean shouldBeMap, boolean shouldBeComplete) {

Modified: lucene/hadoop/trunk/src/java/org/apache/hadoop/mapred/TaskInProgress.java
URL: http://svn.apache.org/viewcvs/lucene/hadoop/trunk/src/java/org/apache/hadoop/mapred/TaskInProgress.java?rev=405871&r1=405870&r2=405871&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/java/org/apache/hadoop/mapred/TaskInProgress.java (original)
+++ lucene/hadoop/trunk/src/java/org/apache/hadoop/mapred/TaskInProgress.java Fri May 12 14:07:07 2006
@@ -160,6 +160,15 @@
     public boolean isMapTask() {
         return split != null;
     }
+    
+    /**
+     * Is this tip currently running any tasks?
+     * @return true if any tasks are running
+     */
+    public boolean isRunning() {
+      return !recentTasks.isEmpty();
+    }
+    
     /**
      */
     public boolean isComplete() {

Modified: lucene/hadoop/trunk/src/java/org/apache/hadoop/util/StringUtils.java
URL: http://svn.apache.org/viewcvs/lucene/hadoop/trunk/src/java/org/apache/hadoop/util/StringUtils.java?rev=405871&r1=405870&r2=405871&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/java/org/apache/hadoop/util/StringUtils.java (original)
+++ lucene/hadoop/trunk/src/java/org/apache/hadoop/util/StringUtils.java Fri May 12 14:07:07 2006
@@ -37,5 +37,18 @@
     wrt.close();
     return stm.toString();
   }
+  
+  /**
+   * Given a full hostname, return the word upto the first dot.
+   * @param fullHostname the full hostname
+   * @return the hostname to the first dot
+   */
+  public static String simpleHostname(String fullHostname) {
+    int offset = fullHostname.indexOf('.');
+    if (offset != -1) {
+      return fullHostname.substring(0, offset);
+    }
+    return fullHostname;
+  }
 
 }

Modified: lucene/hadoop/trunk/src/webapps/mapred/jobdetails.jsp
URL: http://svn.apache.org/viewcvs/lucene/hadoop/trunk/src/webapps/mapred/jobdetails.jsp?rev=405871&r1=405870&r2=405871&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/webapps/mapred/jobdetails.jsp (original)
+++ lucene/hadoop/trunk/src/webapps/mapred/jobdetails.jsp Fri May 12 14:07:07 2006
@@ -4,100 +4,98 @@
   import="javax.servlet.http.*"
   import="java.io.*"
   import="java.util.*"
+  import="java.text.DecimalFormat"
   import="org.apache.hadoop.mapred.*"
-  import="java.lang.Integer"
+  import="org.apache.hadoop.util.*"
 %>
 
-<%
-  String jobid = request.getParameter("jobid");
-  String type = request.getParameter("type");
-  String pagenum = request.getParameter("pagenum");
-  int pnum = Integer.parseInt(pagenum);
-  int next_page = pnum+1;
-  int numperpage = 2000;
+<%!
+  private static DecimalFormat percentFormat = new DecimalFormat("##0.00");
   JobTracker tracker = JobTracker.getTracker();
-  JobInProgress job = (JobInProgress) tracker.getJob(jobid);
-  JobProfile profile = (job != null) ? (job.getProfile()) : null;
-  JobStatus status = (job != null) ? (job.getStatus()) : null;
-  TaskReport[] reports = null;
-  int start_index = (pnum - 1) * numperpage;
-  int end_index = start_index + numperpage;
-  int report_len = 0;
-  if ("map".equals(type)){
-     reports = (job != null) ? tracker.getMapTaskReports(jobid) : null;
+  String trackerName = 
+           StringUtils.simpleHostname(tracker.getJobTrackerMachine());
+  
+  private void printTaskSummary(JspWriter out,
+                                String jobId,
+                                String kind,
+                                double completePercent,
+                                TaskInProgress[] tasks
+                               ) throws IOException {
+    int totalTasks = tasks.length;
+    int runningTasks = 0;
+    int finishedTasks = 0;
+    int failures = 0;
+    for(int i=0; i < totalTasks; ++i) {
+      TaskInProgress task = tasks[i];
+      if (task.isComplete()) {
+        finishedTasks += 1;
+      } else if (task.isRunning()) {
+        runningTasks += 1;
+      }
+      failures += task.numTaskFailures();
+    }
+    out.print("<tr><th><a href=\"/jobtasks.jsp?jobid=" + jobId + 
+              "&type="+ kind + "&pagenum=1\">" + kind + "</a></th><td>" + 
+              percentFormat.format(100.0 * completePercent) +
+              "</td><td>" + totalTasks + "</td><td>" + 
+              (totalTasks - runningTasks - finishedTasks) + "</td><td>" +
+              runningTasks + "</td><td>" +
+              finishedTasks + 
+              "</td><td><a href=\"/jobfailures.jsp?jobid=" + jobId +
+              "&kind=" + kind + "\">" +
+              failures + "</a></td></tr>\n");
+  }
+           
+  private void printJobStatus(JspWriter out, 
+                              String jobId) throws IOException {
+    JobInProgress job = (JobInProgress) tracker.getJob(jobId);
+    if (job == null) {
+      out.print("<b>Job " + jobId + " not found.</b><br>\n");
+      return;
+    }
+    JobProfile profile = job.getProfile();
+    JobStatus status = job.getStatus();
+    out.print("<b>User:</b> " + profile.getUser() + "<br>\n");
+    out.print("<b>Job Name:</b> " + profile.getJobName() + "<br>\n");
+    out.print("<b>Job File:</b> " + profile.getJobFile() + "<br>\n");
+    out.print("<b>Started at:</b> " + new Date(job.getStartTime()) + "<br>\n");
+    int runState = status.getRunState();
+    if (runState == JobStatus.RUNNING) {
+      out.print("<b>Status:</b> Running<br>\n");
+    } else {
+      if (runState == JobStatus.SUCCEEDED) {
+        out.print("<b>Status:</b> Succeeded<br>\n");
+      } else if (runState == JobStatus.FAILED) {
+        out.print("<b>Status:</b> Failed<br>\n");
+      }
+      out.print("<b>Finished at:</b> " + new Date(job.getFinishTime()) +
+                "<br>\n");
     }
-  else{
-    reports = (job != null) ? tracker.getReduceTaskReports(jobid) : null;
+    out.print("<hr>\n");
+    out.print("<table border=2 cellpadding=\"5\" cellspacing=\"2\">");
+    out.print("<tr><th>Kind</th><th>% Complete</th><th>Num Tasks</th>" +
+              "<th>Pending</th><th>Running</th><th>Complete</th>" +
+              "<th><a href=\"/jobfailures.jsp?jobid=" + jobId + 
+              "\">Failures</a></th></tr>\n");
+    printTaskSummary(out, jobId, "map", status.mapProgress(), 
+                     job.getMapTasks());
+    printTaskSummary(out, jobId, "reduce", status.reduceProgress(),
+                     job.getReduceTasks());
+    out.print("</table>\n");
   }
 %>
 
-<html>
-<title>Hadoop MapReduce Job Details</title>
-<body>
 <%
-  if (job == null) {
-    %>
-    No job found<br>
-    <%
-  } else {
- %>
-<h1>Job '<%=jobid%>'</h1>
-
-<b>Job File:</b> <%=profile.getJobFile()%><br>
-<b>The job started at:</b> <%= new Date(job.getStartTime())%><br>
-<%   
-  if (status.getRunState() == JobStatus.RUNNING) {
-    out.print("The job is still running.<br>\n");
-  } else if (status.getRunState() == JobStatus.SUCCEEDED) {
-    out.print("<b>The job completed at:</b> " + new Date(job.getFinishTime()) + 
+    String jobid = request.getParameter("jobid");
+%>
 
-"<br>\n");
-  } else if (status.getRunState() == JobStatus.FAILED) {
-    out.print("<b>The job failed at:</b> " + new Date(job.getFinishTime()) + 
+<html>
+<title>Hadoop <%=jobid%> on <%=trackerName%></title>
+<body>
+<h1>Hadoop <%=jobid%> on <a href="/jobtracker.jsp"><%=trackerName%></a></h1>
 
-"<br>\n");
-  }
-  report_len = reports.length;
-  
-  if (report_len <= start_index) {
-        out.print("<b>No such tasks</b>");
-  }else{
-    out.print("<hr>");
-    out.print("<h2>Tasks</h2>");
-    out.print("<center>");
-    out.print("<table border=2 cellpadding=\"5\" cellspacing=\"2\">");
-    out.print("<tr><td align=\"center\">Task</td><td>Complete</td><td>Status</td><td>Errors</td></tr>");
-    if (end_index > report_len){
-        end_index = report_len;
-    }
-    for (int i = start_index ; i < end_index; i++) {
-          TaskReport report = reports[i];
-          out.print("<tr><td><a href=\"taskdetails.jsp?jobid=" + jobid + 
-"&taskid=" + report.getTaskId() + "\">"  + report.getTaskId() + "</a></td>");
-         out.print("<td>" + report.getProgress() + "</td>");
-         out.print("<td>"  + report.getState() + "</td>");
-         String[] diagnostics = report.getDiagnostics();
-         for (int j = 0; j < diagnostics.length ; j++) {
-                out.print("<td><pre>" + diagnostics[j] + "</pre></td>");
-         }
-            out.print("</tr>\n");
-    }
-    out.print("</table>");
-    out.print("</center>");
-  }
-  
-  %>
-  
- <%
-  if (end_index < report_len) {
-    out.print("<div style=\"text-align:right\">" + "<a href=\"/jobdetails.jsp?jobid="+ jobid + "&type=" + type +"&pagenum=" + next_page 
-            + "\">" + "Next" + "</a></div>");
-   }
-  if (start_index != 0) {
-      out.print("<div style=\"text-align:right\">" + "<a href=\"/jobdetails.jsp?jobid="+ jobid + "&type=" + type +"&pagenum=" + (pnum -1) 
-      + "\">" + "Prev" + "</a></div>");
-   }
-  }
+<% 
+    printJobStatus(out, jobid); 
 %>
 
 <hr>

Added: lucene/hadoop/trunk/src/webapps/mapred/jobfailures.jsp
URL: http://svn.apache.org/viewcvs/lucene/hadoop/trunk/src/webapps/mapred/jobfailures.jsp?rev=405871&view=auto
==============================================================================
--- lucene/hadoop/trunk/src/webapps/mapred/jobfailures.jsp (added)
+++ lucene/hadoop/trunk/src/webapps/mapred/jobfailures.jsp Fri May 12 14:07:07 2006
@@ -0,0 +1,95 @@
+<%@ page
+  contentType="text/html; charset=UTF-8"
+  import="javax.servlet.*"
+  import="javax.servlet.http.*"
+  import="java.io.*"
+  import="java.util.*"
+  import="org.apache.hadoop.mapred.*"
+  import="org.apache.hadoop.util.*"
+%>
+
+<%!
+  JobTracker tracker = JobTracker.getTracker();
+  String trackerName = 
+           StringUtils.simpleHostname(tracker.getJobTrackerMachine());
+  
+  private void printFailedAttempts(JspWriter out,
+                                   String jobId,
+                                   TaskInProgress tip) throws IOException {
+    TaskStatus[] statuses = tip.getTaskStatuses();
+    String tipId = tip.getTIPId();
+    for(int i=0; i < statuses.length; ++i) {
+      if (statuses[i].getRunState() == TaskStatus.FAILED) {
+        out.print("<tr><td>" + statuses[i].getTaskId() +
+                  "</td><td><a href=\"/taskdetails.jsp?jobid="+ jobId + 
+                  "&taskid=" + tipId + "\">" + tipId +
+                  "</a></td><td>" + statuses[i].getHostname() +
+                  "</td><td>" + statuses[i].getDiagnosticInfo() +
+                  "</td></tr>\n");
+      }
+    }
+  }
+             
+  private void printFailures(JspWriter out, 
+                             String jobId,
+                             String kind) throws IOException {
+    JobInProgress job = (JobInProgress) tracker.getJob(jobId);
+    if (job == null) {
+      out.print("<b>Job " + jobId + " not found.</b><br>\n");
+      return;
+    }
+    boolean includeMap = false;
+    boolean includeReduce = false;
+    if (kind == null) {
+      includeMap = true;
+      includeReduce = true;
+    } else if ("map".equals(kind)) {
+      includeMap = true;
+    } else if ("reduce".equals(kind)) {
+      includeReduce = true;
+    } else if ("all".equals(kind)) {
+      includeMap = true;
+      includeReduce = true;
+    } else {
+      out.print("<b>Kind " + kind + " not supported.</b><br>\n");
+      return;
+    }
+    out.print("<table border=2 cellpadding=\"5\" cellspacing=\"2\">");
+    out.print("<tr><th>Attempt</th><th>Task</th><th>Machine</th>" +
+              "<th>Error</th></tr>\n");
+    if (includeMap) {
+      TaskInProgress[] tips = job.getMapTasks();
+      for(int i=0; i < tips.length; ++i) {
+        printFailedAttempts(out, jobId, tips[i]);
+      }
+    }
+    if (includeReduce) {
+      TaskInProgress[] tips = job.getReduceTasks();
+      for(int i=0; i < tips.length; ++i) {
+        printFailedAttempts(out, jobId, tips[i]);
+      }
+    }
+    out.print("</table>\n");
+  }
+%>
+
+<%
+    String jobId = request.getParameter("jobid");
+    String kind = request.getParameter("kind");
+%>
+
+<html>
+<title>Hadoop <%=jobId%> failures on <%=trackerName%></title>
+<body>
+<h1>Hadoop <a href="/jobdetails.jsp?jobid=<%=jobId%>"><%=jobId%></a>
+failures on <a href="/jobtracker.jsp"><%=trackerName%></a></h1>
+
+<% 
+    printFailures(out, jobId, kind); 
+%>
+
+<hr>
+<a href="/jobtracker.jsp">Go back to JobTracker</a><br>
+<a href="http://lucene.apache.org/hadoop">Hadoop</a>, 2006.<br>
+</body>
+</html>

Added: lucene/hadoop/trunk/src/webapps/mapred/jobtasks.jsp
URL: http://svn.apache.org/viewcvs/lucene/hadoop/trunk/src/webapps/mapred/jobtasks.jsp?rev=405871&view=auto
==============================================================================
--- lucene/hadoop/trunk/src/webapps/mapred/jobtasks.jsp (added)
+++ lucene/hadoop/trunk/src/webapps/mapred/jobtasks.jsp Fri May 12 14:07:07 2006
@@ -0,0 +1,94 @@
+<%@ page
+  contentType="text/html; charset=UTF-8"
+  import="javax.servlet.*"
+  import="javax.servlet.http.*"
+  import="java.io.*"
+  import="java.util.*"
+  import="org.apache.hadoop.mapred.*"
+  import="org.apache.hadoop.util.*"
+  import="java.lang.Integer"
+%>
+
+<%
+  String jobid = request.getParameter("jobid");
+  String type = request.getParameter("type");
+  String pagenum = request.getParameter("pagenum");
+  int pnum = Integer.parseInt(pagenum);
+  int next_page = pnum+1;
+  int numperpage = 2000;
+  JobTracker tracker = JobTracker.getTracker();
+  String trackerLabel = 
+           StringUtils.simpleHostname(tracker.getJobTrackerMachine());
+  JobInProgress job = (JobInProgress) tracker.getJob(jobid);
+  JobProfile profile = (job != null) ? (job.getProfile()) : null;
+  JobStatus status = (job != null) ? (job.getStatus()) : null;
+  TaskReport[] reports = null;
+  int start_index = (pnum - 1) * numperpage;
+  int end_index = start_index + numperpage;
+  int report_len = 0;
+  if ("map".equals(type)){
+     reports = (job != null) ? tracker.getMapTaskReports(jobid) : null;
+    }
+  else{
+    reports = (job != null) ? tracker.getReduceTaskReports(jobid) : null;
+  }
+%>
+
+<html>
+<title>Hadoop <%=type%> task list for <%=jobid%> on <%=trackerLabel%></title>
+<body>
+<h1>Hadoop <%=type%> task list for 
+<a href="/jobdetails.jsp?jobid=<%=jobid%>"><%=jobid%></a> on 
+<a href="/jobtracker.jsp"><%=trackerLabel%></a></h1>
+<%
+  if (job == null) {
+    out.print("<b>Job " + jobid + " not found.</b><br>\n");
+    return;
+  }
+  report_len = reports.length;
+  
+  if (report_len <= start_index) {
+    out.print("<b>No such tasks</b>");
+  } else {
+    out.print("<hr>");
+    out.print("<h2>Tasks</h2>");
+    out.print("<center>");
+    out.print("<table border=2 cellpadding=\"5\" cellspacing=\"2\">");
+    out.print("<tr><td align=\"center\">Task</td><td>Complete</td><td>Status</td><td>Errors</td></tr>");
+    if (end_index > report_len){
+        end_index = report_len;
+    }
+    for (int i = start_index ; i < end_index; i++) {
+          TaskReport report = reports[i];
+          out.print("<tr><td><a href=\"taskdetails.jsp?jobid=" + jobid + 
+                    "&taskid=" + report.getTaskId() + "\">"  + 
+                    report.getTaskId() + "</a></td>");
+         out.print("<td>" + report.getProgress() + "</td>");
+         out.print("<td>"  + report.getState() + "</td>");
+         String[] diagnostics = report.getDiagnostics();
+         for (int j = 0; j < diagnostics.length ; j++) {
+                out.print("<td><pre>" + diagnostics[j] + "</pre></td>");
+         }
+         out.print("</tr>\n");
+    }
+    out.print("</table>");
+    out.print("</center>");
+  }
+  if (end_index < report_len) {
+    out.print("<div style=\"text-align:right\">" + 
+              "<a href=\"/jobtasks.jsp?jobid="+ jobid + "&type=" + type +
+              "&pagenum=" + next_page +
+              "\">" + "Next" + "</a></div>");
+  }
+  if (start_index != 0) {
+      out.print("<div style=\"text-align:right\">" + 
+                "<a href=\"/jobtasks.jsp?jobid="+ jobid + "&type=" + type +
+                "&pagenum=" + (pnum -1) + "\">" + "Prev" + "</a></div>");
+  }
+%>
+
+<hr>
+<a href="/jobtracker.jsp">Go back to JobTracker</a><br>
+<a href="http://lucene.apache.org/hadoop">Hadoop</a>, 2006.<br>
+</body>
+</html>

Modified: lucene/hadoop/trunk/src/webapps/mapred/jobtracker.jsp
URL: http://svn.apache.org/viewcvs/lucene/hadoop/trunk/src/webapps/mapred/jobtracker.jsp?rev=405871&r1=405870&r2=405871&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/webapps/mapred/jobtracker.jsp (original)
+++ lucene/hadoop/trunk/src/webapps/mapred/jobtracker.jsp Fri May 12 14:07:07 2006
@@ -6,75 +6,32 @@
   import="java.util.*"
   import="java.text.DecimalFormat"
   import="org.apache.hadoop.mapred.*"
+  import="org.apache.hadoop.util.*"
 %>
 <%!
   JobTracker tracker = JobTracker.getTracker();
-  String trackerLabel = tracker.getJobTrackerMachine() + ":" + tracker.getTrackerPort();
+  String trackerLabel = 
+           StringUtils.simpleHostname(tracker.getJobTrackerMachine());
   private static DecimalFormat percentFormat = new DecimalFormat("##0.00");
 
-  public void generateTaskTrackerTable(JspWriter out) throws IOException {
-    Collection c = tracker.taskTrackers();
-
-    if (c.size() == 0) {
-      out.print("There are currently no known TaskTracker(s).");
-    } else {
-      out.print("<center>\n");
-      out.print("<table border=\"2\" cellpadding=\"5\" cellspacing=\"2\">\n");
-      out.print("<tr><td align=\"center\" colspan=\"5\"><b>Task Trackers</b></td></tr>\n");
-      out.print("<tr><td><b>Name</b></td><td><b>Host</b></td>" +
-                "<td><b># running tasks</b></td><td><b>Failures</b></td>" +
-                "<td><b>Secs since heartbeat</b></td></tr>\n");
-      int maxFailures = 0;
-      String failureKing = null;
-      for (Iterator it = c.iterator(); it.hasNext(); ) {
-        TaskTrackerStatus tt = (TaskTrackerStatus) it.next();
-        long sinceHeartbeat = System.currentTimeMillis() - tt.getLastSeen();
-        if (sinceHeartbeat > 0) {
-          sinceHeartbeat = sinceHeartbeat / 1000;
-        }
-        int numCurTasks = 0;
-        for (Iterator it2 = tt.taskReports(); it2.hasNext(); ) {
-          it2.next();
-          numCurTasks++;
-        }
-        int numFailures = tt.getFailures();
-        if (numFailures > maxFailures) {
-          maxFailures = numFailures;
-          failureKing = tt.getTrackerName();
-        }
-
-        out.print("<tr><td>" + tt.getTrackerName() + "</td><td>" + 
-                  tt.getHost() + "</td><td>" + numCurTasks +
-                  "</td><td>" + numFailures + 
-                  "</td><td>" + sinceHeartbeat + "</td></tr>\n");
-      }
-      out.print("</table>\n");
-      out.print("</center>\n");
-      if (maxFailures > 0) {
-        out.print("Highest Failures: " + failureKing + " with " + maxFailures + 
-                  " failures<br>\n");
-      }
-    }
-  }
-
   public void generateJobTable(JspWriter out, String label, Vector jobs) throws IOException {
       out.print("<center>\n");
       out.print("<table border=\"2\" cellpadding=\"5\" cellspacing=\"2\">\n");
-      out.print("<tr><td align=\"center\" colspan=\"8\"><b>" + label + " Jobs </b></td></tr>\n");
+      out.print("<tr><td align=\"center\" colspan=\"9\"><b>" + label + " Jobs </b></td></tr>\n");
       if (jobs.size() > 0) {
         out.print("<tr><td><b>Jobid</b></td><td><b>User</b></td>");
         out.print("<td><b>Name</b></td>");
-        out.print("<td><b>% complete</b></td><td><b>Required maps</b></td>");
-        out.print("<td><b>maps completed</b></td>");
-        out.print("<td><b>Required reduces</b></td>");
-        out.print("<td><b>reduces completed</b></td></tr>\n");
+        out.print("<td><b>Map % complete</b></td>");
+        out.print("<td><b>Map total</b></td>");
+        out.print("<td><b>Maps completed</b></td>");
+        out.print("<td><b>Reduce % complete</b></td>");
+        out.print("<td><b>Reduce total</b></td>");
+        out.print("<td><b>Reduces completed</b></td></tr>\n");
         for (Iterator it = jobs.iterator(); it.hasNext(); ) {
           JobInProgress job = (JobInProgress) it.next();
           JobProfile profile = job.getProfile();
           JobStatus status = job.getStatus();
           String jobid = profile.getJobId();
-          double completedRatio = (0.5 * (100 * status.mapProgress())) +
-                                 (0.5 * (100 * status.reduceProgress()));
 
           int desiredMaps = job.desiredMaps();
           int desiredReduces = job.desiredReduces();
@@ -82,15 +39,16 @@
           int completedReduces = job.finishedReduces();
           String name = profile.getJobName();
 
-          out.print( "<tr><td>" + jobid + 
-                  "<br>" + "<a href=\"jobdetails.jsp?jobid=" + jobid + "&type=" + "map" + "&pagenum=" + 1 + "\">" + 
-                    "Maps" + "</a>" +  "<br>" +
-                  "<a href=\"jobdetails.jsp?jobid=" + jobid + "&type=" + "reduce" + "&pagenum=" + 1 + "\">" + 
-                    "Reduces" + "</a></td>" +
+          out.print( "<tr><td><a href=\"jobdetails.jsp?jobid=" + jobid + "\">" +
+                     jobid + "</a></td>" +
                   "<td>" + profile.getUser() + "</td>" 
                     + "<td>" + ("".equals(name) ? "&nbsp;" : name) + "</td>" + 
-                    "<td>" + percentFormat.format(completedRatio) + "%</td><td>" + 
+                    "<td>" + 
+                    percentFormat.format(100.0 * status.mapProgress()) + 
+                    "%</td><td>" + 
                     desiredMaps + "</td><td>" + completedMaps + "</td><td>" + 
+                    percentFormat.format(100.0 * status.reduceProgress()) + 
+                    "%</td><td>" + 
                     desiredReduces + "</td><td> " + completedReduces + 
                     "</td></tr>\n");
         }
@@ -105,20 +63,20 @@
     ClusterStatus status = tracker.getClusterStatus();
     out.print("<table border=\"2\" cellpadding=\"5\" cellspacing=\"2\">\n"+
               "<tr><th>Maps</th><th>Reduces</th>" + 
-              "<th>Capacity</th><th>Nodes</th></tr>\n");
+              "<th>Tasks/Node</th><th>Nodes</th></tr>\n");
     out.print("<tr><td>" + status.getMapTasks() + "</td><td>" +
               status.getReduceTasks() + "</td><td>" + 
-              status.getMaxTasks() + "</td><td>" +
-              status.getTaskTrackers() + "</td></tr></table>\n");
+              status.getMaxTasks() + "</td><td><a href=\"/machines.jsp\">" +
+              status.getTaskTrackers() + "</a></td></tr></table>\n");
   }
 %>
 
 <html>
 
-<title>Hadoop MapReduce General Administration</title>
+<title><%= trackerLabel %> Hadoop Map/Reduce Administration</title>
 
 <body>
-<h1>JobTracker '<%=trackerLabel%>'</h1>
+<h1><%= trackerLabel %> Hadoop Map/Reduce Administration</h1>
 
 This JobTracker has been up since <%= new Date(tracker.getStartTime())%>.<br>
 <hr>
@@ -130,13 +88,6 @@
 </center>
 <hr>
 
-
-<h2>Task Trackers</h2>
-<%
-  generateTaskTrackerTable(out);
-%>
-
-<hr>
 <h2>Running Jobs</h2>
 <%
     generateJobTable(out, "Running", tracker.runningJobs());

Added: lucene/hadoop/trunk/src/webapps/mapred/machines.jsp
URL: http://svn.apache.org/viewcvs/lucene/hadoop/trunk/src/webapps/mapred/machines.jsp?rev=405871&view=auto
==============================================================================
--- lucene/hadoop/trunk/src/webapps/mapred/machines.jsp (added)
+++ lucene/hadoop/trunk/src/webapps/mapred/machines.jsp Fri May 12 14:07:07 2006
@@ -0,0 +1,79 @@
+<%@ page
+  contentType="text/html; charset=UTF-8"
+  import="javax.servlet.*"
+  import="javax.servlet.http.*"
+  import="java.io.*"
+  import="java.util.*"
+  import="java.text.DecimalFormat"
+  import="org.apache.hadoop.mapred.*"
+  import="org.apache.hadoop.util.*"
+%>
+<%!
+  JobTracker tracker = JobTracker.getTracker();
+  String trackerLabel = 
+           StringUtils.simpleHostname(tracker.getJobTrackerMachine());
+  private static DecimalFormat percentFormat = new DecimalFormat("##0.00");
+
+  public void generateTaskTrackerTable(JspWriter out) throws IOException {
+    Collection c = tracker.taskTrackers();
+
+    if (c.size() == 0) {
+      out.print("There are currently no known TaskTracker(s).");
+    } else {
+      out.print("<center>\n");
+      out.print("<table border=\"2\" cellpadding=\"5\" cellspacing=\"2\">\n");
+      out.print("<tr><td align=\"center\" colspan=\"5\"><b>Task Trackers</b></td></tr>\n");
+      out.print("<tr><td><b>Name</b></td><td><b>Host</b></td>" +
+                "<td><b># running tasks</b></td><td><b>Failures</b></td>" +
+                "<td><b>Secs since heartbeat</b></td></tr>\n");
+      int maxFailures = 0;
+      String failureKing = null;
+      for (Iterator it = c.iterator(); it.hasNext(); ) {
+        TaskTrackerStatus tt = (TaskTrackerStatus) it.next();
+        long sinceHeartbeat = System.currentTimeMillis() - tt.getLastSeen();
+        if (sinceHeartbeat > 0) {
+          sinceHeartbeat = sinceHeartbeat / 1000;
+        }
+        int numCurTasks = 0;
+        for (Iterator it2 = tt.taskReports(); it2.hasNext(); ) {
+          it2.next();
+          numCurTasks++;
+        }
+        int numFailures = tt.getFailures();
+        if (numFailures > maxFailures) {
+          maxFailures = numFailures;
+          failureKing = tt.getTrackerName();
+        }
+
+        out.print("<tr><td>" + tt.getTrackerName() + "</td><td>" + 
+                  tt.getHost() + "</td><td>" + numCurTasks +
+                  "</td><td>" + numFailures + 
+                  "</td><td>" + sinceHeartbeat + "</td></tr>\n");
+      }
+      out.print("</table>\n");
+      out.print("</center>\n");
+      if (maxFailures > 0) {
+        out.print("Highest Failures: " + failureKing + " with " + maxFailures + 
+                  " failures<br>\n");
+      }
+    }
+  }
+
+%>
+
+<html>
+
+<title><%=trackerLabel%> Hadoop Machine List</title>
+
+<body>
+<h1><a href="/jobtracker.jsp"><%=trackerLabel%></a> Hadoop Machine List</h1>
+
+<h2>Task Trackers</h2>
+<%
+  generateTaskTrackerTable(out);
+%>
+
+<hr>
+<a href="http://lucene.apache.org/hadoop">Hadoop</a>, 2006.<br>
+</body>
+</html>

Modified: lucene/hadoop/trunk/src/webapps/mapred/taskdetails.jsp
URL: http://svn.apache.org/viewcvs/lucene/hadoop/trunk/src/webapps/mapred/taskdetails.jsp?rev=405871&r1=405870&r2=405871&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/webapps/mapred/taskdetails.jsp (original)
+++ lucene/hadoop/trunk/src/webapps/mapred/taskdetails.jsp Fri May 12 14:07:07 2006
@@ -40,7 +40,7 @@
 <html>
 <title>Hadoop Task Details</title>
 <body>
-<h1>Job '<%=jobid%>'</h1>
+<h1>Job <%=jobid%></h1>
 
 <hr>
 
@@ -65,11 +65,7 @@
 </center>
 
 <hr>
-<%
-out.print("<a href=\"/jobdetails.jsp?jobid=" + jobid + "\">" + "Go back to the Job" + "</a><br>");	
-%>
-<a href="http://lucene.apache.org/hadoop">Hadoop</a>, 2006.<br>
-<hr>
+<a href="/jobdetails.jsp?jobid=<%=jobid%>">Go back to the job</a><br>
 <a href="/jobtracker.jsp">Go back to JobTracker</a><br>
 <a href="http://lucene.apache.org/hadoop">Hadoop</a>, 2006.<br>
 </body>