浏览代码

YARN-1884. Added nodeHttpAddress into ContainerReport and fixed the link to NM web page. Contributed by Xuan Gong.

(cherry picked from commit 85f6d67fa78511f255fcfa810afc9a156a7b483b)
(cherry picked from commit 426535007bcdc67331f7a37b5d69cc20b37c26e0)
Zhijie Shen 10 年之前
父节点
当前提交
f4154bdee8
共有 21 个文件被更改,包括 142 次插入34 次删除
  1. 3 0
      hadoop-yarn-project/CHANGES.txt
  2. 16 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ContainerReport.java
  3. 1 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto
  4. 8 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/ApplicationCLI.java
  5. 2 2
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/ProtocolHATestBase.java
  6. 4 2
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestAHSClient.java
  7. 5 2
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java
  8. 14 4
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java
  9. 19 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/ContainerReportPBImpl.java
  10. 1 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/ApplicationHistoryManagerImpl.java
  11. 9 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/ApplicationHistoryManagerOnTimelineStore.java
  12. 2 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/metrics/ContainerMetricsConstants.java
  13. 7 5
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppAttemptBlock.java
  14. 4 7
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppBlock.java
  15. 6 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/ContainerBlock.java
  16. 5 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/dao/ContainerInfo.java
  17. 7 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/ContainerCreatedEvent.java
  18. 4 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/SystemMetricsPublisher.java
  19. 1 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmcontainer/RMContainer.java
  20. 20 2
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmcontainer/RMContainerImpl.java
  21. 4 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/TestSystemMetricsPublisher.java

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

@@ -205,6 +205,9 @@ Release 2.6.1 - 2015-09-09
     YARN-4047. ClientRMService getApplications has high scheduler lock contention.
     (Jason Lowe via jianhe)
 
+    YARN-1884. Added nodeHttpAddress into ContainerReport and fixed the link to NM
+    web page. (Xuan Gong via zjshen)
+
 Release 2.6.0 - 2014-11-18
 
   INCOMPATIBLE CHANGES

+ 16 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ContainerReport.java

@@ -41,6 +41,7 @@ import org.apache.hadoop.yarn.util.Records;
  * <li>{@link ContainerState} of the container.</li>
  * <li>Diagnostic information in case of errors.</li>
  * <li>Log URL.</li>
+ * <li>nodeHttpAddress</li>
  * </ul>
  * </p>
  * 
@@ -54,7 +55,8 @@ public abstract class ContainerReport {
   public static ContainerReport newInstance(ContainerId containerId,
       Resource allocatedResource, NodeId assignedNode, Priority priority,
       long creationTime, long finishTime, String diagnosticInfo, String logUrl,
-      int containerExitStatus, ContainerState containerState) {
+      int containerExitStatus, ContainerState containerState,
+      String nodeHttpAddress) {
     ContainerReport report = Records.newRecord(ContainerReport.class);
     report.setContainerId(containerId);
     report.setAllocatedResource(allocatedResource);
@@ -66,6 +68,7 @@ public abstract class ContainerReport {
     report.setLogUrl(logUrl);
     report.setContainerExitStatus(containerExitStatus);
     report.setContainerState(containerState);
+    report.setNodeHttpAddress(nodeHttpAddress);
     return report;
   }
 
@@ -199,4 +202,16 @@ public abstract class ContainerReport {
   @Unstable
   public abstract void setContainerExitStatus(int containerExitStatus);
 
+  /**
+   * Get the Node Http address of the container
+   * 
+   * @return the node http address of the container
+   */
+  @Public
+  @Unstable
+  public abstract String getNodeHttpAddress();
+
+  @Private
+  @Unstable
+  public abstract void setNodeHttpAddress(String nodeHttpAddress);
 }

+ 1 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto

@@ -98,6 +98,7 @@ message ContainerReportProto {
   optional string log_url = 8;
   optional int32 container_exit_status = 9;
   optional ContainerStateProto container_state = 10;
+  optional string node_http_address = 11;
 }
 
 enum YarnApplicationStateProto {

+ 8 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/ApplicationCLI.java

@@ -58,7 +58,7 @@ public class ApplicationCLI extends YarnCLI {
     "%30s\t%20s\t%35s\t%35s"
       + System.getProperty("line.separator");
   private static final String CONTAINER_PATTERN = 
-    "%30s\t%20s\t%20s\t%20s\t%20s\t%35s"
+    "%30s\t%20s\t%20s\t%20s\t%20s\t%20s\t%35s"
       + System.getProperty("line.separator");
 
   private static final String APP_TYPE_CMD = "appTypes";
@@ -315,6 +315,9 @@ public class ApplicationCLI extends YarnCLI {
       containerReportStr.println(containerReport.getLogUrl());
       containerReportStr.print("\tHost : ");
       containerReportStr.println(containerReport.getAssignedNode());
+      containerReportStr.print("\tNodeHttpAddress : ");
+      containerReportStr.println(containerReport.getNodeHttpAddress() == null
+          ? "N/A" : containerReport.getNodeHttpAddress());
       containerReportStr.print("\tDiagnostics : ");
       containerReportStr.print(containerReport.getDiagnosticsInfo());
     } else {
@@ -535,7 +538,7 @@ public class ApplicationCLI extends YarnCLI {
         .getContainers(ConverterUtils.toApplicationAttemptId(appAttemptId));
     writer.println("Total number of containers " + ":" + appsReport.size());
     writer.printf(CONTAINER_PATTERN, "Container-Id", "Start Time",
-        "Finish Time", "State", "Host", "LOG-URL");
+        "Finish Time", "State", "Host", "Node Http Address", "LOG-URL");
     for (ContainerReport containerReport : appsReport) {
       writer.printf(
           CONTAINER_PATTERN,
@@ -543,7 +546,9 @@ public class ApplicationCLI extends YarnCLI {
           Times.format(containerReport.getCreationTime()),
           Times.format(containerReport.getFinishTime()),      
           containerReport.getContainerState(), containerReport
-              .getAssignedNode(), containerReport.getLogUrl());
+              .getAssignedNode(), containerReport.getNodeHttpAddress() == null
+                  ? "N/A" : containerReport.getNodeHttpAddress(),
+          containerReport.getLogUrl());
     }
     writer.flush();
   }

+ 2 - 2
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/ProtocolHATestBase.java

@@ -77,7 +77,6 @@ import org.apache.hadoop.yarn.api.protocolrecords.RenewDelegationTokenRequest;
 import org.apache.hadoop.yarn.api.protocolrecords.RenewDelegationTokenResponse;
 import org.apache.hadoop.yarn.api.protocolrecords.SubmitApplicationRequest;
 import org.apache.hadoop.yarn.api.protocolrecords.SubmitApplicationResponse;
-import org.apache.hadoop.yarn.api.records.AMCommand;
 import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
 import org.apache.hadoop.yarn.api.records.ApplicationAttemptReport;
 import org.apache.hadoop.yarn.api.records.ApplicationId;
@@ -715,7 +714,8 @@ public abstract class ProtocolHATestBase extends ClientBaseWithFixes {
     public ContainerReport createFakeContainerReport() {
       return ContainerReport.newInstance(createFakeContainerId(), null,
           NodeId.newInstance("localhost", 0), null, 1000l, 1200l, "", "", 0,
-          ContainerState.COMPLETE);
+          ContainerState.COMPLETE,
+          "http://" + NodeId.newInstance("localhost", 0).toString());
     }
 
     public List<ContainerReport> createFakeContainerReports() {

+ 4 - 2
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestAHSClient.java

@@ -371,14 +371,16 @@ public class TestAHSClient {
           ContainerReport.newInstance(
             ContainerId.newContainerId(attempt.getApplicationAttemptId(), 1),
             null, NodeId.newInstance("host", 1234), Priority.UNDEFINED, 1234,
-            5678, "diagnosticInfo", "logURL", 0, ContainerState.COMPLETE);
+            5678, "diagnosticInfo", "logURL", 0, ContainerState.COMPLETE,
+            "http://" + NodeId.newInstance("host", 2345).toString());
       containerReports.add(container);
 
       ContainerReport container1 =
           ContainerReport.newInstance(
             ContainerId.newContainerId(attempt.getApplicationAttemptId(), 2),
             null, NodeId.newInstance("host", 1234), Priority.UNDEFINED, 1234,
-            5678, "diagnosticInfo", "logURL", 0, ContainerState.COMPLETE);
+            5678, "diagnosticInfo", "logURL", 0, ContainerState.COMPLETE,
+            "http://" + NodeId.newInstance("host", 2345).toString());
       containerReports.add(container1);
       containers.put(attempt.getApplicationAttemptId(), containerReports);
 

+ 5 - 2
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java

@@ -501,13 +501,16 @@ public class TestYarnClient {
       ContainerReport container = ContainerReport.newInstance(
           ContainerId.newContainerId(attempt.getApplicationAttemptId(), 1), null,
           NodeId.newInstance("host", 1234), Priority.UNDEFINED, 1234, 5678,
-          "diagnosticInfo", "logURL", 0, ContainerState.COMPLETE);
+          "diagnosticInfo", "logURL", 0, ContainerState.COMPLETE,
+          "http://" + NodeId.newInstance("host", 2345).toString());
       containerReports.add(container);
 
       ContainerReport container1 = ContainerReport.newInstance(
           ContainerId.newContainerId(attempt.getApplicationAttemptId(), 2), null,
           NodeId.newInstance("host", 1234), Priority.UNDEFINED, 1234, 5678,
-          "diagnosticInfo", "logURL", 0, ContainerState.COMPLETE);
+          "diagnosticInfo", "logURL", 0, ContainerState.COMPLETE,
+          "http://" + NodeId.newInstance("host", 2345).toString());
+
       containerReports.add(container1);
       containers.put(attempt.getApplicationAttemptId(), containerReports);
 

+ 14 - 4
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java

@@ -223,7 +223,8 @@ public class TestYarnCLI {
     ContainerId containerId = ContainerId.newContainerId(attemptId, 1);
     ContainerReport container = ContainerReport.newInstance(containerId, null,
         NodeId.newInstance("host", 1234), Priority.UNDEFINED, 1234, 5678,
-        "diagnosticInfo", "logURL", 0, ContainerState.COMPLETE);
+        "diagnosticInfo", "logURL", 0, ContainerState.COMPLETE,
+        "http://" + NodeId.newInstance("host", 2345).toString());
     when(client.getContainerReport(any(ContainerId.class))).thenReturn(
         container);
     int result = cli.run(new String[] { "container", "-status",
@@ -239,6 +240,7 @@ public class TestYarnCLI {
     pw.println("\tState : COMPLETE");
     pw.println("\tLOG-URL : logURL");
     pw.println("\tHost : host:1234");
+    pw.println("\tNodeHttpAddress : http://host:2345");
     pw.println("\tDiagnostics : diagnosticInfo");
     pw.close();
     String appReportStr = baos.toString("UTF-8");
@@ -258,19 +260,23 @@ public class TestYarnCLI {
     long time1=1234,time2=5678;
     ContainerReport container = ContainerReport.newInstance(containerId, null,
         NodeId.newInstance("host", 1234), Priority.UNDEFINED, time1, time2,
-        "diagnosticInfo", "logURL", 0, ContainerState.COMPLETE);
+        "diagnosticInfo", "logURL", 0, ContainerState.COMPLETE,
+        "http://" + NodeId.newInstance("host", 2345).toString());
     ContainerReport container1 = ContainerReport.newInstance(containerId1, null,
         NodeId.newInstance("host", 1234), Priority.UNDEFINED, time1, time2,
-        "diagnosticInfo", "logURL", 0, ContainerState.COMPLETE);
+        "diagnosticInfo", "logURL", 0, ContainerState.COMPLETE,
+        "http://" + NodeId.newInstance("host", 2345).toString());
     ContainerReport container2 = ContainerReport.newInstance(containerId2, null,
         NodeId.newInstance("host", 1234), Priority.UNDEFINED, time1,0,
-        "diagnosticInfo", "", 0, ContainerState.RUNNING);
+        "diagnosticInfo", "", 0, ContainerState.RUNNING,
+        "http://" + NodeId.newInstance("host", 2345).toString());
     List<ContainerReport> reports = new ArrayList<ContainerReport>();
     reports.add(container);
     reports.add(container1);
     reports.add(container2);
     when(client.getContainers(any(ApplicationAttemptId.class))).thenReturn(
         reports);
+    sysOutStream.reset();
     int result = cli.run(new String[] { "container", "-list",
         attemptId.toString() });
     assertEquals(0, result);
@@ -283,24 +289,28 @@ public class TestYarnCLI {
     pw.print("\t         Finish Time");
     pw.print("\t               State");
     pw.print("\t                Host");
+    pw.print("\t   Node Http Address");
     pw.println("\t                            LOG-URL");
     pw.print(" container_1234_0005_01_000001");
     pw.print("\t"+Times.format(time1));
     pw.print("\t"+Times.format(time2));
     pw.print("\t            COMPLETE");
     pw.print("\t           host:1234");
+    pw.print("\t    http://host:2345");
     pw.println("\t                             logURL");
     pw.print(" container_1234_0005_01_000002");
     pw.print("\t"+Times.format(time1));
     pw.print("\t"+Times.format(time2));
     pw.print("\t            COMPLETE");
     pw.print("\t           host:1234");
+    pw.print("\t    http://host:2345");
     pw.println("\t                             logURL");
     pw.print(" container_1234_0005_01_000003");
     pw.print("\t"+Times.format(time1));
     pw.print("\t                 N/A");
     pw.print("\t             RUNNING");
     pw.print("\t           host:1234");
+    pw.print("\t    http://host:2345");
     pw.println("\t                                   ");
     pw.close();
     String appReportStr = baos.toString("UTF-8");

+ 19 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/ContainerReportPBImpl.java

@@ -338,4 +338,23 @@ public class ContainerReportPBImpl extends ContainerReport {
       ContainerStateProto containerState) {
     return ProtoUtils.convertFromProtoFormat(containerState);
   }
+
+  @Override
+  public String getNodeHttpAddress() {
+    ContainerReportProtoOrBuilder p = viaProto ? proto : builder;
+    if (!p.hasNodeHttpAddress()) {
+      return null;
+    }
+    return (p.getNodeHttpAddress());
+  }
+
+  @Override
+  public void setNodeHttpAddress(String nodeHttpAddress) {
+    maybeInitBuilder();
+    if (nodeHttpAddress == null) {
+      builder.clearNodeHttpAddress();
+      return;
+    }
+    builder.setNodeHttpAddress(nodeHttpAddress);
+  }
 }

+ 1 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/ApplicationHistoryManagerImpl.java

@@ -215,7 +215,7 @@ public class ApplicationHistoryManagerImpl extends AbstractService implements
       containerHistory.getStartTime(), containerHistory.getFinishTime(),
       containerHistory.getDiagnosticsInfo(), logUrl,
       containerHistory.getContainerExitStatus(),
-      containerHistory.getContainerState());
+      containerHistory.getContainerState(), null);
   }
 
   @Override

+ 9 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/ApplicationHistoryManagerOnTimelineStore.java

@@ -410,6 +410,7 @@ public class ApplicationHistoryManagerOnTimelineStore extends AbstractService
     String diagnosticsInfo = null;
     int exitStatus = ContainerExitStatus.INVALID;
     ContainerState state = null;
+    String nodeHttpAddress = null;
     Map<String, Object> entityInfo = entity.getOtherInfo();
     if (entityInfo != null) {
       if (entityInfo
@@ -439,6 +440,12 @@ public class ApplicationHistoryManagerOnTimelineStore extends AbstractService
         allocatedPriority = (Integer) entityInfo.get(
                 ContainerMetricsConstants.ALLOCATED_PRIORITY_ENTITY_INFO);
       }
+      if (entityInfo.containsKey(
+          ContainerMetricsConstants.ALLOCATED_HOST_HTTP_ADDRESS_ENTITY_INFO)) {
+        nodeHttpAddress =
+            (String) entityInfo
+              .get(ContainerMetricsConstants.ALLOCATED_HOST_HTTP_ADDRESS_ENTITY_INFO);
+      }
     }
     List<TimelineEvent> events = entity.getEvents();
     if (events != null) {
@@ -488,7 +495,8 @@ public class ApplicationHistoryManagerOnTimelineStore extends AbstractService
         Resource.newInstance(allocatedMem, allocatedVcore),
         NodeId.newInstance(allocatedHost, allocatedPort),
         Priority.newInstance(allocatedPriority),
-        createdTime, finishedTime, diagnosticsInfo, logUrl, exitStatus, state);
+        createdTime, finishedTime, diagnosticsInfo, logUrl, exitStatus, state,
+        nodeHttpAddress);
   }
 
   private ApplicationReportExt generateApplicationReport(TimelineEntity entity,

+ 2 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/metrics/ContainerMetricsConstants.java

@@ -57,4 +57,6 @@ public class ContainerMetricsConstants {
   public static final String STATE_EVENT_INFO =
       "YARN_CONTAINER_STATE";
 
+  public static final String ALLOCATED_HOST_HTTP_ADDRESS_ENTITY_INFO =
+      "YARN_CONTAINER_ALLOCATED_HOST_HTTP_ADDRESS";
 }

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

@@ -191,12 +191,14 @@ public class AppAttemptBlock extends HtmlBlock {
         .append(url("container", container.getContainerId()))
         .append("'>")
         .append(container.getContainerId())
-        .append("</a>\",\"<a href='")
-        .append("#") // TODO: replace with node http address (YARN-1884)
+        .append("</a>\",\"<a ")
+        .append(
+          container.getNodeHttpAddress() == null ? "#" : "href='"
+              + container.getNodeHttpAddress())
         .append("'>")
-        .append(container.getAssignedNodeId() == null ? "N/A" :
+        .append(container.getNodeHttpAddress() == null ? "N/A" :
             StringEscapeUtils.escapeJavaScript(StringEscapeUtils
-                .escapeHtml(container.getAssignedNodeId())))
+                .escapeHtml(container.getNodeHttpAddress())))
         .append("</a>\",\"")
         .append(container.getContainerExitStatus()).append("\",\"<a href='")
         .append(container.getLogUrl() == null ?
@@ -224,4 +226,4 @@ public class AppAttemptBlock extends HtmlBlock {
     }
     return false;
   }
-}
+}

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

