TaskGraphServlet.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:9k
源码类别:

网格计算

开发平台:

Java

  1. /**
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. package org.apache.hadoop.mapred;
  19. import java.io.IOException;
  20. import java.io.PrintWriter;
  21. import javax.servlet.ServletException;
  22. import javax.servlet.http.HttpServlet;
  23. import javax.servlet.http.HttpServletRequest;
  24. import javax.servlet.http.HttpServletResponse;
  25. /** The servlet that outputs svg graphics for map / reduce task
  26.  *  statuses
  27.  */
  28. public class TaskGraphServlet extends HttpServlet {
  29.   private static final long serialVersionUID = -1365683739392460020L;
  30.   /**height of the graph w/o margins*/ 
  31.   public static final int width = 600;
  32.   
  33.   /**height of the graph w/o margins*/ 
  34.   public static final int height = 200;
  35.   
  36.   /**margin space on y axis */
  37.   public static final int ymargin = 20;
  38.   /**margin space on x axis */
  39.   public static final int xmargin = 80;
  40.   
  41.   private static final float oneThird = 1f / 3f;
  42.   
  43.   @Override
  44.   public void doGet(HttpServletRequest request, HttpServletResponse response)
  45.     throws ServletException, IOException {
  46.     response.setContentType("image/svg+xml");
  47.     JobTracker tracker = 
  48.       (JobTracker) getServletContext().getAttribute("job.tracker");
  49.     
  50.     String jobIdStr = request.getParameter("jobid");
  51.     if(jobIdStr == null)
  52.       return;
  53.     JobID jobId = JobID.forName(jobIdStr);
  54.     final boolean isMap = "map".equalsIgnoreCase(request.getParameter("type"));
  55.     final TaskReport[] reports = isMap? tracker.getMapTaskReports(jobId) 
  56.                                       : tracker.getReduceTaskReports(jobId);
  57.     if(reports == null || reports.length == 0) {
  58.       return;
  59.     }
  60.     final int numTasks = reports.length;     
  61.     int tasksPerBar = (int)Math.ceil(numTasks / 600d);
  62.     int numBars = (int) Math.ceil((double)numTasks / tasksPerBar);
  63.     int w = Math.max(600, numBars);
  64.     int barWidth = Math.min(10,  w / numBars); //min 1px, max 10px
  65.     int barsPerNotch = (int)Math.ceil(10d / barWidth);
  66.     w = w + numBars / barsPerNotch;
  67.     int totalWidth = w + 2 * xmargin;
  68.     
  69.     //draw a white rectangle
  70.     final PrintWriter out = response.getWriter();
  71.     out.print("<?xml version="1.0" standalone="no"?>n" + 
  72.       "<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" n" + 
  73.       ""http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">n" +
  74.       "<?xml-stylesheet type="text/css" href="/static/hadoop.css"?>nn"+
  75.       "<svg width="");out.print(totalWidth);
  76.     out.print("" height="");out.print(height + 2 * ymargin);
  77.     out.print("" version="1.1"n" + 
  78.       "xmlns="http://www.w3.org/2000/svg">nn"); 
  79.     
  80.     //axes
  81.     printLine(out, xmargin - 1, xmargin - 1, height + ymargin + 1
  82.         , ymargin - 1, "black" );
  83.     printLine(out, xmargin - 1, w + xmargin + 1 ,height + ymargin + 1 
  84.         , height + ymargin + 1, "black" );
  85.     
  86.     //borderlines
  87.     printLine(out, w + xmargin + 1 , w + xmargin +1
  88.         , height + ymargin + 1,ymargin - 1, "#CCCCCC" );
  89.     printLine(out, xmargin - 1, w + xmargin + 1
  90.         , ymargin - 1 , ymargin - 1, "#CCCCCC" );
  91.     
  92.     String[]  colors = new String[] {"#00DD00", "#E50000", "#AAAAFF"};
  93.     
  94.     //determine the notch interval using the number of digits for numTasks
  95.     int xNotchInterval = (int)(Math.ceil( numTasks / 10d));
  96.     
  97.     int xOffset = -1; 
  98.     int xNotchCount = 0;
  99.     //task bar graph
  100.     for(int i=0, barCnt=0; ;i+=tasksPerBar, barCnt++) {
  101.       if(barCnt % barsPerNotch == 0) {
  102.         xOffset++;
  103.       }
  104.       int x = barCnt * barWidth + xmargin + xOffset;
  105.       //x axis notches
  106.       if(i >= xNotchInterval * xNotchCount) {
  107.         printLine(out, x, x, height + ymargin + 3 
  108.             , height + ymargin - 2, "black");
  109.         printText(out, x, height + ymargin + 15 
  110.             , String.valueOf(xNotchInterval * xNotchCount++ ), "middle");
  111.       }
  112.       if(i >= reports.length) break;
  113.       
  114.       if(isMap) {
  115.         float progress = getMapAvarageProgress(tasksPerBar, i, reports);
  116.         int barHeight = (int)Math.ceil(height * progress);
  117.         int y = height - barHeight + ymargin;
  118.         printRect(out, barWidth, barHeight,x , y , colors[2]);
  119.       }
  120.       else {
  121.         float[] progresses 
  122.           = getReduceAvarageProgresses(tasksPerBar, i, reports);
  123.         //draw three bars stacked, for copy, sort, reduce
  124.         
  125.         int prevHeight =0;
  126.         for(int j=0; j < 3 ; j++) {
  127.           int barHeight = (int)((height / 3) * progresses[j]);
  128.           if(barHeight > height/ 3 - 3)//fix rounding error
  129.             barHeight = height / 3 + 1;
  130.           
  131.           int y = height - barHeight + ymargin - prevHeight;
  132.           prevHeight += barHeight;
  133.           printRect(out, barWidth, barHeight, x, y, colors[j] );
  134.         }
  135.       }
  136.     }
  137.     
  138.     //y axis notches
  139.     for(int i=0;i<=10;i++) {
  140.       printLine(out, xmargin-3 , xmargin+2 , ymargin + (i * height) / 10
  141.           , ymargin + (i * height) / 10 , "black");
  142.       printText(out, xmargin - 10 , ymargin + 4 + (i * height) / 10 
  143.           , String.valueOf(100 - i * 10), "end");
  144.     }
  145.     
  146.     if(!isMap) {
  147.       //print color codes for copy, sort, reduce
  148.       printRect(out, 14, 14, xmargin + w + 4, ymargin + 20, colors[0]);
  149.       printText(out, xmargin + w + 24, ymargin + 30, "copy", "start");
  150.       printRect(out, 14, 14, xmargin + w + 4, ymargin + 50, colors[1]);
  151.       printText(out, xmargin + w + 24, ymargin + 60, "sort", "start");
  152.       printRect(out, 14, 14, xmargin + w + 4, ymargin + 80, colors[2]);
  153.       printText(out, xmargin + w + 24, ymargin + 90, "reduce", "start");
  154.     }
  155.     
  156.     
  157.     //firefox curently does not support vertical text
  158.     //out.print("<text x="");out.print(6);
  159.     //out.print("" y=""); out.print(ymargin + height / 2); 
  160.     //out.print("" style="text-anchor:middle;writing-mode:tb">"
  161.     //+"Percent</text>n");
  162.     
  163.     out.print("</svg>");
  164.   }
  165.   /**Computes average progress per bar*/
  166.   private float getMapAvarageProgress(int tasksPerBar, int index
  167.       , TaskReport[] reports ) {
  168.     float progress = 0f;
  169.     int k=0;
  170.     for(;k < tasksPerBar && index + k < reports.length; k++) { 
  171.       progress += reports[index + k].getProgress();
  172.     }
  173.     progress /= k;
  174.     return progress;
  175.   }
  176.   /**Computes average progresses per bar*/
  177.   private float[] getReduceAvarageProgresses(int tasksPerBar, int index
  178.       , TaskReport[] reports ) {
  179.     float[] progresses = new float[] {0,0,0};
  180.     int k=0;
  181.     for(;k < tasksPerBar && index + k < reports.length; k++) {
  182.       float progress = reports[index+k].getProgress();
  183.       for(int j=0; progress > 0 ; j++, progress -= oneThird) {
  184.         if(progress > oneThird)
  185.           progresses[j] += 1f;
  186.         else 
  187.           progresses[j] += progress * 3 ;
  188.       }
  189.     }
  190.     for(int j=0; j<3; j++) { progresses[j] /= k;}
  191.     
  192.     return progresses;
  193.   }
  194.   
  195.   private void printRect(PrintWriter out, int width, int height
  196.       , int x, int y, String color) throws IOException {
  197.     if(height > 0) {
  198.       out.print("<rect width="");out.print(width);
  199.       out.print("" height="");  out.print(height);
  200.       out.print("" x=""); out.print(x);
  201.       out.print("" y=""); out.print(y);
  202.       out.print("" style="fill:"); out.print(color);out.print(""/>n");
  203.     }
  204.   }
  205.   private void printLine(PrintWriter out, int x1, int x2
  206.       , int y1, int y2, String color) throws IOException {
  207.     out.print("<line x1="");out.print(x1);
  208.     out.print("" x2="");out.print(x2);
  209.     out.print("" y1="");out.print(y1);
  210.     out.print("" y2=""); out.print(y2);
  211.     out.print("" class="taskgraphline" style="stroke:"); 
  212.     out.print(color); out.print(""/>n"); 
  213.   }
  214.   private void printText(PrintWriter out, int x, int y, String text
  215.       , String anchor) throws IOException {
  216.     out.print("<text x="");out.print(String.valueOf(x));
  217.     out.print("" y=""); out.print(String.valueOf(y));
  218.     out.print("" style="fill:black;font-family:sans-serif;" 
  219.         + "text-anchor:");out.print(anchor); out.print("">");
  220.     out.print(text); out.print("</text>n");
  221.   }
  222. }