%@ page
contentType="text/html; charset=UTF-8"
import="javax.servlet.*"
import="javax.servlet.http.*"
import="java.io.*"
import="java.text.*"
import="java.util.*"
import="java.text.DecimalFormat"
import="org.apache.hadoop.http.HtmlQuoting"
import="org.apache.hadoop.mapred.*"
import="org.apache.hadoop.mapred.JSPUtil.JobWithViewAccessCheck"
import="org.apache.hadoop.mapreduce.TaskType"
import="org.apache.hadoop.util.*"
import="org.apache.hadoop.mapreduce.JobACL"
import="org.apache.hadoop.security.UserGroupInformation"
import="java.security.PrivilegedExceptionAction"
import="org.apache.hadoop.security.AccessControlException"
import="org.apache.hadoop.security.authorize.AccessControlList"
%>
<%! private static final long serialVersionUID = 1L;
%>
<%
final JobTracker tracker = (JobTracker) application.getAttribute(
"job.tracker");
String trackerName =
StringUtils.simpleHostname(tracker.getJobTrackerMachine());
%>
<%!
private void printTaskSummary(JspWriter out,
String jobId,
String kind,
double completePercent,
TaskInProgress[] tasks
) throws IOException {
int totalTasks = tasks.length;
int runningTasks = 0;
int finishedTasks = 0;
int killedTasks = 0;
int failedTaskAttempts = 0;
int killedTaskAttempts = 0;
for(int i=0; i < totalTasks; ++i) {
TaskInProgress task = tasks[i];
if (task.isComplete()) {
finishedTasks += 1;
} else if (task.isRunning()) {
runningTasks += 1;
} else if (task.wasKilled()) {
killedTasks += 1;
}
failedTaskAttempts += task.numTaskFailures();
killedTaskAttempts += task.numKilledTasks();
}
int pendingTasks = totalTasks - runningTasks - killedTasks - finishedTasks;
out.print("
" + kind +
" | " +
StringUtils.formatPercent(completePercent, 2) +
ServletUtil.percentageGraph((int)(completePercent * 100), 80) +
" | " +
totalTasks +
" | " +
((pendingTasks > 0)
? "" + pendingTasks + ""
: "0") +
" | " +
((runningTasks > 0)
? "" + runningTasks + ""
: "0") +
" | " +
((finishedTasks > 0)
?"" + finishedTasks + ""
: "0") +
" | " +
((killedTasks > 0)
?"" + killedTasks + ""
: "0") +
" | " +
((failedTaskAttempts > 0) ?
("" + failedTaskAttempts +
"") :
"0"
) +
" / " +
((killedTaskAttempts > 0) ?
("" + killedTaskAttempts +
"") :
"0"
) +
" |
\n");
}
private void printJobLevelTaskSummary(JspWriter out,
String jobId,
String kind,
TaskInProgress[] tasks
) throws IOException {
int totalTasks = tasks.length;
int runningTasks = 0;
int finishedTasks = 0;
int killedTasks = 0;
for(int i=0; i < totalTasks; ++i) {
TaskInProgress task = tasks[i];
if (task.isComplete()) {
finishedTasks += 1;
} else if (task.isRunning()) {
runningTasks += 1;
} else if (task.isFailed()) {
killedTasks += 1;
}
}
int pendingTasks = totalTasks - runningTasks - killedTasks - finishedTasks;
out.print(((runningTasks > 0)
? "" + " Running" +
""
: ((pendingTasks > 0) ? " Pending" :
((finishedTasks > 0)
?"" + " Successful"
+ ""
: ((killedTasks > 0)
?"" + " Failed"
+ "" : "None")))));
}
private void printConfirm(JspWriter out, String jobId) throws IOException{
String url = "jobdetails.jsp?jobid=" + jobId;
out.print(""
+ " Are you sure you want to kill " + jobId
+ " ?
");
}
%>
<%
String jobId = request.getParameter("jobid");
String refreshParam = request.getParameter("refresh");
if (jobId == null) {
out.println("Missing 'jobid'!
");
return;
}
int refresh = 60; // refresh every 60 seconds by default
if (refreshParam != null) {
try {
refresh = Integer.parseInt(refreshParam);
}
catch (NumberFormatException ignored) {
}
}
final JobID jobIdObj = JobID.forName(jobId);
JobWithViewAccessCheck myJob = JSPUtil.checkAccessAndGetJob(tracker, jobIdObj,
request, response);
if (!myJob.isViewJobAllowed()) {
return; // user is not authorized to view this job
}
JobInProgress job = myJob.getJob();
final String newPriority = request.getParameter("prio");
String user = request.getRemoteUser();
UserGroupInformation ugi = null;
if (user != null) {
ugi = UserGroupInformation.createRemoteUser(user);
}
String action = request.getParameter("action");
if(JSPUtil.privateActionsAllowed(tracker.conf) &&
"changeprio".equalsIgnoreCase(action)
&& request.getMethod().equalsIgnoreCase("POST")) {
if (ugi != null) {
try {
ugi.doAs(new PrivilegedExceptionAction() {
public Void run() throws IOException{
// checks job modify permission
tracker.setJobPriority(jobIdObj,
JobPriority.valueOf(newPriority));
return null;
}
});
} catch(AccessControlException e) {
String errMsg = "User " + user + " failed to modify priority of " +
jobIdObj + "!
" + e.getMessage() +
"
Go back to Job
";
JSPUtil.setErrorAndForward(errMsg, request, response);
return;
}
}
else {// no authorization needed
tracker.setJobPriority(jobIdObj,
JobPriority.valueOf(newPriority));;
}
}
if(JSPUtil.privateActionsAllowed(tracker.conf)) {
action = request.getParameter("action");
if(action!=null && action.equalsIgnoreCase("confirm")) {
printConfirm(out, jobId);
return;
}
else if(action != null && action.equalsIgnoreCase("kill") &&
request.getMethod().equalsIgnoreCase("POST")) {
if (ugi != null) {
try {
ugi.doAs(new PrivilegedExceptionAction() {
public Void run() throws IOException{
// checks job modify permission
tracker.killJob(jobIdObj);// checks job modify permission
return null;
}
});
} catch(AccessControlException e) {
String errMsg = "User " + user + " failed to kill " + jobIdObj +
"!
" + e.getMessage() +
"
Go back to Job
";
JSPUtil.setErrorAndForward(errMsg, request, response);
return;
}
}
else {// no authorization needed
tracker.killJob(jobIdObj);
}
}
}
%>
<%@page import="org.apache.hadoop.mapred.TaskGraphServlet"%>
<%
if (refresh != 0) {
%>
<%
}
%>
Hadoop <%=jobId%> on <%=trackerName%>
<%
if (job == null) {
String historyFile = JobHistory.getHistoryFilePath(jobIdObj);
if (historyFile == null) {
out.println("Job " + jobId + " not known!
");
return;
}
String historyUrl = JobHistoryServer.getHistoryUrlPrefix(tracker.conf) +
"/jobdetailshistory.jsp?logFile=" +
JobHistory.JobInfo.encodeJobHistoryFilePath(historyFile);
response.sendRedirect(response.encodeRedirectURL(historyUrl));
return;
}
JobProfile profile = job.getProfile();
JobStatus status = job.getStatus();
int runState = status.getRunState();
int flakyTaskTrackers = job.getNoOfBlackListedTrackers();
out.print("User: " +
HtmlQuoting.quoteHtmlChars(profile.getUser()) + "
\n");
out.print("Job Name: " +
HtmlQuoting.quoteHtmlChars(profile.getJobName()) + "
\n");
out.print("Job File: " +
profile.getJobFile() + "
\n");
out.print("Submit Host: " +
HtmlQuoting.quoteHtmlChars(job.getJobSubmitHostName()) + "
\n");
out.print("Submit Host Address: " +
HtmlQuoting.quoteHtmlChars(job.getJobSubmitHostAddress()) + "
\n");
Map jobAcls = status.getJobACLs();
JSPUtil.printJobACLs(tracker, jobAcls, out);
out.print("Job Setup:");
printJobLevelTaskSummary(out, jobId, "setup",
job.getTasks(TaskType.JOB_SETUP));
out.print("
\n");
if (runState == JobStatus.RUNNING) {
out.print("Status: Running
\n");
out.print("Started at: " + new Date(job.getStartTime()) + "
\n");
out.print("Running for: " + StringUtils.formatTimeDiff(
System.currentTimeMillis(), job.getStartTime()) + "
\n");
} else {
if (runState == JobStatus.SUCCEEDED) {
out.print("Status: Succeeded
\n");
out.print("Started at: " + new Date(job.getStartTime()) + "
\n");
out.print("Finished at: " + new Date(job.getFinishTime()) +
"
\n");
out.print("Finished in: " + StringUtils.formatTimeDiff(
job.getFinishTime(), job.getStartTime()) + "
\n");
} else if (runState == JobStatus.FAILED) {
out.print("Status: Failed
\n");
out.print("Failure Info:" +
HtmlQuoting.quoteHtmlChars(status.getFailureInfo()) + "
\n");
out.print("Started at: " + new Date(job.getStartTime()) + "
\n");
out.print("Failed at: " + new Date(job.getFinishTime()) +
"
\n");
out.print("Failed in: " + StringUtils.formatTimeDiff(
job.getFinishTime(), job.getStartTime()) + "
\n");
} else if (runState == JobStatus.KILLED) {
out.print("Status: Killed
\n");
out.print("Failure Info:" +
HtmlQuoting.quoteHtmlChars(status.getFailureInfo()) + "
\n");
out.print("Started at: " + new Date(job.getStartTime()) + "
\n");
out.print("Killed at: " + new Date(job.getFinishTime()) +
"
\n");
out.print("Killed in: " + StringUtils.formatTimeDiff(
job.getFinishTime(), job.getStartTime()) + "
\n");
}
}
out.print("Job Cleanup:");
printJobLevelTaskSummary(out, jobId, "cleanup",
job.getTasks(TaskType.JOB_CLEANUP));
out.print("
\n");
if (flakyTaskTrackers > 0) {
out.print("Black-listed TaskTrackers: " +
"" +
flakyTaskTrackers + "
\n");
}
if (job.getSchedulingInfo() != null) {
out.print("Job Scheduling information: " +
job.getSchedulingInfo().toString() +"\n");
}
out.print("
\n");
out.print("");
out.print("Kind | % Complete | Num Tasks | " +
"Pending | Running | Complete | " +
"Killed | " +
"Failed/Killed Task Attempts |
\n");
printTaskSummary(out, jobId, "map", status.mapProgress(),
job.getTasks(TaskType.MAP));
printTaskSummary(out, jobId, "reduce", status.reduceProgress(),
job.getTasks(TaskType.REDUCE));
out.print("
\n");
%>
|
Counter |
Map |
Reduce |
Total |
<%
boolean isFine = true;
Counters mapCounters = new Counters();
isFine = job.getMapCounters(mapCounters);
mapCounters = (isFine? mapCounters: new Counters());
Counters reduceCounters = new Counters();
isFine = job.getReduceCounters(reduceCounters);
reduceCounters = (isFine? reduceCounters: new Counters());
Counters totalCounters = new Counters();
isFine = job.getCounters(totalCounters);
totalCounters = (isFine? totalCounters: new Counters());
for (String groupName : totalCounters.getGroupNames()) {
Counters.Group totalGroup = totalCounters.getGroup(groupName);
Counters.Group mapGroup = mapCounters.getGroup(groupName);
Counters.Group reduceGroup = reduceCounters.getGroup(groupName);
Format decimal = new DecimalFormat();
boolean isFirst = true;
for (Counters.Counter counter : totalGroup) {
String name = counter.getDisplayName();
String mapValue = decimal.format(mapGroup.getCounter(name));
String reduceValue = decimal.format(reduceGroup.getCounter(name));
String totalValue = decimal.format(counter.getCounter());
%>
<%
if (isFirst) {
isFirst = false;
%>
<%=HtmlQuoting.quoteHtmlChars(totalGroup.getDisplayName())%> |
<%
}
%>
<%=HtmlQuoting.quoteHtmlChars(name)%> |
<%=mapValue%> |
<%=reduceValue%> |
<%=totalValue%> |
<%
}
}
%>
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"))) { %>
open
<%} else { %>
close
<%}%>
<%if(job.getTasks(TaskType.REDUCE).length > 0) { %>
Reduce Completion Graph -
<%if("off".equals(session.getAttribute("reduce.graph"))) { %>
open
<%} else { %>
close
<%} }%>
<% if(JSPUtil.privateActionsAllowed(tracker.conf)) { %>
<% } %>
<% if(JSPUtil.privateActionsAllowed(tracker.conf)
&& runState == JobStatus.RUNNING) { %>
Kill this job
<% } %>
Go back to JobTracker
<%
out.println(ServletUtil.htmlFooter());
%>