@@ -291,15 +291,12 @@ public class AppBlock extends HtmlBlock {
       }
       long startTime = 0L;
       String logsLink = null;
+      String nodeLink = null;
       if (containerReport != null) {
         ContainerInfo container = new ContainerInfo(containerReport);
         startTime = container.getStartedTime();
         logsLink = containerReport.getLogUrl();
-      }
-      String nodeLink = null;
-      if (appAttempt.getHost() != null && appAttempt.getRpcPort() >= 0
-          && appAttempt.getRpcPort() < 65536) {
-        nodeLink = appAttempt.getHost() + ":" + appAttempt.getRpcPort();
+        nodeLink = containerReport.getNodeHttpAddress();
       }
       // AppAttemptID numerical value parsed by parseHadoopID in
       // yarn.dt.plugins.js
@@ -310,8 +307,8 @@ public class AppBlock extends HtmlBlock {
         .append(appAttempt.getAppAttemptId())
         .append("</a>\",\"")
         .append(startTime)
-        .append("\",\"<a href='")
-        .append("#") // TODO: replace with node http address (YARN-1884)
+        .append("\",\"<a ")
+        .append(nodeLink == null ? "#" : "href='" + nodeLink)
         .append("'>")
         .append(nodeLink == null ? "N/A" : StringEscapeUtils
             .escapeJavaScript(StringEscapeUtils.escapeHtml(nodeLink)))

+ 6 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/ContainerBlock.java

@@ -104,7 +104,12 @@ public class ContainerBlock extends HtmlBlock {
         container.getContainerState() == null ? UNAVAILABLE : container
           .getContainerState())
       ._("Exit Status:", container.getContainerExitStatus())
-      ._("Node:", container.getAssignedNodeId())
+      ._(
+        "Node:",
+        container.getNodeHttpAddress() == null ? "#" : container
+          .getNodeHttpAddress(),
+        container.getNodeHttpAddress() == null ? "N/A" : container
+          .getNodeHttpAddress())
       ._("Priority:", container.getPriority())
       ._("Started:", Times.format(container.getStartedTime()))
       ._(

+ 5 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/dao/ContainerInfo.java

@@ -42,6 +42,7 @@ public class ContainerInfo {
   protected String logUrl;
   protected int containerExitStatus;
   protected ContainerState containerState;
+  protected String nodeHttpAddress;
 
   public ContainerInfo() {
     // JAXB needs this
@@ -64,6 +65,7 @@ public class ContainerInfo {
     logUrl = container.getLogUrl();
     containerExitStatus = container.getContainerExitStatus();
     containerState = container.getContainerState();
+    nodeHttpAddress = container.getNodeHttpAddress();
   }
 
   public String getContainerId() {
@@ -114,4 +116,7 @@ public class ContainerInfo {
     return containerState;
   }
 
+  public String getNodeHttpAddress() {
+    return nodeHttpAddress;
+  }
 }

+ 7 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/ContainerCreatedEvent.java

@@ -29,18 +29,21 @@ public class ContainerCreatedEvent extends SystemMetricsEvent {
   private Resource allocatedResource;
   private NodeId allocatedNode;
   private Priority allocatedPriority;
+  private String nodeHttpAddress;
 
   public ContainerCreatedEvent(
       ContainerId containerId,
       Resource allocatedResource,
       NodeId allocatedNode,
       Priority allocatedPriority,
-      long createdTime) {
+      long createdTime,
+      String nodeHttpAddress) {
     super(SystemMetricsEventType.CONTAINER_CREATED, createdTime);
     this.containerId = containerId;
     this.allocatedResource = allocatedResource;
     this.allocatedNode = allocatedNode;
     this.allocatedPriority = allocatedPriority;
+    this.nodeHttpAddress = nodeHttpAddress;
   }
 
   @Override
@@ -64,4 +67,7 @@ public class ContainerCreatedEvent extends SystemMetricsEvent {
     return allocatedPriority;
   }
 
+  public String getNodeHttpAddress() {
+    return nodeHttpAddress;
+  }
 }

+ 4 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/SystemMetricsPublisher.java

@@ -179,7 +179,7 @@ public class SystemMetricsPublisher extends CompositeService {
               container.getAllocatedResource(),
               container.getAllocatedNode(),
               container.getAllocatedPriority(),
-              createdTime));
+              createdTime, container.getNodeHttpAddress()));
     }
   }
 
