123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- /**
- * 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 Constants from 'yarn-ui/constants';
- export default Ember.Controller.extend({
- queryParams: ["service", "attempt", "containerid"],
- service: undefined,
- attempt: undefined,
- containerid: undefined,
- selectedAttemptId: "",
- attemptContainerList: null,
- selectedContainerId: "",
- selectedLogFileName: "",
- containerLogFiles: null,
- selectedContainerThreaddumpContent: "",
- containerNodeMappings: [],
- threaddumpErrorMessage: "",
- stdoutLogsFetchFailedError: "",
- appAttemptToStateMappings: [],
- _isLoadingTopPanel: false,
- _isLoadingBottomPanel: false,
- _isThreaddumpAttemptFailed: false,
- _isStdoutLogsFetchFailed: false,
- initializeSelect: function(selector = ".js-fetch-attempt-containers") {
- Ember.run.schedule("afterRender", this, function() {
- $(selector).select2({ width: "350px", multiple: false });
- });
- },
- actions: {
- showContainersForAttemptId(attemptId, containerId = "") {
- this.set("selectedAttemptId", "");
- if (attemptId) {
- this.set("_isLoadingTopPanel", true);
- this.set("selectedAttemptId", attemptId);
- this.fetchRunningContainersForAttemptId(attemptId)
- .then(hash => {
- let containers = null;
- let containerIdArr = {};
- var containerNodeMapping = null;
- var nodeHttpAddress = null;
- // Getting RUNNING containers from the RM first.
- if (
- hash.rmContainers.get("length") > 0 &&
- hash.rmContainers.get("content")
- ) {
- // Create a container-to-NMnode mapping for later use.
- hash.rmContainers.get("content").forEach(
- function(containerInfo) {
- nodeHttpAddress = containerInfo._data.nodeHttpAddress;
- nodeHttpAddress = nodeHttpAddress
- .replace(/(^\w+:|^)\/\//, '');
- containerNodeMapping = Ember.Object.create({
- name: containerInfo.id,
- value: nodeHttpAddress
- });
- this.containerNodeMappings.push(containerNodeMapping);
- containerIdArr[containerInfo.id] = true;
- }.bind(this));
- containers = (containers || []).concat(
- hash.rmContainers.get("content")
- );
- }
- this.set("attemptContainerList", containers);
- this.initializeSelect(".js-fetch-threaddump-containers");
- if (containerId) {
- this.send("showThreaddumpForContainer", containerId);
- }
- })
- .finally(() => {
- this.set("_isLoadingTopPanel", false);
- });
- } else {
- this.set("attemptContainerList", null);
- this.set("selectedContainerId", "");
- this.set("containerLogFiles", null);
- this.set("selectedLogFileName", "");
- this.set("selectedContainerThreaddumpContent", "");
- this.set("containerNodeMappings", []);
- }
- },
- showThreaddumpForContainer(containerIdForThreaddump) {
- Ember.$("#logContentTextArea1234554321").val("");
- this.set("showFullThreaddump", false);
- this.set("selectedContainerId", containerIdForThreaddump);
- this.set("_isLoadingBottomPanel", true);
- this.set("_isStdoutLogsFetchFailed", false);
- this.set("stdoutLogsFetchFailedError", "");
- this.set("_isThreaddumpAttemptFailed", false);
- this.set("threaddumpErrorMessage", "");
- if (containerIdForThreaddump) {
- this.set("selectedContainerThreaddumpContent", "");
- this.fetchThreaddumpForContainer(containerIdForThreaddump)
- .then(function() {
- Ember.Logger.log("Threaddump attempt has been successful!");
- var currentContainerId = null;
- var currentContainerNode = null;
- var nodeForContainerThreaddump = null;
- // Fetch the NM node for the selected container from the
- // mappings stored above when
- this.containerNodeMappings.forEach(function(item) {
- currentContainerId = item.name;
- currentContainerNode = item.value;
- if ((currentContainerId === containerIdForThreaddump)
- && nodeForContainerThreaddump == null) {
- nodeForContainerThreaddump = currentContainerNode;
- }
- });
- if (nodeForContainerThreaddump) {
- // Fetch stdout logs after 1.2 seconds of a successful POST
- // request to RM. This is to allow for sufficient time for the NM
- // to heartbeat into RM (default of 1 second) whereupon it will
- // receive RM's signal to post a threaddump that will be captured
- // in the stdout logs of the container. The extra 200ms is to
- // allow for any network/IO delays.
- Ember.run.later((function() {
- this.fetchLogsForContainer(nodeForContainerThreaddump,
- containerIdForThreaddump,
- "stdout")
- .then(
- hash => {
- this.set("selectedContainerThreaddumpContent",
- hash.logs.get('logs').trim());
- }.bind(this))
- .catch(function(error) {
- this.set("_isStdoutLogsFetchFailed", true);
- this.set("stdoutLogsFetchFailedError", error);
- }.bind(this))
- .finally(function() {
- this.set("_isLoadingBottomPanel", false);
- }.bind(this));
- }.bind(this)), 1200);
- }
- }.bind(this), function(error) {
- this.set("_isThreaddumpAttemptFailed", true);
- this.set("threaddumpErrorMessage", error);
- this.set("_isLoadingBottomPanel", false);
- }.bind(this)).finally(function() {
- this.set("selectedContainerThreaddumpContent", "");
- }.bind(this));
- } else {
- this.set("selectedContainerId", "");
- this.set("selectedContainerThreaddumpContent", "");
- }
- }
- },
- // Set up the running attempt for the first time threaddump button is clicked.
- runningAttempt: Ember.computed("model.attempts", function() {
- let attempts = this.get("model.attempts");
- let runningAttemptId = null;
- if (attempts && attempts.get("length") && attempts.get("content")) {
- attempts.get("content").forEach(function(appAttempt) {
- if (appAttempt._data.state === "RUNNING") {
- runningAttemptId = appAttempt._data.appAttemptId;
- }
- });
- }
- return runningAttemptId;
- }),
- /**
- * Create and send fetch running containers request.
- */
- fetchRunningContainersForAttemptId(attemptId) {
- let request = {};
- request["rmContainers"] = this.store
- .query("yarn-container", {
- app_attempt_id: attemptId
- })
- .catch(function(error) {
- return Ember.A();
- });
- return Ember.RSVP.hash(request);
- },
- /**
- * Create and send fetch logs request for a selected container, from a
- * specific node.
- */
- fetchLogsForContainer(nodeForContainer, containerId, logFile) {
- let request = {};
- request["logs"] = this.store
- .queryRecord("yarn-node-container-log", {
- nodeHttpAddr: nodeForContainer,
- containerId: containerId,
- fileName: logFile
- })
- return Ember.RSVP.hash(request);
- },
- /**
- * Send out a POST request to RM to signal a threaddump for the selected
- * container for the currently logged-in user.
- */
- fetchThreaddumpForContainer(containerId) {
- var adapter = this.store.adapterFor("yarn-container-threaddump");
- let requestedUser = "";
- if (this.model
- && this.model.userInfo
- && this.model.userInfo.get('firstObject')) {
- requestedUser = this.model.userInfo
- .get('firstObject')
- .get('requestedUser');
- }
- return adapter.signalContainerForThreaddump({}, containerId, requestedUser);
- },
- /**
- * Reset attributes after a refresh.
- */
- resetAfterRefresh() {
- this.set("selectedAttemptId", "");
- this.set("attemptContainerList", null);
- this.set("selectedContainerId", "");
- this.set("selectedLogFileName", "");
- this.set("containerLogFiles", null);
- this.set("selectedContainerThreaddumpContent", "");
- this.set("containerNodeMappings", []);
- this.set("_isThreaddumpAttemptFailed", false);
- this.set("threaddumpErrorMessage", "");
- this.set("_isStdoutLogsFetchFailed", false);
- this.set("stdoutLogsFetchFailedError", "");
- this.set("appAttemptToStateMappings", []);
- },
- // Set the threaddump content in the content area.
- showThreaddumpContent: Ember.computed(
- "selectedContainerThreaddumpContent",
- function() {
- return this.get("selectedContainerThreaddumpContent");
- }
- ),
- /**
- * Check if the application for the container whose threaddump is being attempted
- * is even running.
- */
- isRunningApp: Ember.computed('model.app.state', function() {
- return this.get('model.app.state') === "RUNNING";
- })
- });
|