YARN-7641. Allow searchable filter for Application page log viewer in new YARN UI. Contributed by Vasudevan Skm. This closes #312.
This commit is contained in:
parent
7efc4f7688
commit
fa4ecd8b98
|
@ -22,90 +22,120 @@ export default Ember.Controller.extend({
|
|||
queryParams: ["service"],
|
||||
service: undefined,
|
||||
|
||||
selectedAttemptId: '',
|
||||
selectedAttemptId: "",
|
||||
attemptContainerList: null,
|
||||
selectedContainerId: '',
|
||||
selectedLogFileName: '',
|
||||
selectedContainerId: "",
|
||||
selectedLogFileName: "",
|
||||
containerLogFiles: null,
|
||||
selectedLogFileContent: '',
|
||||
selectedLogFileContent: "",
|
||||
|
||||
_isLoadingTopPanel: false,
|
||||
_isLoadingBottomPanel: false,
|
||||
|
||||
initializeSelect: function(selector = ".js-fetch-attempt-containers") {
|
||||
Ember.run.schedule("afterRender", this, function() {
|
||||
$(selector).select2({ width: "350px", multiple: false });
|
||||
});
|
||||
},
|
||||
|
||||
actions: {
|
||||
showContainersForAttemptId(attemptId) {
|
||||
this.set('selectedAttemptId', '');
|
||||
this.set("selectedAttemptId", "");
|
||||
if (attemptId) {
|
||||
this.set('_isLoadingTopPanel', true);
|
||||
this.set('selectedAttemptId', attemptId);
|
||||
this.fetchContainersForAttemptId(attemptId).then((hash) => {
|
||||
this.set("_isLoadingTopPanel", true);
|
||||
this.set("selectedAttemptId", attemptId);
|
||||
this.fetchContainersForAttemptId(attemptId)
|
||||
.then(hash => {
|
||||
let containers = null;
|
||||
if (hash.rmContainers.get('length') > 0 && hash.rmContainers.get('content')) {
|
||||
containers = (containers || []).concat(hash.rmContainers.get('content'));
|
||||
if (
|
||||
hash.rmContainers.get("length") > 0 &&
|
||||
hash.rmContainers.get("content")
|
||||
) {
|
||||
containers = (containers || []).concat(
|
||||
hash.rmContainers.get("content")
|
||||
);
|
||||
}
|
||||
if (hash.tsContainers.get('length') > 0 && hash.tsContainers.get('content')) {
|
||||
containers = (containers || []).concat(hash.tsContainers.get('content'));
|
||||
if (
|
||||
hash.tsContainers.get("length") > 0 &&
|
||||
hash.tsContainers.get("content")
|
||||
) {
|
||||
containers = (containers || []).concat(
|
||||
hash.tsContainers.get("content")
|
||||
);
|
||||
}
|
||||
this.set('attemptContainerList', containers);
|
||||
}).finally(() => {
|
||||
this.set('_isLoadingTopPanel', false);
|
||||
this.set("attemptContainerList", containers);
|
||||
this.initializeSelect(".js-fetch-logs-containers");
|
||||
})
|
||||
.finally(() => {
|
||||
this.set("_isLoadingTopPanel", false);
|
||||
});
|
||||
} else {
|
||||
this.set('attemptContainerList', null);
|
||||
this.set('selectedContainerId', '');
|
||||
this.set('containerLogFiles', null);
|
||||
this.set('selectedLogFileName', '');
|
||||
this.set('selectedLogFileContent', '');
|
||||
this.set("attemptContainerList", null);
|
||||
this.set("selectedContainerId", "");
|
||||
this.set("containerLogFiles", null);
|
||||
this.set("selectedLogFileName", "");
|
||||
this.set("selectedLogFileContent", "");
|
||||
}
|
||||
},
|
||||
|
||||
showLogFilesForContainerId(containerId) {
|
||||
this.set('selectedContainerId', '');
|
||||
this.set('containerLogFiles', null);
|
||||
this.set('selectedLogFileName', '');
|
||||
this.set('selectedLogFileContent', '');
|
||||
this.set("selectedContainerId", "");
|
||||
this.set("containerLogFiles", null);
|
||||
this.set("selectedLogFileName", "");
|
||||
this.set("selectedLogFileContent", "");
|
||||
|
||||
if (containerId) {
|
||||
this.set('_isLoadingBottomPanel', true);
|
||||
this.set('selectedContainerId', containerId);
|
||||
this.fetchLogFilesForContainerId(containerId).then((hash) => {
|
||||
if (hash.logs.get('length') > 0) {
|
||||
this.set('containerLogFiles', hash.logs);
|
||||
this.set("_isLoadingBottomPanel", true);
|
||||
this.set("selectedContainerId", containerId);
|
||||
this.fetchLogFilesForContainerId(containerId)
|
||||
.then(hash => {
|
||||
if (hash.logs.get("length") > 0) {
|
||||
this.set("containerLogFiles", hash.logs);
|
||||
} else {
|
||||
this.set('containerLogFiles', null);
|
||||
this.set("containerLogFiles", null);
|
||||
}
|
||||
}).finally(() => {
|
||||
this.set('_isLoadingBottomPanel', false);
|
||||
this.initializeSelect(".js-fetch-log-for-container");
|
||||
})
|
||||
.finally(() => {
|
||||
this.set("_isLoadingBottomPanel", false);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
showContentForLogFile(logFile) {
|
||||
this.set('selectedLogFileName', '');
|
||||
Ember.$("#logContentTextArea1234554321").val('');
|
||||
this.set('showFullLog', false);
|
||||
this.set("selectedLogFileName", "");
|
||||
Ember.$("#logContentTextArea1234554321").val("");
|
||||
this.set("showFullLog", false);
|
||||
if (logFile) {
|
||||
this.set('_isLoadingBottomPanel', true);
|
||||
this.set('selectedLogFileName', logFile);
|
||||
this.fetchContentForLogFile(this.get('selectedContainerId'), logFile).then((content) => {
|
||||
this.set('selectedLogFileContent', content.trim());
|
||||
}, () => {
|
||||
this.set('selectedLogFileContent', '');
|
||||
}).always(() => {
|
||||
this.set('_isLoadingBottomPanel', false);
|
||||
this.set("_isLoadingBottomPanel", true);
|
||||
this.set("selectedLogFileName", logFile);
|
||||
this.fetchContentForLogFile(this.get("selectedContainerId"), logFile)
|
||||
.then(
|
||||
content => {
|
||||
this.set("selectedLogFileContent", content.trim());
|
||||
},
|
||||
() => {
|
||||
this.set("selectedLogFileContent", "");
|
||||
}
|
||||
)
|
||||
.always(() => {
|
||||
this.set("_isLoadingBottomPanel", false);
|
||||
});
|
||||
} else {
|
||||
this.set('selectedLogFileContent', '');
|
||||
this.set("selectedLogFileContent", "");
|
||||
}
|
||||
},
|
||||
|
||||
findNextTextInLogContent() {
|
||||
let searchInputElem = document.getElementById('logSeachInput98765');
|
||||
this.send('searchTextInLogContent', searchInputElem.value);
|
||||
let searchInputElem = document.getElementById("logSeachInput98765");
|
||||
this.send("searchTextInLogContent", searchInputElem.value);
|
||||
},
|
||||
|
||||
searchTextInLogContent(searchText) {
|
||||
Ember.$('body').scrollTop(278);
|
||||
let textAreaElem = document.getElementById('logContentTextArea1234554321');
|
||||
Ember.$("body").scrollTop(278);
|
||||
let textAreaElem = document.getElementById(
|
||||
"logContentTextArea1234554321"
|
||||
);
|
||||
let logContent = textAreaElem.innerText;
|
||||
let startIndex = this.searchTextStartIndex || 0;
|
||||
if (startIndex === -1) {
|
||||
|
@ -130,37 +160,44 @@ export default Ember.Controller.extend({
|
|||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
}
|
||||
this.searchTextStartIndex = logContent.indexOf(searchText, endIndex + 1);
|
||||
this.searchTextStartIndex = logContent.indexOf(
|
||||
searchText,
|
||||
endIndex + 1
|
||||
);
|
||||
} else {
|
||||
this.searchTextStartIndex = 0;
|
||||
}
|
||||
},
|
||||
|
||||
showFullLogFileContent() {
|
||||
this.set('showFullLog', true);
|
||||
this.notifyPropertyChange('selectedLogFileContent');
|
||||
this.set("showFullLog", true);
|
||||
this.notifyPropertyChange("selectedLogFileContent");
|
||||
}
|
||||
},
|
||||
|
||||
attemptList: Ember.computed('model.attempts', function() {
|
||||
let attempts = this.get('model.attempts');
|
||||
attemptList: Ember.computed("model.attempts", function() {
|
||||
let attempts = this.get("model.attempts");
|
||||
let list = null;
|
||||
if (attempts && attempts.get('length') && attempts.get('content')) {
|
||||
list = [].concat(attempts.get('content'));
|
||||
if (attempts && attempts.get("length") && attempts.get("content")) {
|
||||
list = [].concat(attempts.get("content"));
|
||||
}
|
||||
return list;
|
||||
}),
|
||||
|
||||
fetchContainersForAttemptId(attemptId) {
|
||||
return Ember.RSVP.hash({
|
||||
rmContainers: this.store.query('yarn-container', {
|
||||
rmContainers: this.store
|
||||
.query("yarn-container", {
|
||||
app_attempt_id: attemptId
|
||||
}).catch(function() {
|
||||
})
|
||||
.catch(function() {
|
||||
return Ember.A();
|
||||
}),
|
||||
tsContainers: this.store.query('yarn-timeline-container', {
|
||||
tsContainers: this.store
|
||||
.query("yarn-timeline-container", {
|
||||
app_attempt_id: attemptId
|
||||
}).catch(function() {
|
||||
})
|
||||
.catch(function() {
|
||||
return Ember.A();
|
||||
})
|
||||
});
|
||||
|
@ -168,37 +205,41 @@ export default Ember.Controller.extend({
|
|||
|
||||
fetchLogFilesForContainerId(containerId) {
|
||||
return Ember.RSVP.hash({
|
||||
logs: this.store.query('yarn-log', {
|
||||
logs: this.store
|
||||
.query("yarn-log", {
|
||||
containerId: containerId
|
||||
}).catch(function() {
|
||||
})
|
||||
.catch(function() {
|
||||
return Ember.A();
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
fetchContentForLogFile(containerId, logFile) {
|
||||
let logAdapter = this.store.adapterFor('yarn-log');
|
||||
let logAdapter = this.store.adapterFor("yarn-log");
|
||||
return logAdapter.fetchLogFileContent(containerId, logFile);
|
||||
},
|
||||
|
||||
resetAfterRefresh() {
|
||||
this.set('selectedAttemptId', '');
|
||||
this.set('attemptContainerList', null);
|
||||
this.set('selectedContainerId', '');
|
||||
this.set('selectedLogFileName', '');
|
||||
this.set('containerLogFiles', null);
|
||||
this.set('selectedLogFileContent', '');
|
||||
this.set("selectedAttemptId", "");
|
||||
this.set("attemptContainerList", null);
|
||||
this.set("selectedContainerId", "");
|
||||
this.set("selectedLogFileName", "");
|
||||
this.set("containerLogFiles", null);
|
||||
this.set("selectedLogFileContent", "");
|
||||
},
|
||||
|
||||
showFullLog: false,
|
||||
|
||||
showLastFewLinesOfLogContent: Ember.computed('selectedLogFileContent', function() {
|
||||
let content = this.get('selectedLogFileContent');
|
||||
let lines = content.split('\n');
|
||||
if (this.get('showFullLog') || lines.length < 10) {
|
||||
showLastFewLinesOfLogContent: Ember.computed(
|
||||
"selectedLogFileContent",
|
||||
function() {
|
||||
let content = this.get("selectedLogFileContent");
|
||||
let lines = content.split("\n");
|
||||
if (this.get("showFullLog") || lines.length < 10) {
|
||||
return content;
|
||||
}
|
||||
return lines.slice(lines.length - 10).join('\n');
|
||||
})
|
||||
|
||||
return lines.slice(lines.length - 10).join("\n");
|
||||
}
|
||||
)
|
||||
});
|
||||
|
|
|
@ -34,6 +34,11 @@ export default AbstractRoute.extend(AppAttemptMixin, {
|
|||
});
|
||||
},
|
||||
|
||||
activate() {
|
||||
const controller = this.controllerFor("yarn-app.logs");
|
||||
controller.initializeSelect();
|
||||
},
|
||||
|
||||
unloadAll() {
|
||||
this.store.unloadAll('yarn-app-attempt');
|
||||
this.store.unloadAll('yarn-timeline-appattempt');
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<label>Choose attempt to fetch containers</label>
|
||||
<select class="form-control" onchange={{action "showContainersForAttemptId" value="target.value"}} style="max-width:350px;">
|
||||
<select class="js-fetch-attempt-containers" onchange={{action "showContainersForAttemptId" value="target.value"}} style="max-width:350px;">
|
||||
<option value="" selected={{eq selectedAttemptId ''}}>None</option>
|
||||
{{#each attemptList as |attempt|}}
|
||||
<option value="{{attempt.id}}" selected={{eq selectedAttemptId attempt.id}}>{{attempt.id}}</option>
|
||||
|
@ -42,7 +42,7 @@
|
|||
{{#if attemptContainerList}}
|
||||
<div class="col-md-6">
|
||||
<label>Choose container to fetch logs</label>
|
||||
<select class="form-control" onchange={{action "showLogFilesForContainerId" value="target.value"}} style="max-width:350px">
|
||||
<select class="js-fetch-logs-containers" onchange={{action "showLogFilesForContainerId" value="target.value"}} style="max-width:350px">
|
||||
<option value="" selected={{eq selectedContainerId ''}}>None</option>
|
||||
{{#each attemptContainerList as |container|}}
|
||||
<option value="{{container.id}}" selected={{eq selectedContainerId container.id}}>{{container.id}}</option>
|
||||
|
@ -84,7 +84,7 @@
|
|||
<div class="row">
|
||||
<div class="col-md-6" style="margin-bottom:20px;">
|
||||
<label>Choose log for {{selectedContainerId}}</label>
|
||||
<select class="form-control" onchange={{action "showContentForLogFile" value="target.value"}} style="max-width:350px">
|
||||
<select class="js-fetch-log-for-container" onchange={{action "showContentForLogFile" value="target.value"}} style="max-width:350px">
|
||||
<option value="" selected={{eq selectedLogFileName ''}}>None</option>
|
||||
{{#each containerLogFiles as |file|}}
|
||||
<option value="{{file.fileName}}" selected={{eq selectedLogFileName file.fileName}}>{{file.fileName}} - {{file.fileSize}} bytes</option>
|
||||
|
@ -108,10 +108,10 @@
|
|||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div>
|
||||
{{#if selectedLogFileContent}}
|
||||
{{#unless showFullLog}}
|
||||
<div class="col-md-12">
|
||||
<div>
|
||||
<strong>Showing last 10 lines of log. Click <a href="#" {{action "showFullLogFileContent"}}>here</a> for full log.</strong>
|
||||
</div>
|
||||
{{/unless}}
|
||||
|
|
Loading…
Reference in New Issue