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 @@ } %> +<[EMAIL PROTECTED] 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 @@ } %> +<[EMAIL PROTECTED] 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) ? " " : 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"); - } -%> + }%> +<[EMAIL PROTECTED] 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; %> +<[EMAIL PROTECTED] 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; +} + +