Merge -c 1576946 from trunk to branch-2 to fix MAPREDUCE-5553. Allow users to easily access completed/pending/successful/failed tasks on MR AM web-ui. Contributed by Paul Han.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1576947 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
804f86f42c
commit
9e695db974
|
@ -46,6 +46,10 @@ Release 2.4.0 - UNRELEASED
|
||||||
MAPREDUCE-5773. Provide dedicated MRAppMaster syslog length limit (Gera
|
MAPREDUCE-5773. Provide dedicated MRAppMaster syslog length limit (Gera
|
||||||
Shegalov via jlowe)
|
Shegalov via jlowe)
|
||||||
|
|
||||||
|
MAPREDUCE-5553. Allow users to easily access
|
||||||
|
completed/pending/successful/failed tasks on MR AM web-ui. (Paul Han via
|
||||||
|
acmurthy)
|
||||||
|
|
||||||
OPTIMIZATIONS
|
OPTIMIZATIONS
|
||||||
|
|
||||||
BUG FIXES
|
BUG FIXES
|
||||||
|
|
|
@ -27,6 +27,7 @@ public interface AMParams {
|
||||||
static final String JOB_ID = "job.id";
|
static final String JOB_ID = "job.id";
|
||||||
static final String TASK_ID = "task.id";
|
static final String TASK_ID = "task.id";
|
||||||
static final String TASK_TYPE = "task.type";
|
static final String TASK_TYPE = "task.type";
|
||||||
|
static final String TASK_STATE = "task.state";
|
||||||
static final String ATTEMPT_STATE = "attempt.state";
|
static final String ATTEMPT_STATE = "attempt.state";
|
||||||
static final String COUNTER_GROUP = "counter.group";
|
static final String COUNTER_GROUP = "counter.group";
|
||||||
static final String COUNTER_NAME = "counter.name";
|
static final String COUNTER_NAME = "counter.name";
|
||||||
|
|
|
@ -40,7 +40,7 @@ public class AMWebApp extends WebApp implements AMParams {
|
||||||
route(pajoin("/jobcounters", JOB_ID), AppController.class, "jobCounters");
|
route(pajoin("/jobcounters", JOB_ID), AppController.class, "jobCounters");
|
||||||
route(pajoin("/singlejobcounter",JOB_ID, COUNTER_GROUP, COUNTER_NAME),
|
route(pajoin("/singlejobcounter",JOB_ID, COUNTER_GROUP, COUNTER_NAME),
|
||||||
AppController.class, "singleJobCounter");
|
AppController.class, "singleJobCounter");
|
||||||
route(pajoin("/tasks", JOB_ID, TASK_TYPE), AppController.class, "tasks");
|
route(pajoin("/tasks", JOB_ID, TASK_TYPE, TASK_STATE), AppController.class, "tasks");
|
||||||
route(pajoin("/attempts", JOB_ID, TASK_TYPE, ATTEMPT_STATE),
|
route(pajoin("/attempts", JOB_ID, TASK_TYPE, ATTEMPT_STATE),
|
||||||
AppController.class, "attempts");
|
AppController.class, "attempts");
|
||||||
route(pajoin("/task", TASK_ID), AppController.class, "task");
|
route(pajoin("/task", TASK_ID), AppController.class, "task");
|
||||||
|
|
|
@ -127,31 +127,28 @@ public class JobBlock extends HtmlBlock {
|
||||||
th(_TH, "Running").
|
th(_TH, "Running").
|
||||||
th(_TH, "Complete")._().
|
th(_TH, "Complete")._().
|
||||||
tr(_ODD).
|
tr(_ODD).
|
||||||
th().
|
th("Map").
|
||||||
a(url("tasks", jid, "m"), "Map")._().
|
|
||||||
td().
|
td().
|
||||||
div(_PROGRESSBAR).
|
div(_PROGRESSBAR).
|
||||||
$title(join(jinfo.getMapProgressPercent(), '%')). // tooltip
|
$title(join(jinfo.getMapProgressPercent(), '%')). // tooltip
|
||||||
div(_PROGRESSBAR_VALUE).
|
div(_PROGRESSBAR_VALUE).
|
||||||
$style(join("width:", jinfo.getMapProgressPercent(), '%'))._()._()._().
|
$style(join("width:", jinfo.getMapProgressPercent(), '%'))._()._()._().
|
||||||
td(String.valueOf(jinfo.getMapsTotal())).
|
td().a(url("tasks", jid, "m", "ALL"),String.valueOf(jinfo.getMapsTotal()))._().
|
||||||
td(String.valueOf(jinfo.getMapsPending())).
|
td().a(url("tasks", jid, "m", "PENDING"),String.valueOf(jinfo.getMapsPending()))._().
|
||||||
td(String.valueOf(jinfo.getMapsRunning())).
|
td().a(url("tasks", jid, "m", "RUNNING"),String.valueOf(jinfo.getMapsRunning()))._().
|
||||||
td(String.valueOf(jinfo.getMapsCompleted()))._().
|
td().a(url("tasks", jid, "m", "COMPLETED"),String.valueOf(jinfo.getMapsCompleted()))._()._().
|
||||||
tr(_EVEN).
|
tr(_EVEN).
|
||||||
th().
|
th("Reduce").
|
||||||
a(url("tasks", jid, "r"), "Reduce")._().
|
|
||||||
td().
|
td().
|
||||||
div(_PROGRESSBAR).
|
div(_PROGRESSBAR).
|
||||||
$title(join(jinfo.getReduceProgressPercent(), '%')). // tooltip
|
$title(join(jinfo.getReduceProgressPercent(), '%')). // tooltip
|
||||||
div(_PROGRESSBAR_VALUE).
|
div(_PROGRESSBAR_VALUE).
|
||||||
$style(join("width:", jinfo.getReduceProgressPercent(), '%'))._()._()._().
|
$style(join("width:", jinfo.getReduceProgressPercent(), '%'))._()._()._().
|
||||||
td(String.valueOf(jinfo.getReducesTotal())).
|
td().a(url("tasks", jid, "r", "ALL"),String.valueOf(jinfo.getReducesTotal()))._().
|
||||||
td(String.valueOf(jinfo.getReducesPending())).
|
td().a(url("tasks", jid, "r", "PENDING"),String.valueOf(jinfo.getReducesPending()))._().
|
||||||
td(String.valueOf(jinfo.getReducesRunning())).
|
td().a(url("tasks", jid, "r", "RUNNING"),String.valueOf(jinfo.getReducesRunning()))._().
|
||||||
td(String.valueOf(jinfo.getReducesCompleted()))._()
|
td().a(url("tasks", jid, "r", "COMPLETED"),String.valueOf(jinfo.getReducesCompleted()))._()._()
|
||||||
._().
|
._().
|
||||||
|
|
||||||
// Attempts table
|
// Attempts table
|
||||||
table("#job").
|
table("#job").
|
||||||
tr().
|
tr().
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
package org.apache.hadoop.mapreduce.v2.app.webapp;
|
package org.apache.hadoop.mapreduce.v2.app.webapp;
|
||||||
|
|
||||||
|
import static org.apache.hadoop.mapreduce.v2.app.webapp.AMParams.TASK_STATE;
|
||||||
import static org.apache.hadoop.mapreduce.v2.app.webapp.AMParams.TASK_TYPE;
|
import static org.apache.hadoop.mapreduce.v2.app.webapp.AMParams.TASK_TYPE;
|
||||||
import static org.apache.hadoop.yarn.util.StringHelper.join;
|
import static org.apache.hadoop.yarn.util.StringHelper.join;
|
||||||
import static org.apache.hadoop.yarn.util.StringHelper.percent;
|
import static org.apache.hadoop.yarn.util.StringHelper.percent;
|
||||||
|
@ -71,6 +72,25 @@ public class TasksBlock extends HtmlBlock {
|
||||||
if (type != null && task.getType() != type) {
|
if (type != null && task.getType() != type) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
String taskStateStr = $(TASK_STATE);
|
||||||
|
if (taskStateStr == null || taskStateStr.trim().equals("")) {
|
||||||
|
taskStateStr = "ALL";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!taskStateStr.equalsIgnoreCase("ALL"))
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// get stateUI enum
|
||||||
|
MRApps.TaskStateUI stateUI = MRApps.taskState(taskStateStr);
|
||||||
|
if (!stateUI.correspondsTo(task.getState()))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
continue; // not supported state, ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TaskInfo info = new TaskInfo(task);
|
TaskInfo info = new TaskInfo(task);
|
||||||
String tid = info.getId();
|
String tid = info.getId();
|
||||||
String pct = percent(info.getProgress() / 100);
|
String pct = percent(info.getProgress() / 100);
|
||||||
|
|
|
@ -48,6 +48,7 @@ import org.apache.hadoop.mapreduce.v2.api.records.JobId;
|
||||||
import org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptId;
|
import org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptId;
|
||||||
import org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptState;
|
import org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptState;
|
||||||
import org.apache.hadoop.mapreduce.v2.api.records.TaskId;
|
import org.apache.hadoop.mapreduce.v2.api.records.TaskId;
|
||||||
|
import org.apache.hadoop.mapreduce.v2.api.records.TaskState;
|
||||||
import org.apache.hadoop.mapreduce.v2.api.records.TaskType;
|
import org.apache.hadoop.mapreduce.v2.api.records.TaskType;
|
||||||
import org.apache.hadoop.util.StringUtils;
|
import org.apache.hadoop.util.StringUtils;
|
||||||
import org.apache.hadoop.yarn.ContainerLogAppender;
|
import org.apache.hadoop.yarn.ContainerLogAppender;
|
||||||
|
@ -125,6 +126,23 @@ public class MRApps extends Apps {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static enum TaskStateUI {
|
||||||
|
RUNNING(
|
||||||
|
new TaskState[]{TaskState.RUNNING}),
|
||||||
|
PENDING(new TaskState[]{TaskState.SCHEDULED}),
|
||||||
|
COMPLETED(new TaskState[]{TaskState.SUCCEEDED, TaskState.FAILED, TaskState.KILLED});
|
||||||
|
|
||||||
|
private final List<TaskState> correspondingStates;
|
||||||
|
|
||||||
|
private TaskStateUI(TaskState[] correspondingStates) {
|
||||||
|
this.correspondingStates = Arrays.asList(correspondingStates);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean correspondsTo(TaskState state) {
|
||||||
|
return this.correspondingStates.contains(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static TaskType taskType(String symbol) {
|
public static TaskType taskType(String symbol) {
|
||||||
// JDK 7 supports switch on strings
|
// JDK 7 supports switch on strings
|
||||||
if (symbol.equals("m")) return TaskType.MAP;
|
if (symbol.equals("m")) return TaskType.MAP;
|
||||||
|
@ -136,6 +154,10 @@ public class MRApps extends Apps {
|
||||||
return TaskAttemptStateUI.valueOf(attemptStateStr);
|
return TaskAttemptStateUI.valueOf(attemptStateStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TaskStateUI taskState(String taskStateStr) {
|
||||||
|
return TaskStateUI.valueOf(taskStateStr);
|
||||||
|
}
|
||||||
|
|
||||||
// gets the base name of the MapReduce framework or null if no
|
// gets the base name of the MapReduce framework or null if no
|
||||||
// framework was configured
|
// framework was configured
|
||||||
private static String getMRFrameworkName(Configuration conf) {
|
private static String getMRFrameworkName(Configuration conf) {
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.apache.hadoop.mapreduce.filecache.DistributedCache;
|
||||||
import org.apache.hadoop.mapreduce.v2.api.records.JobId;
|
import org.apache.hadoop.mapreduce.v2.api.records.JobId;
|
||||||
import org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptId;
|
import org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptId;
|
||||||
import org.apache.hadoop.mapreduce.v2.api.records.TaskId;
|
import org.apache.hadoop.mapreduce.v2.api.records.TaskId;
|
||||||
|
import org.apache.hadoop.mapreduce.v2.api.records.TaskState;
|
||||||
import org.apache.hadoop.mapreduce.v2.api.records.TaskType;
|
import org.apache.hadoop.mapreduce.v2.api.records.TaskType;
|
||||||
import org.apache.hadoop.util.StringUtils;
|
import org.apache.hadoop.util.StringUtils;
|
||||||
import org.apache.hadoop.yarn.api.ApplicationConstants;
|
import org.apache.hadoop.yarn.api.ApplicationConstants;
|
||||||
|
@ -460,4 +461,13 @@ public class TestMRApps {
|
||||||
public void initialize(URI name, Configuration conf) throws IOException {}
|
public void initialize(URI name, Configuration conf) throws IOException {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTaskStateUI() {
|
||||||
|
assertTrue(MRApps.TaskStateUI.PENDING.correspondsTo(TaskState.SCHEDULED));
|
||||||
|
assertTrue(MRApps.TaskStateUI.COMPLETED.correspondsTo(TaskState.SUCCEEDED));
|
||||||
|
assertTrue(MRApps.TaskStateUI.COMPLETED.correspondsTo(TaskState.FAILED));
|
||||||
|
assertTrue(MRApps.TaskStateUI.COMPLETED.correspondsTo(TaskState.KILLED));
|
||||||
|
assertTrue(MRApps.TaskStateUI.RUNNING.correspondsTo(TaskState.RUNNING));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue