YARN-3379. Fixed missing data in localityTable and ResourceRequests table in RM WebUI. Contributed by Xuan Gong
This commit is contained in:
parent
e37ca221bf
commit
4e886eb9cb
|
@ -796,6 +796,9 @@ Release 2.7.0 - UNRELEASED
|
||||||
YARN-3349. Treat all exceptions as failure in
|
YARN-3349. Treat all exceptions as failure in
|
||||||
TestFSRMStateStore#testFSRMStateStoreClientRetry. (Zhihai Xu via ozawa)
|
TestFSRMStateStore#testFSRMStateStoreClientRetry. (Zhihai Xu via ozawa)
|
||||||
|
|
||||||
|
YARN-3379. Fixed missing data in localityTable and ResourceRequests table
|
||||||
|
in RM WebUI. (Xuan Gong via jianhe)
|
||||||
|
|
||||||
Release 2.6.0 - 2014-11-18
|
Release 2.6.0 - 2014-11-18
|
||||||
|
|
||||||
INCOMPATIBLE CHANGES
|
INCOMPATIBLE CHANGES
|
||||||
|
|
|
@ -19,12 +19,6 @@ package org.apache.hadoop.yarn.server.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.webapp.YarnWebParams.APPLICATION_ATTEMPT_ID;
|
import static org.apache.hadoop.yarn.webapp.YarnWebParams.APPLICATION_ATTEMPT_ID;
|
||||||
import static org.apache.hadoop.yarn.webapp.YarnWebParams.WEB_UI_TYPE;
|
|
||||||
import static org.apache.hadoop.yarn.webapp.view.JQueryUI._EVEN;
|
|
||||||
import static org.apache.hadoop.yarn.webapp.view.JQueryUI._INFO_WRAP;
|
|
||||||
import static org.apache.hadoop.yarn.webapp.view.JQueryUI._ODD;
|
|
||||||
import static org.apache.hadoop.yarn.webapp.view.JQueryUI._TH;
|
|
||||||
|
|
||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
@ -43,20 +37,18 @@ import org.apache.hadoop.yarn.api.records.YarnApplicationAttemptState;
|
||||||
import org.apache.hadoop.yarn.server.webapp.dao.AppAttemptInfo;
|
import org.apache.hadoop.yarn.server.webapp.dao.AppAttemptInfo;
|
||||||
import org.apache.hadoop.yarn.server.webapp.dao.ContainerInfo;
|
import org.apache.hadoop.yarn.server.webapp.dao.ContainerInfo;
|
||||||
import org.apache.hadoop.yarn.util.ConverterUtils;
|
import org.apache.hadoop.yarn.util.ConverterUtils;
|
||||||
import org.apache.hadoop.yarn.webapp.YarnWebParams;
|
|
||||||
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
|
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.TABLE;
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TABLE;
|
||||||
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TBODY;
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TBODY;
|
||||||
import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
|
import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
|
||||||
import org.apache.hadoop.yarn.webapp.view.InfoBlock;
|
import org.apache.hadoop.yarn.webapp.view.InfoBlock;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
public class AppAttemptBlock extends HtmlBlock {
|
public class AppAttemptBlock extends HtmlBlock {
|
||||||
|
|
||||||
private static final Log LOG = LogFactory.getLog(AppAttemptBlock.class);
|
private static final Log LOG = LogFactory.getLog(AppAttemptBlock.class);
|
||||||
protected ApplicationBaseProtocol appBaseProt;
|
protected ApplicationBaseProtocol appBaseProt;
|
||||||
|
protected ApplicationAttemptId appAttemptId = null;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public AppAttemptBlock(ApplicationBaseProtocol appBaseProt, ViewContext ctx) {
|
public AppAttemptBlock(ApplicationBaseProtocol appBaseProt, ViewContext ctx) {
|
||||||
|
@ -66,14 +58,12 @@ public class AppAttemptBlock extends HtmlBlock {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void render(Block html) {
|
protected void render(Block html) {
|
||||||
String webUiType = $(WEB_UI_TYPE);
|
|
||||||
String attemptid = $(APPLICATION_ATTEMPT_ID);
|
String attemptid = $(APPLICATION_ATTEMPT_ID);
|
||||||
if (attemptid.isEmpty()) {
|
if (attemptid.isEmpty()) {
|
||||||
puts("Bad request: requires application attempt ID");
|
puts("Bad request: requires application attempt ID");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplicationAttemptId appAttemptId = null;
|
|
||||||
try {
|
try {
|
||||||
appAttemptId = ConverterUtils.toApplicationAttemptId(attemptid);
|
appAttemptId = ConverterUtils.toApplicationAttemptId(attemptid);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
|
@ -183,17 +173,7 @@ public class AppAttemptBlock extends HtmlBlock {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO need to render applicationHeadRoom value from
|
createAttemptHeadRoomTable(html);
|
||||||
// ApplicationAttemptMetrics after YARN-3284
|
|
||||||
if (webUiType.equals(YarnWebParams.RM_WEB_UI)) {
|
|
||||||
if (!isApplicationInFinalState(appAttempt.getAppAttemptState())) {
|
|
||||||
DIV<Hamlet> pdiv = html._(InfoBlock.class).div(_INFO_WRAP);
|
|
||||||
info("Application Attempt Overview").clear();
|
|
||||||
info("Application Attempt Metrics")._(
|
|
||||||
"Application Attempt Headroom : ", 0);
|
|
||||||
pdiv._();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
html._(InfoBlock.class);
|
html._(InfoBlock.class);
|
||||||
|
|
||||||
// Container Table
|
// Container Table
|
||||||
|
@ -236,45 +216,6 @@ public class AppAttemptBlock extends HtmlBlock {
|
||||||
._("var containersTableData=" + containersTableData)._();
|
._("var containersTableData=" + containersTableData)._();
|
||||||
|
|
||||||
tbody._()._();
|
tbody._()._();
|
||||||
|
|
||||||
if (webUiType.equals(YarnWebParams.RM_WEB_UI)) {
|
|
||||||
createContainerLocalityTable(html); // TODO:YARN-3284
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: YARN-3284
|
|
||||||
//The containerLocality metrics will be exposed from AttemptReport
|
|
||||||
private void createContainerLocalityTable(Block html) {
|
|
||||||
int totalAllocatedContainers = 0; //TODO: YARN-3284
|
|
||||||
int[][] localityStatistics = new int[0][0];//TODO:YARN-3284
|
|
||||||
DIV<Hamlet> div = html.div(_INFO_WRAP);
|
|
||||||
TABLE<DIV<Hamlet>> table =
|
|
||||||
div.h3(
|
|
||||||
"Total Allocated Containers: "
|
|
||||||
+ totalAllocatedContainers).h3("Each table cell"
|
|
||||||
+ " represents the number of NodeLocal/RackLocal/OffSwitch containers"
|
|
||||||
+ " satisfied by NodeLocal/RackLocal/OffSwitch resource requests.").table(
|
|
||||||
"#containerLocality");
|
|
||||||
table.
|
|
||||||
tr().
|
|
||||||
th(_TH, "").
|
|
||||||
th(_TH, "Node Local Request").
|
|
||||||
th(_TH, "Rack Local Request").
|
|
||||||
th(_TH, "Off Switch Request").
|
|
||||||
_();
|
|
||||||
|
|
||||||
String[] containersType =
|
|
||||||
{ "Num Node Local Containers (satisfied by)", "Num Rack Local Containers (satisfied by)",
|
|
||||||
"Num Off Switch Containers (satisfied by)" };
|
|
||||||
boolean odd = false;
|
|
||||||
for (int i = 0; i < localityStatistics.length; i++) {
|
|
||||||
table.tr((odd = !odd) ? _ODD : _EVEN).td(containersType[i])
|
|
||||||
.td(String.valueOf(localityStatistics[i][0]))
|
|
||||||
.td(i == 0 ? "" : String.valueOf(localityStatistics[i][1]))
|
|
||||||
.td(i <= 1 ? "" : String.valueOf(localityStatistics[i][2]))._();
|
|
||||||
}
|
|
||||||
table._();
|
|
||||||
div._();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasAMContainer(ContainerId containerId,
|
private boolean hasAMContainer(ContainerId containerId,
|
||||||
|
@ -286,10 +227,8 @@ public class AppAttemptBlock extends HtmlBlock {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isApplicationInFinalState(YarnApplicationAttemptState state) {
|
protected void createAttemptHeadRoomTable(Block html) {
|
||||||
return state == YarnApplicationAttemptState.FINISHED
|
|
||||||
|| state == YarnApplicationAttemptState.FAILED
|
|
||||||
|| state == YarnApplicationAttemptState.KILLED;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,8 @@ package org.apache.hadoop.yarn.server.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.webapp.YarnWebParams.APPLICATION_ID;
|
import static org.apache.hadoop.yarn.webapp.YarnWebParams.APPLICATION_ID;
|
||||||
import static org.apache.hadoop.yarn.webapp.YarnWebParams.WEB_UI_TYPE;
|
import static org.apache.hadoop.yarn.webapp.YarnWebParams.WEB_UI_TYPE;
|
||||||
import static org.apache.hadoop.yarn.webapp.view.JQueryUI._INFO_WRAP;
|
|
||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.StringEscapeUtils;
|
import org.apache.commons.lang.StringEscapeUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
@ -39,12 +36,9 @@ import org.apache.hadoop.yarn.api.protocolrecords.GetContainerReportRequest;
|
||||||
import org.apache.hadoop.yarn.api.records.ApplicationAttemptReport;
|
import org.apache.hadoop.yarn.api.records.ApplicationAttemptReport;
|
||||||
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
||||||
import org.apache.hadoop.yarn.api.records.ApplicationReport;
|
import org.apache.hadoop.yarn.api.records.ApplicationReport;
|
||||||
import org.apache.hadoop.yarn.api.records.ApplicationResourceUsageReport;
|
|
||||||
import org.apache.hadoop.yarn.api.records.ContainerId;
|
import org.apache.hadoop.yarn.api.records.ContainerId;
|
||||||
import org.apache.hadoop.yarn.api.records.ContainerReport;
|
import org.apache.hadoop.yarn.api.records.ContainerReport;
|
||||||
import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
|
import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
|
||||||
import org.apache.hadoop.yarn.api.records.Resource;
|
|
||||||
import org.apache.hadoop.yarn.api.records.ResourceRequest;
|
|
||||||
import org.apache.hadoop.yarn.api.records.YarnApplicationState;
|
import org.apache.hadoop.yarn.api.records.YarnApplicationState;
|
||||||
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
||||||
import org.apache.hadoop.yarn.exceptions.ContainerNotFoundException;
|
import org.apache.hadoop.yarn.exceptions.ContainerNotFoundException;
|
||||||
|
@ -53,10 +47,8 @@ import org.apache.hadoop.yarn.server.webapp.dao.AppInfo;
|
||||||
import org.apache.hadoop.yarn.server.webapp.dao.ContainerInfo;
|
import org.apache.hadoop.yarn.server.webapp.dao.ContainerInfo;
|
||||||
import org.apache.hadoop.yarn.util.Apps;
|
import org.apache.hadoop.yarn.util.Apps;
|
||||||
import org.apache.hadoop.yarn.util.Times;
|
import org.apache.hadoop.yarn.util.Times;
|
||||||
import org.apache.hadoop.yarn.util.resource.Resources;
|
|
||||||
import org.apache.hadoop.yarn.webapp.YarnWebParams;
|
import org.apache.hadoop.yarn.webapp.YarnWebParams;
|
||||||
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
|
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.TABLE;
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TABLE;
|
||||||
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TBODY;
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TBODY;
|
||||||
import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
|
import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
|
||||||
|
@ -69,9 +61,11 @@ public class AppBlock extends HtmlBlock {
|
||||||
private static final Log LOG = LogFactory.getLog(AppBlock.class);
|
private static final Log LOG = LogFactory.getLog(AppBlock.class);
|
||||||
protected ApplicationBaseProtocol appBaseProt;
|
protected ApplicationBaseProtocol appBaseProt;
|
||||||
protected Configuration conf;
|
protected Configuration conf;
|
||||||
|
protected ApplicationId appID = null;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
AppBlock(ApplicationBaseProtocol appBaseProt, ViewContext ctx, Configuration conf) {
|
protected AppBlock(ApplicationBaseProtocol appBaseProt, ViewContext ctx,
|
||||||
|
Configuration conf) {
|
||||||
super(ctx);
|
super(ctx);
|
||||||
this.appBaseProt = appBaseProt;
|
this.appBaseProt = appBaseProt;
|
||||||
this.conf = conf;
|
this.conf = conf;
|
||||||
|
@ -86,7 +80,6 @@ public class AppBlock extends HtmlBlock {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplicationId appID = null;
|
|
||||||
try {
|
try {
|
||||||
appID = Apps.toAppID(aid);
|
appID = Apps.toAppID(aid);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -213,31 +206,7 @@ public class AppBlock extends HtmlBlock {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO:YARN-3284
|
createApplicationMetricsTable(html);
|
||||||
//The preemption metrics will be exposed from ApplicationReport
|
|
||||||
// and ApplicationAttemptReport
|
|
||||||
ApplicationResourceUsageReport usageReport =
|
|
||||||
appReport.getApplicationResourceUsageReport();
|
|
||||||
DIV<Hamlet> pdiv = html.
|
|
||||||
_(InfoBlock.class).
|
|
||||||
div(_INFO_WRAP);
|
|
||||||
info("Application Overview").clear();
|
|
||||||
info("Application Metrics")
|
|
||||||
._("Total Resource Preempted:",
|
|
||||||
Resources.none()) // TODO: YARN-3284
|
|
||||||
._("Total Number of Non-AM Containers Preempted:",
|
|
||||||
String.valueOf(0)) // TODO: YARN-3284
|
|
||||||
._("Total Number of AM Containers Preempted:",
|
|
||||||
String.valueOf(0)) // TODO: YARN-3284
|
|
||||||
._("Resource Preempted from Current Attempt:",
|
|
||||||
Resources.none()) // TODO: YARN-3284
|
|
||||||
._("Number of Non-AM Containers Preempted from Current Attempt:",
|
|
||||||
0) // TODO: YARN-3284
|
|
||||||
._("Aggregate Resource Allocation:",
|
|
||||||
String.format("%d MB-seconds, %d vcore-seconds", usageReport == null
|
|
||||||
? 0 : usageReport.getMemorySeconds(), usageReport == null ? 0
|
|
||||||
: usageReport.getVcoreSeconds()));
|
|
||||||
pdiv._();
|
|
||||||
|
|
||||||
html._(InfoBlock.class);
|
html._(InfoBlock.class);
|
||||||
|
|
||||||
|
@ -319,49 +288,6 @@ public class AppBlock extends HtmlBlock {
|
||||||
._("var attemptsTableData=" + attemptsTableData)._();
|
._("var attemptsTableData=" + attemptsTableData)._();
|
||||||
|
|
||||||
tbody._()._();
|
tbody._()._();
|
||||||
|
|
||||||
if (webUiType != null && webUiType.equals(YarnWebParams.RM_WEB_UI)) {
|
|
||||||
createResourceRequestsTable(html, null); // TODO:YARN-3284
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO:YARN-3284
|
|
||||||
//The resource requests metrics will be exposed from attemptReport
|
|
||||||
private void createResourceRequestsTable(Block html, List<ResourceRequest> resouceRequests) {
|
|
||||||
TBODY<TABLE<Hamlet>> tbody =
|
|
||||||
html.table("#ResourceRequests").thead().tr()
|
|
||||||
.th(".priority", "Priority")
|
|
||||||
.th(".resourceName", "ResourceName")
|
|
||||||
.th(".totalResource", "Capability")
|
|
||||||
.th(".numContainers", "NumContainers")
|
|
||||||
.th(".relaxLocality", "RelaxLocality")
|
|
||||||
.th(".nodeLabelExpression", "NodeLabelExpression")._()._().tbody();
|
|
||||||
|
|
||||||
Resource totalResource = Resource.newInstance(0, 0);
|
|
||||||
if (resouceRequests != null) {
|
|
||||||
for (ResourceRequest request : resouceRequests) {
|
|
||||||
if (request.getNumContainers() == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
tbody.tr()
|
|
||||||
.td(String.valueOf(request.getPriority()))
|
|
||||||
.td(request.getResourceName())
|
|
||||||
.td(String.valueOf(request.getCapability()))
|
|
||||||
.td(String.valueOf(request.getNumContainers()))
|
|
||||||
.td(String.valueOf(request.getRelaxLocality()))
|
|
||||||
.td(request.getNodeLabelExpression() == null ? "N/A" : request
|
|
||||||
.getNodeLabelExpression())._();
|
|
||||||
if (request.getResourceName().equals(ResourceRequest.ANY)) {
|
|
||||||
Resources.addTo(totalResource,
|
|
||||||
Resources.multiply(request.getCapability(),
|
|
||||||
request.getNumContainers()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
html.div().$class("totalResourceRequests")
|
|
||||||
.h3("Total Outstanding Resource Requests: " + totalResource)._();
|
|
||||||
tbody._()._();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String clarifyAppState(YarnApplicationState state) {
|
private String clarifyAppState(YarnApplicationState state) {
|
||||||
|
@ -389,4 +315,9 @@ public class AppBlock extends HtmlBlock {
|
||||||
}
|
}
|
||||||
return status.toString();
|
return status.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The preemption metrics only need to be shown in RM WebUI
|
||||||
|
protected void createApplicationMetricsTable(Block html) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ 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 org.apache.hadoop.yarn.server.webapp.AppAttemptBlock;
|
|
||||||
import org.apache.hadoop.yarn.server.webapp.WebPageUtils;
|
import org.apache.hadoop.yarn.server.webapp.WebPageUtils;
|
||||||
import org.apache.hadoop.yarn.webapp.SubView;
|
import org.apache.hadoop.yarn.webapp.SubView;
|
||||||
import org.apache.hadoop.yarn.webapp.YarnWebParams;
|
import org.apache.hadoop.yarn.webapp.YarnWebParams;
|
||||||
|
@ -51,7 +50,7 @@ public class AppAttemptPage extends RmView {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<? extends SubView> content() {
|
protected Class<? extends SubView> content() {
|
||||||
return AppAttemptBlock.class;
|
return RMAppAttemptBlock.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -23,7 +23,6 @@ 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 org.apache.hadoop.yarn.server.webapp.AppBlock;
|
|
||||||
import org.apache.hadoop.yarn.server.webapp.WebPageUtils;
|
import org.apache.hadoop.yarn.server.webapp.WebPageUtils;
|
||||||
import org.apache.hadoop.yarn.webapp.SubView;
|
import org.apache.hadoop.yarn.webapp.SubView;
|
||||||
import org.apache.hadoop.yarn.webapp.YarnWebParams;
|
import org.apache.hadoop.yarn.webapp.YarnWebParams;
|
||||||
|
@ -50,6 +49,6 @@ public class AppPage extends RmView {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<? extends SubView> content() {
|
protected Class<? extends SubView> content() {
|
||||||
return AppBlock.class;
|
return RMAppBlock.class;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
||||||
|
|
||||||
|
import static org.apache.hadoop.yarn.webapp.view.JQueryUI._EVEN;
|
||||||
|
import static org.apache.hadoop.yarn.webapp.view.JQueryUI._INFO_WRAP;
|
||||||
|
import static org.apache.hadoop.yarn.webapp.view.JQueryUI._ODD;
|
||||||
|
import static org.apache.hadoop.yarn.webapp.view.JQueryUI._TH;
|
||||||
|
|
||||||
|
import org.apache.hadoop.conf.Configuration;
|
||||||
|
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
||||||
|
import org.apache.hadoop.yarn.api.records.Resource;
|
||||||
|
import org.apache.hadoop.yarn.api.records.ResourceRequest;
|
||||||
|
import org.apache.hadoop.yarn.api.records.YarnApplicationAttemptState;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttempt;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttemptMetrics;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppInfo;
|
||||||
|
import org.apache.hadoop.yarn.server.webapp.AppAttemptBlock;
|
||||||
|
import org.apache.hadoop.yarn.util.resource.Resources;
|
||||||
|
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.TABLE;
|
||||||
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TBODY;
|
||||||
|
import org.apache.hadoop.yarn.webapp.util.WebAppUtils;
|
||||||
|
import org.apache.hadoop.yarn.webapp.view.InfoBlock;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
public class RMAppAttemptBlock extends AppAttemptBlock{
|
||||||
|
|
||||||
|
private final ResourceManager rm;
|
||||||
|
protected Configuration conf;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
RMAppAttemptBlock(ViewContext ctx, ResourceManager rm, Configuration conf) {
|
||||||
|
super(rm.getClientRMService(), ctx);
|
||||||
|
this.rm = rm;
|
||||||
|
this.conf = conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void render(Block html) {
|
||||||
|
super.render(html);
|
||||||
|
createContainerLocalityTable(html);
|
||||||
|
createResourceRequestsTable(html);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createResourceRequestsTable(Block html) {
|
||||||
|
AppInfo app =
|
||||||
|
new AppInfo(rm, rm.getRMContext().getRMApps()
|
||||||
|
.get(this.appAttemptId.getApplicationId()), true,
|
||||||
|
WebAppUtils.getHttpSchemePrefix(conf));
|
||||||
|
TBODY<TABLE<Hamlet>> tbody =
|
||||||
|
html.table("#ResourceRequests").thead().tr()
|
||||||
|
.th(".priority", "Priority")
|
||||||
|
.th(".resourceName", "ResourceName")
|
||||||
|
.th(".totalResource", "Capability")
|
||||||
|
.th(".numContainers", "NumContainers")
|
||||||
|
.th(".relaxLocality", "RelaxLocality")
|
||||||
|
.th(".nodeLabelExpression", "NodeLabelExpression")._()._().tbody();
|
||||||
|
|
||||||
|
Resource totalResource = Resource.newInstance(0, 0);
|
||||||
|
if (app.getResourceRequests() != null) {
|
||||||
|
for (ResourceRequest request : app.getResourceRequests()) {
|
||||||
|
if (request.getNumContainers() == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody.tr()
|
||||||
|
.td(String.valueOf(request.getPriority()))
|
||||||
|
.td(request.getResourceName())
|
||||||
|
.td(String.valueOf(request.getCapability()))
|
||||||
|
.td(String.valueOf(request.getNumContainers()))
|
||||||
|
.td(String.valueOf(request.getRelaxLocality()))
|
||||||
|
.td(request.getNodeLabelExpression() == null ? "N/A" : request
|
||||||
|
.getNodeLabelExpression())._();
|
||||||
|
if (request.getResourceName().equals(ResourceRequest.ANY)) {
|
||||||
|
Resources.addTo(totalResource,
|
||||||
|
Resources.multiply(request.getCapability(),
|
||||||
|
request.getNumContainers()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
html.div().$class("totalResourceRequests")
|
||||||
|
.h3("Total Outstanding Resource Requests: " + totalResource)._();
|
||||||
|
tbody._()._();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createContainerLocalityTable(Block html) {
|
||||||
|
RMAppAttemptMetrics attemptMetrics = null;
|
||||||
|
RMAppAttempt attempt = getRMAppAttempt();
|
||||||
|
if (attempt != null) {
|
||||||
|
attemptMetrics = attempt.getRMAppAttemptMetrics();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attemptMetrics == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DIV<Hamlet> div = html.div(_INFO_WRAP);
|
||||||
|
TABLE<DIV<Hamlet>> table =
|
||||||
|
div.h3(
|
||||||
|
"Total Allocated Containers: "
|
||||||
|
+ attemptMetrics.getTotalAllocatedContainers()).h3("Each table cell"
|
||||||
|
+ " represents the number of NodeLocal/RackLocal/OffSwitch containers"
|
||||||
|
+ " satisfied by NodeLocal/RackLocal/OffSwitch resource requests.").table(
|
||||||
|
"#containerLocality");
|
||||||
|
table.
|
||||||
|
tr().
|
||||||
|
th(_TH, "").
|
||||||
|
th(_TH, "Node Local Request").
|
||||||
|
th(_TH, "Rack Local Request").
|
||||||
|
th(_TH, "Off Switch Request").
|
||||||
|
_();
|
||||||
|
|
||||||
|
String[] containersType =
|
||||||
|
{ "Num Node Local Containers (satisfied by)", "Num Rack Local Containers (satisfied by)",
|
||||||
|
"Num Off Switch Containers (satisfied by)" };
|
||||||
|
boolean odd = false;
|
||||||
|
for (int i = 0; i < attemptMetrics.getLocalityStatistics().length; i++) {
|
||||||
|
table.tr((odd = !odd) ? _ODD : _EVEN).td(containersType[i])
|
||||||
|
.td(String.valueOf(attemptMetrics.getLocalityStatistics()[i][0]))
|
||||||
|
.td(i == 0 ? "" : String.valueOf(attemptMetrics.getLocalityStatistics()[i][1]))
|
||||||
|
.td(i <= 1 ? "" : String.valueOf(attemptMetrics.getLocalityStatistics()[i][2]))._();
|
||||||
|
}
|
||||||
|
table._();
|
||||||
|
div._();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isApplicationInFinalState(YarnApplicationAttemptState state) {
|
||||||
|
return state == YarnApplicationAttemptState.FINISHED
|
||||||
|
|| state == YarnApplicationAttemptState.FAILED
|
||||||
|
|| state == YarnApplicationAttemptState.KILLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void createAttemptHeadRoomTable(Block html) {
|
||||||
|
RMAppAttempt attempt = getRMAppAttempt();
|
||||||
|
if (attempt != null) {
|
||||||
|
if (!isApplicationInFinalState(YarnApplicationAttemptState
|
||||||
|
.valueOf(attempt.getAppAttemptState().toString()))) {
|
||||||
|
DIV<Hamlet> pdiv = html._(InfoBlock.class).div(_INFO_WRAP);
|
||||||
|
info("Application Attempt Overview").clear();
|
||||||
|
info("Application Attempt Metrics")._(
|
||||||
|
"Application Attempt Headroom : ", 0);
|
||||||
|
pdiv._();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private RMAppAttempt getRMAppAttempt() {
|
||||||
|
ApplicationId appId = this.appAttemptId.getApplicationId();
|
||||||
|
RMAppAttempt attempt = null;
|
||||||
|
RMApp rmApp = rm.getRMContext().getRMApps().get(appId);
|
||||||
|
if (rmApp != null) {
|
||||||
|
attempt = rmApp.getAppAttempts().get(appAttemptId);
|
||||||
|
}
|
||||||
|
return attempt;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
||||||
|
|
||||||
|
import static org.apache.hadoop.yarn.webapp.view.JQueryUI._INFO_WRAP;
|
||||||
|
|
||||||
|
import org.apache.hadoop.conf.Configuration;
|
||||||
|
import org.apache.hadoop.yarn.api.records.Resource;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppMetrics;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttemptMetrics;
|
||||||
|
import org.apache.hadoop.yarn.server.webapp.AppBlock;
|
||||||
|
import org.apache.hadoop.yarn.util.resource.Resources;
|
||||||
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
|
||||||
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.DIV;
|
||||||
|
import org.apache.hadoop.yarn.webapp.view.InfoBlock;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
public class RMAppBlock extends AppBlock{
|
||||||
|
|
||||||
|
private final ResourceManager rm;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
RMAppBlock(ViewContext ctx, Configuration conf, ResourceManager rm) {
|
||||||
|
super(rm.getClientRMService(), ctx, conf);
|
||||||
|
this.rm = rm;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void render(Block html) {
|
||||||
|
super.render(html);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void createApplicationMetricsTable(Block html){
|
||||||
|
RMApp rmApp = this.rm.getRMContext().getRMApps().get(appID);
|
||||||
|
RMAppMetrics appMetrics = rmApp == null ? null : rmApp.getRMAppMetrics();
|
||||||
|
// Get attempt metrics and fields, it is possible currentAttempt of RMApp is
|
||||||
|
// null. In that case, we will assume resource preempted and number of Non
|
||||||
|
// AM container preempted on that attempt is 0
|
||||||
|
RMAppAttemptMetrics attemptMetrics;
|
||||||
|
if (rmApp == null || null == rmApp.getCurrentAppAttempt()) {
|
||||||
|
attemptMetrics = null;
|
||||||
|
} else {
|
||||||
|
attemptMetrics = rmApp.getCurrentAppAttempt().getRMAppAttemptMetrics();
|
||||||
|
}
|
||||||
|
Resource attemptResourcePreempted =
|
||||||
|
attemptMetrics == null ? Resources.none() : attemptMetrics
|
||||||
|
.getResourcePreempted();
|
||||||
|
int attemptNumNonAMContainerPreempted =
|
||||||
|
attemptMetrics == null ? 0 : attemptMetrics
|
||||||
|
.getNumNonAMContainersPreempted();
|
||||||
|
DIV<Hamlet> pdiv = html.
|
||||||
|
_(InfoBlock.class).
|
||||||
|
div(_INFO_WRAP);
|
||||||
|
info("Application Overview").clear();
|
||||||
|
info("Application Metrics")
|
||||||
|
._("Total Resource Preempted:",
|
||||||
|
appMetrics == null ? "N/A" : appMetrics.getResourcePreempted())
|
||||||
|
._("Total Number of Non-AM Containers Preempted:",
|
||||||
|
appMetrics == null ? "N/A"
|
||||||
|
: appMetrics.getNumNonAMContainersPreempted())
|
||||||
|
._("Total Number of AM Containers Preempted:",
|
||||||
|
appMetrics == null ? "N/A"
|
||||||
|
: appMetrics.getNumAMContainersPreempted())
|
||||||
|
._("Resource Preempted from Current Attempt:",
|
||||||
|
attemptResourcePreempted)
|
||||||
|
._("Number of Non-AM Containers Preempted from Current Attempt:",
|
||||||
|
attemptNumNonAMContainerPreempted)
|
||||||
|
._("Aggregate Resource Allocation:",
|
||||||
|
String.format("%d MB-seconds, %d vcore-seconds",
|
||||||
|
appMetrics == null ? "N/A" : appMetrics.getMemorySeconds(),
|
||||||
|
appMetrics == null ? "N/A" : appMetrics.getVcoreSeconds()));
|
||||||
|
pdiv._();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue