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 en...@apache.org on 2007/09/27 09:17:04 UTC

svn commit: r579928 - in /lucene/hadoop/trunk: ./ src/java/org/apache/hadoop/dfs/ src/java/org/apache/hadoop/mapred/ src/webapps/dfs/ src/webapps/job/ src/webapps/static/

Author: enis
Date: Thu Sep 27 00:17:03 2007
New Revision: 579928

URL: http://svn.apache.org/viewvc?rev=579928&view=rev
Log:
HADOOP-1894. Add percentage graphs and mapred task completion graphs
to Web User Interface. Contributed by Enis Soztutar. 

Modified:
    lucene/hadoop/trunk/CHANGES.txt
    lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/JspHelper.java
    lucene/hadoop/trunk/src/java/org/apache/hadoop/mapred/StatusHttpServer.java
    lucene/hadoop/trunk/src/webapps/dfs/dfshealth.jsp
    lucene/hadoop/trunk/src/webapps/job/jobdetails.jsp
    lucene/hadoop/trunk/src/webapps/job/jobtasks.jsp
    lucene/hadoop/trunk/src/webapps/job/jobtracker.jsp
    lucene/hadoop/trunk/src/webapps/job/taskdetails.jsp
    lucene/hadoop/trunk/src/webapps/static/hadoop.css

Modified: lucene/hadoop/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/CHANGES.txt?rev=579928&r1=579927&r2=579928&view=diff
==============================================================================
--- lucene/hadoop/trunk/CHANGES.txt (original)
+++ lucene/hadoop/trunk/CHANGES.txt Thu Sep 27 00:17:03 2007
@@ -62,6 +62,10 @@
 
     HADOOP-1809. Add a link in web site to #hadoop IRC channel. (enis)
 
+    HADOOP-1894. Add percentage graphs and mapred task completion graphs 
+    to Web User Interface. Users not using Firefox may install a plugin to 
+    their browsers to see svg graphics. (enis)
+
   OPTIMIZATIONS
 
     HADOOP-1910.  Reduce the number of RPCs that DistributedFileSystem.create()

Modified: lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/JspHelper.java
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/JspHelper.java?rev=579928&r1=579927&r2=579928&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/JspHelper.java (original)
+++ lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/JspHelper.java Thu Sep 27 00:17:03 2007
@@ -18,16 +18,21 @@
 
 package org.apache.hadoop.dfs;
 
-import javax.servlet.*;
-import javax.servlet.jsp.*;
-import javax.servlet.http.*;
-import java.io.*;
-import java.util.*;
-import java.net.*;
-import org.apache.hadoop.dfs.*;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Random;
+import java.util.TreeSet;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.jsp.JspWriter;
+
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.io.*;
-import org.apache.hadoop.conf.*;
 
 public class JspHelper {
   static FSNamesystem fsn = null;
@@ -276,4 +281,28 @@
     out.print("<title>HDFS:" + file + "</title>");
   }
 
+  public static String percentageGraph(int perc, int width) 
+    throws IOException {
+    
+    assert perc >= 0; assert perc <= 100;
+
+    StringBuilder builder = new StringBuilder();
+
+    builder.append("<table border=\"1px\" width=\""); builder.append(width);
+    builder.append("px\"><tr>");
+    if(perc > 0) {
+      builder.append("<td cellspacing=\"0\" class=\"perc_filled\" width=\"");
+      builder.append(perc); builder.append("%\"></td>");
+    }if(perc < 100) {
+      builder.append("<td cellspacing=\"0\" class=\"perc_nonfilled\" width=\"");
+      builder.append(100 - perc); builder.append("%\"></td>");
+    }
+    builder.append("</tr></table>");
+    return builder.toString();
+  }
+  
+  public static String percentageGraph(float perc, int width) throws IOException {
+  	return percentageGraph((int)perc, width);
+  }
+  
 }

Modified: lucene/hadoop/trunk/src/java/org/apache/hadoop/mapred/StatusHttpServer.java
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/java/org/apache/hadoop/mapred/StatusHttpServer.java?rev=579928&r1=579927&r2=579928&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/java/org/apache/hadoop/mapred/StatusHttpServer.java (original)
+++ lucene/hadoop/trunk/src/java/org/apache/hadoop/mapred/StatusHttpServer.java Thu Sep 27 00:17:03 2007
@@ -17,9 +17,11 @@
  */
 package org.apache.hadoop.mapred;
 
-import java.io.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
 import java.net.URL;
-import java.net.URLDecoder;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
@@ -28,10 +30,10 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.util.*;
+import org.apache.hadoop.util.ReflectionUtils;
 import org.mortbay.http.HttpContext;
-import org.mortbay.http.handler.ResourceHandler;
 import org.mortbay.http.SocketListener;
+import org.mortbay.http.handler.ResourceHandler;
 import org.mortbay.jetty.servlet.WebApplicationContext;
 
 /**
@@ -51,7 +53,7 @@
   private WebApplicationContext webAppContext;
   private static final Log LOG =
     LogFactory.getLog(StatusHttpServer.class.getName());
-  
+
   /**
    * Create a status server on the given port.
    * The jsp scripts are taken from src/webapps/<name>.
@@ -91,6 +93,7 @@
     webAppContext = 
       webServer.addWebApplication("/", appDir + File.separator + name);
     addServlet("stacks", "/stacks", StackServlet.class);
+    addServlet("reducegraph", "/taskgraph", TaskGraphServlet.class);
   }
 
   /**
@@ -110,8 +113,9 @@
    * @param servletClass The servlet class
    */
   public <T extends HttpServlet> 
-                    void addServlet(String name, String pathSpec, 
-                                    Class<T> servletClass) {
+   void addServlet(String name, String pathSpec, 
+                   Class<T> servletClass) {
+   
     WebApplicationContext context = webAppContext;
     try {
       if (name == null) {
@@ -127,7 +131,7 @@
       throw makeRuntimeException("Problem instantiating class", ex);
     }
   }
-  
+
   private static RuntimeException makeRuntimeException(String msg, 
                                                        Throwable cause) {
     RuntimeException result = new RuntimeException(msg);
@@ -136,7 +140,7 @@
     }
     return result;
   }
-  
+
   /**
    * Get the value in the webapp context.
    * @param name The name of the attribute
@@ -145,7 +149,7 @@
   public Object getAttribute(String name) {
     return webAppContext.getAttribute(name);
   }
-  
+
   /**
    * Get the pathname to the webapps files.
    * @return the pathname as a URL
@@ -156,7 +160,7 @@
       throw new IOException("webapps not found in CLASSPATH"); 
     return url.toString();
   }
-  
+
   /**
    * Get the port that the server is on
    * @return the port
@@ -204,14 +208,14 @@
       throw ie;
     }
   }
-  
+
   /**
    * stop the server
    */
   public void stop() throws InterruptedException {
     webServer.stop();
   }
-  
+
   /**
    * A very simple servlet to serve up a text representation of the current
    * stack traces. It both returns the stacks to the caller and logs them.
@@ -219,9 +223,13 @@
    * same data.
    */
   public static class StackServlet extends HttpServlet {
-    public void doGet(HttpServletRequest request, 
-                      HttpServletResponse response
-                      ) throws ServletException, IOException {
+
+    private static final long serialVersionUID = -6284183679759467039L;
+
+    @Override
+    public void doGet(HttpServletRequest request, HttpServletResponse response)
+      throws ServletException, IOException {
+      
       OutputStream outStream = response.getOutputStream();
       ReflectionUtils.printThreadInfo(new PrintWriter(outStream), "");
       outStream.close();
@@ -229,4 +237,219 @@
     }
   }
 
+  /** The servlet that outputs svg graphics for map / reduce task 
+   *  statuses
+   */
+  public static class TaskGraphServlet extends HttpServlet {
+
+    private static final long serialVersionUID = -1365683739392460020L;
+
+    /**height of the graph w/o margins*/ 
+    public static final int width = 600;
+    
+    /**height of the graph w/o margins*/ 
+    public static final int height = 200;
+    
+    /**margin space on y axis */
+    public static final int ymargin = 20;
+
+    /**margin space on x axis */
+    public static final int xmargin = 80;
+    
+    private static final float oneThird = 1f / 3f;
+    
+    @Override
+    public void doGet(HttpServletRequest request, HttpServletResponse response)
+      throws ServletException, IOException {
+
+      JobTracker tracker = 
+        (JobTracker) getServletContext().getAttribute("job.tracker");
+      
+      String jobId = request.getParameter("jobid");
+      if(jobId == null)
+        return;
+      String typeStr = request.getParameter("type");
+      boolean isMap = false;
+      if("map".equalsIgnoreCase(typeStr)) {
+        isMap = true;
+      }
+      
+      PrintWriter out = response.getWriter();
+      TaskReport[] reports = null;
+      
+      reports = isMap ? tracker.getMapTaskReports(jobId) 
+                      : tracker.getReduceTaskReports(jobId);
+      
+      int numTasks = reports.length;
+      if(numTasks <= 0) {
+        return;
+      }
+       
+      int tasksPerBar = (int)Math.ceil(numTasks / 600d);
+      int numBars = (int) Math.ceil((double)numTasks / tasksPerBar);
+      int w = Math.max(600, numBars);
+      int barWidth = Math.min(10,  w / numBars); //min 1px, max 10px
+      int barsPerNotch = (int)Math.ceil(10d / barWidth);
+      w = w + numBars / barsPerNotch;
+      int totalWidth = w + 2 * xmargin;
+      
+      //draw a white rectangle
+      out.print("<?xml version=\"1.0\" standalone=\"no\"?>\n" + 
+        "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \n" + 
+        "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n" +
+        "<?xml-stylesheet type=\"text/css\" href=\"/static/hadoop.css\"?>\n\n"+
+        "<svg width=\"");out.print(totalWidth);
+      out.print("\" height=\"");out.print(height + 2 * ymargin);
+      out.print("\" version=\"1.1\"\n" + 
+        "xmlns=\"http://www.w3.org/2000/svg\">\n\n"); 
+      
+      //axes
+      printLine(out, xmargin - 1, xmargin - 1, height + ymargin + 1
+          , ymargin - 1, "black" );
+      printLine(out, xmargin - 1, w + xmargin + 1 ,height + ymargin + 1 
+          , height + ymargin + 1, "black" );
+      
+      //borderlines
+      printLine(out, w + xmargin + 1 , w + xmargin +1
+          , height + ymargin + 1,ymargin - 1, "#CCCCCC" );
+      printLine(out, xmargin - 1, w + xmargin + 1
+          , ymargin - 1 , ymargin - 1, "#CCCCCC" );
+      
+      String[]  colors = new String[] {"#00DD00", "#E50000", "#AAAAFF"};
+      
+      //determine the notch interval using the number of digits for numTasks
+      int xNotchInterval = (int)(Math.ceil( numTasks / 10d));
+      
+      int xOffset = -1; 
+      int xNotchCount = 0;
+      //task bar graph
+      if(reports != null) {
+        for(int i=0, barCnt=0; ;i+=tasksPerBar, barCnt++) {
+          if(barCnt % barsPerNotch == 0) {
+            xOffset++;
+          }
+          int x = barCnt * barWidth + xmargin + xOffset;
+          //x axis notches
+          if(i >= xNotchInterval * xNotchCount) {
+            printLine(out, x, x, height + ymargin + 3 
+                , height + ymargin - 2, "black");
+            printText(out, x, height + ymargin + 15 
+                , String.valueOf(xNotchInterval * xNotchCount++ ), "middle");
+          }
+          if(i >= reports.length) break;
+          
+          if(isMap) {
+            float progress = getMapAvarageProgress(tasksPerBar, i, reports);
+            int barHeight = (int)Math.ceil(height * progress);
+            int y = height - barHeight + ymargin;
+            printRect(out, barWidth, barHeight,x , y , colors[2]);
+          }
+          else {
+            float[] progresses 
+              = getReduceAvarageProgresses(tasksPerBar, i, reports);
+            //draw three bars stacked, for copy, sort, reduce
+            
+            int prevHeight =0;
+            for(int j=0; j < 3 ; j++) {
+              int barHeight = (int)((height / 3) * progresses[j]);
+              if(barHeight > height/ 3 - 3)//fix rounding error
+                barHeight = height / 3 + 1;
+              
+              int y = height - barHeight + ymargin - prevHeight;
+              prevHeight += barHeight;
+              printRect(out, barWidth, barHeight, x, y, colors[j] );
+            }
+          }
+        }
+      }
+      
+      //y axis notches
+      for(int i=0;i<=10;i++) {
+        printLine(out, xmargin-3 , xmargin+2 , ymargin + (i * height) / 10
+            , ymargin + (i * height) / 10 , "black");
+        printText(out, xmargin - 10 , ymargin + 4 + (i * height) / 10 
+            , String.valueOf(100 - i * 10), "end");
+      }
+      
+      if(!isMap) {
+        //print color codes for copy, sort, reduce
+        printRect(out, 14, 14, xmargin + w + 4, ymargin + 20, colors[0]);
+        printText(out, xmargin + w + 24, ymargin + 30, "copy", "start");
+        printRect(out, 14, 14, xmargin + w + 4, ymargin + 50, colors[1]);
+        printText(out, xmargin + w + 24, ymargin + 60, "sort", "start");
+        printRect(out, 14, 14, xmargin + w + 4, ymargin + 80, colors[2]);
+        printText(out, xmargin + w + 24, ymargin + 90, "reduce", "start");
+      }
+      
+      
+      //firefox curently does not support vertical text
+      //out.print("<text x=\"");out.print(6);
+      //out.print("\" y=\""); out.print(ymargin + height / 2); 
+      //out.print("\" style=\"text-anchor:middle;writing-mode:tb\">"
+      //+"Percent</text>\n");
+      
+      out.print("</svg>");
+    }
+  
+    /**Computes average progress per bar*/
+    private float getMapAvarageProgress(int tasksPerBar, int index
+        , TaskReport[] reports ) {
+      float progress = 0f;
+      int k=0;
+      for(;k < tasksPerBar && index + k < reports.length; k++) { 
+        progress += reports[index + k].getProgress();
+      }
+      progress /= k;
+      return progress;
+    }
+  
+    /**Computes average progresses per bar*/
+    private float[] getReduceAvarageProgresses(int tasksPerBar, int index
+        , TaskReport[] reports ) {
+      float[] progresses = new float[] {0,0,0};
+      int k=0;
+      for(;k < tasksPerBar && index + k < reports.length; k++) {
+        float progress = reports[index+k].getProgress();
+        for(int j=0; progress > 0 ; j++, progress -= oneThird) {
+          if(progress > oneThird)
+            progresses[j] += 1f;
+          else 
+            progresses[j] += progress * 3 ;
+        }
+      }
+      for(int j=0; j<3; j++) { progresses[j] /= k;}
+      
+      return progresses;
+    }
+    
+    private void printRect(PrintWriter out, int width, int height
+        , int x, int y, String color) throws IOException {
+      if(height > 0) {
+        out.print("<rect width=\"");out.print(width);
+        out.print("\" height=\"");  out.print(height);
+        out.print("\" x=\""); out.print(x);
+        out.print("\" y=\""); out.print(y);
+        out.print("\" style=\"fill:"); out.print(color);out.print("\"/>\n");
+      }
+    }
+    private void printLine(PrintWriter out, int x1, int x2
+        , int y1, int y2, String color) throws IOException {
+      out.print("<line x1=\"");out.print(x1);
+      out.print("\" x2=\"");out.print(x2);
+      out.print("\" y1=\"");out.print(y1);
+      out.print("\" y2=\""); out.print(y2);
+      out.print("\" class=\"taskgraphline\" style=\"stroke:"); 
+      out.print(color); out.print("\"/>\n"); 
+    }
+    private void printText(PrintWriter out, int x, int y, String text
+        , String anchor) throws IOException {
+      out.print("<text x=\"");out.print(String.valueOf(x));
+      out.print("\" y=\""); out.print(String.valueOf(y));
+      out.print("\" style=\"fill:black;font-family:sans-serif;" 
+          + "text-anchor:");out.print(anchor); out.print("\">");
+      out.print(text); out.print("</text>\n");
+    }
+  }
+  
 }
+

Modified: lucene/hadoop/trunk/src/webapps/dfs/dfshealth.jsp
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/webapps/dfs/dfshealth.jsp?rev=579928&r1=579927&r2=579928&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/webapps/dfs/dfshealth.jsp (original)
+++ lucene/hadoop/trunk/src/webapps/dfs/dfshealth.jsp Thu Sep 27 00:17:03 2007
@@ -11,8 +11,7 @@
   import="java.lang.Math"
   import="java.net.URLEncoder"
 %>
-<%!
-  FSNamesystem fsn = FSNamesystem.getFSNamesystem();
+<%!FSNamesystem fsn = FSNamesystem.getFSNamesystem();
   String namenodeLabel = fsn.getDFSNameNodeMachine() + ":" + fsn.getDFSNameNodePort();
   JspHelper jspHelper = new JspHelper();
 
@@ -90,7 +89,7 @@
       percentUsed = FsShell.limitDecimalTo2(((1.0 * u)/c)*100);
     else
       percentUsed = "100";
-
+    
     String adminState = (d.isDecommissioned() ? "Decommissioned" :
                          (d.isDecommissionInProgress() ? "Decommission In Progress":
                           "In Service"));
@@ -103,7 +102,8 @@
               adminState +
 	      "<td class=\"size\">" +
               FsShell.limitDecimalTo2(c*1.0/diskBytes) +
-	      "<td class=\"pcused\">" + percentUsed +
+	      "<td class=\"pcused\">" + percentUsed +"<td class=\"pcused\">" +
+	      JspHelper.percentageGraph( (int)Double.parseDouble(percentUsed) , 100) +
 	      "<td class=\"size\">" +
               FsShell.limitDecimalTo2(d.getRemaining()*1.0/diskBytes) +
           "<td class=\"blocks\">" + d.numBlocks() + "\n");
@@ -188,7 +188,8 @@
                        NodeHeaderStr("adminstate") + "> Admin State <th " +
                        NodeHeaderStr("size") + "> Size (" + diskByteStr +
                        ") <th " + NodeHeaderStr("pcused") +
-                       "> Used (%) <th " + 
+                       "> Used (%) <th " + NodeHeaderStr("pcused") +
+                       "> Used (%) <th " +
                        NodeHeaderStr("remaining") + "> Remaining (" + 
                        diskByteStr + ") <th " +
                        NodeHeaderStr("blocks") + "> Blocks\n" );
@@ -216,8 +217,7 @@
 	}
 	out.print("</div>");
     }
-  }
-%>
+  }%>
 
 <html>
 

Modified: lucene/hadoop/trunk/src/webapps/job/jobdetails.jsp
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/webapps/job/jobdetails.jsp?rev=579928&r1=579927&r2=579928&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/webapps/job/jobdetails.jsp (original)
+++ lucene/hadoop/trunk/src/webapps/job/jobdetails.jsp Thu Sep 27 00:17:03 2007
@@ -17,8 +17,7 @@
            StringUtils.simpleHostname(tracker.getJobTrackerMachine());
 %>
 <%!
-  
-	private static final String PRIVATE_ACTIONS_KEY 
+  private static final String PRIVATE_ACTIONS_KEY 
 		= "webinterface.private.actions";
  
   private void printTaskSummary(JspWriter out,
@@ -49,6 +48,7 @@
               "&type="+ kind + "&pagenum=1\">" + kind + 
               "</a></th><td align=\"right\">" + 
               StringUtils.formatPercent(completePercent, 2) +
+              JspHelper.percentageGraph((int)(completePercent * 100), 80) +
               "</td><td align=\"right\">" + 
               totalTasks + 
               "</td><td align=\"right\">" + 
@@ -121,6 +121,7 @@
     }
 %>
 
