diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/KillApplicationRequest.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/KillApplicationRequest.java
index 606cf4e..a7679a0 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/KillApplicationRequest.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/KillApplicationRequest.java
@@ -20,6 +20,7 @@
import org.apache.hadoop.classification.InterfaceAudience.Public;
import org.apache.hadoop.classification.InterfaceStability.Stable;
+import org.apache.hadoop.classification.InterfaceStability.Unstable;
import org.apache.hadoop.yarn.api.ApplicationClientProtocol;
import org.apache.hadoop.yarn.api.records.ApplicationId;
import org.apache.hadoop.yarn.util.Records;
@@ -57,4 +58,21 @@ public static KillApplicationRequest newInstance(ApplicationId applicationId) {
@Public
@Stable
public abstract void setApplicationId(ApplicationId applicationId);
+
+ /**
+ * Get the diagnostics to which the application is being killed.
+ * @return diagnostics to which the application is being killed
+ */
+ @Public
+ @Unstable
+ public abstract String getDiagnostics();
+
+ /**
+ * Set the diagnostics to which the application is being killed.
+ * @param diagnostics diagnostics to which the application is being
+ * killed
+ */
+ @Public
+ @Unstable
+ public abstract void setDiagnostics(String diagnostics);
}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_service_protos.proto b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_service_protos.proto
index 97eaa5c..1385ea4 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_service_protos.proto
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_service_protos.proto
@@ -156,6 +156,7 @@ message FailApplicationAttemptResponseProto {
message KillApplicationRequestProto {
optional ApplicationIdProto application_id = 1;
+ optional string diagnostics = 2;
}
message KillApplicationResponseProto {
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/KillApplicationRequestPBImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/KillApplicationRequestPBImpl.java
index db97367..0520222 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/KillApplicationRequestPBImpl.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/KillApplicationRequestPBImpl.java
@@ -127,6 +127,24 @@ private ApplicationIdProto convertToProtoFormat(ApplicationId t) {
return ((ApplicationIdPBImpl)t).getProto();
}
+ @Override
+ public String getDiagnostics() {
+ KillApplicationRequestProtoOrBuilder p = viaProto ? proto : builder;
+ if (!p.hasDiagnostics()) {
+ return null;
+ }
+ return (p.getDiagnostics());
+ }
+
+ @Override
+ public void setDiagnostics(String diagnostics) {
+ maybeInitBuilder();
+ if (diagnostics == null) {
+ builder.clearDiagnostics();
+ return;
+ }
+ builder.setDiagnostics(diagnostics);
+ }
}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java
index 70e1863..2e38cb4 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java
@@ -173,6 +173,9 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.SettableFuture;
+
+import io.netty.util.internal.StringUtil;
+
import org.apache.hadoop.yarn.util.timeline.TimelineUtils;
@@ -775,15 +778,22 @@ public KillApplicationResponse forceKillApplication(
return KillApplicationResponse.newInstance(true);
}
- String message = "Kill application " + applicationId + " received from "
- + callerUGI;
+ StringBuilder message = new StringBuilder();
+ message.append(
+ "Kill application " + applicationId + " received from " + callerUGI);
+
InetAddress remoteAddress = Server.getRemoteIp();
if (null != remoteAddress) {
- message += " at " + remoteAddress.getHostAddress();
+ message.append(" at " + remoteAddress.getHostAddress());
}
+ String diagnostics = request.getDiagnostics();
+ if (diagnostics != null && diagnostics.trim().length() != 0) {
+ message.append("\n").append(diagnostics);
+ }
+
this.rmContext.getDispatcher().getEventHandler()
- .handle(new RMAppKillByClientEvent(applicationId, message, callerUGI,
- remoteAddress));
+ .handle(new RMAppKillByClientEvent(applicationId, message.toString(),
+ callerUGI, remoteAddress));
// For UnmanagedAMs, return true so they don't retry
return KillApplicationResponse.newInstance(
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java
index 4305fd5..ef6fd06 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java
@@ -925,7 +925,7 @@ public Response updateAppState(AppState targetState,
// allow users to kill the app
if (targetState.getState().equals(YarnApplicationState.KILLED.toString())) {
- return killApp(app, callerUGI, hsr);
+ return killApp(app, callerUGI, hsr, targetState.getDiagnostics());
}
throw new BadRequestException("Only '"
+ YarnApplicationState.KILLED.toString()
@@ -1141,7 +1141,8 @@ public NodeLabelsInfo getLabelsOnNode(@Context HttpServletRequest hsr,
}
protected Response killApp(RMApp app, UserGroupInformation callerUGI,
- HttpServletRequest hsr) throws IOException, InterruptedException {
+ HttpServletRequest hsr, String diagnostic)
+ throws IOException, InterruptedException {
if (app == null) {
throw new IllegalArgumentException("app cannot be null");
@@ -1158,6 +1159,9 @@ public KillApplicationResponse run() throws IOException,
YarnException {
KillApplicationRequest req =
KillApplicationRequest.newInstance(appid);
+ if (diagnostic != null) {
+ req.setDiagnostics(diagnostic);
+ }
return rm.getClientRMService().forceKillApplication(req);
}
});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/AppState.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/AppState.java
index e8f1cc3..24c1916 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/AppState.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/AppState.java
@@ -27,6 +27,7 @@
public class AppState {
String state;
+ String diagnostics;
public AppState() {
}
@@ -43,4 +44,11 @@ public String getState() {
return this.state;
}
+ public String getDiagnostics() {
+ return diagnostics;
+ }
+
+ public void setDiagnostics(String diagnostics) {
+ this.diagnostics = diagnostics;
+ }
}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestClientRMService.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestClientRMService.java
index 2a7971e..576666a 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestClientRMService.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestClientRMService.java
@@ -522,6 +522,8 @@ public void testForceKillApplication() throws Exception {
KillApplicationRequest killRequest1 =
KillApplicationRequest.newInstance(app1.getApplicationId());
+ String diagnostic = "message1";
+ killRequest1.setDiagnostics(diagnostic);
KillApplicationRequest killRequest2 =
KillApplicationRequest.newInstance(app2.getApplicationId());
@@ -539,6 +541,8 @@ public void testForceKillApplication() throws Exception {
killAttemptCount > 1);
assertEquals("Incorrect number of apps in the RM", 1,
rmService.getApplications(getRequest).getApplicationList().size());
+ assertTrue("Diagnostic message is incorrect",
+ app1.getDiagnostics().toString().contains(diagnostic));
KillApplicationResponse killResponse2 =
rmService.forceKillApplication(killRequest2);