YARN-5650. Render Application Timeout value in web UI. Contributed by Akhil PB.
This commit is contained in:
parent
fcbe152342
commit
ef2dd7b78c
@ -40,6 +40,7 @@
|
||||
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.ApplicationTimeoutType;
|
||||
import org.apache.hadoop.yarn.api.records.ContainerReport;
|
||||
import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
|
||||
import org.apache.hadoop.yarn.api.records.LogAggregationStatus;
|
||||
@ -207,6 +208,14 @@ public ApplicationReport run() throws Exception {
|
||||
overviewTable._("Log Aggregation Status:",
|
||||
root_url("logaggregationstatus", app.getAppId()), status.name());
|
||||
}
|
||||
long timeout = appReport.getApplicationTimeouts()
|
||||
.get(ApplicationTimeoutType.LIFETIME).getRemainingTime();
|
||||
if (timeout < 0) {
|
||||
overviewTable._("Application Timeout (Remaining Time):", "Unlimited");
|
||||
} else {
|
||||
overviewTable._("Application Timeout (Remaining Time):",
|
||||
String.format("%d seconds", timeout));
|
||||
}
|
||||
}
|
||||
overviewTable._("Diagnostics:",
|
||||
app.getDiagnosticsInfo() == null ? "" : app.getDiagnosticsInfo());
|
||||
|
@ -259,8 +259,12 @@ public AppInfo(ResourceManager rm, RMApp app, Boolean hasAccess,
|
||||
timeout.setTimeoutType(entry.getKey());
|
||||
long timeoutInMillis = entry.getValue().longValue();
|
||||
timeout.setExpiryTime(Times.formatISO8601(timeoutInMillis));
|
||||
if (app.isAppInCompletedStates()) {
|
||||
timeout.setRemainingTime(0);
|
||||
} else {
|
||||
timeout.setRemainingTime(Math
|
||||
.max((timeoutInMillis - System.currentTimeMillis()) / 1000, 0));
|
||||
}
|
||||
timeouts.add(timeout);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
import Converter from 'yarn-ui/utils/converter';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
app: null,
|
||||
|
||||
appTimeoutValue: function() {
|
||||
var timeoutValueInSecs = this.get("app.remainingTimeoutInSeconds");
|
||||
if (timeoutValueInSecs > -1) {
|
||||
return Converter.msToElapsedTime(timeoutValueInSecs * 1000);
|
||||
} else {
|
||||
return timeoutValueInSecs;
|
||||
}
|
||||
}.property("app.remainingTimeoutInSeconds"),
|
||||
|
||||
isAppTimedOut: function() {
|
||||
if (this.get("app.remainingTimeoutInSeconds") > 0) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}.property("app.remainingTimeoutInSeconds"),
|
||||
|
||||
appTimeoutBarStyle: function() {
|
||||
var remainingInSecs = this.get("app.remainingTimeoutInSeconds"),
|
||||
expiryTimestamp = Converter.dateToTimeStamp(this.get("app.applicationExpiryTime")),
|
||||
expiryInSecs = expiryTimestamp / 1000,
|
||||
startTimestamp = Converter.dateToTimeStamp(this.get("app.startTime")),
|
||||
startInSecs = startTimestamp / 1000,
|
||||
totalRunInSecs = 0,
|
||||
appRunDurationInSecs = 0,
|
||||
width = 0;
|
||||
|
||||
if (remainingInSecs > 0) {
|
||||
totalRunInSecs = expiryInSecs - startInSecs;
|
||||
appRunDurationInSecs = totalRunInSecs - remainingInSecs;
|
||||
width = appRunDurationInSecs / totalRunInSecs * 100;
|
||||
}
|
||||
|
||||
return "width: " + width + "%";
|
||||
}.property("app.remainingTimeoutInSeconds", "app.applicationExpiryTime", "app.startTime")
|
||||
});
|
@ -50,6 +50,8 @@ export default DS.Model.extend({
|
||||
clusterUsagePercentage: DS.attr('number'),
|
||||
queueUsagePercentage: DS.attr('number'),
|
||||
currentAppAttemptId: DS.attr('string'),
|
||||
remainingTimeoutInSeconds: DS.attr('number'),
|
||||
applicationExpiryTime: DS.attr('string'),
|
||||
|
||||
isFailed: function() {
|
||||
return this.get('finalStatus') == "FAILED"
|
||||
|
@ -26,6 +26,15 @@ export default DS.JSONAPISerializer.extend({
|
||||
payload = payload.app;
|
||||
}
|
||||
|
||||
var timeoutInSecs = -1;
|
||||
var appExpiryTime = Converter.timeStampToDate(payload.finishedTime);
|
||||
if (payload.timeouts && payload.timeouts.timeout && payload.timeouts.timeout[0]) {
|
||||
timeoutInSecs = payload.timeouts.timeout[0].remainingTimeInSeconds;
|
||||
if (timeoutInSecs > -1) {
|
||||
appExpiryTime = Converter.isoDateToDate(payload.timeouts.timeout[0].expiryTime);
|
||||
}
|
||||
}
|
||||
|
||||
var fixedPayload = {
|
||||
id: id,
|
||||
type: primaryModelClass.modelName, // yarn-app
|
||||
@ -58,7 +67,9 @@ export default DS.JSONAPISerializer.extend({
|
||||
numAMContainerPreempted: payload.numAMContainerPreempted,
|
||||
clusterUsagePercentage: payload.clusterUsagePercentage,
|
||||
queueUsagePercentage: payload.queueUsagePercentage,
|
||||
currentAppAttemptId: payload.currentAppAttemptId
|
||||
currentAppAttemptId: payload.currentAppAttemptId,
|
||||
remainingTimeoutInSeconds: timeoutInSecs,
|
||||
applicationExpiryTime: appExpiryTime
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,34 @@
|
||||
{{!
|
||||
* 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.
|
||||
}}
|
||||
|
||||
<div class="app-timeout-wrapper">
|
||||
{{#unless isAppTimedOut}}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<label>Application will be timed out after <span class="text-danger">{{appTimeoutValue}}</span></label>
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-danger progress-bar-striped active" style="{{appTimeoutBarStyle}}"></div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="pull-left">{{app.startTime}}</label>
|
||||
<label class="pull-right">{{app.applicationExpiryTime}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/unless}}
|
||||
</div>
|
@ -45,6 +45,12 @@
|
||||
</div>
|
||||
|
||||
<div class="col-md-10 container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
{{app-timeout-bar app=model.app}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
@ -116,10 +122,10 @@
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<div class="panel-heading">
|
||||
Diagnostics
|
||||
</div>
|
||||
<div class="panel-footer">{{model.app.diagnostics}}</div>
|
||||
<div class="panel-body">{{model.app.diagnostics}}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
@ -91,6 +91,9 @@ export default {
|
||||
return ts;
|
||||
}
|
||||
},
|
||||
isoDateToDate: function(isoDate) {
|
||||
return moment(isoDate).format("YYYY/MM/DD HH:mm:ss");
|
||||
},
|
||||
splitForContainerLogs: function(id) {
|
||||
if (id) {
|
||||
var splits = id.split(Constants.PARAM_SEPARATOR);
|
||||
|
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
moduleForComponent('app-timeout-bar', 'Integration | Component | app timeout bar', {
|
||||
integration: true
|
||||
});
|
||||
|
||||
test('it renders', function(assert) {
|
||||
|
||||
// Set any properties with this.set('myProperty', 'value');
|
||||
// Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL +
|
||||
|
||||
this.render(hbs`{{app-timeout-bar}}`);
|
||||
|
||||
assert.equal(this.$().text().trim(), '');
|
||||
});
|
Loading…
Reference in New Issue
Block a user