TaskGraphServlet.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:9k
- /**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.apache.hadoop.mapred;
- import java.io.IOException;
- import java.io.PrintWriter;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- /** The servlet that outputs svg graphics for map / reduce task
- * statuses
- */
- public 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 {
- response.setContentType("image/svg+xml");
- JobTracker tracker =
- (JobTracker) getServletContext().getAttribute("job.tracker");
-
- String jobIdStr = request.getParameter("jobid");
- if(jobIdStr == null)
- return;
- JobID jobId = JobID.forName(jobIdStr);
- final boolean isMap = "map".equalsIgnoreCase(request.getParameter("type"));
- final TaskReport[] reports = isMap? tracker.getMapTaskReports(jobId)
- : tracker.getReduceTaskReports(jobId);
- if(reports == null || reports.length == 0) {
- return;
- }
- final int numTasks = reports.length;
- 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
- final PrintWriter out = response.getWriter();
- 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"?>nn"+
- "<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">nn");
-
- //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
- 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");
- }
- }