Browse Source

YARN-3379. Fixed missing data in localityTable and ResourceRequests table in RM WebUI. Contributed by Xuan Gong
(cherry picked from commit 4e886eb9cbd2dcb128bbfd17309c734083093a4c)

Jian He 10 năm trước cách đây
mục cha
commit
3f0c9e5fe3

+ 3 - 0
hadoop-yarn-project/CHANGES.txt

@@ -751,6 +751,9 @@ Release 2.7.0 - UNRELEASED
     YARN-3349. Treat all exceptions as failure in
     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
 
   INCOMPATIBLE CHANGES

+ 5 - 66
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppAttemptBlock.java

@@ -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.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.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.ContainerInfo;
 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.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.view.HtmlBlock;
 import org.apache.hadoop.yarn.webapp.view.InfoBlock;
-
 import com.google.inject.Inject;
 
 public class AppAttemptBlock extends HtmlBlock {
 
   private static final Log LOG = LogFactory.getLog(AppAttemptBlock.class);
   protected ApplicationBaseProtocol appBaseProt;
+  protected ApplicationAttemptId appAttemptId = null;
 
   @Inject
   public AppAttemptBlock(ApplicationBaseProtocol appBaseProt, ViewContext ctx) {
@@ -66,14 +58,12 @@ public class AppAttemptBlock extends HtmlBlock {
 
   @Override
   protected void render(Block html) {
-    String webUiType = $(WEB_UI_TYPE);
     String attemptid = $(APPLICATION_ATTEMPT_ID);
     if (attemptid.isEmpty()) {
       puts("Bad request: requires application attempt ID");
       return;
     }
 
-    ApplicationAttemptId appAttemptId = null;
     try {
       appAttemptId = ConverterUtils.toApplicationAttemptId(attemptid);
     } catch (IllegalArgumentException e) {
@@ -183,17 +173,7 @@ public class AppAttemptBlock extends HtmlBlock {
       return;
     }
 
-    // TODO need to render applicationHeadRoom value from
-    // 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._();
-      }
-    }
+    createAttemptHeadRoomTable(html);
     html._(InfoBlock.class);
 
     // Container Table
@@ -236,45 +216,6 @@ public class AppAttemptBlock extends HtmlBlock {
       ._("var containersTableData=" + containersTableData)._();
 
     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,
@@ -286,10 +227,8 @@ public class AppAttemptBlock extends HtmlBlock {
     }
     return false;
   }
-  
-  private boolean isApplicationInFinalState(YarnApplicationAttemptState state) {
-    return state == YarnApplicationAttemptState.FINISHED
-        || state == YarnApplicationAttemptState.FAILED
-        || state == YarnApplicationAttemptState.KILLED;
+
+  protected void createAttemptHeadRoomTable(Block html) {
+    
   }
 }

+ 9 - 78
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppBlock.java

@@ -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.webapp.YarnWebParams.APPLICATION_ID;
 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.util.Collection;
-import java.util.List;
-
 import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.commons.logging.Log;
 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.ApplicationId;
 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.ContainerReport;
 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.conf.YarnConfiguration;
 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.util.Apps;
 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.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.view.HtmlBlock;
@@ -69,9 +61,11 @@ public class AppBlock extends HtmlBlock {
   private static final Log LOG = LogFactory.getLog(AppBlock.class);
   protected ApplicationBaseProtocol appBaseProt;
   protected Configuration conf;
+  protected ApplicationId appID = null;
 
   @Inject
-  AppBlock(ApplicationBaseProtocol appBaseProt, ViewContext ctx, Configuration conf) {
+  protected AppBlock(ApplicationBaseProtocol appBaseProt, ViewContext ctx,
+      Configuration conf) {
     super(ctx);
     this.appBaseProt = appBaseProt;
     this.conf = conf;
@@ -86,7 +80,6 @@ public class AppBlock extends HtmlBlock {
       return;
     }
 
-    ApplicationId appID = null;
     try {
       appID = Apps.toAppID(aid);
     } catch (Exception e) {
@@ -213,31 +206,7 @@ public class AppBlock extends HtmlBlock {
       return;
     }
 
-    //TODO:YARN-3284
-    //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._();
+    createApplicationMetricsTable(html);
 
     html._(InfoBlock.class);
 
@@ -319,49 +288,6 @@ public class AppBlock extends HtmlBlock {
       ._("var attemptsTableData=" + attemptsTableData)._();
 
     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) {
@@ -389,4 +315,9 @@ public class AppBlock extends HtmlBlock {
     }
     return status.toString();
   }
+
+  // The preemption metrics only need to be shown in RM WebUI
+  protected void createApplicationMetricsTable(Block html) {
+
+  }
 }

+ 1 - 2
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/AppAttemptPage.java

@@ -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.initID;
 
-import org.apache.hadoop.yarn.server.webapp.AppAttemptBlock;
 import org.apache.hadoop.yarn.server.webapp.WebPageUtils;
 import org.apache.hadoop.yarn.webapp.SubView;
 import org.apache.hadoop.yarn.webapp.YarnWebParams;
@@ -51,7 +50,7 @@ public class AppAttemptPage extends RmView {
 
   @Override
   protected Class<? extends SubView> content() {
-    return AppAttemptBlock.class;
+    return RMAppAttemptBlock.class;
   }
 
 }

+ 1 - 2
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/AppPage.java

@@ -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.initID;
 
-import org.apache.hadoop.yarn.server.webapp.AppBlock;
 import org.apache.hadoop.yarn.server.webapp.WebPageUtils;
 import org.apache.hadoop.yarn.webapp.SubView;
 import org.apache.hadoop.yarn.webapp.YarnWebParams;
@@ -50,6 +49,6 @@ public class AppPage extends RmView {
 
   @Override 
   protected Class<? extends SubView> content() {
-    return AppBlock.class;
+    return RMAppBlock.class;
   }
 }

+ 177 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMAppAttemptBlock.java

@@ -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;
+  }
+}

+ 94 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMAppBlock.java

@@ -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._();
+  }
+}