+<%@page import="org.apache.hadoop.mapred.StatusHttpServer.TaskGraphServlet"%>
 <html>
 <head>
   <% 
@@ -131,6 +132,7 @@
   }
   %>
 <title>Hadoop <%=jobId%> on <%=trackerName%></title>
+<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
 </head>
 <body>
 <h1>Hadoop <%=jobId%> on <a href="jobtracker.jsp"><%=trackerName%></a></h1>
@@ -236,6 +238,41 @@
     %>
     </table>
 
+<hr>Map Completion Graph - 
+<%
+if("off".equals(request.getParameter("map.graph"))) {
+  session.setAttribute("map.graph", "off");
+} else if("on".equals(request.getParameter("map.graph"))){
+  session.setAttribute("map.graph", "on");
+}
+if("off".equals(request.getParameter("reduce.graph"))) {
+  session.setAttribute("reduce.graph", "off");
+} else if("on".equals(request.getParameter("reduce.graph"))){
+  session.setAttribute("reduce.graph", "on");
+}
+
+if("off".equals(session.getAttribute("map.graph"))) { %>
+<a href="/jobdetails.jsp?jobid=<%=jobId%>&refresh=<%=refresh%>&map.graph=on" > open </a>
+<%} else { %> 
+<a href="/jobdetails.jsp?jobid=<%=jobId%>&refresh=<%=refresh%>&map.graph=off" > close </a>
+<br><embed src="/taskgraph?type=map&jobid=<%=jobId%>" 
+       width="<%=StatusHttpServer.TaskGraphServlet.width + 2 * StatusHttpServer.TaskGraphServlet.xmargin%>" 
+       height="<%=StatusHttpServer.TaskGraphServlet.height + 3 * StatusHttpServer.TaskGraphServlet.ymargin%>"
+       style="width:100%" type="image/svg+xml" pluginspage="http://www.adobe.com/svg/viewer/install/" />
+<%}%>
+
+<%if(job.getReduceTasks().length > 0) { %>
+<hr>Reduce Completion Graph -
+<%if("off".equals(session.getAttribute("reduce.graph"))) { %>
+<a href="/jobdetails.jsp?jobid=<%=jobId%>&refresh=<%=refresh%>&reduce.graph=on" > open </a>
+<%} else { %> 
+<a href="/jobdetails.jsp?jobid=<%=jobId%>&refresh=<%=refresh%>&reduce.graph=off" > close </a>
+ 
+ <br><embed src="/taskgraph?type=reduce&jobid=<%=jobId%>" 
+       width="<%=StatusHttpServer.TaskGraphServlet.width + 2 * StatusHttpServer.TaskGraphServlet.xmargin%>" 
+       height="<%=StatusHttpServer.TaskGraphServlet.height + 3 * StatusHttpServer.TaskGraphServlet.ymargin%>" 
+       style="width:100%" type="image/svg+xml" pluginspage="http://www.adobe.com/svg/viewer/install/" />
+<%} }%>
 
 <hr>Change priority from <%=job.getPriority()%> to: 
 <%
@@ -252,6 +289,9 @@
     	&& runState == JobStatus.RUNNING) { %>
 	<br/><a href="jobdetails.jsp?action=confirm&jobid=<%=jobId%>"> Kill this job </a>
 <% } %>
+
+<hr>
+
 <hr>
 <a href="jobtracker.jsp">Go back to JobTracker</a><br>
 <a href="http://lucene.apache.org/hadoop">Hadoop</a>, 2007.<br>

Modified: lucene/hadoop/trunk/src/webapps/job/jobtasks.jsp
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/webapps/job/jobtasks.jsp?rev=579928&r1=579927&r2=579928&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/webapps/job/jobtasks.jsp (original)
+++ lucene/hadoop/trunk/src/webapps/job/jobtasks.jsp Thu Sep 27 00:17:03 2007
@@ -35,16 +35,18 @@
   }
 %>
 
+<%@page import="org.apache.hadoop.dfs.JspHelper"%>
 <html>
   <head>
     <title>Hadoop <%=type%> task list for <%=jobid%> on <%=trackerName%></title>
+    <link rel="stylesheet" type="text/css" href="/static/hadoop.css">
   </head>
 <body>
 <h1>Hadoop <%=type%> task list for 
 <a href="jobdetails.jsp?jobid=<%=jobid%>"><%=jobid%></a> on 
 <a href="jobtracker.jsp"><%=trackerName%></a></h1>
 <%
-  if (job == null) {
+    if (job == null) {
     out.print("<b>Job " + jobid + " not found.</b><br>\n");
     return;
   }
@@ -67,8 +69,8 @@
           out.print("<tr><td><a href=\"taskdetails.jsp?jobid=" + jobid + 
                     "&tipid=" + report.getTaskId() + "\">"  + 
                     report.getTaskId() + "</a></td>");
-         out.print("<td>" + StringUtils.formatPercent(report.getProgress(),2) + 
-                   "</td>");
+         out.print("<td>" + StringUtils.formatPercent(report.getProgress(),2) +
+        		   JspHelper.percentageGraph(report.getProgress() * 100f, 80) + "</td>");
          out.print("<td>"  + report.getState() + "<br/></td>");
          out.println("<td>" + StringUtils.getFormattedTimeWithDiff(dateFormat, report.getStartTime(),0) + "<br/></td>");
          out.println("<td>" + StringUtils.getFormattedTimeWithDiff(dateFormat, 

Modified: lucene/hadoop/trunk/src/webapps/job/jobtracker.jsp
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/webapps/job/jobtracker.jsp?rev=579928&r1=579927&r2=579928&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/webapps/job/jobtracker.jsp (original)
+++ lucene/hadoop/trunk/src/webapps/job/jobtracker.jsp Thu Sep 27 00:17:03 2007
@@ -47,10 +47,12 @@
                   "<td>" + profile.getUser() + "</td>" 
                     + "<td>" + ("".equals(name) ? "&nbsp;" : name) + "</td>" + 
                     "<td>" + 
-                    StringUtils.formatPercent(status.mapProgress(),2) + 
+                    StringUtils.formatPercent(status.mapProgress(),2) +
+                    JspHelper.percentageGraph(status.mapProgress()  * 100, 80) +
                     "</td><td>" + 
                     desiredMaps + "</td><td>" + completedMaps + "</td><td>" + 
-                    StringUtils.formatPercent(status.reduceProgress(),2) + 
+                    StringUtils.formatPercent(status.reduceProgress(),2) +
+                    JspHelper.percentageGraph(status.reduceProgress() * 100, 80) +
                     "</td><td>" + 
                     desiredReduces + "</td><td> " + completedReduces + 
                     "</td></tr>\n");
@@ -74,13 +76,14 @@
               status.getMaxTasks() + "</td><td>" +
               tracker.getTotalSubmissions() + "</td><td><a href=\"machines.jsp\">" +
               status.getTaskTrackers() + "</a></td></tr></table>\n");
-  }
-%>
+  }%>
 
+<%@page import="org.apache.hadoop.dfs.JspHelper"%>
 <html>
-
+<head>
 <title><%= trackerName %> Hadoop Map/Reduce Administration</title>
-
+<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+</head>
 <body>
 <h1><%= trackerName %> Hadoop Map/Reduce Administration</h1>
 
@@ -103,7 +106,7 @@
 
 <h2>Running Jobs</h2>
 <%
-    generateJobTable(out, "Running", tracker.runningJobs(), 10);
+    generateJobTable(out, "Running", tracker.runningJobs(), 30);
 %>
 <hr>
 

Modified: lucene/hadoop/trunk/src/webapps/job/taskdetails.jsp
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/webapps/job/taskdetails.jsp?rev=579928&r1=579927&r2=579928&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/webapps/job/taskdetails.jsp (original)
+++ lucene/hadoop/trunk/src/webapps/job/taskdetails.jsp Thu Sep 27 00:17:03 2007
@@ -62,8 +62,12 @@
         : null;
 %>
 
+<%@page import="org.apache.hadoop.dfs.JspHelper"%>
 <html>
-<title>Hadoop Task Details</title>
+<head>
+  <link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+  <title>Hadoop Task Details</title>
+</head>
 <body>
 <h1>Job <a href="/jobdetails.jsp?jobid=<%=jobid%>"><%=jobid%></a></h1>
 
@@ -105,7 +109,7 @@
         }
         out.print("<td>" + status.getRunState() + "</td>");
         out.print("<td>" + StringUtils.formatPercent(status.getProgress(), 2)
-          + "</td>");
+          + JspHelper.percentageGraph(status.getProgress() * 100f, 80) + "</td>");
         out.print("<td>"
           + StringUtils.getFormattedTimeWithDiff(dateFormat, status
           .getStartTime(), 0) + "</td>");

Modified: lucene/hadoop/trunk/src/webapps/static/hadoop.css
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/webapps/static/hadoop.css?rev=579928&r1=579927&r2=579928&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/webapps/static/hadoop.css (original)
+++ lucene/hadoop/trunk/src/webapps/static/hadoop.css Thu Sep 27 00:17:03 2007
@@ -27,8 +27,7 @@
 }
 
 div#dfsnodetable A:link, A:visited {
-	text-decoration : none;
-        color : black;
+	text-decoration : none;       
 }
 
 div#dfsnodetable th.header, th.headerASC, th.headerDSC {
@@ -60,3 +59,17 @@
 	padding-left : 10px;
 	padding-right : 10px;
 }
+
+td.perc_filled {
+  background-color:#AAAAFF;
+}
+
+td.perc_nonfilled {
+  background-color:#FFFFFF;
+}
+
+line.taskgraphline {
+  stroke-width:1;stroke-linecap:round;  
+}
+
+