Browse Source

YARN-3451. Display attempt start time and elapsed time on the web UI. Contributed by Rohith Sharmaks
(cherry picked from commit 6779467ab6fcc6a02d0e8c80b138cc9df1aa831e)

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

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

@@ -94,6 +94,9 @@ Release 2.8.0 - UNRELEASED
     YARN-2696. Queue sorting in CapacityScheduler should consider node label.
     (Wangda Tan via jianhe)
 
+    YARN-3451. Display attempt start time and elapsed time on the web UI.
+    (Rohith Sharmaks via jianhe)
+
   OPTIMIZATIONS
 
     YARN-3339. TestDockerContainerExecutor should pull a single image and not

+ 33 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ApplicationAttemptReport.java

@@ -47,7 +47,8 @@ public abstract class ApplicationAttemptReport {
   public static ApplicationAttemptReport newInstance(
       ApplicationAttemptId applicationAttemptId, String host, int rpcPort,
       String url, String oUrl, String diagnostics,
-      YarnApplicationAttemptState state, ContainerId amContainerId) {
+      YarnApplicationAttemptState state, ContainerId amContainerId,
+      long startTime, long finishTime) {
     ApplicationAttemptReport report =
         Records.newRecord(ApplicationAttemptReport.class);
     report.setApplicationAttemptId(applicationAttemptId);
@@ -58,9 +59,19 @@ public abstract class ApplicationAttemptReport {
     report.setDiagnostics(diagnostics);
     report.setYarnApplicationAttemptState(state);
     report.setAMContainerId(amContainerId);
+    report.setStartTime(startTime);
+    report.setFinishTime(finishTime);
     return report;
   }
 
+  public static ApplicationAttemptReport newInstance(
+      ApplicationAttemptId applicationAttemptId, String host, int rpcPort,
+      String url, String oUrl, String diagnostics,
+      YarnApplicationAttemptState state, ContainerId amContainerId) {
+    return newInstance(applicationAttemptId, host, rpcPort, url, oUrl,
+        diagnostics, state, amContainerId, 0L, 0L);
+  }
+
   /**
    * Get the <em>YarnApplicationAttemptState</em> of the application attempt.
    * 
@@ -171,4 +182,25 @@ public abstract class ApplicationAttemptReport {
   @Private
   @Unstable
   public abstract void setAMContainerId(ContainerId amContainerId);
+
+  @Public
+  @Unstable
+  public abstract long getStartTime();
+
+  @Private
+  @Unstable
+  public abstract void setStartTime(long startTime);
+
+  /**
+   * Get the <em>finish time</em> of the application.
+   * 
+   * @return <em>finish time</em> of the application
+   */
+  @Public
+  @Unstable
+  public abstract long getFinishTime();
+
+  @Private
+  @Unstable
+  public abstract void setFinishTime(long finishTime);
 }

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

@@ -215,6 +215,8 @@ message ApplicationAttemptReportProto {
   optional YarnApplicationAttemptStateProto yarn_application_attempt_state = 6;
   optional ContainerIdProto am_container_id = 7;
   optional string original_tracking_url = 8;
+  optional int64 startTime = 9;
+  optional int64 finishTime = 10;
 }
 
 enum NodeStateProto {

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

@@ -700,7 +700,8 @@ public abstract class ProtocolHATestBase extends ClientBaseWithFixes {
     public ApplicationAttemptReport createFakeApplicationAttemptReport() {
       return ApplicationAttemptReport.newInstance(
           createFakeApplicationAttemptId(), "localhost", 0, "", "", "",
-          YarnApplicationAttemptState.RUNNING, createFakeContainerId());
+          YarnApplicationAttemptState.RUNNING, createFakeContainerId(), 1000l,
+          1200l);
     }
 
     public List<ApplicationAttemptReport>

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

@@ -593,7 +593,8 @@ public class TestYarnClient {
           "diagnostics",
           YarnApplicationAttemptState.FINISHED,
           ContainerId.newContainerId(
-              newApplicationReport.getCurrentApplicationAttemptId(), 1));
+                  newApplicationReport.getCurrentApplicationAttemptId(), 1), 0,
+              0);
       appAttempts.add(attempt);
       ApplicationAttemptReport attempt1 = ApplicationAttemptReport.newInstance(
           ApplicationAttemptId.newInstance(applicationId, 2),

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

@@ -145,10 +145,10 @@ public class TestYarnCLI {
     ApplicationId applicationId = ApplicationId.newInstance(1234, 5);
     ApplicationAttemptId attemptId = ApplicationAttemptId.newInstance(
         applicationId, 1);
-    ApplicationAttemptReport attemptReport = ApplicationAttemptReport
-        .newInstance(attemptId, "host", 124, "url", "oUrl", "diagnostics",
-            YarnApplicationAttemptState.FINISHED, ContainerId.newContainerId(
-                attemptId, 1));
+    ApplicationAttemptReport attemptReport =
+        ApplicationAttemptReport.newInstance(attemptId, "host", 124, "url",
+            "oUrl", "diagnostics", YarnApplicationAttemptState.FINISHED,
+            ContainerId.newContainerId(attemptId, 1), 1000l, 2000l);
     when(
         client
             .getApplicationAttemptReport(any(ApplicationAttemptId.class)))

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

@@ -286,4 +286,28 @@ public class ApplicationAttemptReportPBImpl extends ApplicationAttemptReport {
       builder.clearAmContainerId();
     this.amContainerId = amContainerId;
   }
+
+  @Override
+  public void setStartTime(long startTime) {
+    maybeInitBuilder();
+    builder.setStartTime(startTime);
+  }
+
+  @Override
+  public void setFinishTime(long finishTime) {
+    maybeInitBuilder();
+    builder.setFinishTime(finishTime);
+  }
+
+  @Override
+  public long getStartTime() {
+    ApplicationAttemptReportProtoOrBuilder p = viaProto ? proto : builder;
+    return p.getStartTime();
+  }
+
+  @Override
+  public long getFinishTime() {
+    ApplicationAttemptReportProtoOrBuilder p = viaProto ? proto : builder;
+    return p.getFinishTime();
+  }
 }

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

@@ -37,6 +37,8 @@ public class AppAttemptInfo {
   protected String diagnosticsInfo;
   protected YarnApplicationAttemptState appAttemptState;
   protected String amContainerId;
+  protected long startedTime;
+  protected long finishedTime;
 
   public AppAttemptInfo() {
     // JAXB needs this
@@ -53,6 +55,8 @@ public class AppAttemptInfo {
     if (appAttempt.getAMContainerId() != null) {
       amContainerId = appAttempt.getAMContainerId().toString();
     }
+    startedTime = appAttempt.getStartTime();
+    finishedTime = appAttempt.getFinishTime();
   }
 
   public String getAppAttemptId() {
@@ -87,4 +91,12 @@ public class AppAttemptInfo {
     return amContainerId;
   }
 
+  public long getStartedTime() {
+    return startedTime;
+  }
+
+  public long getFinishedTime() {
+    return finishedTime;
+  }
+
 }

+ 2 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/attempt/RMAppAttemptImpl.java

@@ -1906,7 +1906,8 @@ public class RMAppAttemptImpl implements RMAppAttempt, Recoverable {
       attemptReport = ApplicationAttemptReport.newInstance(this
           .getAppAttemptId(), this.getHost(), this.getRpcPort(), this
           .getTrackingUrl(), this.getOriginalTrackingUrl(), this.getDiagnostics(),
-          YarnApplicationAttemptState .valueOf(this.getState().toString()), amId);
+              YarnApplicationAttemptState.valueOf(this.getState().toString()),
+              amId, this.startTime, this.finishTime);
     } finally {
       this.readLock.unlock();
     }

+ 5 - 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

@@ -41,6 +41,7 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerApplicat
 import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppInfo;
 import org.apache.hadoop.yarn.server.webapp.AppAttemptBlock;
 import org.apache.hadoop.yarn.server.webapp.dao.AppAttemptInfo;
+import org.apache.hadoop.yarn.util.Times;
 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;
@@ -205,6 +206,10 @@ public class RMAppAttemptBlock extends AppAttemptBlock{
         "Application Attempt State:",
         appAttempt.getAppAttemptState() == null ? UNAVAILABLE : appAttempt
           .getAppAttemptState())
+        ._("Started:", Times.format(appAttempt.getStartedTime()))
+        ._("Elapsed:",
+            org.apache.hadoop.util.StringUtils.formatTime(Times.elapsed(
+                appAttempt.getStartedTime(), appAttempt.getFinishedTime())))
       ._(
         "AM Container:",
         appAttempt.getAmContainerId() == null || containers == null