You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by om...@apache.org on 2011/03/04 05:32:46 UTC
svn commit: r1077590 [2/2] - in
/hadoop/common/branches/branch-0.20-security-patches: ./ bin/
src/core/org/apache/hadoop/http/ src/mapred/org/apache/hadoop/mapred/
src/test/org/apache/hadoop/mapred/ src/webapps/history/ src/webapps/job/
Added: hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/jobhistoryhome.jsp
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/jobhistoryhome.jsp?rev=1077590&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/jobhistoryhome.jsp (added)
+++ hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/jobhistoryhome.jsp Fri Mar 4 04:32:45 2011
@@ -0,0 +1,573 @@
+<%@ page
+ contentType="text/html; charset=UTF-8"
+ import="java.io.*"
+ import="java.net.URLEncoder"
+ import="java.util.*"
+ import="java.util.regex.Pattern"
+ import="java.util.regex.Matcher"
+ import="java.util.concurrent.atomic.AtomicBoolean"
+ import="org.apache.hadoop.mapred.*"
+ import="org.apache.hadoop.util.*"
+ import="org.apache.hadoop.fs.*"
+ import="javax.servlet.jsp.*"
+ import="java.text.SimpleDateFormat"
+ import="org.apache.hadoop.http.HtmlQuoting"
+%>
+<%
+ JobConf jobConf = (JobConf) application.getAttribute("jobConf");
+ String trackerAddress = jobConf.get("mapred.job.tracker.http.address");
+ String trackerName =
+ StringUtils.simpleHostname(trackerAddress);
+%>
+<%!
+ private static SimpleDateFormat dateFormat =
+ new SimpleDateFormat("d/MM HH:mm:ss");
+%>
+<%! private static final long serialVersionUID = 1L;
+%>
+<html>
+<head>
+<script type="text/JavaScript">
+<!--
+function showUserHistory(search)
+{
+var url
+if (search == null || "".equals(search)) {
+ url="jobhistoryhome.jsp";
+} else {
+ url="jobhistoryhome.jsp?pageno=1&search=" + search;
+}
+window.location.href = url;
+}
+//-->
+</script>
+<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<title><%= trackerName %> Hadoop Map/Reduce History Viewer</title>
+<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+</head>
+<body>
+<h1> <a href="http://<%=trackerAddress%>/jobtracker.jsp"><%= trackerName %></a> Hadoop Map/Reduce
+ <a href="jobhistoryhome.jsp">History Viewer</a></h1>
+<hr>
+<%
+ //{ // these braces are here to make indentation work and
+ // {// must be removed.
+
+ final int JOB_ID_START = 0;
+
+ final int FILENAME_JOBID_END = JOB_ID_START + 3;
+
+ final int FILENAME_SUBMIT_TIMESTAMP_PART = FILENAME_JOBID_END;
+
+ final int FILENAME_USER_PART = FILENAME_JOBID_END + 1;
+
+ final int FILENAME_JOBNAME_PART = FILENAME_JOBID_END + 2;
+
+ final int[] SCAN_SIZES = { 20, 50, 200 };
+
+ final int FILES_PER_SCAN = 1000;
+
+ final int DEFAULT_PAGE_SIZE = 100;
+
+ final String DEFAULT_DATE_GLOB_COMPONENT = "*/*/*";
+
+ final String SERIAL_NUMBER_GLOB_COMPONENT = "/*";
+
+ final String search = (request.getParameter("search") == null)
+ ? ""
+ : request.getParameter("search");
+
+ final String dateSplit[] = search.split(";");
+
+ final String soughtDate = dateSplit.length > 1 ? dateSplit[1] : "";
+
+ final String parts[] = dateSplit[0].split(":");
+
+ final String rawUser = (parts.length >= 1)
+ ? parts[0].toLowerCase()
+ : "";
+
+ final String userInFname
+ = escapeUnderscores(JobHistory.JobInfo.encodeJobHistoryFileName(
+ HtmlQuoting.unquoteHtmlChars(rawUser))).toLowerCase();
+
+ final int currentScanSizeIndex
+ = (request.getParameter("scansize") == null)
+ ? 0 : Integer.parseInt(request.getParameter("scansize"));
+
+ final String SEARCH_PARSE_REGEX
+ = "([0-1]?[0-9])/([0-3]?[0-9])/((?:2[0-9])[0-9][0-9])";
+
+ final Pattern dateSearchParse = Pattern.compile(SEARCH_PARSE_REGEX);
+
+ final String rawJobname = (parts.length >= 2)
+ ? parts[1].toLowerCase()
+ : "";
+
+ final String jobnameKeywordInFname
+ = escapeUnderscores(JobHistory.JobInfo.encodeJobHistoryFileName(
+ HtmlQuoting.unquoteHtmlChars(rawJobname))).toLowerCase();
+
+ PathFilter jobLogFileFilter = new PathFilter() {
+ private boolean matchUser(String fileName) {
+ // return true if
+ // - user is not specified
+ // - user matches
+ return "".equals(userInFname)
+ || userInFname.equals(fileName.split("_")[FILENAME_USER_PART]
+ .toLowerCase());
+ }
+
+ private boolean matchJobName(String fileName) {
+ // return true if
+ // - jobname is not specified
+ // - jobname contains the keyword
+ return "".equals(jobnameKeywordInFname)
+ || fileName.split("_")[FILENAME_JOBNAME_PART].toLowerCase()
+ .contains(jobnameKeywordInFname);
+ }
+
+ public boolean accept(Path path) {
+ String name = path.getName();
+
+ return !(name.endsWith(".xml")) && matchUser(name) && matchJobName(name);
+ }
+ };
+
+ FileSystem fs = (FileSystem) application.getAttribute("fileSys");
+ String historyLogDir = (String) application.getAttribute("historyLogDir");
+ if (fs == null) {
+ out.println("Null file system. May be namenode is in safemode!");
+ return;
+ }
+
+ Comparator<Path> lastPathFirst
+ = new Comparator<Path>() {
+ public int compare(Path path1, Path path2) {
+ // these are backwards because we want the lexically lesser names
+ // to occur later in the sort.
+ return path2.getName().compareTo(path1.getName());
+ }
+ };
+
+ Comparator<Path> latestFirstCreationTimeComparator
+ = new Comparator<Path>() {
+ public int compare(Path p1, Path p2) {
+ String dp1 = null;
+ String dp2 = null;
+
+ try {
+ dp1 = JobHistory.JobInfo.decodeJobHistoryFileName(p1.getName());
+ dp2 = JobHistory.JobInfo.decodeJobHistoryFileName(p2.getName());
+ } catch (IOException ioe) {
+ throw new RuntimeException(ioe);
+ }
+
+ String[] split1 = dp1.split("_");
+ String[] split2 = dp2.split("_");
+
+ // compare job tracker start time
+ // reverse the sense, because we want the newest records first
+ int res = new Date(Long.parseLong(split2[1]))
+ .compareTo(new Date(Long.parseLong(split1[1])));
+ // compare the submit times next
+ // again, reverse the sense
+ if (res == 0) {
+ res = new Date(Long.parseLong(split2[3]))
+ .compareTo(new Date(Long.parseLong(split1[3])));
+ }
+ // lastly, compare the serial numbers [a certain tiebreaker]
+ // again, reverse the sense
+ if (res == 0) {
+ Long l1 = Long.parseLong(split2[2]);
+ res = l1.compareTo(Long.parseLong(split1[2]));
+ }
+ return res;
+ }
+ };
+
+ String versionComponent = JobHistory.DONE_DIRECTORY_FORMAT_DIRNAME;
+
+ String trackerComponent = "*";
+
+ // build the glob
+ // first find the date component
+ String dateComponent = DEFAULT_DATE_GLOB_COMPONENT;
+
+ Matcher dateMatcher = dateSearchParse.matcher(soughtDate);
+
+ // burst the sought date: must be [m]m/[d]d/[2y]yy
+ if (dateMatcher.matches()) {
+ String year = dateMatcher.group(3);
+ if (year.length() == 2) {
+ year = "20" + year;
+ }
+
+ String month = dateMatcher.group(1);
+ if (month.length() == 1) {
+ month = "0" + month;
+ }
+
+ String date = dateMatcher.group(2);
+ if (date.length() == 1) {
+ date = "0" + date;
+ }
+
+ dateComponent = year + "/" + month + "/" + date;
+ }
+
+ // now we find all of the serial numbers. This looks up all the serial
+ // number directories, but not the individual files.
+ Path historyPath = new Path(historyLogDir);
+
+ String leadGlob = (versionComponent
+ + "/" + trackerComponent
+ + "/" + dateComponent);
+
+ // Atomicity is unimportant here.
+ // I would have used MutableBoxedBoolean if such had been provided.
+ AtomicBoolean hasLegacyFiles = new AtomicBoolean(false);
+
+ Path[] snPaths
+ = FileUtil.stat2Paths(JobHistory.localGlobber
+ (fs, historyPath, "/" + leadGlob, null, hasLegacyFiles));
+
+ Arrays.sort(snPaths, lastPathFirst);
+
+ int arrayLimit = 0;
+ int tranchesSeen = 0;
+
+ Path lastPath = null;
+
+ while (arrayLimit < snPaths.length
+ && tranchesSeen <= SCAN_SIZES[currentScanSizeIndex]) {
+ if (lastPath == null
+ || lastPathFirst.compare(lastPath, snPaths[arrayLimit]) != 0) {
+ ++tranchesSeen;
+ lastPath = snPaths[arrayLimit];
+ }
+
+ ++arrayLimit;
+ }
+
+ if (tranchesSeen > SCAN_SIZES[currentScanSizeIndex]) {
+ --arrayLimit;
+ }
+
+ // arrayLimit points to the first element [which could be element 0] that
+ // we shouldn't consider
+
+ int numHistoryFiles = 0;
+
+ Path[] jobFiles = null;
+
+ {
+ Path[][] pathVectorVector = new Path[arrayLimit][];
+
+ for (int i = 0; i < arrayLimit; ++i) {
+ pathVectorVector[i]
+ = FileUtil.stat2Paths(fs.listStatus(snPaths[i], jobLogFileFilter));
+ numHistoryFiles += pathVectorVector[i].length;
+ }
+
+ jobFiles = new Path[numHistoryFiles];
+
+ int pathsCursor = 0;
+
+ for (int i = 0; i < arrayLimit; ++i) {
+ System.arraycopy(pathVectorVector[i], 0, jobFiles, pathsCursor,
+ pathVectorVector[i].length);
+ pathsCursor += pathVectorVector[i].length;
+ }
+ }
+
+ boolean sizeIsExact = arrayLimit == snPaths.length;
+
+ // sizeIsExact will be true if arrayLimit is zero.
+ long lengthEstimate
+ = sizeIsExact ? numHistoryFiles
+ : (long) numHistoryFiles * snPaths.length / arrayLimit;
+
+ if (hasLegacyFiles.get()) {
+ out.println("<h2>This history has some legacy files. "
+ + "<a href=\"legacyjobhistory.jsp\">go to Legacy History Viewer</a>"
+ + "</h2>");
+ }
+
+ out.println("<!-- user : " + rawUser +
+ ", jobname : " + rawJobname + "-->");
+ if (null == jobFiles || jobFiles.length == 0) {
+ out.println("No files found!");
+ return ;
+ }
+
+ // get the pageno
+ int pageno = request.getParameter("pageno") == null
+ ? 1
+ : Integer.parseInt(request.getParameter("pageno"));
+
+ // get the total number of files to display
+ int size = DEFAULT_PAGE_SIZE;
+
+ // if show-all is requested or jobfiles < size(100)
+ if (pageno == -1 || size > jobFiles.length) {
+ size = jobFiles.length;
+ }
+
+ if (pageno == -1) { // special case 'show all'
+ pageno = 1;
+ }
+
+ int maxPageNo = (jobFiles.length + size - 1) / size;
+ // int maxPageNo = (int)Math.ceil((float)jobFiles.length / size);
+
+ // check and fix pageno
+ if (pageno < 1 || pageno > maxPageNo) {
+ out.println("Invalid page index");
+ return ;
+ }
+
+ int length = size ; // determine the length of job history files to be displayed
+ if (pageno == maxPageNo) {
+ // find the number of files to be shown on the last page
+ int startOnLast = ((pageno - 1) * size) + 1;
+ length = jobFiles.length - startOnLast + 1;
+ }
+
+ // Display the search box
+ out.println("<form name=search><b> Filter (username:jobname) </b>"); // heading
+ out.println("<input type=text name=search size=\"20\" "
+ + "value=\"" + search + "\">"); // search box
+ out.println("<input type=submit value=\"Filter!\" onClick=\"showUserHistory"
+ + "(document.getElementById('search').value)\"></form>");
+ out.println("<p><span class=\"small\">Specify [user][:jobname keyword(s)]"
+ + "[;MM/DD/YYYY] . Each of the three components is "
+ + "optional. Filter components are conjunctive.</span></p>");
+ out.println("<p><span class=\"small\">Example: 'smith' will display jobs"
+ + " submitted by user 'smith'. 'smith:sort' will display "
+ + "jobs from user 'smith' having a 'sort' keyword in the jobname."
+ + " ';07/04/2010' restricts to July 4, 2010</span></p>"); // example
+ out.println("<hr>");
+
+ //Show the status
+ int start = (pageno - 1) * size + 1;
+
+ // DEBUG
+ out.println("<!-- pageno : " + pageno + ", size : " + size + ", length : "
+ + length + ", start : " + start + ", maxpg : "
+ + maxPageNo + "-->");
+
+ out.println("<font size=5><b>Available Jobs in History </b></font>");
+ // display the number of jobs, start index, end index
+ out.println("(<i> <span class=\"small\">Displaying <b>" + length
+ + "</b> jobs from <b>" + start + "</b> to <b>"
+ + (start + length - 1) + "</b> out of "
+ + (sizeIsExact
+ ? "" : "approximately ") + "<b>"
+ + lengthEstimate + "</b> jobs"
+ + (sizeIsExact
+ ? ""
+ : ", <b>" + numHistoryFiles + "</b> gotten"));
+ if (!"".equals(rawUser)) {
+ // show the user if present
+ out.println(" for user <b>" + rawUser + "</b>");
+ }
+ if (!"".equals(rawJobname)) {
+ out.println(" with jobname having the keyword <b>" +
+ rawJobname + "</b> in it.");
+ // show the jobname keyword if present
+ }
+ if (!DEFAULT_DATE_GLOB_COMPONENT.equals(dateComponent)) {
+ out.println(" for the date <b>" + soughtDate + "</b>");
+ }
+ out.print("</span></i>)");
+
+ final String searchPart = "&search=" + search;
+
+ final String scansizePart = "&scansize=" + currentScanSizeIndex;
+
+ final String searchPlusScan = searchPart + scansizePart;
+
+ // show the expand scope link, if we're restricted
+ if (sizeIsExact || currentScanSizeIndex == SCAN_SIZES.length - 1) {
+ out.println("[<span class=\"small\">get more results</span>]");
+ } else {
+ out.println(" [<span class=\"small\"><a href=\"jobhistoryhome.jsp?pageno=1"
+ + searchPart + "&scansize=" + (currentScanSizeIndex + 1)
+ + "\">get more results</a></span>]");
+ }
+
+ // show the 'show-all' link
+ out.println(" [<span class=\"small\"><a href=\"jobhistoryhome.jsp?pageno=-1"
+ + searchPlusScan + "\">show in one page</a></span>]");
+
+ // show the 'first-page' link
+ if (pageno > 1) {
+ out.println(" [<span class=\"small\"><a href=\"jobhistoryhome.jsp?pageno=1"
+ + searchPlusScan + "\">first page</a></span>]");
+ } else {
+ out.println("[<span class=\"small\">first page]</span>");
+ }
+
+ // show the 'last-page' link
+ if (pageno < maxPageNo) {
+ out.println(" [<span class=\"small\"><a href=\"jobhistoryhome.jsp?pageno="
+ + maxPageNo + searchPlusScan + "\">last page</a></span>]");
+ } else {
+ out.println("<span class=\"small\">[last page]</span>");
+ }
+
+ // sort the files on creation time.
+ Arrays.sort(jobFiles, latestFirstCreationTimeComparator);
+
+ out.println("<br><br>");
+
+ // print the navigation info (top)
+ printNavigationTool(pageno, size, maxPageNo, searchPlusScan, out);
+
+ out.print("<table align=center border=2 cellpadding=\"5\" cellspacing=\"2\">");
+ out.print("<tr>");
+ out.print("<td>Job submit time</td>" +
+ "<td>Job Id</td><td>Name</td><td>User</td>") ;
+ out.print("</tr>");
+
+ Set<String> displayedJobs = new HashSet<String>();
+ for (int i = start - 1; i < start + length - 1; ++i) {
+ Path jobFile = jobFiles[i];
+
+ String fname = jobFile.getName();
+ String marker = JobHistory.nonOccursString(fname);
+ String reescapedFname = JobHistory.replaceStringInstances(fname,
+ JobHistory.UNDERSCORE_ESCAPE, marker);
+
+ String decodedJobFileName =
+ JobHistory.JobInfo.decodeJobHistoryFileName(reescapedFname);
+
+ String[] jobDetails = decodedJobFileName.split("_");
+ String trackerStartTime = jobDetails[1];
+ String jobId = (jobDetails[JOB_ID_START]
+ + "_" + jobDetails[JOB_ID_START + 1]
+ + "_" + jobDetails[JOB_ID_START + 2]);
+ String submitTimestamp = jobDetails[FILENAME_SUBMIT_TIMESTAMP_PART];
+ String userName = JobHistory.replaceStringInstances(jobDetails[FILENAME_USER_PART],
+ marker, JobHistory.UNDERSCORE_ESCAPE);
+ String jobName = JobHistory.replaceStringInstances(jobDetails[FILENAME_JOBNAME_PART],
+ marker, JobHistory.UNDERSCORE_ESCAPE);
+
+ // Check if the job is already displayed. There can be multiple job
+ // history files for jobs that have restarted
+ if (displayedJobs.contains(jobId)) {
+ continue;
+ } else {
+ displayedJobs.add(jobId);
+ }
+
+ // Encode the logfile name again to cancel the decoding done by the browser
+ String preEncodedJobFileName =
+ JobHistory.JobInfo.encodeJobHistoryFileName(jobFile.getName());
+
+ String encodedJobFileName =
+ JobHistory.replaceStringInstances(preEncodedJobFileName, "%5F", "%255F");
+%>
+<center>
+<%
+ printJob(submitTimestamp, jobId,
+ jobName, userName, new Path(jobFile.getParent(), encodedJobFileName),
+ out) ;
+%>
+</center>
+<%
+ } // end while trackers
+ out.print("</table>");
+
+ // show the navigation info (bottom)
+ printNavigationTool(pageno, size, maxPageNo, searchPlusScan, out);
+%>
+<%!
+ private void printJob(String timestamp,
+ String jobId, String jobName,
+ String user, Path logFile, JspWriter out)
+ throws IOException {
+ out.print("<tr>");
+ out.print("<td>" + new Date(Long.parseLong(timestamp)) + "</td>");
+ out.print("<td>" + "<a href=\"jobdetailshistory.jsp?logFile="
+ + logFile.toString() + "\">" + jobId + "</a></td>");
+ out.print("<td>"
+ + HtmlQuoting.quoteHtmlChars(unescapeUnderscores(jobName))
+ + "</td>");
+ out.print("<td>"
+ + HtmlQuoting.quoteHtmlChars(unescapeUnderscores(user))
+ + "</td>");
+ out.print("</tr>");
+ }
+
+ private String escapeUnderscores(String rawString) {
+ return convertStrings(rawString, "_", "%5F");
+ }
+
+ private String unescapeUnderscores(String rawString) {
+ return convertStrings(rawString, "%5F", "_");
+ }
+
+ // inefficient if there are a lot of underscores
+ private String convertStrings(String escapedString, String from, String to) {
+ int firstEscape = escapedString.indexOf(from);
+
+ if (firstEscape < 0) {
+ return escapedString;
+ }
+
+ return escapedString.substring(0, firstEscape)
+ + to
+ + unescapeUnderscores(escapedString.substring
+ (firstEscape + from.length()));
+ }
+
+ private void printNavigationTool(int pageno, int size, int max,
+ String searchPlusScan, JspWriter out)
+ throws IOException {
+
+ final int NUMBER_INDICES_TO_SHOW = 5;
+
+ int numIndexToShow = NUMBER_INDICES_TO_SHOW; // num indexes to show on either side
+
+ //TODO check this on boundary cases
+ out.print("<center> <");
+
+ // show previous link
+ if (pageno > 1) {
+ out.println("<a href=\"jobhistoryhome.jsp?pageno=" + (pageno - 1)
+ + searchPlusScan + "\">Previous</a>");
+ }
+
+ // display the numbered index 1 2 3 4
+ int firstPage = pageno - numIndexToShow;
+ if (firstPage < 1) {
+ firstPage = 1; // boundary condition
+ }
+
+ int lastPage = pageno + numIndexToShow;
+ if (lastPage > max) {
+ lastPage = max; // boundary condition
+ }
+
+ // debug
+ out.println("<!--DEBUG : firstPage : " + firstPage + ", lastPage : " + lastPage + " -->");
+
+ for (int i = firstPage; i <= lastPage; ++i) {
+ if (i != pageno) {// needs hyperlink
+ out.println(" <a href=\"jobhistoryhome.jsp?pageno=" + i
+ + searchPlusScan + "\">" + i + "</a> ");
+ } else { // current page
+ out.println(i);
+ }
+ }
+
+ // show the next link
+ if (pageno < max) {
+ out.println("<a href=\"jobhistoryhome.jsp?pageno=" + (pageno + 1) + searchPlusScan + "\">Next</a>");
+ }
+ out.print("></center>");
+ }
+%>
+</body></html>
Added: hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/jobtaskshistory.jsp
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/jobtaskshistory.jsp?rev=1077590&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/jobtaskshistory.jsp (added)
+++ hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/jobtaskshistory.jsp Fri Mar 4 04:32:45 2011
@@ -0,0 +1,77 @@
+<%@ page
+ contentType="text/html; charset=UTF-8"
+ import="javax.servlet.http.*"
+ import="java.io.*"
+ import="java.util.*"
+ import="org.apache.hadoop.http.HtmlQuoting"
+ import="org.apache.hadoop.mapred.*"
+ import="org.apache.hadoop.fs.*"
+ import="org.apache.hadoop.util.*"
+ import="java.text.SimpleDateFormat"
+ import="org.apache.hadoop.mapred.JobHistory.*"
+%>
+
+<%!
+ private static SimpleDateFormat dateFormat =
+ new SimpleDateFormat("d/MM HH:mm:ss") ;
+%>
+<%! private static final long serialVersionUID = 1L;
+%>
+
+<%
+ String logFile = request.getParameter("logFile");
+ String encodedLogFileName = JobHistory.JobInfo.encodeJobHistoryFilePath(logFile);
+ String jobid = JSPUtil.getJobID(new Path(logFile).getName());
+ String taskStatus = request.getParameter("status");
+ String taskType = request.getParameter("taskType");
+
+ FileSystem fs = (FileSystem) application.getAttribute("fileSys");
+ JobConf jobConf = (JobConf) application.getAttribute("jobConf");
+ ACLsManager aclsManager = (ACLsManager) application.getAttribute("aclManager");
+ JobHistory.JobInfo job = JSPUtil.checkAccessAndGetJobInfo(request,
+ response, jobConf, aclsManager, fs, new Path(logFile));
+ if (job == null) {
+ return;
+ }
+ Map<String, JobHistory.Task> tasks = job.getAllTasks();
+%>
+<html>
+<body>
+<h2><%=taskStatus%> <%=taskType %> task list for <a href="jobdetailshistory.jsp?logFile=<%=encodedLogFileName%>"><%=jobid %> </a></h2>
+<center>
+<table border="2" cellpadding="5" cellspacing="2">
+<tr><td>Task Id</td><td>Start Time</td><td>Finish Time<br/></td><td>Error</td></tr>
+<%
+ for (JobHistory.Task task : tasks.values()) {
+ if (taskType.equals(task.get(Keys.TASK_TYPE))){
+ Map <String, TaskAttempt> taskAttempts = task.getTaskAttempts();
+ for (JobHistory.TaskAttempt taskAttempt : taskAttempts.values()) {
+ if (taskStatus.equals(taskAttempt.get(Keys.TASK_STATUS)) ||
+ taskStatus.equals("all")){
+ printTask(encodedLogFileName, taskAttempt, out);
+ }
+ }
+ }
+ }
+%>
+</table>
+<%!
+ private void printTask(String logFile,
+ JobHistory.TaskAttempt attempt, JspWriter out) throws IOException{
+ out.print("<tr>");
+ out.print("<td>" + "<a href=\"taskdetailshistory.jsp?logFile="+ logFile
+ +"&tipid="+attempt.get(Keys.TASKID)+"\">" +
+ attempt.get(Keys.TASKID) + "</a></td>");
+ out.print("<td>" + StringUtils.getFormattedTimeWithDiff(dateFormat,
+ attempt.getLong(Keys.START_TIME), 0 ) + "</td>");
+ out.print("<td>" + StringUtils.getFormattedTimeWithDiff(dateFormat,
+ attempt.getLong(Keys.FINISH_TIME),
+ attempt.getLong(Keys.START_TIME) ) + "</td>");
+ out.print("<td>" + HtmlQuoting.quoteHtmlChars(attempt.get(Keys.ERROR)) +
+ "</td>");
+ out.print("</tr>");
+ }
+%>
+</center>
+</body>
+</html>
Added: hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/legacyjobhistory.jsp
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/legacyjobhistory.jsp?rev=1077590&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/legacyjobhistory.jsp (added)
+++ hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/legacyjobhistory.jsp Fri Mar 4 04:32:45 2011
@@ -0,0 +1,321 @@
+<%@ page
+ contentType="text/html; charset=UTF-8"
+ import="java.io.*"
+ import="java.util.*"
+ import="org.apache.hadoop.mapred.*"
+ import="org.apache.hadoop.util.*"
+ import="org.apache.hadoop.fs.*"
+ import="javax.servlet.jsp.*"
+ import="java.text.SimpleDateFormat"
+ import="org.apache.hadoop.http.HtmlQuoting"
+ import="org.apache.hadoop.mapred.*"
+%>
+<%
+ JobConf jobConf = (JobConf)application.getAttribute("jobConf");
+ String trackerAddress = jobConf.get("mapred.job.tracker.http.address");
+ String trackerName = StringUtils.simpleHostname(trackerAddress);
+%>
+<%!
+ private static SimpleDateFormat dateFormat =
+ new SimpleDateFormat("d/MM HH:mm:ss");
+%>
+<%! private static final long serialVersionUID = 1L;
+%>
+<html>
+<head>
+<script type="text/JavaScript">
+<!--
+function showUserHistory(search)
+{
+var url
+if (search == null || "".equals(search)) {
+ url="legacyjobhistory.jsp";
+} else {
+ url="legacyjobhistory.jsp?pageno=1&search=" + search;
+}
+window.location.href = url;
+}
+//-->
+</script>
+<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<title><%= trackerName %> Hadoop Map/Reduce History Viewer</title>
+<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+</head>
+<body>
+<h1> <a href="http://<%=trackerAddress%>/jobtracker.jsp"><%= trackerName %></a> Hadoop Map/Reduce
+ <a href="jobhistoryhome.jsp">History Viewer</a></h1>
+<hr>
+<%
+ final String search = (request.getParameter("search") == null)
+ ? ""
+ : request.getParameter("search");
+
+ String parts[] = search.split(":");
+
+ final String user = (parts.length >= 1)
+ ? parts[0].toLowerCase()
+ : "";
+ final String jobname = (parts.length >= 2)
+ ? parts[1].toLowerCase()
+ : "";
+ PathFilter jobLogFileFilter = new PathFilter() {
+ // unquote params before encoding for search
+ final String uqUser = JobHistory.JobInfo.encodeJobHistoryFileName(
+ HtmlQuoting.unquoteHtmlChars(user));
+ final String uqJobname = JobHistory.JobInfo.encodeJobHistoryFileName(
+ HtmlQuoting.unquoteHtmlChars(jobname));
+ private boolean matchUser(String fileName) {
+ // return true if
+ // - user is not specified
+ // - user matches
+ return "".equals(uqUser) || uqUser.equals(fileName.split("_")[5]);
+ }
+
+ private boolean matchJobName(String fileName) {
+ // return true if
+ // - jobname is not specified
+ // - jobname contains the keyword
+ return "".equals(uqJobname) || fileName.split("_")[6].toLowerCase().contains(uqJobname);
+ }
+
+ public boolean accept(Path path) {
+ return !(path.getName().endsWith(".xml")) && matchUser(path.getName()) && matchJobName(path.getName());
+ }
+ };
+
+ FileSystem fs = (FileSystem) application.getAttribute("fileSys");
+ String historyLogDir = (String) application.getAttribute("historyLogDir");
+ if (fs == null) {
+ out.println("Null file system. May be namenode is in safemode!");
+ return;
+ }
+
+ Path[] jobFiles
+ = JobHistory.filteredStat2Paths(fs.listStatus(new Path(historyLogDir),
+ jobLogFileFilter),
+ false, null);
+
+ out.println("<!-- user : " + user +
+ ", jobname : " + jobname + "-->");
+ if (null == jobFiles || jobFiles.length == 0) {
+ out.println("No files found!");
+ return ;
+ }
+
+ // get the pageno
+ int pageno = request.getParameter("pageno") == null
+ ? 1
+ : Integer.parseInt(request.getParameter("pageno"));
+
+ // get the total number of files to display
+ int size = 100;
+
+ // if show-all is requested or jobfiles < size(100)
+ if (pageno == -1 || size > jobFiles.length) {
+ size = jobFiles.length;
+ }
+
+ if (pageno == -1) { // special case 'show all'
+ pageno = 1;
+ }
+
+ int maxPageNo = (int)Math.ceil((float)jobFiles.length / size);
+
+ // check and fix pageno
+ if (pageno < 1 || pageno > maxPageNo) {
+ out.println("Invalid page index");
+ return ;
+ }
+
+ int length = size ; // determine the length of job history files to be displayed
+ if (pageno == maxPageNo) {
+ // find the number of files to be shown on the last page
+ int startOnLast = ((pageno - 1) * size) + 1;
+ length = jobFiles.length - startOnLast + 1;
+ }
+
+ // Display the search box
+ out.println("<form name=search><b> Filter (username:jobname) </b>"); // heading
+ out.println("<input type=text name=search size=\"20\" value=\"" + search + "\">"); // search box
+ out.println("<input type=submit value=\"Filter!\" onClick=\"showUserHistory(document.getElementById('search').value)\"></form>");
+ out.println("<span class=\"small\">Example: 'smith' will display jobs either submitted by user 'smith'. 'smith:sort' will display jobs from user 'smith' having 'sort' keyword in the jobname.</span>"); // example
+ out.println("<hr>");
+
+ //Show the status
+ int start = (pageno - 1) * size + 1;
+
+ // DEBUG
+ out.println("<!-- pageno : " + pageno + ", size : " + size + ", length : " + length + ", start : " + start + ", maxpg : " + maxPageNo + "-->");
+
+ out.println("<font size=5><b>Available Jobs in History </b></font>");
+ // display the number of jobs, start index, end index
+ out.println("(<i> <span class=\"small\">Displaying <b>" + length + "</b> jobs from <b>" + start + "</b> to <b>" + (start + length - 1) + "</b> out of <b>" + jobFiles.length + "</b> jobs");
+ if (!"".equals(user)) {
+ // show the user if present
+ out.println(" for user <b>" + user + "</b>");
+ }
+ if (!"".equals(jobname)) {
+ out.println(" with jobname having the keyword <b>" +
+ jobname + "</b> in it."); // show the jobname keyword if present
+ }
+ out.print("</span></i>)");
+
+ // show the 'show-all' link
+ out.println(" [<span class=\"small\"><a href=\"legacyjobhistory.jsp?pageno=-1&search=" + search + "\">show all</a></span>]");
+
+ // show the 'first-page' link
+ if (pageno > 1) {
+ out.println(" [<span class=\"small\"><a href=\"legacyjobhistory.jsp?pageno=1&search=" + search + "\">first page</a></span>]");
+ } else {
+ out.println("[<span class=\"small\">first page]</span>");
+ }
+
+ // show the 'last-page' link
+ if (pageno < maxPageNo) {
+ out.println(" [<span class=\"small\"><a href=\"legacyjobhistory.jsp?pageno=" + maxPageNo + "&search=" + search + "\">last page</a></span>]");
+ } else {
+ out.println("<span class=\"small\">[last page]</span>");
+ }
+
+ // sort the files on creation time.
+ Arrays.sort(jobFiles, new Comparator<Path>() {
+ public int compare(Path p1, Path p2) {
+ String dp1 = null;
+ String dp2 = null;
+
+ try {
+ dp1 = JobHistory.JobInfo.decodeJobHistoryFileName(p1.getName());
+ dp2 = JobHistory.JobInfo.decodeJobHistoryFileName(p2.getName());
+ } catch (IOException ioe) {
+ throw new RuntimeException(ioe);
+ }
+
+ String[] split1 = dp1.split("_");
+ String[] split2 = dp2.split("_");
+
+ // compare job tracker start time
+ int res = new Date(Long.parseLong(split1[1])).compareTo(
+ new Date(Long.parseLong(split2[1])));
+ if (res == 0) {
+ res = new Date(Long.parseLong(split1[3])).compareTo(
+ new Date(Long.parseLong(split2[3])));
+ }
+ if (res == 0) {
+ Long l1 = Long.parseLong(split1[4]);
+ res = l1.compareTo(Long.parseLong(split2[4]));
+ }
+ return res;
+ }
+ });
+
+ out.println("<br><br>");
+
+ // print the navigation info (top)
+ printNavigation(pageno, size, maxPageNo, search, out);
+
+ out.print("<table align=center border=2 cellpadding=\"5\" cellspacing=\"2\">");
+ out.print("<tr>");
+ out.print("<td>Job tracker Host Name</td>" +
+ "<td>Job tracker Start time</td>" +
+ "<td>Job Id</td><td>Name</td><td>User</td>") ;
+ out.print("</tr>");
+
+ Set<String> displayedJobs = new HashSet<String>();
+ for (int i = start - 1; i < start + length - 1; ++i) {
+ Path jobFile = jobFiles[i];
+
+ String decodedJobFileName =
+ JobHistory.JobInfo.decodeJobHistoryFileName(jobFile.getName());
+
+ String[] jobDetails = decodedJobFileName.split("_");
+ String trackerHostName = jobDetails[0];
+ String trackerStartTime = jobDetails[1];
+ String jobId = jobDetails[2] + "_" +jobDetails[3] + "_" + jobDetails[4] ;
+ String userName = jobDetails[5];
+ String jobName = jobDetails[6];
+
+ // Check if the job is already displayed. There can be multiple job
+ // history files for jobs that have restarted
+ if (displayedJobs.contains(jobId)) {
+ continue;
+ } else {
+ displayedJobs.add(jobId);
+ }
+
+ // Encode the logfile name again to cancel the decoding done by the browser
+ String encodedJobFileName =
+ JobHistory.JobInfo.encodeJobHistoryFileName(jobFile.getName());
+%>
+<center>
+<%
+ printJob(trackerHostName, trackerStartTime, jobId,
+ jobName, userName, new Path(jobFile.getParent(), encodedJobFileName),
+ out) ;
+%>
+</center>
+<%
+ } // end while trackers
+ out.print("</table>");
+
+ // show the navigation info (bottom)
+ printNavigation(pageno, size, maxPageNo, search, out);
+%>
+<%!
+ private void printJob(String trackerHostName, String trackerid,
+ String jobId, String jobName,
+ String user, Path logFile, JspWriter out)
+ throws IOException {
+ out.print("<tr>");
+ out.print("<td>" + trackerHostName + "</td>");
+ out.print("<td>" + new Date(Long.parseLong(trackerid)) + "</td>");
+ out.print("<td>" + "<a href=\"jobdetailshistory.jsp?logFile="
+ + logFile.toString() + "\">" + jobId + "</a></td>");
+ out.print("<td>" + HtmlQuoting.quoteHtmlChars(jobName) + "</td>");
+ out.print("<td>" + HtmlQuoting.quoteHtmlChars(user) + "</td>");
+ out.print("</tr>");
+ }
+
+ private void printNavigation(int pageno, int size, int max, String search,
+ JspWriter out) throws IOException {
+ int numIndexToShow = 5; // num indexes to show on either side
+
+ //TODO check this on boundary cases
+ out.print("<center> <");
+
+ // show previous link
+ if (pageno > 1) {
+ out.println("<a href=\"legacyjobhistory.jsp?pageno=" + (pageno - 1) +
+ "&search=" + search + "\">Previous</a>");
+ }
+
+ // display the numbered index 1 2 3 4
+ int firstPage = pageno - numIndexToShow;
+ if (firstPage < 1) {
+ firstPage = 1; // boundary condition
+ }
+
+ int lastPage = pageno + numIndexToShow;
+ if (lastPage > max) {
+ lastPage = max; // boundary condition
+ }
+
+ // debug
+ out.println("<!--DEBUG : firstPage : " + firstPage + ", lastPage : " + lastPage + " -->");
+
+ for (int i = firstPage; i <= lastPage; ++i) {
+ if (i != pageno) {// needs hyperlink
+ out.println(" <a href=\"legacyjobhistory.jsp?pageno=" + i + "&search=" +
+ search + "\">" + i + "</a> ");
+ } else { // current page
+ out.println(i);
+ }
+ }
+
+ // show the next link
+ if (pageno < max) {
+ out.println("<a href=\"legacyjobhistory.jsp?pageno=" + (pageno + 1) + "&search=" + search + "\">Next</a>");
+ }
+ out.print("></center>");
+ }
+%>
+</body></html>
Added: hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/loadhistory.jsp
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/loadhistory.jsp?rev=1077590&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/loadhistory.jsp (added)
+++ hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/loadhistory.jsp Fri Mar 4 04:32:45 2011
@@ -0,0 +1,46 @@
+<%@ page
+ contentType="text/html; charset=UTF-8"
+ import="org.apache.hadoop.mapred.*"
+ import="org.apache.hadoop.fs.*"
+ import="org.apache.hadoop.mapred.JobHistory.*"
+%>
+<%! private static final long serialVersionUID = 1L;
+%>
+<%
+ PathFilter jobLogFileFilter = new PathFilter() {
+ public boolean accept(Path path) {
+ return !(path.getName().endsWith(".xml"));
+ }
+ };
+
+ FileSystem fs = (FileSystem) application.getAttribute("fileSys");
+ String jobId = request.getParameter("jobid");
+ JobHistory.JobInfo job = (JobHistory.JobInfo)
+ request.getSession().getAttribute("job");
+ // if session attribute of JobInfo exists and is of different job's,
+ // then remove the attribute
+ // if the job has not yet finished, remove the attribute sothat it
+ // gets refreshed.
+ boolean isJobComplete = false;
+ if (null != job) {
+ String jobStatus = job.get(Keys.JOB_STATUS);
+ isJobComplete = Values.SUCCESS.name() == jobStatus
+ || Values.FAILED.name() == jobStatus
+ || Values.KILLED.name() == jobStatus;
+ }
+ if (null != job &&
+ (!jobId.equals(job.get(Keys.JOBID))
+ || !isJobComplete)) {
+ // remove jobInfo from session, keep only one job in session at a time
+ request.getSession().removeAttribute("job");
+ job = null ;
+ }
+
+ if (null == job) {
+ String jobLogFile = request.getParameter("logFile");
+ job = new JobHistory.JobInfo(jobId);
+ DefaultJobHistoryParser.parseJobTasks(jobLogFile, job, fs) ;
+ request.getSession().setAttribute("job", job);
+ request.getSession().setAttribute("fs", fs);
+ }
+%>
Added: hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/taskdetailshistory.jsp
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/taskdetailshistory.jsp?rev=1077590&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/taskdetailshistory.jsp (added)
+++ hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/taskdetailshistory.jsp Fri Mar 4 04:32:45 2011
@@ -0,0 +1,134 @@
+<%@ page
+ contentType="text/html; charset=UTF-8"
+ import="javax.servlet.http.*"
+ import="java.io.*"
+ import="java.util.*"
+ import="org.apache.hadoop.http.HtmlQuoting"
+ import="org.apache.hadoop.mapred.*"
+ import="org.apache.hadoop.fs.*"
+ import="org.apache.hadoop.util.*"
+ import="java.text.SimpleDateFormat"
+ import="org.apache.hadoop.mapred.JobHistory.*"
+%>
+
+<%! private static SimpleDateFormat dateFormat = new SimpleDateFormat("d/MM HH:mm:ss") ; %>
+<%! private static final long serialVersionUID = 1L;
+%>
+
+<%
+ String logFile = request.getParameter("logFile");
+ String tipid = request.getParameter("tipid");
+ if (logFile == null || tipid == null) {
+ out.println("Missing job!!");
+ return;
+ }
+ String encodedLogFileName = JobHistory.JobInfo.encodeJobHistoryFilePath(logFile);
+ String jobid = JSPUtil.getJobID(new Path(encodedLogFileName).getName());
+ FileSystem fs = (FileSystem) application.getAttribute("fileSys");
+ JobConf jobConf = (JobConf) application.getAttribute("jobConf");
+ ACLsManager aclsManager = (ACLsManager) application.getAttribute("aclManager");
+ JobHistory.JobInfo job = JSPUtil.checkAccessAndGetJobInfo(request,
+ response, jobConf, aclsManager, fs, new Path(logFile));
+ if (job == null) {
+ return;
+ }
+ JobHistory.Task task = job.getAllTasks().get(tipid);
+ String type = task.get(Keys.TASK_TYPE);
+%>
+<html>
+<body>
+<h2><%=tipid %> attempts for <a href="jobdetailshistory.jsp?logFile=<%=encodedLogFileName%>"> <%=jobid %> </a></h2>
+<center>
+<table border="2" cellpadding="5" cellspacing="2">
+<tr><td>Task Id</td><td>Start Time</td>
+<%
+ if (Values.REDUCE.name().equals(type)) {
+%>
+ <td>Shuffle Finished</td><td>Sort Finished</td>
+<%
+ }
+%>
+<td>Finish Time</td><td>Host</td><td>Error</td><td>Task Logs</td>
+<td>Counters</td></tr>
+<%
+ for (JobHistory.TaskAttempt attempt : task.getTaskAttempts().values()) {
+ printTaskAttempt(attempt, type, out, encodedLogFileName);
+ }
+%>
+</table>
+</center>
+<%
+ if (Values.MAP.name().equals(type)) {
+%>
+<h3>Input Split Locations</h3>
+<table border="2" cellpadding="5" cellspacing="2">
+<%
+ for (String split : StringUtils.split(task.get(Keys.SPLITS)))
+ {
+ out.println("<tr><td>" + split + "</td></tr>");
+ }
+%>
+</table>
+<%
+ }
+%>
+<%!
+ private void printTaskAttempt(JobHistory.TaskAttempt taskAttempt,
+ String type, JspWriter out,
+ String logFile)
+ throws Exception {
+ out.print("<tr>");
+ out.print("<td>" + taskAttempt.get(Keys.TASK_ATTEMPT_ID) + "</td>");
+ out.print("<td>" + StringUtils.getFormattedTimeWithDiff(dateFormat,
+ taskAttempt.getLong(Keys.START_TIME), 0 ) + "</td>");
+ if (Values.REDUCE.name().equals(type)) {
+ JobHistory.ReduceAttempt reduceAttempt =
+ (JobHistory.ReduceAttempt)taskAttempt;
+ out.print("<td>" +
+ StringUtils.getFormattedTimeWithDiff(dateFormat,
+ reduceAttempt.getLong(Keys.SHUFFLE_FINISHED),
+ reduceAttempt.getLong(Keys.START_TIME)) + "</td>");
+ out.print("<td>" + StringUtils.getFormattedTimeWithDiff(dateFormat,
+ reduceAttempt.getLong(Keys.SORT_FINISHED),
+ reduceAttempt.getLong(Keys.SHUFFLE_FINISHED)) + "</td>");
+ }
+ out.print("<td>"+ StringUtils.getFormattedTimeWithDiff(dateFormat,
+ taskAttempt.getLong(Keys.FINISH_TIME),
+ taskAttempt.getLong(Keys.START_TIME) ) + "</td>");
+ out.print("<td>" + taskAttempt.get(Keys.HOSTNAME) + "</td>");
+ out.print("<td>" + HtmlQuoting.quoteHtmlChars(taskAttempt.get(Keys.ERROR)) +
+ "</td>");
+
+ // Print task log urls
+ out.print("<td>");
+ String taskLogsUrl = JobHistory.getTaskLogsUrl(taskAttempt);
+ if (taskLogsUrl != null) {
+ String tailFourKBUrl = taskLogsUrl + "&start=-4097";
+ String tailEightKBUrl = taskLogsUrl + "&start=-8193";
+ String entireLogUrl = taskLogsUrl + "&all=true";
+ out.print("<a href=\"" + tailFourKBUrl + "\">Last 4KB</a><br/>");
+ out.print("<a href=\"" + tailEightKBUrl + "\">Last 8KB</a><br/>");
+ out.print("<a href=\"" + entireLogUrl + "\">All</a><br/>");
+ } else {
+ out.print("n/a");
+ }
+ out.print("</td>");
+ Counters counters =
+ Counters.fromEscapedCompactString(taskAttempt.get(Keys.COUNTERS));
+ if (counters != null) {
+ TaskAttemptID attemptId =
+ TaskAttemptID.forName(taskAttempt.get(Keys.TASK_ATTEMPT_ID));
+ TaskID tipid = attemptId.getTaskID();
+ org.apache.hadoop.mapreduce.JobID jobId = tipid.getJobID();
+ out.print("<td>"
+ + "<a href=\"taskstatshistory.jsp?attemptid=" + attemptId
+ + "&logFile=" + logFile + "\">"
+ + counters.size() + "</a></td>");
+ } else {
+ out.print("<td></td>");
+ }
+ out.print("</tr>");
+ }
+%>
+</body>
+</html>
Added: hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/taskstatshistory.jsp
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/taskstatshistory.jsp?rev=1077590&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/taskstatshistory.jsp (added)
+++ hadoop/common/branches/branch-0.20-security-patches/src/webapps/history/taskstatshistory.jsp Fri Mar 4 04:32:45 2011
@@ -0,0 +1,117 @@
+<%
+/*
+ * 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.http.HtmlQuoting"
+ import="org.apache.hadoop.mapred.*"
+ import="org.apache.hadoop.fs.*"
+ import="org.apache.hadoop.util.*"
+ import="java.text.*"
+ import="org.apache.hadoop.mapred.JobHistory.*"
+%>
+<%! private static SimpleDateFormat dateFormat = new SimpleDateFormat("d/MM HH:mm:ss") ;
+ private static final long serialVersionUID = 1L;
+%>
+
+<%
+ String attemptid = request.getParameter("attemptid");
+ if(attemptid == null) {
+ out.println("No attemptid found! Pass a 'attemptid' parameter in the request.");
+ return;
+ }
+ TaskID tipid = TaskAttemptID.forName(attemptid).getTaskID();
+ String logFile = request.getParameter("logFile");
+ String encodedLogFileName =
+ JobHistory.JobInfo.encodeJobHistoryFilePath(logFile);
+ String jobid = JSPUtil.getJobID(new Path(encodedLogFileName).getName());
+ Format decimal = new DecimalFormat();
+
+ FileSystem fs = (FileSystem) application.getAttribute("fileSys");
+ JobConf jobConf = (JobConf) application.getAttribute("jobConf");
+ ACLsManager aclsManager = (ACLsManager) application.getAttribute("aclManager");
+ JobHistory.JobInfo job = JSPUtil.checkAccessAndGetJobInfo(request,
+ response, jobConf, aclsManager, fs, new Path(logFile));
+ if (job == null) {
+ return;
+ }
+
+ JobHistory.Task task = job.getAllTasks().get(tipid.toString());
+ JobHistory.TaskAttempt attempt = task.getTaskAttempts().get(attemptid);
+
+ Counters counters =
+ Counters.fromEscapedCompactString(attempt.get(Keys.COUNTERS));
+%>
+
+<html>
+ <head>
+ <title>Counters for <%=attemptid%></title>
+ </head>
+<body>
+<h1>Counters for <%=attemptid%></h1>
+
+<hr>
+
+<%
+ if (counters == null) {
+%>
+ <h3>No counter information found for this attempt</h3>
+<%
+ } else {
+%>
+ <table>
+<%
+ for (String groupName : counters.getGroupNames()) {
+ Counters.Group group = counters.getGroup(groupName);
+ String displayGroupName = group.getDisplayName();
+%>
+ <tr>
+ <td colspan="3"><br/><b>
+ <%=HtmlQuoting.quoteHtmlChars(displayGroupName)%></b></td>
+ </tr>
+<%
+ Iterator<Counters.Counter> ctrItr = group.iterator();
+ while(ctrItr.hasNext()) {
+ Counters.Counter counter = ctrItr.next();
+ String displayCounterName = counter.getDisplayName();
+ long value = counter.getCounter();
+%>
+ <tr>
+ <td width="50"></td>
+ <td><%=HtmlQuoting.quoteHtmlChars(displayCounterName)%></td>
+ <td align="right"><%=decimal.format(value)%></td>
+ </tr>
+<%
+ }
+ }
+%>
+ </table>
+<%
+ }
+%>
+
+<hr>
+<a href="jobdetailshistory.jsp?logFile=<%=encodedLogFileName%>">Go back to the job</a><br>
+<a href="jobhistoryhome.jsp">Go back to Job History Viewer</a><br>
+<%
+out.println(ServletUtil.htmlFooter());
+%>
Modified: hadoop/common/branches/branch-0.20-security-patches/src/webapps/job/jobdetails.jsp
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/webapps/job/jobdetails.jsp?rev=1077590&r1=1077589&r2=1077590&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/webapps/job/jobdetails.jsp (original)
+++ hadoop/common/branches/branch-0.20-security-patches/src/webapps/job/jobdetails.jsp Fri Mar 4 04:32:45 2011
@@ -268,7 +268,8 @@
out.println("<h2>Job " + jobId + " not known!</h2>");
return;
}
- String historyUrl = "/jobdetailshistory.jsp?logFile=" +
+ String historyUrl = JobHistoryServer.getHistoryUrlPrefix(tracker.conf) +
+ "/jobdetailshistory.jsp?logFile=" +
JobHistory.JobInfo.encodeJobHistoryFilePath(historyFile);
response.sendRedirect(response.encodeRedirectURL(historyUrl));
return;
Modified: hadoop/common/branches/branch-0.20-security-patches/src/webapps/job/jobhistory.jsp
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/webapps/job/jobhistory.jsp?rev=1077590&r1=1077589&r2=1077590&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/webapps/job/jobhistory.jsp (original)
+++ hadoop/common/branches/branch-0.20-security-patches/src/webapps/job/jobhistory.jsp Fri Mar 4 04:32:45 2011
@@ -1,574 +1,33 @@
-<%@ page
- contentType="text/html; charset=UTF-8"
- import="java.io.*"
- import="java.net.URLEncoder"
- import="java.util.*"
- import="java.util.regex.Pattern"
- import="java.util.regex.Matcher"
- import="java.util.concurrent.atomic.AtomicBoolean"
- import="org.apache.hadoop.mapred.*"
- import="org.apache.hadoop.util.*"
- import="org.apache.hadoop.fs.*"
- import="javax.servlet.jsp.*"
- import="java.text.SimpleDateFormat"
- import="org.apache.hadoop.http.HtmlQuoting"
- import="org.apache.hadoop.mapred.*"
- import="org.apache.hadoop.mapred.JobHistory.*"
-%>
-<%
- JobTracker tracker = (JobTracker) application.getAttribute("job.tracker");
- String trackerName =
- StringUtils.simpleHostname(tracker.getJobTrackerMachine());
-%>
-<%!
- private static SimpleDateFormat dateFormat =
- new SimpleDateFormat("d/MM HH:mm:ss");
-%>
-<%! private static final long serialVersionUID = 1L;
-%>
-<html>
-<head>
-<script type="text/JavaScript">
-<!--
-function showUserHistory(search)
-{
-var url
-if (search == null || "".equals(search)) {
- url="jobhistory.jsp";
-} else {
- url="jobhistory.jsp?pageno=1&search=" + search;
-}
-window.location.href = url;
-}
-//-->
-</script>
-<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
-<title><%= trackerName %> Hadoop Map/Reduce History Viewer</title>
-<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
-</head>
-<body>
-<h1> <a href="jobtracker.jsp"><%= trackerName %></a> Hadoop Map/Reduce
- <a href="jobhistory.jsp">History Viewer</a></h1>
-<hr>
<%
- //{ // these braces are here to make indentation work and
- // {// must be removed.
-
- final int JOB_ID_START = 0;
-
- final int FILENAME_JOBID_END = JOB_ID_START + 3;
-
- final int FILENAME_SUBMIT_TIMESTAMP_PART = FILENAME_JOBID_END;
-
- final int FILENAME_USER_PART = FILENAME_JOBID_END + 1;
-
- final int FILENAME_JOBNAME_PART = FILENAME_JOBID_END + 2;
-
- final int[] SCAN_SIZES = { 20, 50, 200 };
-
- final int FILES_PER_SCAN = 1000;
-
- final int DEFAULT_PAGE_SIZE = 100;
-
- final String DEFAULT_DATE_GLOB_COMPONENT = "*/*/*";
-
- final String SERIAL_NUMBER_GLOB_COMPONENT = "/*";
-
- final String search = (request.getParameter("search") == null)
- ? ""
- : request.getParameter("search");
-
- final String dateSplit[] = search.split(";");
-
- final String soughtDate = dateSplit.length > 1 ? dateSplit[1] : "";
-
- final String parts[] = dateSplit[0].split(":");
-
- final String rawUser = (parts.length >= 1)
- ? parts[0].toLowerCase()
- : "";
-
- final String userInFname
- = escapeUnderscores(JobHistory.JobInfo.encodeJobHistoryFileName(
- HtmlQuoting.unquoteHtmlChars(rawUser))).toLowerCase();
-
- final int currentScanSizeIndex
- = (request.getParameter("scansize") == null)
- ? 0 : Integer.parseInt(request.getParameter("scansize"));
-
- final String SEARCH_PARSE_REGEX
- = "([0-1]?[0-9])/([0-3]?[0-9])/((?:2[0-9])[0-9][0-9])";
-
- final Pattern dateSearchParse = Pattern.compile(SEARCH_PARSE_REGEX);
-
- final String rawJobname = (parts.length >= 2)
- ? parts[1].toLowerCase()
- : "";
-
- final String jobnameKeywordInFname
- = escapeUnderscores(JobHistory.JobInfo.encodeJobHistoryFileName(
- HtmlQuoting.unquoteHtmlChars(rawJobname))).toLowerCase();
-
- PathFilter jobLogFileFilter = new PathFilter() {
- private boolean matchUser(String fileName) {
- // return true if
- // - user is not specified
- // - user matches
- return "".equals(userInFname)
- || userInFname.equals(fileName.split("_")[FILENAME_USER_PART]
- .toLowerCase());
- }
-
- private boolean matchJobName(String fileName) {
- // return true if
- // - jobname is not specified
- // - jobname contains the keyword
- return "".equals(jobnameKeywordInFname)
- || fileName.split("_")[FILENAME_JOBNAME_PART].toLowerCase()
- .contains(jobnameKeywordInFname);
- }
-
- public boolean accept(Path path) {
- String name = path.getName();
-
- return !(name.endsWith(".xml")) && matchUser(name) && matchJobName(name);
- }
- };
-
- FileSystem fs = (FileSystem) application.getAttribute("fileSys");
- String historyLogDir = (String) application.getAttribute("historyLogDir");
- if (fs == null) {
- out.println("Null file system. May be namenode is in safemode!");
- return;
- }
-
- Comparator<Path> lastPathFirst
- = new Comparator<Path>() {
- public int compare(Path path1, Path path2) {
- // these are backwards because we want the lexically lesser names
- // to occur later in the sort.
- return path2.getName().compareTo(path1.getName());
- }
- };
-
- Comparator<Path> latestFirstCreationTimeComparator
- = new Comparator<Path>() {
- public int compare(Path p1, Path p2) {
- String dp1 = null;
- String dp2 = null;
-
- try {
- dp1 = JobHistory.JobInfo.decodeJobHistoryFileName(p1.getName());
- dp2 = JobHistory.JobInfo.decodeJobHistoryFileName(p2.getName());
- } catch (IOException ioe) {
- throw new RuntimeException(ioe);
- }
-
- String[] split1 = dp1.split("_");
- String[] split2 = dp2.split("_");
-
- // compare job tracker start time
- // reverse the sense, because we want the newest records first
- int res = new Date(Long.parseLong(split2[1]))
- .compareTo(new Date(Long.parseLong(split1[1])));
- // compare the submit times next
- // again, reverse the sense
- if (res == 0) {
- res = new Date(Long.parseLong(split2[3]))
- .compareTo(new Date(Long.parseLong(split1[3])));
- }
- // lastly, compare the serial numbers [a certain tiebreaker]
- // again, reverse the sense
- if (res == 0) {
- Long l1 = Long.parseLong(split2[2]);
- res = l1.compareTo(Long.parseLong(split1[2]));
- }
- return res;
- }
- };
-
- String versionComponent = JobHistory.DONE_DIRECTORY_FORMAT_DIRNAME;
-
- String trackerComponent = "*";
-
- // build the glob
- // first find the date component
- String dateComponent = DEFAULT_DATE_GLOB_COMPONENT;
-
- Matcher dateMatcher = dateSearchParse.matcher(soughtDate);
-
- // burst the sought date: must be [m]m/[d]d/[2y]yy
- if (dateMatcher.matches()) {
- String year = dateMatcher.group(3);
- if (year.length() == 2) {
- year = "20" + year;
- }
-
- String month = dateMatcher.group(1);
- if (month.length() == 1) {
- month = "0" + month;
- }
-
- String date = dateMatcher.group(2);
- if (date.length() == 1) {
- date = "0" + date;
- }
-
- dateComponent = year + "/" + month + "/" + date;
- }
-
- // now we find all of the serial numbers. This looks up all the serial
- // number directories, but not the individual files.
- Path historyPath = new Path(historyLogDir);
-
- String leadGlob = (versionComponent
- + "/" + trackerComponent
- + "/" + dateComponent);
-
- // Atomicity is unimportant here.
- // I would have used MutableBoxedBoolean if such had been provided.
- AtomicBoolean hasLegacyFiles = new AtomicBoolean(false);
-
- Path[] snPaths
- = FileUtil.stat2Paths(JobHistory.localGlobber
- (fs, historyPath, "/" + leadGlob, null, hasLegacyFiles));
-
- Arrays.sort(snPaths, lastPathFirst);
-
- int arrayLimit = 0;
- int tranchesSeen = 0;
-
- Path lastPath = null;
-
- while (arrayLimit < snPaths.length
- && tranchesSeen <= SCAN_SIZES[currentScanSizeIndex]) {
- if (lastPath == null
- || lastPathFirst.compare(lastPath, snPaths[arrayLimit]) != 0) {
- ++tranchesSeen;
- lastPath = snPaths[arrayLimit];
- }
-
- ++arrayLimit;
- }
-
- if (tranchesSeen > SCAN_SIZES[currentScanSizeIndex]) {
- --arrayLimit;
- }
-
- // arrayLimit points to the first element [which could be element 0] that
- // we shouldn't consider
-
- int numHistoryFiles = 0;
-
- Path[] jobFiles = null;
-
- {
- Path[][] pathVectorVector = new Path[arrayLimit][];
-
- for (int i = 0; i < arrayLimit; ++i) {
- pathVectorVector[i]
- = FileUtil.stat2Paths(fs.listStatus(snPaths[i], jobLogFileFilter));
- numHistoryFiles += pathVectorVector[i].length;
- }
-
- jobFiles = new Path[numHistoryFiles];
-
- int pathsCursor = 0;
-
- for (int i = 0; i < arrayLimit; ++i) {
- System.arraycopy(pathVectorVector[i], 0, jobFiles, pathsCursor,
- pathVectorVector[i].length);
- pathsCursor += pathVectorVector[i].length;
- }
- }
-
- boolean sizeIsExact = arrayLimit == snPaths.length;
-
- // sizeIsExact will be true if arrayLimit is zero.
- long lengthEstimate
- = sizeIsExact ? numHistoryFiles
- : (long) numHistoryFiles * snPaths.length / arrayLimit;
-
- if (hasLegacyFiles.get()) {
- out.println("<h2>This history has some legacy files. "
- + "<a href=\"legacyjobhistory.jsp\">go to Legacy History Viewer</a>"
- + "</h2>");
- }
-
- out.println("<!-- user : " + rawUser +
- ", jobname : " + rawJobname + "-->");
- if (null == jobFiles || jobFiles.length == 0) {
- out.println("No files found!");
- return ;
- }
-
- // get the pageno
- int pageno = request.getParameter("pageno") == null
- ? 1
- : Integer.parseInt(request.getParameter("pageno"));
-
- // get the total number of files to display
- int size = DEFAULT_PAGE_SIZE;
-
- // if show-all is requested or jobfiles < size(100)
- if (pageno == -1 || size > jobFiles.length) {
- size = jobFiles.length;
- }
-
- if (pageno == -1) { // special case 'show all'
- pageno = 1;
- }
-
- int maxPageNo = (jobFiles.length + size - 1) / size;
- // int maxPageNo = (int)Math.ceil((float)jobFiles.length / size);
-
- // check and fix pageno
- if (pageno < 1 || pageno > maxPageNo) {
- out.println("Invalid page index");
- return ;
- }
-
- int length = size ; // determine the length of job history files to be displayed
- if (pageno == maxPageNo) {
- // find the number of files to be shown on the last page
- int startOnLast = ((pageno - 1) * size) + 1;
- length = jobFiles.length - startOnLast + 1;
- }
-
- // Display the search box
- out.println("<form name=search><b> Filter (username:jobname) </b>"); // heading
- out.println("<input type=text name=search size=\"20\" "
- + "value=\"" + search + "\">"); // search box
- out.println("<input type=submit value=\"Filter!\" onClick=\"showUserHistory"
- + "(document.getElementById('search').value)\"></form>");
- out.println("<p><span class=\"small\">Specify [user][:jobname keyword(s)]"
- + "[;MM/DD/YYYY] . Each of the three components is "
- + "optional. Filter components are conjunctive.</span></p>");
- out.println("<p><span class=\"small\">Example: 'smith' will display jobs"
- + " submitted by user 'smith'. 'smith:sort' will display "
- + "jobs from user 'smith' having a 'sort' keyword in the jobname."
- + " ';07/04/2010' restricts to July 4, 2010</span></p>"); // example
- out.println("<hr>");
-
- //Show the status
- int start = (pageno - 1) * size + 1;
-
- // DEBUG
- out.println("<!-- pageno : " + pageno + ", size : " + size + ", length : "
- + length + ", start : " + start + ", maxpg : "
- + maxPageNo + "-->");
-
- out.println("<font size=5><b>Available Jobs in History </b></font>");
- // display the number of jobs, start index, end index
- out.println("(<i> <span class=\"small\">Displaying <b>" + length
- + "</b> jobs from <b>" + start + "</b> to <b>"
- + (start + length - 1) + "</b> out of "
- + (sizeIsExact
- ? "" : "approximately ") + "<b>"
- + lengthEstimate + "</b> jobs"
- + (sizeIsExact
- ? ""
- : ", <b>" + numHistoryFiles + "</b> gotten"));
- if (!"".equals(rawUser)) {
- // show the user if present
- out.println(" for user <b>" + rawUser + "</b>");
- }
- if (!"".equals(rawJobname)) {
- out.println(" with jobname having the keyword <b>" +
- rawJobname + "</b> in it.");
- // show the jobname keyword if present
- }
- if (!DEFAULT_DATE_GLOB_COMPONENT.equals(dateComponent)) {
- out.println(" for the date <b>" + soughtDate + "</b>");
- }
- out.print("</span></i>)");
-
- final String searchPart = "&search=" + search;
-
- final String scansizePart = "&scansize=" + currentScanSizeIndex;
-
- final String searchPlusScan = searchPart + scansizePart;
-
- // show the expand scope link, if we're restricted
- if (sizeIsExact || currentScanSizeIndex == SCAN_SIZES.length - 1) {
- out.println("[<span class=\"small\">get more results</span>]");
- } else {
- out.println(" [<span class=\"small\"><a href=\"jobhistory.jsp?pageno=1"
- + searchPart + "&scansize=" + (currentScanSizeIndex + 1)
- + "\">get more results</a></span>]");
- }
-
- // show the 'show-all' link
- out.println(" [<span class=\"small\"><a href=\"jobhistory.jsp?pageno=-1"
- + searchPlusScan + "\">show in one page</a></span>]");
-
- // show the 'first-page' link
- if (pageno > 1) {
- out.println(" [<span class=\"small\"><a href=\"jobhistory.jsp?pageno=1"
- + searchPlusScan + "\">first page</a></span>]");
- } else {
- out.println("[<span class=\"small\">first page]</span>");
- }
-
- // show the 'last-page' link
- if (pageno < maxPageNo) {
- out.println(" [<span class=\"small\"><a href=\"jobhistory.jsp?pageno="
- + maxPageNo + searchPlusScan + "\">last page</a></span>]");
- } else {
- out.println("<span class=\"small\">[last page]</span>");
- }
-
- // sort the files on creation time.
- Arrays.sort(jobFiles, latestFirstCreationTimeComparator);
-
- out.println("<br><br>");
-
- // print the navigation info (top)
- printNavigationTool(pageno, size, maxPageNo, searchPlusScan, out);
-
- out.print("<table align=center border=2 cellpadding=\"5\" cellspacing=\"2\">");
- out.print("<tr>");
- out.print("<td>Job submit time</td>" +
- "<td>Job Id</td><td>Name</td><td>User</td>") ;
- out.print("</tr>");
-
- Set<String> displayedJobs = new HashSet<String>();
- for (int i = start - 1; i < start + length - 1; ++i) {
- Path jobFile = jobFiles[i];
-
- String fname = jobFile.getName();
- String marker = JobHistory.nonOccursString(fname);
- String reescapedFname = JobHistory.replaceStringInstances(fname,
- JobHistory.UNDERSCORE_ESCAPE, marker);
-
- String decodedJobFileName =
- JobHistory.JobInfo.decodeJobHistoryFileName(reescapedFname);
-
- String[] jobDetails = decodedJobFileName.split("_");
- String trackerStartTime = jobDetails[1];
- String jobId = (jobDetails[JOB_ID_START]
- + "_" + jobDetails[JOB_ID_START + 1]
- + "_" + jobDetails[JOB_ID_START + 2]);
- String submitTimestamp = jobDetails[FILENAME_SUBMIT_TIMESTAMP_PART];
- String userName = JobHistory.replaceStringInstances(jobDetails[FILENAME_USER_PART],
- marker, JobHistory.UNDERSCORE_ESCAPE);
- String jobName = JobHistory.replaceStringInstances(jobDetails[FILENAME_JOBNAME_PART],
- marker, JobHistory.UNDERSCORE_ESCAPE);
-
- // Check if the job is already displayed. There can be multiple job
- // history files for jobs that have restarted
- if (displayedJobs.contains(jobId)) {
- continue;
- } else {
- displayedJobs.add(jobId);
- }
-
- // Encode the logfile name again to cancel the decoding done by the browser
- String preEncodedJobFileName =
- JobHistory.JobInfo.encodeJobHistoryFileName(jobFile.getName());
-
- String encodedJobFileName =
- JobHistory.replaceStringInstances(preEncodedJobFileName, "%5F", "%255F");
-%>
-<center>
-<%
- printJob(submitTimestamp, jobId,
- jobName, userName, new Path(jobFile.getParent(), encodedJobFileName),
- out) ;
+/*
+ * 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.
+ */
%>
-</center>
-<%
- } // end while trackers
- out.print("</table>");
- // show the navigation info (bottom)
- printNavigationTool(pageno, size, maxPageNo, searchPlusScan, out);
+<%@ page
+ contentType="text/html; charset=UTF-8"
+ import="org.apache.hadoop.mapred.JobHistoryServer"
+ import="org.apache.hadoop.mapred.JobConf"
%>
-<%!
- private void printJob(String timestamp,
- String jobId, String jobName,
- String user, Path logFile, JspWriter out)
- throws IOException {
- out.print("<tr>");
- out.print("<td>" + new Date(Long.parseLong(timestamp)) + "</td>");
- out.print("<td>" + "<a href=\"jobdetailshistory.jsp?logFile="
- + logFile.toString() + "\">" + jobId + "</a></td>");
- out.print("<td>"
- + HtmlQuoting.quoteHtmlChars(unescapeUnderscores(jobName))
- + "</td>");
- out.print("<td>"
- + HtmlQuoting.quoteHtmlChars(unescapeUnderscores(user))
- + "</td>");
- out.print("</tr>");
- }
-
- private String escapeUnderscores(String rawString) {
- return convertStrings(rawString, "_", "%5F");
- }
-
- private String unescapeUnderscores(String rawString) {
- return convertStrings(rawString, "%5F", "_");
- }
- // inefficient if there are a lot of underscores
- private String convertStrings(String escapedString, String from, String to) {
- int firstEscape = escapedString.indexOf(from);
-
- if (firstEscape < 0) {
- return escapedString;
- }
-
- return escapedString.substring(0, firstEscape)
- + to
- + unescapeUnderscores(escapedString.substring
- (firstEscape + from.length()));
- }
-
- private void printNavigationTool(int pageno, int size, int max,
- String searchPlusScan, JspWriter out)
- throws IOException {
-
- final int NUMBER_INDICES_TO_SHOW = 5;
-
- int numIndexToShow = NUMBER_INDICES_TO_SHOW; // num indexes to show on either side
-
- //TODO check this on boundary cases
- out.print("<center> <");
-
- // show previous link
- if (pageno > 1) {
- out.println("<a href=\"jobhistory.jsp?pageno=" + (pageno - 1)
- + searchPlusScan + "\">Previous</a>");
- }
-
- // display the numbered index 1 2 3 4
- int firstPage = pageno - numIndexToShow;
- if (firstPage < 1) {
- firstPage = 1; // boundary condition
- }
-
- int lastPage = pageno + numIndexToShow;
- if (lastPage > max) {
- lastPage = max; // boundary condition
- }
-
- // debug
- out.println("<!--DEBUG : firstPage : " + firstPage + ", lastPage : " + lastPage + " -->");
-
- for (int i = firstPage; i <= lastPage; ++i) {
- if (i != pageno) {// needs hyperlink
- out.println(" <a href=\"jobhistory.jsp?pageno=" + i
- + searchPlusScan + "\">" + i + "</a> ");
- } else { // current page
- out.println(i);
- }
- }
-
- // show the next link
- if (pageno < max) {
- out.println("<a href=\"jobhistory.jsp?pageno=" + (pageno + 1) + searchPlusScan + "\">Next</a>");
- }
- out.print("></center>");
- }
-%>
-</body></html>
+<%
+ JobConf clusterConf = (JobConf) application.getAttribute("jobConf");
+ String historyUrl = JobHistoryServer.getHistoryUrlPrefix(clusterConf) +
+ "/jobhistoryhome.jsp";
+ response.sendRedirect(response.encodeRedirectURL(historyUrl));
+ return;
+%>
\ No newline at end of file
Modified: hadoop/common/branches/branch-0.20-security-patches/src/webapps/job/jobtracker.jsp
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/webapps/job/jobtracker.jsp?rev=1077590&r1=1077589&r2=1077590&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/webapps/job/jobtracker.jsp (original)
+++ hadoop/common/branches/branch-0.20-security-patches/src/webapps/job/jobtracker.jsp Fri Mar 4 04:32:45 2011
@@ -174,7 +174,8 @@ if (failedJobs.size() > 0) {
<hr>
<h2 id="local_logs">Local Logs</h2>
-<a href="logs/">Log</a> directory, <a href="jobhistory.jsp">
+<a href="logs/">Log</a> directory,
+<a href="<%=JobHistoryServer.getHistoryUrlPrefix(tracker.conf)%>/jobhistoryhome.jsp">
Job Tracker History</a>
<%