|
@@ -18,14 +18,21 @@
|
|
|
|
|
|
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.NODE_STATE;
|
|
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES;
|
|
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES;
|
|
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES_ID;
|
|
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES_ID;
|
|
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.initID;
|
|
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.initID;
|
|
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.tableInit;
|
|
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.tableInit;
|
|
|
|
|
|
|
|
+import org.apache.hadoop.util.StringUtils;
|
|
import org.apache.hadoop.yarn.api.records.NodeHealthStatus;
|
|
import org.apache.hadoop.yarn.api.records.NodeHealthStatus;
|
|
|
|
+import org.apache.hadoop.yarn.api.records.NodeId;
|
|
import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
|
|
import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
|
|
|
|
+import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
|
|
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.rmnode.RMNodeState;
|
|
|
|
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
|
|
|
|
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerNodeReport;
|
|
import org.apache.hadoop.yarn.util.Times;
|
|
import org.apache.hadoop.yarn.util.Times;
|
|
import org.apache.hadoop.yarn.webapp.SubView;
|
|
import org.apache.hadoop.yarn.webapp.SubView;
|
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
|
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
|
|
@@ -38,45 +45,75 @@ import com.google.inject.Inject;
|
|
class NodesPage extends RmView {
|
|
class NodesPage extends RmView {
|
|
|
|
|
|
static class NodesBlock extends HtmlBlock {
|
|
static class NodesBlock extends HtmlBlock {
|
|
|
|
+ private static final long BYTES_IN_MB = 1024 * 1024;
|
|
final RMContext rmContext;
|
|
final RMContext rmContext;
|
|
|
|
+ final ResourceManager rm;
|
|
|
|
|
|
@Inject
|
|
@Inject
|
|
- NodesBlock(RMContext context, ViewContext ctx) {
|
|
|
|
|
|
+ NodesBlock(RMContext context, ResourceManager rm, ViewContext ctx) {
|
|
super(ctx);
|
|
super(ctx);
|
|
this.rmContext = context;
|
|
this.rmContext = context;
|
|
|
|
+ this.rm = rm;
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
protected void render(Block html) {
|
|
protected void render(Block html) {
|
|
|
|
+ html._(MetricsOverviewTable.class);
|
|
|
|
+
|
|
|
|
+ ResourceScheduler sched = rm.getResourceScheduler();
|
|
|
|
+ String type = $(NODE_STATE);
|
|
TBODY<TABLE<Hamlet>> tbody = html.table("#nodes").
|
|
TBODY<TABLE<Hamlet>> tbody = html.table("#nodes").
|
|
thead().
|
|
thead().
|
|
tr().
|
|
tr().
|
|
th(".rack", "Rack").
|
|
th(".rack", "Rack").
|
|
|
|
+ th(".state", "Node State").
|
|
th(".nodeaddress", "Node Address").
|
|
th(".nodeaddress", "Node Address").
|
|
th(".nodehttpaddress", "Node HTTP Address").
|
|
th(".nodehttpaddress", "Node HTTP Address").
|
|
th(".healthStatus", "Health-status").
|
|
th(".healthStatus", "Health-status").
|
|
th(".lastHealthUpdate", "Last health-update").
|
|
th(".lastHealthUpdate", "Last health-update").
|
|
th(".healthReport", "Health-report").
|
|
th(".healthReport", "Health-report").
|
|
th(".containers", "Containers").
|
|
th(".containers", "Containers").
|
|
-// th(".mem", "Mem Used (MB)").
|
|
|
|
-// th(".mem", "Mem Avail (MB)").
|
|
|
|
|
|
+ th(".mem", "Mem Used").
|
|
|
|
+ th(".mem", "Mem Avail").
|
|
_()._().
|
|
_()._().
|
|
tbody();
|
|
tbody();
|
|
|
|
+ RMNodeState stateFilter = null;
|
|
|
|
+ if(type != null && !type.isEmpty()) {
|
|
|
|
+ stateFilter = RMNodeState.valueOf(type.toUpperCase());
|
|
|
|
+ }
|
|
for (RMNode ni : this.rmContext.getRMNodes().values()) {
|
|
for (RMNode ni : this.rmContext.getRMNodes().values()) {
|
|
|
|
+ if(stateFilter != null) {
|
|
|
|
+ RMNodeState state = ni.getState();
|
|
|
|
+ if(!stateFilter.equals(state)) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ NodeId id = ni.getNodeID();
|
|
|
|
+ SchedulerNodeReport report = sched.getNodeReport(id);
|
|
|
|
+ int numContainers = 0;
|
|
|
|
+ int usedMemory = 0;
|
|
|
|
+ int availableMemory = 0;
|
|
|
|
+ if(report != null) {
|
|
|
|
+ numContainers = report.getNumContainers();
|
|
|
|
+ usedMemory = report.getUsedResource().getMemory();
|
|
|
|
+ availableMemory = report.getAvailableResource().getMemory();
|
|
|
|
+ }
|
|
|
|
+
|
|
NodeHealthStatus health = ni.getNodeHealthStatus();
|
|
NodeHealthStatus health = ni.getNodeHealthStatus();
|
|
tbody.tr().
|
|
tbody.tr().
|
|
td(ni.getRackName()).
|
|
td(ni.getRackName()).
|
|
|
|
+ td(String.valueOf(ni.getState())).
|
|
td(String.valueOf(ni.getNodeID().toString())).
|
|
td(String.valueOf(ni.getNodeID().toString())).
|
|
td().a("http://" + ni.getHttpAddress(), ni.getHttpAddress())._().
|
|
td().a("http://" + ni.getHttpAddress(), ni.getHttpAddress())._().
|
|
td(health.getIsNodeHealthy() ? "Healthy" : "Unhealthy").
|
|
td(health.getIsNodeHealthy() ? "Healthy" : "Unhealthy").
|
|
td(Times.format(health.getLastHealthReportTime())).
|
|
td(Times.format(health.getLastHealthReportTime())).
|
|
td(String.valueOf(health.getHealthReport())).
|
|
td(String.valueOf(health.getHealthReport())).
|
|
- // TODO: acm: refactor2 FIXME
|
|
|
|
- //td(String.valueOf(ni.getNumContainers())).
|
|
|
|
- // TODO: FIXME Vinodkv
|
|
|
|
-// td(String.valueOf(ni.getUsedResource().getMemory())).
|
|
|
|
-// td(String.valueOf(ni.getAvailableResource().getMemory())).
|
|
|
|
- td("n/a")._();
|
|
|
|
|
|
+ td(String.valueOf(numContainers)).
|
|
|
|
+ td().br().$title(String.valueOf(usedMemory))._().
|
|
|
|
+ _(StringUtils.byteDesc(usedMemory * BYTES_IN_MB))._().
|
|
|
|
+ td().br().$title(String.valueOf(usedMemory))._().
|
|
|
|
+ _(StringUtils.byteDesc(availableMemory * BYTES_IN_MB))._().
|
|
|
|
+ _();
|
|
}
|
|
}
|
|
tbody._()._();
|
|
tbody._()._();
|
|
}
|
|
}
|
|
@@ -84,7 +121,12 @@ class NodesPage extends RmView {
|
|
|
|
|
|
@Override protected void preHead(Page.HTML<_> html) {
|
|
@Override protected void preHead(Page.HTML<_> html) {
|
|
commonPreHead(html);
|
|
commonPreHead(html);
|
|
- setTitle("Nodes of the cluster");
|
|
|
|
|
|
+ String type = $(NODE_STATE);
|
|
|
|
+ String title = "Nodes of the cluster";
|
|
|
|
+ if(type != null && !type.isEmpty()) {
|
|
|
|
+ title = title+" ("+type+")";
|
|
|
|
+ }
|
|
|
|
+ setTitle(title);
|
|
set(DATATABLES_ID, "nodes");
|
|
set(DATATABLES_ID, "nodes");
|
|
set(initID(DATATABLES, "nodes"), nodesTableInit());
|
|
set(initID(DATATABLES, "nodes"), nodesTableInit());
|
|
setTableStyles(html, "nodes", ".healthStatus {width:10em}",
|
|
setTableStyles(html, "nodes", ".healthStatus {width:10em}",
|
|
@@ -96,11 +138,10 @@ class NodesPage extends RmView {
|
|
}
|
|
}
|
|
|
|
|
|
private String nodesTableInit() {
|
|
private String nodesTableInit() {
|
|
- return tableInit().
|
|
|
|
- // rack, nodeid, host, healthStatus, health update ts, health report,
|
|
|
|
- // containers, memused, memavail
|
|
|
|
- append(", aoColumns:[null, null, null, null, null, null, ").
|
|
|
|
- append("{sType:'title-numeric', bSearchable:false}]}").
|
|
|
|
- toString();
|
|
|
|
|
|
+ StringBuilder b = tableInit().append(",aoColumnDefs:[");
|
|
|
|
+ b.append("{'bSearchable':false, 'aTargets': [7]} ,");
|
|
|
|
+ b.append("{'sType':'title-numeric', 'bSearchable':false, " +
|
|
|
|
+ "'aTargets': [ 8, 9] }]}");
|
|
|
|
+ return b.toString();
|
|
}
|
|
}
|
|
}
|
|
}
|