@@ -380,6 +380,9 @@ public class SystemMetricsPublisher extends CompositeService {
         event.getAllocatedNode().getPort());
     entityInfo.put(ContainerMetricsConstants.ALLOCATED_PRIORITY_ENTITY_INFO,
         event.getAllocatedPriority().getPriority());
+    entityInfo.put(
+      ContainerMetricsConstants.ALLOCATED_HOST_HTTP_ADDRESS_ENTITY_INFO,
+      event.getNodeHttpAddress());
     entity.setOtherInfo(entityInfo);
     TimelineEvent tEvent = new TimelineEvent();
     tEvent.setEventType(ContainerMetricsConstants.CREATED_EVENT_TYPE);

+ 1 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmcontainer/RMContainer.java

@@ -79,4 +79,5 @@ public interface RMContainer extends EventHandler<RMContainerEvent> {
   
   List<ResourceRequest> getResourceRequests();
 
+  String getNodeHttpAddress();
 }

+ 20 - 2
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmcontainer/RMContainerImpl.java

@@ -42,7 +42,6 @@ import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.hadoop.yarn.event.EventHandler;
 import org.apache.hadoop.yarn.server.api.protocolrecords.NMContainerStatus;
 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.RMAppRunningOnNodeEvent;
 import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttempt;
 import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.event.RMAppAttemptContainerAllocatedEvent;
