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

网格计算

开发平台:

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.text.SimpleDateFormat;
  21. import java.util.Arrays;
  22. import java.util.Comparator;
  23. import java.util.Date;
  24. import java.util.Map;
  25. import java.util.Set;
  26. import java.util.TreeMap;
  27. import org.apache.hadoop.conf.Configuration;
  28. import org.apache.hadoop.fs.FileSystem;
  29. import org.apache.hadoop.fs.FileUtil;
  30. import org.apache.hadoop.fs.Path;
  31. import org.apache.hadoop.fs.PathFilter;
  32. import org.apache.hadoop.mapred.DefaultJobHistoryParser.*;
  33. import org.apache.hadoop.mapred.JobHistory.*;
  34. import org.apache.hadoop.util.StringUtils;
  35. /**
  36.  * This class is to view job history files.
  37.  */
  38. class HistoryViewer {
  39.   private static SimpleDateFormat dateFormat = new SimpleDateFormat(
  40.                                              "d-MMM-yyyy HH:mm:ss");
  41.   private FileSystem fs;
  42.   private Configuration conf;
  43.   private Path historyLogDir;
  44.   private String jobLogFile;
  45.   private JobHistory.JobInfo job;
  46.   private String trackerHostName;
  47.   private String trackerStartTime;
  48.   private String jobId;
  49.   private boolean printAll;
  50.   
  51.   private PathFilter jobLogFileFilter = new PathFilter() {
  52.     public boolean accept(Path path) {
  53.       return !(path.getName().endsWith(".xml"));
  54.     }
  55.   };
  56.   public HistoryViewer(String outputDir, Configuration conf, boolean printAll)
  57.   throws IOException {
  58.     this.conf = conf;
  59.     this.printAll = printAll;
  60.     Path output = new Path(outputDir);
  61.     historyLogDir = new Path(output, "_logs/history");
  62.     try {
  63.       fs = output.getFileSystem(this.conf);
  64.       if (!fs.exists(output)) {
  65.         throw new IOException("History directory " + historyLogDir.toString()
  66.                               + "does not exist");
  67.       }
  68.       Path[] jobFiles = FileUtil.stat2Paths(fs.listStatus(historyLogDir,
  69.                                                           jobLogFileFilter));
  70.       if (jobFiles.length == 0) {
  71.         throw new IOException("Not a valid history directory " 
  72.                               + historyLogDir.toString());
  73.       }
  74.       jobLogFile = jobFiles[0].toString();
  75.       String[] jobDetails = 
  76.           JobInfo.decodeJobHistoryFileName(jobFiles[0].getName()).split("_");
  77.       trackerHostName = jobDetails[0];
  78.       trackerStartTime = jobDetails[1];
  79.       jobId = jobDetails[2] + "_" + jobDetails[3] + "_" + jobDetails[4];
  80.       job = new JobHistory.JobInfo(jobId); 
  81.       DefaultJobHistoryParser.parseJobTasks(jobFiles[0].toString(), job, fs);
  82.     } catch(Exception e) {
  83.       throw new IOException("Not able to initialize History viewer", e);
  84.     }
  85.   }
  86.   
  87.   public void print() throws IOException{
  88.     printJobDetails();
  89.     printTaskSummary();
  90.     printJobAnalysis();
  91.     printTasks("SETUP", "FAILED");
  92.     printTasks("SETUP", "KILLED");
  93.     printTasks("MAP", "FAILED");
  94.     printTasks("MAP", "KILLED");
  95.     printTasks("REDUCE", "FAILED");
  96.     printTasks("REDUCE", "KILLED");
  97.     printTasks("CLEANUP", "FAILED");
  98.     printTasks("CLEANUP", "KILLED");
  99.     if (printAll) {
  100.       printTasks("SETUP", "SUCCESS");
  101.       printTasks("MAP", "SUCCESS");
  102.       printTasks("REDUCE", "SUCCESS");
  103.       printTasks("CLEANUP", "SUCCESS");
  104.       printAllTaskAttempts("SETUP");
  105.       printAllTaskAttempts("MAP");
  106.       printAllTaskAttempts("REDUCE");
  107.       printAllTaskAttempts("CLEANUP");
  108.     }
  109.     NodesFilter filter = new FailedOnNodesFilter();
  110.     printFailedAttempts(filter);
  111.     filter = new KilledOnNodesFilter();
  112.     printFailedAttempts(filter);
  113.   }
  114.   private void printJobDetails() {
  115.     StringBuffer jobDetails = new StringBuffer();
  116.     jobDetails.append("nHadoop job: " ).append(jobId);
  117.     jobDetails.append("n=====================================");
  118.     jobDetails.append("nJob tracker host name: ").append(trackerHostName);
  119.     jobDetails.append("njob tracker start time: ").append( 
  120.                       new Date(Long.parseLong(trackerStartTime))); 
  121.     jobDetails.append("nUser: ").append(job.get(Keys.USER)); 
  122.     jobDetails.append("nJobName: ").append(job.get(Keys.JOBNAME)); 
  123.     jobDetails.append("nJobConf: ").append(job.get(Keys.JOBCONF)); 
  124.     jobDetails.append("nSubmitted At: ").append(StringUtils.
  125.                         getFormattedTimeWithDiff(dateFormat,
  126.                         job.getLong(Keys.SUBMIT_TIME), 0)); 
  127.     jobDetails.append("nLaunched At: ").append(StringUtils.
  128.                         getFormattedTimeWithDiff(dateFormat,
  129.                         job.getLong(Keys.LAUNCH_TIME),
  130.                         job.getLong(Keys.SUBMIT_TIME)));
  131.     jobDetails.append("nFinished At: ").append(StringUtils.
  132.                         getFormattedTimeWithDiff(dateFormat,
  133.                         job.getLong(Keys.FINISH_TIME),
  134.                         job.getLong(Keys.LAUNCH_TIME)));
  135.     jobDetails.append("nStatus: ").append(((job.get(Keys.JOB_STATUS) == "") ? 
  136.                       "Incomplete" :job.get(Keys.JOB_STATUS)));
  137.     jobDetails.append("n=====================================");
  138.     System.out.println(jobDetails.toString());
  139.   }
  140.   
  141.   private void printTasks(String taskType, String taskStatus) {
  142.     Map<String, JobHistory.Task> tasks = job.getAllTasks();
  143.     StringBuffer taskList = new StringBuffer();
  144.     taskList.append("n").append(taskStatus).append(" ");
  145.     taskList.append(taskType).append(" task list for ").append(jobId);
  146.     taskList.append("nTaskIdttStartTimetFinishTimetError");
  147.     if (Values.MAP.name().equals(taskType)) {
  148.       taskList.append("tInputSplits");
  149.     }
  150.     taskList.append("n====================================================");
  151.     System.out.println(taskList.toString());
  152.     for (JobHistory.Task task : tasks.values()) {
  153.       if (taskType.equals(task.get(Keys.TASK_TYPE)) &&
  154.          (taskStatus.equals(task.get(Keys.TASK_STATUS))
  155.           || taskStatus.equals("all"))) {
  156.         taskList.setLength(0);
  157.         taskList.append(task.get(Keys.TASKID));
  158.         taskList.append("t").append(StringUtils.getFormattedTimeWithDiff(
  159.                    dateFormat, task.getLong(Keys.START_TIME), 0));
  160.         taskList.append("t").append(StringUtils.getFormattedTimeWithDiff(
  161.                    dateFormat, task.getLong(Keys.FINISH_TIME),
  162.                    task.getLong(Keys.START_TIME))); 
  163.         taskList.append("t").append(task.get(Keys.ERROR));
  164.         if (Values.MAP.name().equals(taskType)) {
  165.           taskList.append("t").append(task.get(Keys.SPLITS));
  166.         }
  167.         System.out.println(taskList.toString());
  168.       }
  169.     }
  170.   }
  171.   
  172.   private void printAllTaskAttempts(String taskType) {
  173.     Map<String, JobHistory.Task> tasks = job.getAllTasks();
  174.     StringBuffer taskList = new StringBuffer();
  175.     taskList.append("n").append(taskType);
  176.     taskList.append(" task list for ").append(jobId);
  177.     taskList.append("nTaskIdttStartTime");
  178.     if (Values.REDUCE.name().equals(taskType)) {
  179.       taskList.append("tShuffleFinishedtSortFinished");
  180.     }
  181.     taskList.append("tFinishTimetHostNametErrortTaskLogs");
  182.     taskList.append("n====================================================");
  183.     System.out.println(taskList.toString());
  184.     for (JobHistory.Task task : tasks.values()) {
  185.       for (JobHistory.TaskAttempt attempt : task.getTaskAttempts().values()) {
  186.         if (taskType.equals(task.get(Keys.TASK_TYPE))){
  187.           taskList.setLength(0); 
  188.           taskList.append(attempt.get(Keys.TASK_ATTEMPT_ID)).append("t");
  189.           taskList.append(StringUtils.getFormattedTimeWithDiff(dateFormat,
  190.                           attempt.getLong(Keys.START_TIME), 0)).append("t");
  191.           if (Values.REDUCE.name().equals(taskType)) {
  192.             ReduceAttempt reduceAttempt = (ReduceAttempt)attempt; 
  193.             taskList.append(StringUtils.getFormattedTimeWithDiff(dateFormat,
  194.                             reduceAttempt.getLong(Keys.SHUFFLE_FINISHED),
  195.                             reduceAttempt.getLong(Keys.START_TIME)));
  196.             taskList.append("t"); 
  197.             taskList.append(StringUtils.getFormattedTimeWithDiff(dateFormat, 
  198.                             reduceAttempt.getLong(Keys.SORT_FINISHED),
  199.                             reduceAttempt.getLong(Keys.SHUFFLE_FINISHED))); 
  200.           } 
  201.           taskList.append(StringUtils.getFormattedTimeWithDiff(dateFormat,
  202.                           attempt.getLong(Keys.FINISH_TIME),
  203.                           attempt.getLong(Keys.START_TIME))); 
  204.           taskList.append("t"); 
  205.           taskList.append(attempt.get(Keys.HOSTNAME)).append("t");
  206.           taskList.append(attempt.get(Keys.ERROR));
  207.           String taskLogsUrl = JobHistory.getTaskLogsUrl(attempt);
  208.           taskList.append(taskLogsUrl != null ? taskLogsUrl : "n/a");
  209.           System.out.println(taskList.toString());
  210.         }
  211.       }
  212.     }
  213.   }
  214.   
  215.   private void printTaskSummary() {
  216.     Map<String, JobHistory.Task> tasks = job.getAllTasks();
  217.     int totalMaps = 0; 
  218.     int totalReduces = 0; 
  219.     int totalCleanups = 0;
  220.     int totalSetups = 0;
  221.     int numFailedMaps = 0; 
  222.     int numKilledMaps = 0;
  223.     int numFailedReduces = 0; 
  224.     int numKilledReduces = 0;
  225.     int numFinishedCleanups = 0;
  226.     int numFailedCleanups = 0;
  227.     int numKilledCleanups = 0;
  228.     int numFinishedSetups = 0;
  229.     int numFailedSetups = 0;
  230.     int numKilledSetups = 0;
  231.     long mapStarted = 0; 
  232.     long mapFinished = 0; 
  233.     long reduceStarted = 0; 
  234.     long reduceFinished = 0; 
  235.     long cleanupStarted = 0;
  236.     long cleanupFinished = 0;
  237.     long setupStarted = 0;
  238.     long setupFinished = 0;
  239.     Map <String, String> allHosts = new TreeMap<String, String>();
  240.     for (JobHistory.Task task : tasks.values()) {
  241.       Map<String, TaskAttempt> attempts = task.getTaskAttempts();
  242.       allHosts.put(task.get(Keys.HOSTNAME), "");
  243.       for (TaskAttempt attempt : attempts.values()) {
  244.         long startTime = attempt.getLong(Keys.START_TIME); 
  245.         long finishTime = attempt.getLong(Keys.FINISH_TIME); 
  246.         if (Values.MAP.name().equals(task.get(Keys.TASK_TYPE))) {
  247.           if (mapStarted==0 || mapStarted > startTime) {
  248.             mapStarted = startTime; 
  249.           }
  250.           if (mapFinished < finishTime) {
  251.             mapFinished = finishTime; 
  252.           }
  253.           totalMaps++; 
  254.           if (Values.FAILED.name().equals(attempt.get(Keys.TASK_STATUS))) {
  255.             numFailedMaps++; 
  256.           } else if (Values.KILLED.name().equals(
  257.                                             attempt.get(Keys.TASK_STATUS))) {
  258.             numKilledMaps++;
  259.           }
  260.         } else if (Values.REDUCE.name().equals(task.get(Keys.TASK_TYPE))) {
  261.           if (reduceStarted==0||reduceStarted > startTime) {
  262.             reduceStarted = startTime; 
  263.           }
  264.           if (reduceFinished < finishTime) {
  265.             reduceFinished = finishTime; 
  266.           }
  267.           totalReduces++; 
  268.           if (Values.FAILED.name().equals(attempt.get(Keys.TASK_STATUS))) {
  269.             numFailedReduces++;
  270.           } else if (Values.KILLED.name().equals(
  271.                                             attempt.get(Keys.TASK_STATUS))) {
  272.             numKilledReduces++;
  273.           }
  274.         } else if (Values.CLEANUP.name().equals(task.get(Keys.TASK_TYPE))){
  275.           if (cleanupStarted==0||cleanupStarted > startTime) {
  276.             cleanupStarted = startTime; 
  277.           }
  278.           if (cleanupFinished < finishTime) {
  279.             cleanupFinished = finishTime; 
  280.           }
  281.           totalCleanups++; 
  282.           if (Values.SUCCESS.name().equals(attempt.get(Keys.TASK_STATUS))) {
  283.             numFinishedCleanups++;
  284.           } else if (Values.FAILED.name().equals(
  285.                                             attempt.get(Keys.TASK_STATUS))) {
  286.             numFailedCleanups++;
  287.           } else if (Values.KILLED.name().equals(
  288.                                             attempt.get(Keys.TASK_STATUS))) {
  289.             numKilledCleanups++;
  290.           }
  291.         } else if (Values.SETUP.name().equals(task.get(Keys.TASK_TYPE))){
  292.           if (setupStarted==0||setupStarted > startTime) {
  293.             setupStarted = startTime; 
  294.           }
  295.           if (setupFinished < finishTime) {
  296.             setupFinished = finishTime; 
  297.           }
  298.           totalSetups++; 
  299.           if (Values.SUCCESS.name().equals(attempt.get(Keys.TASK_STATUS))) {
  300.             numFinishedSetups++;
  301.           } else if (Values.FAILED.name().equals(
  302.                                             attempt.get(Keys.TASK_STATUS))) {
  303.             numFailedSetups++;
  304.           } else if (Values.KILLED.name().equals(
  305.                                             attempt.get(Keys.TASK_STATUS))) {
  306.             numKilledSetups++;
  307.           }
  308.         }
  309.       }
  310.     }
  311.     
  312.     StringBuffer taskSummary = new StringBuffer();
  313.     taskSummary.append("nTask Summary");
  314.     taskSummary.append("n============================");
  315.     taskSummary.append("nKindtTotalt");
  316.     taskSummary.append("SuccessfultFailedtKilledtStartTimetFinishTime");
  317.     taskSummary.append("n");
  318.     taskSummary.append("nSetupt").append(totalSetups);
  319.     taskSummary.append("t").append(numFinishedSetups);
  320.     taskSummary.append("tt").append(numFailedSetups);
  321.     taskSummary.append("t").append(numKilledSetups);
  322.     taskSummary.append("t").append(StringUtils.getFormattedTimeWithDiff(
  323.                                dateFormat, setupStarted, 0));
  324.     taskSummary.append("t").append(StringUtils.getFormattedTimeWithDiff(
  325.                                dateFormat, setupFinished, setupStarted)); 
  326.     taskSummary.append("nMapt").append(totalMaps);
  327.     taskSummary.append("t").append(job.getInt(Keys.FINISHED_MAPS));
  328.     taskSummary.append("tt").append(numFailedMaps);
  329.     taskSummary.append("t").append(numKilledMaps);
  330.     taskSummary.append("t").append(StringUtils.getFormattedTimeWithDiff(
  331.                                dateFormat, mapStarted, 0));
  332.     taskSummary.append("t").append(StringUtils.getFormattedTimeWithDiff(
  333.                                dateFormat, mapFinished, mapStarted));
  334.     taskSummary.append("nReducet").append(totalReduces);
  335.     taskSummary.append("t").append(job.getInt(Keys.FINISHED_REDUCES));
  336.     taskSummary.append("tt").append(numFailedReduces);
  337.     taskSummary.append("t").append(numKilledReduces);
  338.     taskSummary.append("t").append(StringUtils.getFormattedTimeWithDiff(
  339.                                dateFormat, reduceStarted, 0));
  340.     taskSummary.append("t").append(StringUtils.getFormattedTimeWithDiff(
  341.                                dateFormat, reduceFinished, reduceStarted)); 
  342.     taskSummary.append("nCleanupt").append(totalCleanups);
  343.     taskSummary.append("t").append(numFinishedCleanups);
  344.     taskSummary.append("tt").append(numFailedCleanups);
  345.     taskSummary.append("t").append(numKilledCleanups);
  346.     taskSummary.append("t").append(StringUtils.getFormattedTimeWithDiff(
  347.                                dateFormat, cleanupStarted, 0));
  348.     taskSummary.append("t").append(StringUtils.getFormattedTimeWithDiff(
  349.                                dateFormat, cleanupFinished, cleanupStarted)); 
  350.     taskSummary.append("n============================n");
  351.     System.out.println(taskSummary.toString());
  352.   }
  353.   
  354.   private void printFailedAttempts(NodesFilter filter) throws IOException {
  355.     JobHistory.parseHistoryFromFS(jobLogFile, filter, fs); 
  356.     Map<String, Set<String>> badNodes = filter.getValues();
  357.     StringBuffer attempts = new StringBuffer(); 
  358.     if (badNodes.size() > 0) {
  359.       attempts.append("n").append(filter.getFailureType());
  360.       attempts.append(" task attempts by nodes");
  361.       attempts.append("nHostnametFailedTasks");
  362.       attempts.append("n===============================");
  363.       System.out.println(attempts.toString());
  364.       for (Map.Entry<String, Set<String>> entry : badNodes.entrySet()) {
  365.         String node = entry.getKey();
  366.         Set<String> failedTasks = entry.getValue();
  367.         attempts.setLength(0);
  368.         attempts.append(node).append("t");
  369.         for (String t : failedTasks) {
  370.           attempts.append(t).append(", ");
  371.         }
  372.         System.out.println(attempts.toString());
  373.       }
  374.     }
  375.   }
  376.   
  377.   private void printJobAnalysis() {
  378.     if (!Values.SUCCESS.name().equals(job.get(Keys.JOB_STATUS))) {
  379.       System.out.println("No Analysis available as job did not finish");
  380.       return;
  381.     }
  382.     
  383.     Map<String, JobHistory.Task> tasks = job.getAllTasks();
  384.     int finishedMaps = job.getInt(Keys.FINISHED_MAPS);
  385.     int finishedReduces = job.getInt(Keys.FINISHED_REDUCES);
  386.     JobHistory.Task [] mapTasks = new JobHistory.Task[finishedMaps]; 
  387.     JobHistory.Task [] reduceTasks = new JobHistory.Task[finishedReduces]; 
  388.     int mapIndex = 0 , reduceIndex=0; 
  389.     long avgMapTime = 0;
  390.     long avgReduceTime = 0;
  391.     long avgShuffleTime = 0;
  392.     for (JobHistory.Task task : tasks.values()) {
  393.       Map<String, TaskAttempt> attempts = task.getTaskAttempts();
  394.       for (JobHistory.TaskAttempt attempt : attempts.values()) {
  395.         if (attempt.get(Keys.TASK_STATUS).equals(Values.SUCCESS.name())) {
  396.           long avgFinishTime = (attempt.getLong(Keys.FINISH_TIME) -
  397.                                 attempt.getLong(Keys.START_TIME));
  398.           if (Values.MAP.name().equals(task.get(Keys.TASK_TYPE))) {
  399.             mapTasks[mapIndex++] = attempt; 
  400.             avgMapTime += avgFinishTime;
  401.           } else if (Values.REDUCE.name().equals(task.get(Keys.TASK_TYPE))) { 
  402.             reduceTasks[reduceIndex++] = attempt;
  403.             avgShuffleTime += (attempt.getLong(Keys.SHUFFLE_FINISHED) - 
  404.                                attempt.getLong(Keys.START_TIME));
  405.             avgReduceTime += (attempt.getLong(Keys.FINISH_TIME) -
  406.                               attempt.getLong(Keys.SHUFFLE_FINISHED));
  407.           }
  408.           break;
  409.         }
  410.       }
  411.     }
  412.     if (finishedMaps > 0) {
  413.       avgMapTime /= finishedMaps;
  414.     }
  415.     if (finishedReduces > 0) {
  416.       avgReduceTime /= finishedReduces;
  417.       avgShuffleTime /= finishedReduces;
  418.     }
  419.     System.out.println("nAnalysis");
  420.     System.out.println("=========");
  421.     printAnalysis(mapTasks, cMap, "map", avgMapTime, 10);
  422.     printLast(mapTasks, "map", cFinishMapRed);
  423.     if (reduceTasks.length > 0) {
  424.       printAnalysis(reduceTasks, cShuffle, "shuffle", avgShuffleTime, 10);
  425.       printLast(reduceTasks, "shuffle", cFinishShuffle);
  426.       printAnalysis(reduceTasks, cReduce, "reduce", avgReduceTime, 10);
  427.       printLast(reduceTasks, "reduce", cFinishMapRed);
  428.     }
  429.     System.out.println("=========");
  430.   }
  431.   
  432.   private void printLast(JobHistory.Task [] tasks,
  433.                          String taskType,
  434.                          Comparator<JobHistory.Task> cmp
  435.                          ) {
  436.     Arrays.sort(tasks, cFinishMapRed);
  437.     JobHistory.Task last = tasks[0];
  438.     StringBuffer lastBuf = new StringBuffer();
  439.     lastBuf.append("The last ").append(taskType);
  440.     lastBuf.append(" task ").append(last.get(Keys.TASKID));
  441.     Long finishTime;
  442.     if ("shuffle".equals(taskType)) {
  443.       finishTime = last.getLong(Keys.SHUFFLE_FINISHED);
  444.     } else {
  445.       finishTime = last.getLong(Keys.FINISH_TIME);
  446.     }
  447.     lastBuf.append(" finished at (relative to the Job launch time): ");
  448.     lastBuf.append(StringUtils.getFormattedTimeWithDiff(dateFormat,
  449.                                  finishTime, job.getLong(Keys.LAUNCH_TIME)));
  450.     System.out.println(lastBuf.toString());
  451.   }
  452.   private void printAnalysis(JobHistory.Task [] tasks,
  453.                              Comparator<JobHistory.Task> cmp,
  454.                              String taskType,
  455.                              long avg,
  456.                              int showTasks) {
  457.     Arrays.sort(tasks, cmp);
  458.     JobHistory.Task min = tasks[tasks.length-1];
  459.     StringBuffer details = new StringBuffer();
  460.     details.append("nTime taken by best performing ");
  461.     details.append(taskType).append(" task ");
  462.     details.append(min.get(Keys.TASKID)).append(": ");
  463.     if ("map".equals(taskType)) {
  464.       details.append(StringUtils.formatTimeDiff(
  465.                      min.getLong(Keys.FINISH_TIME),
  466.                      min.getLong(Keys.START_TIME)));
  467.     } else if ("shuffle".equals(taskType)) {
  468.       details.append(StringUtils.formatTimeDiff(
  469.                      min.getLong(Keys.SHUFFLE_FINISHED),
  470.                      min.getLong(Keys.START_TIME)));
  471.     } else {
  472.       details.append(StringUtils.formatTimeDiff(
  473.                 min.getLong(Keys.FINISH_TIME),
  474.                 min.getLong(Keys.SHUFFLE_FINISHED)));
  475.     }
  476.     details.append("nAverage time taken by ");
  477.     details.append(taskType).append(" tasks: "); 
  478.     details.append(StringUtils.formatTimeDiff(avg, 0));
  479.     details.append("nWorse performing ");
  480.     details.append(taskType).append(" tasks: ");
  481.     details.append("nTaskIdttTimetaken");
  482.     System.out.println(details.toString());
  483.     for (int i = 0; i < showTasks && i < tasks.length; i++) {
  484.       details.setLength(0);
  485.       details.append(tasks[i].get(Keys.TASKID)).append(" ");
  486.       if ("map".equals(taskType)) {
  487.         details.append(StringUtils.formatTimeDiff(
  488.                        tasks[i].getLong(Keys.FINISH_TIME),
  489.                        tasks[i].getLong(Keys.START_TIME)));
  490.       } else if ("shuffle".equals(taskType)) {
  491.         details.append(StringUtils.formatTimeDiff(
  492.                        tasks[i].getLong(Keys.SHUFFLE_FINISHED),
  493.                        tasks[i].getLong(Keys.START_TIME)));
  494.       } else {
  495.         details.append(StringUtils.formatTimeDiff(
  496.                        tasks[i].getLong(Keys.FINISH_TIME),
  497.                        tasks[i].getLong(Keys.SHUFFLE_FINISHED)));
  498.       }
  499.       System.out.println(details.toString());
  500.     }
  501.   }
  502.   
  503.   private Comparator<JobHistory.Task> cMap = 
  504.                                         new Comparator<JobHistory.Task>() {
  505.     public int compare(JobHistory.Task t1, JobHistory.Task t2) {
  506.       long l1 = t1.getLong(Keys.FINISH_TIME) - t1.getLong(Keys.START_TIME);
  507.       long l2 = t2.getLong(Keys.FINISH_TIME) - t2.getLong(Keys.START_TIME);
  508.       return (l2 < l1 ? -1 : (l2 == l1 ? 0 : 1));
  509.     }
  510.   };
  511.   
  512.   private Comparator<JobHistory.Task> cShuffle = 
  513.     new Comparator<JobHistory.Task>() {
  514.     public int compare(JobHistory.Task t1, JobHistory.Task t2) {
  515.       long l1 = t1.getLong(Keys.SHUFFLE_FINISHED) - 
  516.                 t1.getLong(Keys.START_TIME);
  517.       long l2 = t2.getLong(Keys.SHUFFLE_FINISHED) -
  518.                 t2.getLong(Keys.START_TIME);
  519.       return (l2 < l1 ? -1 : (l2 == l1 ? 0 : 1));
  520.     }
  521.   };
  522.   private Comparator<JobHistory.Task> cFinishShuffle = 
  523.     new Comparator<JobHistory.Task>() {
  524.     public int compare(JobHistory.Task t1, JobHistory.Task t2) {
  525.       long l1 = t1.getLong(Keys.SHUFFLE_FINISHED); 
  526.       long l2 = t2.getLong(Keys.SHUFFLE_FINISHED);
  527.       return (l2 < l1 ? -1 : (l2 == l1 ? 0 : 1));
  528.     }
  529.   };
  530.   private Comparator<JobHistory.Task> cFinishMapRed = 
  531.     new Comparator<JobHistory.Task>() {
  532.     public int compare(JobHistory.Task t1, JobHistory.Task t2) {
  533.       long l1 = t1.getLong(Keys.FINISH_TIME); 
  534.       long l2 = t2.getLong(Keys.FINISH_TIME);
  535.       return (l2 < l1 ? -1 : (l2 == l1 ? 0 : 1));
  536.     }
  537.   };
  538.   
  539.   private Comparator<JobHistory.Task> cReduce = 
  540.     new Comparator<JobHistory.Task>() {
  541.     public int compare(JobHistory.Task t1, JobHistory.Task t2) {
  542.       long l1 = t1.getLong(Keys.FINISH_TIME) -
  543.                 t1.getLong(Keys.SHUFFLE_FINISHED);
  544.       long l2 = t2.getLong(Keys.FINISH_TIME) -
  545.                 t2.getLong(Keys.SHUFFLE_FINISHED);
  546.       return (l2 < l1 ? -1 : (l2 == l1 ? 0 : 1));
  547.     }
  548.   }; 
  549. }