| <% |
| /* |
| * 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. |
| */ |
| %> |
| <%@ page |
| contentType="text/html; charset=UTF-8" |
| import="javax.servlet.http.*" |
| import="java.io.*" |
| import="java.util.*" |
| import="org.apache.hadoop.fs.*" |
| import="org.apache.hadoop.http.HtmlQuoting" |
| import="org.apache.hadoop.mapreduce.TaskAttemptID" |
| import="org.apache.hadoop.mapreduce.TaskID" |
| import="org.apache.hadoop.mapreduce.Counter" |
| import="org.apache.hadoop.mapreduce.Counters" |
| import="org.apache.hadoop.mapreduce.CounterGroup" |
| import="org.apache.hadoop.mapred.*" |
| import="org.apache.hadoop.util.*" |
| import="java.text.*" |
| import="org.apache.hadoop.mapreduce.jobhistory.*" |
| import="java.security.PrivilegedExceptionAction" |
| import="org.apache.hadoop.security.AccessControlException" |
| import="org.apache.hadoop.mapreduce.jobhistory.JobHistoryParser.JobInfo" |
| import="org.apache.hadoop.mapreduce.JobACL" |
| import="org.apache.hadoop.security.authorize.AccessControlList" |
| %> |
| <%!private static final long serialVersionUID = 1L; |
| %> |
| |
| <%! static SimpleDateFormat dateFormat = new SimpleDateFormat("d-MMM-yyyy HH:mm:ss") ; %> |
| <% |
| String logFile = request.getParameter("logFile"); |
| String reasonforFailure = " "; |
| final Path jobFile = new Path(logFile); |
| String jobid = JobHistory.getJobIDFromHistoryFilePath(jobFile).toString(); |
| |
| final FileSystem fs = (FileSystem) application.getAttribute("fileSys"); |
| final JobTracker jobTracker = (JobTracker) application.getAttribute("job.tracker"); |
| JobInfo job = JSPUtil.checkAccessAndGetJobInfo(request, response, |
| jobTracker, fs, jobFile); |
| if (job == null) { |
| return; |
| } |
| if (job.getJobStatus().equals("FAILED")) |
| reasonforFailure = job.getErrorInfo(); |
| %> |
| |
| <!DOCTYPE html> |
| <html> |
| <head> |
| <title>Hadoop Job <%=jobid%> on History Viewer</title> |
| <link rel="stylesheet" type="text/css" href="/static/hadoop.css"> |
| </head> |
| <body> |
| |
| <h2>Hadoop Job <%=jobid %> on <a href="jobhistory.jsp">History Viewer</a></h2> |
| |
| <b>User: </b> <%=HtmlQuoting.quoteHtmlChars(job.getUsername()) %><br/> |
| <b>JobName: </b> <%=HtmlQuoting.quoteHtmlChars(job.getJobname()) %><br/> |
| <b>JobConf: </b> <a href="jobconf_history.jsp?logFile=<%=logFile%>"> |
| <%=job.getJobConfPath() %></a><br/> |
| <% |
| Map<JobACL, AccessControlList> jobAcls = job.getJobACLs(); |
| JSPUtil.printJobACLs(jobTracker, jobAcls, out); |
| %> |
| <b>Submitted At: </b> <%=StringUtils.getFormattedTimeWithDiff(dateFormat, job.getSubmitTime(), 0 ) %><br/> |
| <b>Launched At: </b> <%=StringUtils.getFormattedTimeWithDiff(dateFormat, job.getLaunchTime(), job.getSubmitTime()) %><br/> |
| <b>Finished At: </b> <%=StringUtils.getFormattedTimeWithDiff(dateFormat, job.getFinishTime(), job.getLaunchTime()) %><br/> |
| <b>Status: </b> <%= ((job.getJobStatus()) == null ? "Incomplete" :job.getJobStatus()) %><br/> |
| <b>ReasonForFailure: </b> <%=reasonforFailure %><br/> |
| <% |
| HistoryViewer.SummarizedJob sj = new HistoryViewer.SummarizedJob(job); |
| %> |
| <b><a href="analysejobhistory.jsp?logFile=<%=logFile%>">Analyse This Job</a></b> |
| <hr/> |
| <center> |
| <table border="2" cellpadding="5" cellspacing="2"> |
| <tr> |
| <td>Kind</td><td>Total Tasks(successful+failed+killed)</td><td>Successful tasks</td><td>Failed tasks</td><td>Killed tasks</td><td>Start Time</td><td>Finish Time</td> |
| </tr> |
| <tr> |
| <td>Setup</td> |
| <td><a href="jobtaskshistory.jsp?logFile=<%=logFile%>&taskType=JOB_SETUP&status=all"> |
| <%=sj.getTotalSetups()%></a></td> |
| <td><a href="jobtaskshistory.jsp?logFile=<%=logFile%>&taskType=JOB_SETUP&status=SUCCEEDED"> |
| <%=sj.getNumFinishedSetups()%></a></td> |
| <td><a href="jobtaskshistory.jsp?logFile=<%=logFile%>&taskType=JOB_SETUP&status=FAILED"> |
| <%=sj.getNumFailedSetups()%></a></td> |
| <td><a href="jobtaskshistory.jsp?logFile=<%=logFile%>&taskType=JOB_SETUP&status=KILLED"> |
| <%=sj.getNumKilledSetups()%></a></td> |
| <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, sj.getSetupStarted(), 0) %></td> |
| <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, sj.getSetupFinished(), sj.getSetupStarted()) %></td> |
| </tr> |
| <tr> |
| <td>Map</td> |
| <td><a href="jobtaskshistory.jsp?logFile=<%=logFile%>&taskType=MAP&status=all"> |
| <%=sj.getTotalMaps()%></a></td> |
| <td><a href="jobtaskshistory.jsp?logFile=<%=logFile%>&taskType=MAP&status=SUCCEEDED"> |
| <%=job.getFinishedMaps() %></a></td> |
| <td><a href="jobtaskshistory.jsp?logFile=<%=logFile%>&taskType=MAP&status=FAILED"> |
| <%=sj.getNumFailedMaps()%></a></td> |
| <td><a href="jobtaskshistory.jsp?logFile=<%=logFile%>&taskType=MAP&status=KILLED"> |
| <%=sj.getNumKilledMaps()%></a></td> |
| <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, sj.getMapStarted(), 0) %></td> |
| <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, sj.getMapFinished(), sj.getMapStarted()) %></td> |
| </tr> |
| <tr> |
| <td>Reduce</td> |
| <td><a href="jobtaskshistory.jsp?logFile=<%=logFile%>&taskType=REDUCE&status=all"> |
| <%=sj.getTotalReduces()%></a></td> |
| <td><a href="jobtaskshistory.jsp?logFile=<%=logFile%>&taskType=REDUCE&status=SUCCEEDED"> |
| <%=job.getFinishedReduces()%></a></td> |
| <td><a href="jobtaskshistory.jsp?logFile=<%=logFile%>&taskType=REDUCE&status=FAILED"> |
| <%=sj.getNumFailedReduces()%></a></td> |
| <td><a href="jobtaskshistory.jsp?logFile=<%=logFile%>&taskType=REDUCE&status=KILLED"> |
| <%=sj.getNumKilledReduces()%></a></td> |
| <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, sj.getReduceStarted(), 0) %></td> |
| <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, sj.getReduceFinished(), sj.getReduceStarted()) %></td> |
| </tr> |
| <tr> |
| <td>Cleanup</td> |
| <td><a href="jobtaskshistory.jsp?logFile=<%=logFile%>&taskType=JOB_CLEANUP&status=all"> |
| <%=sj.getTotalCleanups()%></a></td> |
| <td><a href="jobtaskshistory.jsp?logFile=<%=logFile%>&taskType=JOB_CLEANUP&status=SUCCEEDED"> |
| <%=sj.getNumFinishedCleanups()%></a></td> |
| <td><a href="jobtaskshistory.jsp?logFile=<%=logFile%>&taskType=JOB_CLEANUP&status=FAILED"> |
| <%=sj.getNumFailedCleanups()%></a></td> |
| <td><a href="jobtaskshistory.jsp?logFile=<%=logFile%>&taskType=JOB_CLEANUP&status=KILLED>"> |
| <%=sj.getNumKilledCleanups()%></a></td> |
| <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, sj.getCleanupStarted(), 0) %></td> |
| <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, sj.getCleanupFinished(), sj.getCleanupStarted()) %></td> |
| </tr> |
| </table> |
| |
| <br> |
| <br> |
| |
| <table border=2 cellpadding="5" cellspacing="2"> |
| <tr> |
| <th><br/></th> |
| <th>Counter</th> |
| <th>Map</th> |
| <th>Reduce</th> |
| <th>Total</th> |
| </tr> |
| |
| <% |
| |
| Counters totalCounters = job.getTotalCounters(); |
| Counters mapCounters = job.getMapCounters(); |
| Counters reduceCounters = job.getReduceCounters(); |
| |
| if (totalCounters != null) { |
| for (String groupName : totalCounters.getGroupNames()) { |
| CounterGroup totalGroup = totalCounters.getGroup(groupName); |
| CounterGroup mapGroup = mapCounters.getGroup(groupName); |
| CounterGroup reduceGroup = reduceCounters.getGroup(groupName); |
| |
| Format decimal = new DecimalFormat(); |
| |
| boolean isFirst = true; |
| Iterator<Counter> ctrItr = totalGroup.iterator(); |
| while(ctrItr.hasNext()) { |
| Counter counter = ctrItr.next(); |
| String name = counter.getName(); |
| String mapValue = |
| decimal.format(mapGroup.findCounter(name).getValue()); |
| String reduceValue = |
| decimal.format(reduceGroup.findCounter(name).getValue()); |
| String totalValue = |
| decimal.format(counter.getValue()); |
| %> |
| <tr> |
| <% |
| if (isFirst) { |
| isFirst = false; |
| %> |
| <td rowspan="<%=totalGroup.size()%>"> |
| <%=HtmlQuoting.quoteHtmlChars(totalGroup.getDisplayName())%></td> |
| <% |
| } |
| %> |
| <td><%=HtmlQuoting.quoteHtmlChars(counter.getDisplayName())%></td> |
| <td align="right"><%=mapValue%></td> |
| <td align="right"><%=reduceValue%></td> |
| <td align="right"><%=totalValue%></td> |
| </tr> |
| <% |
| } |
| } |
| } |
| %> |
| </table> |
| <br> |
| |
| <br/> |
| <% |
| HistoryViewer.FilteredJob filter = new HistoryViewer.FilteredJob(job,TaskStatus.State.FAILED.toString()); |
| Map<String, Set<TaskID>> badNodes = filter.getFilteredMap(); |
| if (badNodes.size() > 0) { |
| %> |
| <h3>Failed tasks attempts by nodes </h3> |
| <table border="1"> |
| <tr><td>Hostname</td><td>Failed Tasks</td></tr> |
| <% |
| for (Map.Entry<String, Set<TaskID>> entry : badNodes.entrySet()) { |
| String node = entry.getKey(); |
| Set<TaskID> failedTasks = entry.getValue(); |
| %> |
| <tr> |
| <td><%=node %></td> |
| <td> |
| <% |
| boolean firstId = true; |
| for (TaskID tid : failedTasks) { |
| if (firstId) { |
| firstId = false; |
| %> |
| <a href="taskdetailshistory.jsp?logFile=<%=logFile%>&tipid=<%=tid %>"><%=tid %></a> |
| <% |
| } else { |
| %> |
| , <a href="taskdetailshistory.jsp?logFile=<%=logFile%>&tipid=<%=tid %>"><%=tid %></a> |
| <% |
| } |
| } |
| %> |
| </td> |
| </tr> |
| <% |
| } |
| } |
| %> |
| </table> |
| <br/> |
| |
| <% |
| filter = new HistoryViewer.FilteredJob(job, TaskStatus.State.KILLED.toString()); |
| badNodes = filter.getFilteredMap(); |
| if (badNodes.size() > 0) { |
| %> |
| <h3>Killed tasks attempts by nodes </h3> |
| <table border="1"> |
| <tr><td>Hostname</td><td>Killed Tasks</td></tr> |
| <% |
| for (Map.Entry<String, Set<TaskID>> entry : badNodes.entrySet()) { |
| String node = entry.getKey(); |
| Set<TaskID> killedTasks = entry.getValue(); |
| %> |
| <tr> |
| <td><%=node %></td> |
| <td> |
| <% |
| boolean firstId = true; |
| for (TaskID tid : killedTasks) { |
| if (firstId) { |
| firstId = false; |
| %> |
| <a href="taskdetailshistory.jsp?logFile=<%=logFile%>&tipid=<%=tid %>"><%=tid %></a> |
| <% |
| } else { |
| %> |
| , <a href="taskdetailshistory.jsp?logFile=<%=logFile%>&tipid=<%=tid %>"><%=tid %></a> |
| <% |
| } |
| } |
| %> |
| </td> |
| </tr> |
| <% |
| } |
| } |
| %> |
| </table> |
| </center> |
| </body></html> |