@@ -608,10 +607,29 @@ public class RMContainerImpl implements RMContainer {
           this.getAllocatedResource(), this.getAllocatedNode(),
           this.getAllocatedPriority(), this.getCreationTime(),
           this.getFinishTime(), this.getDiagnosticsInfo(), this.getLogURL(),
-          this.getContainerExitStatus(), this.getContainerState());
+          this.getContainerExitStatus(), this.getContainerState(),
+          this.getNodeHttpAddress());
     } finally {
       this.readLock.unlock();
     }
     return containerReport;
   }
+
+  @Override
+  public String getNodeHttpAddress() {
+    try {
+      readLock.lock();
+      if (container.getNodeHttpAddress() != null) {
+        StringBuilder httpAddress = new StringBuilder();
+        httpAddress.append(WebAppUtils.getHttpSchemePrefix(rmContext
+            .getYarnConfiguration()));
+        httpAddress.append(container.getNodeHttpAddress());
+        return httpAddress.toString();
+      } else {
+        return null;
+      }
+    } finally {
+      readLock.unlock();
+    }
+  }
 }

+ 4 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/TestSystemMetricsPublisher.java

@@ -38,7 +38,6 @@ import org.apache.hadoop.yarn.api.records.timeline.TimelineEntity;
 import org.apache.hadoop.yarn.api.records.timeline.TimelineEvent;
 import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.hadoop.yarn.server.applicationhistoryservice.ApplicationHistoryServer;
-import org.apache.hadoop.yarn.server.applicationhistoryservice.webapp.AHSWebApp;
 import org.apache.hadoop.yarn.server.metrics.AppAttemptMetricsConstants;
 import org.apache.hadoop.yarn.server.metrics.ApplicationMetricsConstants;
 import org.apache.hadoop.yarn.server.metrics.ContainerMetricsConstants;
@@ -369,6 +368,10 @@ public class TestSystemMetricsPublisher {
     when(container.getDiagnosticsInfo()).thenReturn("test diagnostics info");
     when(container.getContainerExitStatus()).thenReturn(-1);
     when(container.getContainerState()).thenReturn(ContainerState.COMPLETE);
+    Container mockContainer = mock(Container.class);
+    when(container.getContainer()).thenReturn(mockContainer);
+    when(mockContainer.getNodeHttpAddress())
+      .thenReturn("http://localhost:1234");
     return container;
   }