MAPREDUCE-3754. Modified RM UI to filter applications based on state of the applications. (vinodkv)
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1238887 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f8a245c273
commit
d1f805f942
|
@ -217,6 +217,9 @@ Release 0.23.1 - Unreleased
|
||||||
MAPREDUCE-3679. AM logs and others should not automatically refresh after every 1
|
MAPREDUCE-3679. AM logs and others should not automatically refresh after every 1
|
||||||
second. (Vinod KV via mahadev)
|
second. (Vinod KV via mahadev)
|
||||||
|
|
||||||
|
MAPREDUCE-3754. Modified RM UI to filter applications based on state of the
|
||||||
|
applications. (vinodkv)
|
||||||
|
|
||||||
OPTIMIZATIONS
|
OPTIMIZATIONS
|
||||||
|
|
||||||
MAPREDUCE-3567. Extraneous JobConf objects in AM heap. (Vinod Kumar
|
MAPREDUCE-3567. Extraneous JobConf objects in AM heap. (Vinod Kumar
|
||||||
|
|
|
@ -25,4 +25,7 @@ public interface YarnWebParams {
|
||||||
String CONTAINER_LOG_TYPE= "log.type";
|
String CONTAINER_LOG_TYPE= "log.type";
|
||||||
String ENTITY_STRING = "entity.string";
|
String ENTITY_STRING = "entity.string";
|
||||||
String APP_OWNER = "app.owner";
|
String APP_OWNER = "app.owner";
|
||||||
|
String APP_STATE = "app.state";
|
||||||
|
String QUEUE_NAME = "queue.name";
|
||||||
|
String NODE_STATE = "node.state";
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,13 @@
|
||||||
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
||||||
|
|
||||||
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.sjoin;
|
||||||
|
import static org.apache.hadoop.yarn.webapp.YarnWebParams.APP_STATE;
|
||||||
import static org.apache.hadoop.yarn.webapp.view.JQueryUI._PROGRESSBAR;
|
import static org.apache.hadoop.yarn.webapp.view.JQueryUI._PROGRESSBAR;
|
||||||
import static org.apache.hadoop.yarn.webapp.view.JQueryUI._PROGRESSBAR_VALUE;
|
import static org.apache.hadoop.yarn.webapp.view.JQueryUI._PROGRESSBAR_VALUE;
|
||||||
|
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppInfo;
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppInfo;
|
||||||
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
|
||||||
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TABLE;
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TABLE;
|
||||||
|
@ -56,7 +59,12 @@ class AppsBlock extends HtmlBlock {
|
||||||
th(".note", "Note")._()._().
|
th(".note", "Note")._()._().
|
||||||
tbody();
|
tbody();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
String reqState = $(APP_STATE);
|
||||||
|
reqState = (reqState == null ? "" : reqState);
|
||||||
for (RMApp app : list.apps.values()) {
|
for (RMApp app : list.apps.values()) {
|
||||||
|
if (!reqState.isEmpty() && app.getState() != RMAppState.valueOf(reqState)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
AppInfo appInfo = new AppInfo(app, true);
|
AppInfo appInfo = new AppInfo(app, true);
|
||||||
String percent = String.format("%.1f", appInfo.getProgress());
|
String percent = String.format("%.1f", appInfo.getProgress());
|
||||||
tbody.
|
tbody.
|
||||||
|
@ -86,7 +94,7 @@ class AppsBlock extends HtmlBlock {
|
||||||
if (list.rendering == Render.JS_ARRAY) {
|
if (list.rendering == Render.JS_ARRAY) {
|
||||||
echo("<script type='text/javascript'>\n",
|
echo("<script type='text/javascript'>\n",
|
||||||
"var appsData=");
|
"var appsData=");
|
||||||
list.toDataTableArrays(writer());
|
list.toDataTableArrays(reqState, writer());
|
||||||
echo("\n</script>\n");
|
echo("\n</script>\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import java.util.concurrent.ConcurrentMap;
|
||||||
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
|
import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppInfo;
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppInfo;
|
||||||
import org.apache.hadoop.yarn.webapp.Controller.RequestContext;
|
import org.apache.hadoop.yarn.webapp.Controller.RequestContext;
|
||||||
import org.apache.hadoop.yarn.webapp.ToJSON;
|
import org.apache.hadoop.yarn.webapp.ToJSON;
|
||||||
|
@ -51,10 +52,14 @@ class AppsList implements ToJSON {
|
||||||
apps = rmContext.getRMApps();
|
apps = rmContext.getRMApps();
|
||||||
}
|
}
|
||||||
|
|
||||||
void toDataTableArrays(PrintWriter out) {
|
void toDataTableArrays(String requiredAppState, PrintWriter out) {
|
||||||
out.append('[');
|
out.append('[');
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (RMApp app : apps.values()) {
|
for (RMApp app : apps.values()) {
|
||||||
|
if (requiredAppState != null && !requiredAppState.isEmpty()
|
||||||
|
&& app.getState() != RMAppState.valueOf(requiredAppState)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
AppInfo appInfo = new AppInfo(app, false);
|
AppInfo appInfo = new AppInfo(app, false);
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
first = false;
|
||||||
|
@ -84,7 +89,7 @@ class AppsList implements ToJSON {
|
||||||
@Override
|
@Override
|
||||||
public void toJSON(PrintWriter out) {
|
public void toJSON(PrintWriter out) {
|
||||||
out.print("{\"aaData\":");
|
out.print("{\"aaData\":");
|
||||||
toDataTableArrays(out);
|
toDataTableArrays(null, out);
|
||||||
out.print("}\n");
|
out.print("}\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,18 +18,32 @@
|
||||||
|
|
||||||
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
||||||
|
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState;
|
||||||
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
|
||||||
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.DIV;
|
||||||
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.LI;
|
||||||
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.UL;
|
||||||
import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
|
import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
|
||||||
|
|
||||||
public class NavBlock extends HtmlBlock {
|
public class NavBlock extends HtmlBlock {
|
||||||
|
|
||||||
@Override public void render(Block html) {
|
@Override public void render(Block html) {
|
||||||
html.
|
UL<DIV<Hamlet>> mainList = html.
|
||||||
div("#nav").
|
div("#nav").
|
||||||
h3("Cluster").
|
h3("Cluster").
|
||||||
ul().
|
ul().
|
||||||
li().a(url("cluster"), "About")._().
|
li().a(url("cluster"), "About")._().
|
||||||
li().a(url("nodes"), "Nodes")._().
|
li().a(url("nodes"), "Nodes")._();
|
||||||
li().a(url("apps"), "Applications")._().
|
UL<LI<UL<DIV<Hamlet>>>> subAppsList = mainList.
|
||||||
|
li().a(url("apps"), "Applications").
|
||||||
|
ul();
|
||||||
|
subAppsList.li()._();
|
||||||
|
for (RMAppState state : RMAppState.values()) {
|
||||||
|
subAppsList.
|
||||||
|
li().a(url("apps", state.toString()), state.toString())._();
|
||||||
|
}
|
||||||
|
subAppsList._()._();
|
||||||
|
mainList.
|
||||||
li().a(url("scheduler"), "Scheduler")._()._().
|
li().a(url("scheduler"), "Scheduler")._()._().
|
||||||
h3("Tools").
|
h3("Tools").
|
||||||
ul().
|
ul().
|
||||||
|
|
|
@ -25,14 +25,12 @@ import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
|
||||||
import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
|
import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
|
||||||
import org.apache.hadoop.yarn.webapp.GenericExceptionHandler;
|
import org.apache.hadoop.yarn.webapp.GenericExceptionHandler;
|
||||||
import org.apache.hadoop.yarn.webapp.WebApp;
|
import org.apache.hadoop.yarn.webapp.WebApp;
|
||||||
|
import org.apache.hadoop.yarn.webapp.YarnWebParams;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The RM webapp
|
* The RM webapp
|
||||||
*/
|
*/
|
||||||
public class RMWebApp extends WebApp {
|
public class RMWebApp extends WebApp implements YarnWebParams {
|
||||||
static final String APP_ID = "app.id";
|
|
||||||
static final String QUEUE_NAME = "queue.name";
|
|
||||||
static final String NODE_STATE = "node.state";
|
|
||||||
|
|
||||||
private final ResourceManager rm;
|
private final ResourceManager rm;
|
||||||
|
|
||||||
|
@ -53,9 +51,9 @@ public class RMWebApp extends WebApp {
|
||||||
}
|
}
|
||||||
route("/", RmController.class);
|
route("/", RmController.class);
|
||||||
route(pajoin("/nodes", NODE_STATE), RmController.class, "nodes");
|
route(pajoin("/nodes", NODE_STATE), RmController.class, "nodes");
|
||||||
route("/apps", RmController.class);
|
route(pajoin("/apps", APP_STATE), RmController.class);
|
||||||
route("/cluster", RmController.class, "about");
|
route("/cluster", RmController.class, "about");
|
||||||
route(pajoin("/app", APP_ID), RmController.class, "app");
|
route(pajoin("/app", APPLICATION_ID), RmController.class, "app");
|
||||||
route("/scheduler", RmController.class, "scheduler");
|
route("/scheduler", RmController.class, "scheduler");
|
||||||
route(pajoin("/queue", QUEUE_NAME), RmController.class, "queue");
|
route(pajoin("/queue", QUEUE_NAME), RmController.class, "queue");
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
|
|
||||||
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
||||||
|
|
||||||
import static org.apache.hadoop.yarn.server.resourcemanager.webapp.RMWebApp.APP_ID;
|
|
||||||
import static org.apache.hadoop.yarn.server.resourcemanager.webapp.RMWebApp.QUEUE_NAME;
|
import static org.apache.hadoop.yarn.server.resourcemanager.webapp.RMWebApp.QUEUE_NAME;
|
||||||
import static org.apache.hadoop.yarn.util.StringHelper.join;
|
import static org.apache.hadoop.yarn.util.StringHelper.join;
|
||||||
|
import static org.apache.hadoop.yarn.webapp.YarnWebParams.APPLICATION_ID;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ public class RmController extends Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void app() {
|
public void app() {
|
||||||
String aid = $(APP_ID);
|
String aid = $(APPLICATION_ID);
|
||||||
if (aid.isEmpty()) {
|
if (aid.isEmpty()) {
|
||||||
setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||||
setTitle("Bad request: requires application ID");
|
setTitle("Bad request: requires application ID");
|
||||||
|
|
|
@ -21,6 +21,8 @@ package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
||||||
import org.apache.hadoop.yarn.webapp.SubView;
|
import org.apache.hadoop.yarn.webapp.SubView;
|
||||||
import org.apache.hadoop.yarn.webapp.view.TwoColumnLayout;
|
import org.apache.hadoop.yarn.webapp.view.TwoColumnLayout;
|
||||||
|
|
||||||
|
import static org.apache.hadoop.yarn.util.StringHelper.sjoin;
|
||||||
|
import static org.apache.hadoop.yarn.webapp.YarnWebParams.APP_STATE;
|
||||||
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.*;
|
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.*;
|
||||||
|
|
||||||
// Do NOT rename/refactor this to RMView as it will wreak havoc
|
// Do NOT rename/refactor this to RMView as it will wreak havoc
|
||||||
|
@ -36,6 +38,11 @@ public class RmView extends TwoColumnLayout {
|
||||||
set(DATATABLES_ID, "apps");
|
set(DATATABLES_ID, "apps");
|
||||||
set(initID(DATATABLES, "apps"), appsTableInit());
|
set(initID(DATATABLES, "apps"), appsTableInit());
|
||||||
setTableStyles(html, "apps", ".queue {width:6em}", ".ui {width:8em}");
|
setTableStyles(html, "apps", ".queue {width:6em}", ".ui {width:8em}");
|
||||||
|
|
||||||
|
// Set the correct title.
|
||||||
|
String reqState = $(APP_STATE);
|
||||||
|
reqState = (reqState == null || reqState.isEmpty() ? "All" : reqState);
|
||||||
|
setTitle(sjoin(reqState, "Applications"));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void commonPreHead(Page.HTML<_> html) {
|
protected void commonPreHead(Page.HTML<_> html) {
|
||||||
|
|
|
@ -22,14 +22,14 @@ import java.util.List;
|
||||||
import org.apache.hadoop.classification.InterfaceAudience;
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
import org.apache.hadoop.yarn.MockApps;
|
import org.apache.hadoop.yarn.MockApps;
|
||||||
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
|
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
|
||||||
import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
|
|
||||||
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
||||||
import org.apache.hadoop.yarn.api.records.ApplicationMaster;
|
import org.apache.hadoop.yarn.api.records.ApplicationMaster;
|
||||||
import org.apache.hadoop.yarn.api.records.ApplicationReport;
|
import org.apache.hadoop.yarn.api.records.ApplicationReport;
|
||||||
import org.apache.hadoop.yarn.api.records.YarnApplicationState;
|
|
||||||
import org.apache.hadoop.yarn.api.records.ApplicationStatus;
|
import org.apache.hadoop.yarn.api.records.ApplicationStatus;
|
||||||
import org.apache.hadoop.yarn.api.records.Container;
|
import org.apache.hadoop.yarn.api.records.Container;
|
||||||
import org.apache.hadoop.yarn.api.records.ContainerId;
|
import org.apache.hadoop.yarn.api.records.ContainerId;
|
||||||
|
import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
|
||||||
|
import org.apache.hadoop.yarn.api.records.YarnApplicationState;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.recovery.ApplicationsStore.ApplicationStore;
|
import org.apache.hadoop.yarn.server.resourcemanager.recovery.ApplicationsStore.ApplicationStore;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppEvent;
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppEvent;
|
||||||
|
@ -41,7 +41,6 @@ import com.google.common.collect.Lists;
|
||||||
|
|
||||||
@InterfaceAudience.Private
|
@InterfaceAudience.Private
|
||||||
public abstract class MockAsm extends MockApps {
|
public abstract class MockAsm extends MockApps {
|
||||||
static final int DT = 1000000; // ms
|
|
||||||
|
|
||||||
public static class AppMasterBase implements ApplicationMaster {
|
public static class AppMasterBase implements ApplicationMaster {
|
||||||
@Override
|
@Override
|
||||||
|
@ -232,9 +231,10 @@ public abstract class MockAsm extends MockApps {
|
||||||
final String user = newUserName();
|
final String user = newUserName();
|
||||||
final String name = newAppName();
|
final String name = newAppName();
|
||||||
final String queue = newQueue();
|
final String queue = newQueue();
|
||||||
final long start = System.currentTimeMillis() - (int)(Math.random()*DT);
|
final long start = 123456 + i * 1000;
|
||||||
final long finish = Math.random() < 0.5 ? 0 :
|
final long finish = 234567 + i * 1000;
|
||||||
System.currentTimeMillis() + (int)(Math.random()*DT);
|
RMAppState[] allStates = RMAppState.values();
|
||||||
|
final RMAppState state = allStates[i % allStates.length];
|
||||||
return new ApplicationBase() {
|
return new ApplicationBase() {
|
||||||
@Override
|
@Override
|
||||||
public ApplicationId getApplicationId() {
|
public ApplicationId getApplicationId() {
|
||||||
|
@ -270,7 +270,7 @@ public abstract class MockAsm extends MockApps {
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public RMAppState getState() {
|
public RMAppState getState() {
|
||||||
return RMAppState.RUNNING;
|
return state;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public StringBuilder getDiagnostics() {
|
public StringBuilder getDiagnostics() {
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.applicationsmanager.MockAsm;
|
import org.apache.hadoop.yarn.server.resourcemanager.applicationsmanager.MockAsm;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.recovery.MemStore;
|
import org.apache.hadoop.yarn.server.resourcemanager.recovery.MemStore;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode;
|
import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler;
|
||||||
|
@ -45,6 +46,7 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.Capacity
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler;
|
||||||
import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
|
import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
|
||||||
import org.apache.hadoop.yarn.webapp.WebApps;
|
import org.apache.hadoop.yarn.webapp.WebApps;
|
||||||
|
import org.apache.hadoop.yarn.webapp.YarnWebParams;
|
||||||
import org.apache.hadoop.yarn.webapp.test.WebAppTests;
|
import org.apache.hadoop.yarn.webapp.test.WebAppTests;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -74,7 +76,7 @@ public class TestRMWebApp {
|
||||||
|
|
||||||
@Test public void testView() {
|
@Test public void testView() {
|
||||||
Injector injector = WebAppTests.createMockInjector(RMContext.class,
|
Injector injector = WebAppTests.createMockInjector(RMContext.class,
|
||||||
mockRMContext(3, 1, 2, 8*GiB),
|
mockRMContext(15, 1, 2, 8*GiB),
|
||||||
new Module() {
|
new Module() {
|
||||||
@Override
|
@Override
|
||||||
public void configure(Binder binder) {
|
public void configure(Binder binder) {
|
||||||
|
@ -85,7 +87,9 @@ public class TestRMWebApp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
injector.getInstance(RmView.class).render();
|
RmView rmViewInstance = injector.getInstance(RmView.class);
|
||||||
|
rmViewInstance.set(YarnWebParams.APP_STATE, RMAppState.RUNNING.toString());
|
||||||
|
rmViewInstance.render();
|
||||||
WebAppTests.flushOutput(injector);
|
WebAppTests.flushOutput(injector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue