YARN-5321. [YARN-3368] Add resource usage for application by node managers (Wangda Tan via Sunil G) YARN-5320. [YARN-3368] Add resource usage by applications and queues to cluster overview page (Wangda Tan via Sunil G) YARN-5322. [YARN-3368] Add a node heat chart map (Wangda Tan via Sunil G) YARN-5347. [YARN-3368] Applications page improvements (Sreenath Somarajapuram via Sunil G) YARN-5348. [YARN-3368] Node details page improvements (Sreenath Somarajapuram via Sunil G) YARN-5346. [YARN-3368] Queues page improvements (Sreenath Somarajapuram via Sunil G) YARN-5345. [YARN-3368] Cluster overview page improvements (Sreenath Somarajapuram via Sunil G) YARN-5344. [YARN-3368] Generic UI improvements (Sreenath Somarajapuram via Sunil G)
Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/d0ccf6f9 Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/d0ccf6f9 Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/d0ccf6f9 Branch: refs/heads/YARN-3368 Commit: d0ccf6f9330f0bd28112e1256113105d9e9ef1b0 Parents: ecf062d Author: Sunil <sun...@apache.org> Authored: Fri Jul 15 21:16:06 2016 +0530 Committer: sunilg <sun...@apache.org> Committed: Thu Sep 8 12:05:08 2016 +0530 ---------------------------------------------------------------------- .../src/main/webapp/app/adapters/yarn-app.js | 14 + .../app/components/app-usage-donut-chart.js | 67 ++++ .../src/main/webapp/app/components/bar-chart.js | 5 + .../app/components/base-chart-component.js | 55 ++- .../app/components/base-usage-donut-chart.js | 43 +++ .../main/webapp/app/components/donut-chart.js | 55 ++- .../main/webapp/app/components/nodes-heatmap.js | 209 +++++++++++ ...er-app-memusage-by-nodes-stacked-barchart.js | 88 +++++ ...app-ncontainers-by-nodes-stacked-barchart.js | 67 ++++ .../app/components/queue-usage-donut-chart.js | 69 ++++ .../main/webapp/app/components/queue-view.js | 3 +- .../main/webapp/app/components/simple-table.js | 9 +- .../webapp/app/components/stacked-barchart.js | 198 +++++++++++ .../main/webapp/app/components/timeline-view.js | 2 +- .../main/webapp/app/components/tree-selector.js | 43 ++- .../webapp/app/controllers/cluster-overview.js | 9 + .../webapp/app/controllers/yarn-app-attempt.js | 40 +++ .../webapp/app/controllers/yarn-app-attempts.js | 40 +++ .../src/main/webapp/app/controllers/yarn-app.js | 38 ++ .../main/webapp/app/controllers/yarn-apps.js | 9 + .../webapp/app/controllers/yarn-node-apps.js | 39 +++ .../app/controllers/yarn-node-containers.js | 39 +++ .../main/webapp/app/controllers/yarn-node.js | 37 ++ .../app/controllers/yarn-nodes-heatmap.js | 36 ++ .../main/webapp/app/controllers/yarn-nodes.js | 33 ++ .../webapp/app/controllers/yarn-queue-apps.js | 46 +++ .../main/webapp/app/controllers/yarn-queue.js | 20 ++ .../main/webapp/app/controllers/yarn-queues.js | 34 ++ .../webapp/app/controllers/yarn-services.js | 34 ++ .../main/webapp/app/models/cluster-metric.js | 2 +- .../main/webapp/app/models/yarn-app-attempt.js | 11 + .../src/main/webapp/app/models/yarn-app.js | 4 + .../src/main/webapp/app/models/yarn-rm-node.js | 7 + .../src/main/webapp/app/router.js | 15 +- .../src/main/webapp/app/routes/application.js | 2 + .../main/webapp/app/routes/cluster-overview.js | 9 +- .../main/webapp/app/routes/yarn-app-attempts.js | 30 ++ .../src/main/webapp/app/routes/yarn-app.js | 17 +- .../src/main/webapp/app/routes/yarn-apps.js | 6 +- .../main/webapp/app/routes/yarn-apps/apps.js | 22 ++ .../webapp/app/routes/yarn-apps/services.js | 22 ++ .../src/main/webapp/app/routes/yarn-node.js | 1 + .../src/main/webapp/app/routes/yarn-nodes.js | 5 +- .../webapp/app/routes/yarn-nodes/heatmap.js | 22 ++ .../main/webapp/app/routes/yarn-nodes/table.js | 22 ++ .../main/webapp/app/routes/yarn-queue-apps.js | 36 ++ .../src/main/webapp/app/routes/yarn-queues.js | 38 ++ .../webapp/app/serializers/yarn-app-attempt.js | 19 +- .../src/main/webapp/app/serializers/yarn-app.js | 8 +- .../webapp/app/serializers/yarn-container.js | 20 +- .../src/main/webapp/app/styles/app.css | 139 ++++++-- .../main/webapp/app/templates/application.hbs | 99 ++++-- .../webapp/app/templates/cluster-overview.hbs | 168 ++++++--- .../app/templates/components/app-table.hbs | 10 +- .../templates/components/node-menu-panel.hbs | 2 +- .../app/templates/components/nodes-heatmap.hbs | 27 ++ .../components/queue-configuration-table.hbs | 4 - .../templates/components/queue-navigator.hbs | 14 +- .../app/templates/components/timeline-view.hbs | 3 +- .../webapp/app/templates/yarn-app-attempt.hbs | 13 +- .../webapp/app/templates/yarn-app-attempts.hbs | 57 +++ .../src/main/webapp/app/templates/yarn-app.hbs | 346 ++++++++++++------- .../src/main/webapp/app/templates/yarn-apps.hbs | 82 ++++- .../webapp/app/templates/yarn-apps/apps.hbs | 24 ++ .../webapp/app/templates/yarn-apps/services.hbs | 27 ++ .../webapp/app/templates/yarn-node-apps.hbs | 4 + .../app/templates/yarn-node-container.hbs | 4 + .../app/templates/yarn-node-containers.hbs | 4 + .../src/main/webapp/app/templates/yarn-node.hbs | 148 ++++---- .../main/webapp/app/templates/yarn-nodes.hbs | 99 +++--- .../webapp/app/templates/yarn-nodes/heatmap.hbs | 30 ++ .../webapp/app/templates/yarn-nodes/table.hbs | 67 ++++ .../webapp/app/templates/yarn-queue-apps.hbs | 66 ++++ .../main/webapp/app/templates/yarn-queue.hbs | 126 ++++--- .../main/webapp/app/templates/yarn-queues.hbs | 72 ++++ .../src/main/webapp/app/utils/color-utils.js | 67 ++++ .../src/main/webapp/app/utils/converter.js | 17 + .../main/webapp/app/utils/href-address-utils.js | 29 ++ .../src/main/webapp/app/utils/mock.js | 36 ++ .../hadoop-yarn-ui/src/main/webapp/bower.json | 3 +- .../hadoop-yarn-ui/src/main/webapp/package.json | 4 + .../unit/controllers/yarn-app-attempt-test.js | 30 ++ .../unit/controllers/yarn-app-attempts-test.js | 30 ++ .../tests/unit/controllers/yarn-app-test.js | 30 ++ .../unit/controllers/yarn-node-apps-test.js | 30 ++ .../controllers/yarn-node-containers-test.js | 30 ++ .../tests/unit/controllers/yarn-node-test.js | 30 ++ .../unit/controllers/yarn-nodes-heatmap-test.js | 30 ++ .../tests/unit/controllers/yarn-nodes-test.js | 30 ++ .../unit/controllers/yarn-queue-apps-test.js | 30 ++ .../tests/unit/controllers/yarn-queues-test.js | 4 +- .../unit/controllers/yarn-services-test.js | 30 ++ .../tests/unit/routes/yarn-app-attempts-test.js | 29 ++ .../tests/unit/routes/yarn-queue-apps-test.js | 29 ++ .../tests/unit/routes/yarn-queues-test.js | 29 ++ 95 files changed, 3399 insertions(+), 482 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js index afd93f4..67a2847 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js @@ -23,6 +23,20 @@ export default AbstractAdapter.extend({ restNameSpace: "cluster", serverName: "RM", + urlForQuery(query, modelName) { + var url = this._buildURL(); + if (query.state) { + url = url + '/apps/?state=' + query.state; + } + return url; + }, + + urlForFindRecord(id, modelName, snapshot) { + var url = this._buildURL(); + url = url + '/apps/' + id; + return url; + }, + pathForType(modelName) { return 'apps'; // move to some common place, return path by modelname. }, http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-usage-donut-chart.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-usage-donut-chart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-usage-donut-chart.js new file mode 100644 index 0000000..0baf630 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-usage-donut-chart.js @@ -0,0 +1,67 @@ +/** + * 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 DonutChart from 'yarn-ui/components/donut-chart'; +import BaseUsageDonutChart from 'yarn-ui/components/base-usage-donut-chart'; +import ColorUtils from 'yarn-ui/utils/color-utils'; +import HrefAddressUtils from 'yarn-ui/utils/href-address-utils'; + +export default BaseUsageDonutChart.extend({ + colors: d3.scale.category20().range(), + + draw: function() { + this.initChart(); + var usageByApps = []; + var avail = 100; + + this.get("data").forEach(function (app) { + var v = app.get("clusterUsagePercentage"); + if (v > 1e-2) { + usageByApps.push({ + label: app.get("id"), + link: HrefAddressUtils.getApplicationLink(app.get("id")), + value: v.toFixed(2) + }); + + console.log(v); + avail = avail - v; + } + }.bind(this)); + + usageByApps.sort(function(a,b) { + return b.value - a.value; + }); + + usageByApps = this.mergeLongTails(usageByApps, 8); + + usageByApps.push({ + label: "Available", + value: avail.toFixed(4) + }) + + this.colors = ColorUtils.getColors(usageByApps.length, ["others", "good"], true); + + this.renderDonutChart(usageByApps, this.get("title"), this.get("showLabels"), + this.get("middleLabel"), "100%", "%"); + }, + + didInsertElement: function() { + this.draw(); + }, +}) \ No newline at end of file http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js index 8e48279..7bb292f 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js @@ -116,6 +116,11 @@ export default BaseChartComponent.extend({ this.renderBarChart(this.get("data"), this.get("title"), this.get("textWidth")); }, + _dataChange: Ember.observer("data", function() { + this.chart.g.selectAll("*").remove(); + this.renderBarChart(this.get("data"), this.get("title"), this.get("textWidth")); + }), + didInsertElement: function() { this.draw(); }, http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-chart-component.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-chart-component.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-chart-component.js index b85b6ab4..d221488 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-chart-component.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-chart-component.js @@ -17,23 +17,26 @@ */ import Ember from 'ember'; +import Converter from 'yarn-ui/utils/converter'; export default Ember.Component.extend({ - chart: undefined, tooltip : undefined, colors: d3.scale.category10().range(), - initChart: function() { - this.chart = { + init: function () { + this._super(); + this.set("chart", { svg: undefined, g: undefined, h: 0, w: 0, tooltip: undefined - }; + }); + }, + initChart: function(removeLast = false) { // Init tooltip if it is not initialized - this.tooltip = d3.select("#chart-tooltip"); + // this.tooltip = d3.select("#chart-tooltip"); if (!this.tooltip) { this.tooltip = d3.select("body") .append("div") @@ -42,13 +45,16 @@ export default Ember.Component.extend({ .style("opacity", 0); } - // Init svg - var svg = this.chart.svg; - if (svg) { - svg.remove(); + var parentId = this.get("parentId"); + + if (removeLast) { + // Init svg + var svg = d3.select("#" + parentId + "-svg"); + if (svg) { + svg.remove(); + } } - var parentId = this.get("parentId"); var parent = d3.select("#" + parentId); var bbox = parent.node().getBoundingClientRect(); this.chart.w = bbox.width - 30; @@ -65,12 +71,13 @@ export default Ember.Component.extend({ this.chart.svg = parent.append("svg") .attr("width", this.chart.w) - .attr("height", this.chart.h); + .attr("height", this.chart.h) + .attr("id", parentId + "-svg"); this.chart.g = this.chart.svg.append("g"); }, - renderTitleAndBG: function(g, title, layout) { + renderTitleAndBG: function(g, title, layout, background=true) { var bg = g.append("g"); bg.append("text") .text(title) @@ -78,12 +85,14 @@ export default Ember.Component.extend({ .attr("y", layout.y1 + layout.margin + 20) .attr("class", "chart-title"); - bg.append("rect") - .attr("x", layout.x1) - .attr("y", layout.y1) - .attr("width", layout.x2 - layout.x1) - .attr("height", layout.y2 - layout.y1) - .attr("class", "chart-frame"); + if (background) { + bg.append("rect") + .attr("x", layout.x1) + .attr("y", layout.y1) + .attr("width", layout.x2 - layout.x1) + .attr("height", layout.y2 - layout.y1) + .attr("class", "chart-frame"); + } }, bindTooltip: function(d) { @@ -100,7 +109,11 @@ export default Ember.Component.extend({ } this.tooltip.style("opacity", .9); - this.tooltip.html(data.label + " = " + data.value) + var value = data.value; + if (this.get("type") == "memory") { + value = Converter.memoryToSimpliedUnit(value); + } + this.tooltip.html(data.label + " = " + value) .style("left", (d3.event.pageX) + "px") .style("top", (d3.event.pageY - 28) + "px"); }.bind(this)) @@ -109,6 +122,10 @@ export default Ember.Component.extend({ }.bind(this)); }, + adjustMaxHeight: function(h) { + this.chart.svg.attr("height", h); + }, + getLayout: function() { var x1 = 0; var y1 = 0; http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-usage-donut-chart.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-usage-donut-chart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-usage-donut-chart.js new file mode 100644 index 0000000..bec06c9 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-usage-donut-chart.js @@ -0,0 +1,43 @@ +/** + * 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 DonutChart from 'yarn-ui/components/donut-chart'; + +export default DonutChart.extend({ + mergeLongTails: function(usages, nItemsKept) { + var arr = []; + for (var i = 0; i < Math.min(usages.length, nItemsKept); i++) { + arr.push(usages[i]); + } + + var others = { + label: "Used by others", + value: 0 + } + + for (var i = nItemsKept; i < usages.length; i++) { + others.value += Number(usages[i].value); + } + others.value = others.value.toFixed(2); + + arr.push(others) + + return arr; + }, +}) \ No newline at end of file http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js index e6dcb12..9a90855 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js @@ -18,13 +18,15 @@ import Ember from 'ember'; import BaseChartComponent from 'yarn-ui/components/base-chart-component'; +import ColorUtils from 'yarn-ui/utils/color-utils'; +import Converter from 'yarn-ui/utils/converter'; export default BaseChartComponent.extend({ /* * data = [{label="xx", value=},{...}] */ renderDonutChart: function(data, title, showLabels = false, - middleLabel = "Total", middleValue = undefined) { + middleLabel = "Total", middleValue = undefined, suffix = "") { var g = this.chart.g; var layout = this.getLayout(); this.renderTitleAndBG(g, title, layout); @@ -39,7 +41,11 @@ export default BaseChartComponent.extend({ } if (!middleValue) { - middleValue = total; + if (this.get("type") == "memory") { + middleValue = Converter.memoryToSimpliedUnit(total); + } else { + middleValue = total; + } } //Width and height @@ -48,6 +54,8 @@ export default BaseChartComponent.extend({ // 50 is for title var outerRadius = (h - 50 - 2 * layout.margin) / 2; var innerRadius = outerRadius * 0.618; + console.log("inner:" + innerRadius + " outer:" + outerRadius); + var arc = d3.svg.arc() .innerRadius(innerRadius) .outerRadius(outerRadius); @@ -104,12 +112,14 @@ export default BaseChartComponent.extend({ return this.colors[i]; } }.bind(this)) - .attr("stroke-dasharray", function(d, i) { - if (d.value <= 1e-6) { - return "10,10"; - } - }.bind(this)); this.bindTooltip(path); + path.on("click", function (d) { + var data = d.data; + if (data.link) { + this.tooltip.remove(); + document.location.href = data.link; + } + }.bind(this)) // Show labels if (showLabels) { @@ -126,27 +136,30 @@ export default BaseChartComponent.extend({ }.bind(this)) .attr("x", lx) .attr("y", function(d, i) { - return layout.y1 + 50 + (squareW + margin) * i + layout.margin; + return layout.y1 + 75 + (squareW + margin) * i + layout.margin; }) .attr("width", squareW) .attr("height", squareW); select.append("text") .attr("x", lx + squareW + margin) .attr("y", function(d, i) { - return layout.y1 + 50 + (squareW + margin) * i + layout.margin + squareW / 2; + return layout.y1 + 80 + (squareW + margin) * i + layout.margin + squareW / 2; }) .text(function(d) { - return d.label + ' = ' + d.value; - }); + var value = d.value; + if (this.get("type") == "memory") { + value = Converter.memoryToSimpliedUnit(value); + } + return d.label + ' = ' + value + suffix; + }.bind(this)); } if (middleLabel) { var highLightColor = this.colors[0]; g.append("text").text(middleLabel).attr("x", cx).attr("y", cy - 10). attr("class", "donut-highlight-text").attr("fill", highLightColor); - g.append("text").text(middleValue).attr("x", cx).attr("y", cy + 20). - attr("class", "donut-highlight-text").attr("fill", highLightColor). - style("font-size", "30px"); + g.append("text").text(middleValue).attr("x", cx).attr("y", cy + 15). + attr("class", "donut-highlight-sub").attr("fill", highLightColor); } path.transition() @@ -154,8 +167,22 @@ export default BaseChartComponent.extend({ .attrTween('d', tweenPie); }, + _dataChange: Ember.observer("data", function() { + this.chart.g.selectAll("*").remove(); + this.renderDonutChart(this.get("data"), this.get("title"), this.get("showLabels"), + this.get("middleLabel"), this.get("middleValue")); + }), + draw: function() { this.initChart(); + + var colorTargets = this.get("colorTargets"); + if (colorTargets) { + var colorTargetReverse = Boolean(this.get("colorTargetReverse")); + var targets = colorTargets.split(" "); + this.colors = ColorUtils.getColors(this.get("data").length, targets, colorTargetReverse); + } + this.renderDonutChart(this.get("data"), this.get("title"), this.get("showLabels"), this.get("middleLabel"), this.get("middleValue")); }, http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/nodes-heatmap.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/nodes-heatmap.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/nodes-heatmap.js new file mode 100644 index 0000000..af8ceb3 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/nodes-heatmap.js @@ -0,0 +1,209 @@ +/** + * 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 BaseChartComponent from 'yarn-ui/components/base-chart-component'; +import Mock from 'yarn-ui/utils/mock'; + +export default BaseChartComponent.extend({ + CELL_WIDTH: 250, + SAMPLE_CELL_WIDTH: 100, + SAMPLE_HEIGHT: 30, + CELL_HEIGHT: 30, + CELL_MARGIN: 2, + RACK_MARGIN: 20, + filter: "", + + bindTP: function(element) { + element.on("mouseover", function() { + this.tooltip + .style("left", (d3.event.pageX) + "px") + .style("top", (d3.event.pageY - 28) + "px"); + element.style("opacity", 1.0); + }.bind(this)) + .on("mousemove", function() { + // Handle pie chart case + var text = element.attr("tooltiptext"); + + this.tooltip.style("opacity", .9); + this.tooltip.html(text) + .style("left", (d3.event.pageX) + "px") + .style("top", (d3.event.pageY - 28) + "px"); + }.bind(this)) + .on("mouseout", function() { + this.tooltip.style("opacity", 0); + element.style("opacity", 0.8); + }.bind(this)); + }, + + // data: + // [{label=label1, value=value1}, ...] + // ... + renderCells: function (model, title) { + var data = []; + model.forEach(function (o) { + data.push(o); + }); + + this.chart.g.remove(); + this.chart.g = this.chart.svg.append("g"); + var g = this.chart.g; + var layout = this.getLayout(); + layout.margin = 50; + + let racks = new Set(); + for (var i = 0; i < data.length; i++) { + racks.add(data[i].get("rack")); + } + + let racksArray = []; + racks.forEach(v => racksArray.push(v)); + + var xOffset = layout.margin; + var yOffset = layout.margin * 3; + + var colorFunc = d3.interpolate(d3.rgb("#bdddf5"), d3.rgb("#0f3957")); + + var sampleXOffset = (layout.x2 - layout.x1) / 2 - 2.5 * this.SAMPLE_CELL_WIDTH - + 2 * this.CELL_MARGIN; + var sampleYOffset = layout.margin * 2; + + for (var i = 1; i <= 5; i++) { + var ratio = i * 0.2 - 0.1; + + var rect = g.append("rect") + .attr("x", sampleXOffset) + .attr("y", sampleYOffset) + .attr("fill", colorFunc(ratio)) + .attr("width", this.SAMPLE_CELL_WIDTH) + .attr("height", this.SAMPLE_HEIGHT); + g.append("text") + .text("" + (ratio * 100).toFixed(1) + "% Used") + .attr("y", sampleYOffset + this.SAMPLE_HEIGHT / 2 + 5) + .attr("x", sampleXOffset + this.SAMPLE_CELL_WIDTH / 2) + .attr("class", "heatmap-cell"); + sampleXOffset += this.CELL_MARGIN + this.SAMPLE_CELL_WIDTH; + } + + var chartXOffset = -1; + + for (var i = 0; i < racksArray.length; i++) { + var text = g.append("text") + .text(racksArray[i]) + .attr("y", yOffset + this.CELL_HEIGHT / 2 + 5) + .attr("x", layout.margin) + .attr("class", "heatmap-rack"); + + if (-1 == chartXOffset) { + chartXOffset = layout.margin + text.node().getComputedTextLength() + 30; + } + + xOffset = chartXOffset; + + for (var j = 0; j < data.length; j++) { + var rack = data[j].get("rack"); + var host = data[j].get("nodeHostName"); + + if (rack == racksArray[i]) { + if (!rack.includes(this.filter) && !host.includes(this.filter)) { + this.addNode(g, xOffset, yOffset, colorFunc, data[j], false); + var text = g.append("text") + .text(host) + .attr("y", yOffset + this.CELL_HEIGHT / 2 + 5) + .attr("x", xOffset + this.CELL_WIDTH / 2) + .attr("class", "heatmap-cell-notselected"); + } else { + this.addNode(g, xOffset, yOffset, colorFunc, data[j], true); + g.append("text") + .text(host) + .attr("y", yOffset + this.CELL_HEIGHT / 2 + 5) + .attr("x", xOffset + this.CELL_WIDTH / 2) + .attr("class", "heatmap-cell"); + } + + xOffset += this.CELL_MARGIN + this.CELL_WIDTH; + if (xOffset + this.CELL_MARGIN + this.CELL_WIDTH >= layout.x2 - + layout.margin) { + xOffset = chartXOffset; + yOffset = yOffset + this.CELL_MARGIN + this.CELL_HEIGHT; + } + + } + } + + while (xOffset > chartXOffset && xOffset + this.CELL_MARGIN + + this.CELL_WIDTH < layout.x2 - layout.margin) { + this.addPlaceholderNode(g, xOffset, yOffset); + xOffset += this.CELL_MARGIN + this.CELL_WIDTH; + } + + if (xOffset != chartXOffset) { + xOffset = chartXOffset; + yOffset += this.CELL_MARGIN + this.CELL_HEIGHT; + } + yOffset += this.RACK_MARGIN; + } + + layout.y2 = yOffset + layout.margin; + this.adjustMaxHeight(layout.y2); + this.renderTitleAndBG(g, title, layout, false); + }, + + addNode: function (g, xOffset, yOffset, colorFunc, data, selected) { + var rect = g.append("rect") + .attr("y", yOffset) + .attr("x", xOffset) + .attr("height", this.CELL_HEIGHT) + .attr("fill", colorFunc(data.get("usedMemoryMB") / + (data.get("usedMemoryMB") + data.get("availMemoryMB")))) + .attr("width", this.CELL_WIDTH) + .attr("tooltiptext", data.get("toolTipText")); + if (selected) { + rect.style("opacity", 0.8); + this.bindTP(rect); + } else { + rect.style("opacity", 0.8); + rect.attr("fill", "DimGray"); + } + }, + + addPlaceholderNode: function(g, xOffset, yOffset) { + var rect = g.append("rect") + .attr("y", yOffset) + .attr("x", xOffset) + .attr("height", this.CELL_HEIGHT) + .attr("fill", "grey") + .attr("width", this.CELL_WIDTH) + .style("opacity", 0.20); + }, + + draw: function() { + this.initChart(true); + this.renderCells(this.get("model"), this.get("title"), this.get("textWidth")); + }, + + didInsertElement: function () { + this.draw(); + }, + + actions: { + applyFilter: function(event) { + this.filter = event.srcElement.value; + this.didInsertElement(); + } + } +}) \ No newline at end of file http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-memusage-by-nodes-stacked-barchart.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-memusage-by-nodes-stacked-barchart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-memusage-by-nodes-stacked-barchart.js new file mode 100644 index 0000000..7feb7bb --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-memusage-by-nodes-stacked-barchart.js @@ -0,0 +1,88 @@ +/** + * 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 StackedBarchart from 'yarn-ui/components/stacked-barchart'; +import Converter from 'yarn-ui/utils/converter'; + +export default StackedBarchart.extend({ + getDataForRender: function(containers, nodes) { + var arr = []; + var nodeToResources = {}; + nodes.forEach(function(n) { + nodeToResources[n.id] = + { + used: Number(n.get("usedMemoryMB")), + avail: Number(n.get("availMemoryMB")) + } + }); + + containers.forEach(function(c) { + res = nodeToResources[c.get("assignedNodeId")]; + if (res) { + if (!res.usedByTheApp) { + res.usedByTheApp = 0; + } + res.usedByTheApp += Number(c.get("allocatedMB")); + } + }); + + for (var nodeId in nodeToResources) { + var res = nodeToResources[nodeId]; + + var subArr = []; + var value = res.usedByTheApp ? res.usedByTheApp : 0; + subArr.push({ + value: value, + bindText: "This app uses " + Converter.memoryToSimpliedUnit(value) + ". On node=" + nodeId, + }); + + value = res.used - value; + value = Math.max(value, 0); + subArr.push({ + value: value, + bindText: "Other applications uses " + Converter.memoryToSimpliedUnit(value) + ". On node=" + nodeId, + }); + + subArr.push({ + value: res.avail, + bindText: "Free resource " + Converter.memoryToSimpliedUnit(res.avail) + " . On node=" + nodeId + }); + + arr.push(subArr); + } + + console.log(arr); + + return arr; + }, + + didInsertElement: function() { + this.initChart(true); + + this.colors = ["Orange", "Grey", "LimeGreen"]; + + var containers = this.get("rmContainers"); + var nodes = this.get("nodes"); + + var data = this.getDataForRender(containers, nodes); + + this.show( + data, this.get("title"), ["Used by this app", "Used by other apps", + "Available"]); + }, +}) http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-ncontainers-by-nodes-stacked-barchart.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-ncontainers-by-nodes-stacked-barchart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-ncontainers-by-nodes-stacked-barchart.js new file mode 100644 index 0000000..251f557 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-ncontainers-by-nodes-stacked-barchart.js @@ -0,0 +1,67 @@ +/** + * 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 StackedBarchart from 'yarn-ui/components/stacked-barchart'; + +export default StackedBarchart.extend({ + getDataForRender: function(containers, nodes) { + var arr = []; + var nodeToContainers = {}; + nodes.forEach(function(n) { + nodeToContainers[n.id] = 0; + }); + + containers.forEach(function(c) { + var nodeId = c.get("assignedNodeId"); + var n = nodeToContainers[nodeId]; + if (undefined != n) { + nodeToContainers[nodeId] += 1; + } + }); + + for (var nodeId in nodeToContainers) { + var n = nodeToContainers[nodeId]; + + var subArr = []; + subArr.push({ + value: n, + bindText: "This app has " + n + " containers running on node=" + nodeId + }); + + arr.push(subArr); + } + + console.log(arr); + + return arr; + }, + + didInsertElement: function() { + this.initChart(true); + + this.colors = ["Orange", "Grey", "Gainsboro"]; + + var containers = this.get("rmContainers"); + var nodes = this.get("nodes"); + + var data = this.getDataForRender(containers, nodes); + + this.show( + data, this.get("title"), ["Running containers from this app"]); + }, +}) http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-usage-donut-chart.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-usage-donut-chart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-usage-donut-chart.js new file mode 100644 index 0000000..3532726 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-usage-donut-chart.js @@ -0,0 +1,69 @@ +/** + * 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 DonutChart from 'yarn-ui/components/donut-chart'; +import BaseUsageDonutChart from 'yarn-ui/components/base-usage-donut-chart'; +import ColorUtils from 'yarn-ui/utils/color-utils'; +import HrefAddressUtils from 'yarn-ui/utils/href-address-utils'; + +export default BaseUsageDonutChart.extend({ + colors: d3.scale.category20().range(), + + draw: function() { + this.initChart(); + var usageByQueues = []; + var avail = 100; + + this.get("data").forEach(function (queue) { + var v = queue.get("absUsedCapacity"); + + if (queue.get("isLeafQueue")) { + if (v > 1e-2) { + usageByQueues.push({ + label: queue.get("id"), + link: HrefAddressUtils.getQueueLink(queue.get("id")), + value: v.toFixed(2) + }); + + avail = avail - v; + } + } + }); + + usageByQueues.sort(function(a, b) { + return b.value - a.value; + }); + + usageByQueues = this.mergeLongTails(usageByQueues, 8); + + usageByQueues.push({ + label: "Available", + value: avail.toFixed(4) + }); + + this.colors = ColorUtils.getColors(usageByQueues.length, ["others", "good"], true); + + this.renderDonutChart(usageByQueues, this.get("title"), this.get("showLabels"), + this.get("middleLabel"), "100%", "%"); + }, + + didInsertElement: function() { + this.draw(); + }, +}) \ No newline at end of file http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-view.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-view.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-view.js index 2a90771..adedf9a 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-view.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-view.js @@ -90,7 +90,6 @@ export default Ember.Component.extend(ChartUtilsMixin, { .attr("class", "queue"); circle.on('mouseover', function () { - circle.style("fill", this.queueColors[1]); }.bind(this)); circle.on('mouseout', function () { if (circle != this.queues.selectedQueueCircle) { @@ -206,7 +205,7 @@ export default Ember.Component.extend(ChartUtilsMixin, { renderQueueCapacities: function (queue, layout) { // Render bar chart - this.renderBarChart(this.charts.g, [{ + this.renderCells(this.charts.g, [{ label: "Cap", value: queue.get("capacity") }, { http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/simple-table.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/simple-table.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/simple-table.js index e5da81a..359583d 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/simple-table.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/simple-table.js @@ -1,3 +1,4 @@ + /** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -24,6 +25,7 @@ export default Ember.Component.extend({ var ordering = this.get("ordering") ? true : this.get("ordering"); var info = this.get("info") ? true : this.get("info"); var bFilter = this.get("bFilter") ? true : this.get("bFilter"); + var defaultSearch = this.get("defaultSearch") ? this.get("defaultSearch") : ""; // Defines sorter for the columns if not default. // Can also specify a custom sorter. @@ -66,11 +68,14 @@ export default Ember.Component.extend({ console.log(orderArr[0]); Ember.$('#' + this.get('table-id')).DataTable({ "paging": paging, - "ordering": ordering, + "ordering": ordering, "info": info, "bFilter": bFilter, "order": orderArr, - "columnDefs": colDefs + "columnDefs": colDefs, + "oSearch": { + "sSearch": defaultSearch + } }); } }); http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/stacked-barchart.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/stacked-barchart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/stacked-barchart.js new file mode 100644 index 0000000..4a121fe --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/stacked-barchart.js @@ -0,0 +1,198 @@ +/** + * 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 BaseChartComponent from 'yarn-ui/components/base-chart-component'; +import Mock from 'yarn-ui/utils/mock'; + +export default BaseChartComponent.extend({ + MAX_BAR_HEIGHT: 120, + MAX_BAR_WIDTH: 30, + GAP: 5, + filter: "", + WIDTH_OF_SAMPLE: 200, + + bindTP: function(element) { + element.on("mouseover", function() { + this.tooltip + .style("left", (d3.event.pageX) + "px") + .style("top", (d3.event.pageY - 28) + "px"); + element.style("opacity", 1.0); + }.bind(this)) + .on("mousemove", function() { + // Handle pie chart case + var text = element.attr("tooltiptext"); + + this.tooltip.style("opacity", .9); + this.tooltip.html(text) + .style("left", (d3.event.pageX) + "px") + .style("top", (d3.event.pageY - 28) + "px"); + }.bind(this)) + .on("mouseout", function() { + this.tooltip.style("opacity", 0); + element.style("opacity", 0.8); + }.bind(this)); + + element.on("click", function() { + if (element.attr("link")) { + this.tooltip.remove(); + document.location.href = element.attr("link"); + } + }.bind(this)); + }, + + printSamples: function(n, layout, g, colorTitles) { + var yOffset = layout.margin * 3; + + for (var i = 0; i < n; i++) { + var xOffset = layout.x2 - this.WIDTH_OF_SAMPLE - layout.margin; + g.append("rect"). + attr("fill", this.colors[i]). + attr("x", xOffset). + attr("y", yOffset). + attr("width", 20). + attr("height", 20); + + g.append("text"). + attr("x", xOffset + 30). + attr("y", yOffset + 10). + text(colorTitles[i]); + + yOffset = yOffset + 30; + } + }, + + // data: + // [[{value=xx, bindText=xx}, {value=yy, bindText=yy}], [ ... ]] + // __________________________________________________ ___________ + // bar-1 bar-2 + show: function (data, title, colorTitles) { + var width = this.MAX_BAR_WIDTH; + var height = this.MAX_BAR_HEIGHT; + + this.chart.g.remove(); + this.chart.g = this.chart.svg.append("g"); + var g = this.chart.g; + var layout = this.getLayout(); + layout.margin = 50; + + var nBarPerRow = Math.floor((layout.x2 - layout.x1 - 3 * layout.margin - + this.WIDTH_OF_SAMPLE) / + (width + this.GAP)); + + var xOffset; + var yOffset = layout.margin * 2; + + var maxValue = 0; + var maxN = 0; + for (var i = 0; i < data.length; i++) { + var total = 0; + for (var j = 0; j < data[i].length; j++) { + total += data[i][j].value; + } + + if (total > maxValue) { + maxValue = total; + } + if (data[i].length > maxN) { + maxN = data[i].length; + } + } + + // print samples + this.printSamples(maxN, layout, g, colorTitles); + + // print data + data.sort(function(a, b) { + return b[0].value - a[0].value; + }); + + for (var i = 0; i < data.length; i++) { + if (i % nBarPerRow == 0) { + xOffset = layout.margin; + yOffset += layout.margin + height; + } + + var leftTopY = yOffset; + for (var j = 0; j < data[i].length; j++) { + var dy = data[i][j].value * height / maxValue; + if (dy > 0) { + leftTopY = leftTopY - dy; + + var node = g.append("rect"). + attr("fill", this.colors[j]). + attr("x", xOffset). + attr("y", leftTopY). + attr("width", width). + attr("height", dy). + attr("tooltiptext", + (data[i][j].bindText) ? data[i][j].bindText : data[i][j].value). + attr("link", data[i][j].link) + .style("opacity", 0.8); + + this.bindTP(node); + } + } + + if (data[i].length == 1) { + g.append("text") + .text(data[i][0].value) + .attr("y", leftTopY - 10) + .attr("x", xOffset + width / 2) + .attr("class", "heatmap-cell") + .style("fill", "black"); + } + + xOffset += width + this.GAP; + } + + layout.y2 = yOffset + layout.margin; + this.adjustMaxHeight(layout.y2); + this.renderTitleAndBG(g, title, layout, false); + }, + + draw: function(data, title, textWidth) { + this.initChart(true); + //Mock.initMockNodesData(this); + + // mock data + var arr = []; + for (var i = 0; i < 5; i++) { + var subArr = []; + for (var j = 0; j < Math.random() * 4 + 1; j++) { + subArr.push({ + value : Math.abs(Math.random()) + }); + } + arr.push(subArr); + } + + this.show( + arr, this.get("title")); + }, + + didInsertElement: function () { + this.draw(); + }, + + actions: { + applyFilter: function(event) { + this.filter = event.srcElement.value; + this.didInsertElement(); + } + } +}) \ No newline at end of file http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js index 8a2b3de..516b114 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js @@ -105,7 +105,7 @@ export default Ember.Component.extend({ var border = 30; var singleBarHeight = this.getPerItemHeight(); var gap = this.getPerItemGap(); - var textWidth = 50; + var textWidth = 200; /* start-time end-time |--------------------------------------| http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/tree-selector.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/tree-selector.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/tree-selector.js index 1af98ab..5e7cfa0 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/tree-selector.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/tree-selector.js @@ -18,6 +18,8 @@ import Ember from 'ember'; +const INBETWEEN_HEIGHT = 130; + export default Ember.Component.extend({ // Map: <queue-name, queue> map : undefined, @@ -124,12 +126,25 @@ export default Ember.Component.extend({ var nodeEnter = node.enter().append("g") .attr("class", "node") .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; }) - .on("click", function(d,i){ + .on("mouseover", function(d,i){ if (d.queueData.get("name") != this.get("selected")) { - document.location.href = "#/yarn-queue/" + d.queueData.get("name"); + document.location.href = "#/yarn-queues/" + d.queueData.get("name"); } - }.bind(this)); - // .on("click", click); + + Ember.run.later(this, function () { + var treeWidth = this.maxDepth * 200; + var treeHeight = this.numOfLeafQueue * INBETWEEN_HEIGHT; + var tree = d3.layout.tree().size([treeHeight, treeWidth]); + var diagonal = d3.svg.diagonal() + .projection(function(d) { return [d.y, d.x]; }); + + this.update(this.treeData, this.treeData, tree, diagonal); + }, 100); + + }.bind(this)) + .on("click", function (d) { + document.location.href = "#/yarn-queue/" + d.queueData.get("name"); + }); nodeEnter.append("circle") .attr("r", 1e-6) @@ -148,6 +163,7 @@ export default Ember.Component.extend({ nodeEnter.append("text") .attr("x", function(d) { return 0; }) .attr("dy", ".35em") + .attr("fill", "white") .attr("text-anchor", function(d) { return "middle"; }) .text(function(d) { var usedCap = d.queueData.get("usedCapacity"); @@ -161,9 +177,9 @@ export default Ember.Component.extend({ // append queue name nodeEnter.append("text") - .attr("x", function(d) { return 40; }) - .attr("dy", ".35em") - .attr("text-anchor", function(d) { return "start"; }) + .attr("x", "0px") + .attr("dy", "45px") + .attr("text-anchor", "middle") .text(function(d) { return d.name; }) .style("fill-opacity", 1e-6); @@ -173,14 +189,21 @@ export default Ember.Component.extend({ .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }); nodeUpdate.select("circle") - .attr("r", 20) + .attr("r", 30) .attr("href", function(d) { return "#/yarn-queues/" + d.queueData.get("name"); }) + .style("stroke-width", function(d) { + if (d.queueData.get("name") == this.get("selected")) { + return 7; + } else { + return 2; + } + }.bind(this)) .style("stroke", function(d) { if (d.queueData.get("name") == this.get("selected")) { - return "red"; + return "gray"; } else { return "gray"; } @@ -239,7 +262,7 @@ export default Ember.Component.extend({ var margin = {top: 20, right: 120, bottom: 20, left: 120}; var treeWidth = this.maxDepth * 200; - var treeHeight = this.numOfLeafQueue * 80; + var treeHeight = this.numOfLeafQueue * INBETWEEN_HEIGHT; var width = treeWidth + margin.left + margin.right; var height = treeHeight + margin.top + margin.bottom; var layout = { }; http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/cluster-overview.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/cluster-overview.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/cluster-overview.js index dc2f6e4..22e6267 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/cluster-overview.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/cluster-overview.js @@ -20,4 +20,13 @@ import Ember from 'ember'; export default Ember.Controller.extend({ loading: true, + + breadcrumbs: [{ + text: "Home", + routeName: 'application' + }, { + text: "Cluster Overview", + routeName: 'cluster-overview', + }] + }); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempt.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempt.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempt.js new file mode 100644 index 0000000..a458842 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempt.js @@ -0,0 +1,40 @@ +/** + * 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'; + +export default Ember.Controller.extend({ + + breadcrumbs: Ember.computed("model.attempt.appId", function () { + var appId = this.get("model.attempt.appId"); + return [{ + text: "Home", + routeName: 'application' + },{ + text: "Applications", + routeName: 'yarn-apps' + }, { + text: `App [${appId}]`, + routeName: 'yarn-app', + model: appId + }, { + text: "Attempt", + }]; + }) + +}); http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempts.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempts.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempts.js new file mode 100644 index 0000000..9ebc2a6 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempts.js @@ -0,0 +1,40 @@ +/** + * 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'; + +export default Ember.Controller.extend({ + + breadcrumbs: Ember.computed("model.appId", function () { + var appId = this.get("model.appId"); + return [{ + text: "Home", + routeName: 'application' + },{ + text: "Applications", + routeName: 'yarn-apps' + }, { + text: `App [${appId}]`, + routeName: 'yarn-app', + model: appId + }, { + text: "Attempts", + }]; + }) + +}); http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app.js new file mode 100644 index 0000000..f6b9404 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app.js @@ -0,0 +1,38 @@ +/** + * 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'; + +export default Ember.Controller.extend({ + + breadcrumbs: Ember.computed("model.app.id", function () { + var appId = this.get("model.app.id"); + return [{ + text: "Home", + routeName: 'application' + },{ + text: "Applications", + routeName: 'yarn-apps' + }, { + text: `App [${appId}]`, + routeName: 'yarn-app', + model: appId + }]; + }) + +}); http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-apps.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-apps.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-apps.js index dc99fd1..396f83b 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-apps.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-apps.js @@ -19,4 +19,13 @@ import Ember from 'ember'; export default Ember.Controller.extend({ + + breadcrumbs: [{ + text: "Home", + routeName: 'application' + }, { + text: "Applications", + routeName: 'yarn-apps', + }] + }); http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-apps.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-apps.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-apps.js new file mode 100644 index 0000000..4bfe9d0 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-apps.js @@ -0,0 +1,39 @@ +/** + * 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'; + +export default Ember.Controller.extend({ + + breadcrumbs: Ember.computed("model.attempt.appId", function () { + var nodeInfo = this.get("model.nodeInfo"); + return [{ + text: "Home", + routeName: 'application' + },{ + text: "Nodes", + routeName: 'yarn-nodes' + }, { + text: `Node [ ${nodeInfo.id} ]`, + href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`, + }, { + text: "Applications", + }]; + }) + +}); http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-containers.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-containers.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-containers.js new file mode 100644 index 0000000..59c8591 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-containers.js @@ -0,0 +1,39 @@ +/** + * 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'; + +export default Ember.Controller.extend({ + + breadcrumbs: Ember.computed("model.nodeInfo", function () { + var nodeInfo = this.get("model.nodeInfo"); + return [{ + text: "Home", + routeName: 'application' + },{ + text: "Nodes", + routeName: 'yarn-nodes' + }, { + text: `Node [ ${nodeInfo.id} ]`, + href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`, + }, { + text: "Containers", + }]; + }) + +}); http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node.js new file mode 100644 index 0000000..e505022 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node.js @@ -0,0 +1,37 @@ +/** + * 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'; + +export default Ember.Controller.extend({ + + breadcrumbs: Ember.computed("model.attempt.appId", function () { + var nodeInfo = this.get("model.nodeInfo"); + return [{ + text: "Home", + routeName: 'application' + },{ + text: "Nodes", + routeName: 'yarn-nodes' + }, { + text: `Node [ ${nodeInfo.id} ]`, + href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`, + }]; + }) + +}); http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes-heatmap.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes-heatmap.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes-heatmap.js new file mode 100644 index 0000000..fbe77fa --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes-heatmap.js @@ -0,0 +1,36 @@ +/** + * 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'; + +export default Ember.Controller.extend({ + needReload: true, + selectedQueue: undefined, + + breadcrumbs: [{ + text: "Home", + routeName: 'application' + }, { + text: "Nodes", + routeName: 'yarn-nodes', + }, { + text: "Heatmap", + routeName: 'yarn-nodes-heatmap', + }] + +}); http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes.js new file mode 100644 index 0000000..b4bf0f0 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes.js @@ -0,0 +1,33 @@ +/** + * 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'; + +export default Ember.Controller.extend({ + needReload: true, + selectedQueue: undefined, + + breadcrumbs: [{ + text: "Home", + routeName: 'application' + }, { + text: "Nodes", + routeName: 'yarn-nodes', + }] + +}); http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue-apps.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue-apps.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue-apps.js new file mode 100644 index 0000000..e7bedd6 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue-apps.js @@ -0,0 +1,46 @@ +/** + * 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'; + +export default Ember.Controller.extend({ + needReload: true, + selectedQueue: undefined, + + breadcrumbs: Ember.computed("model.selected", function () { + var queueName = this.get("model.selected"); + + return [{ + text: "Home", + routeName: 'application' + }, { + text: "Queues", + routeName: 'yarn-queues', + model: 'root' + }, { + text: `Queue [ ${queueName} ]`, + routeName: 'yarn-queue', + model: queueName + }, { + text: "Applications", + }]; + + }), + + +}); http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue.js index 38cf352..0b4150f 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue.js @@ -21,4 +21,24 @@ import Ember from 'ember'; export default Ember.Controller.extend({ needReload: true, selectedQueue: undefined, + + breadcrumbs: Ember.computed("model.selected", function () { + var queueName = this.get("model.selected"); + + return [{ + text: "Home", + routeName: 'application' + }, { + text: "Queues", + routeName: 'yarn-queues', + model: 'root' + }, { + text: `Queue [ ${queueName} ]`, + routeName: 'yarn-queue', + model: queueName + }]; + + }), + + }); http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queues.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queues.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queues.js new file mode 100644 index 0000000..941e150 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queues.js @@ -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 Ember from 'ember'; + +export default Ember.Controller.extend({ + needReload: true, + selectedQueue: undefined, + + breadcrumbs: [{ + text: "Home", + routeName: 'application' + }, { + text: "Queues", + routeName: 'yarn-queues', + model: 'root' + }] + +}); http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-services.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-services.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-services.js new file mode 100644 index 0000000..597962a --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-services.js @@ -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 Ember from 'ember'; + +export default Ember.Controller.extend({ + + breadcrumbs: [{ + text: "Home", + routeName: 'application' + }, { + text: "Applications", + routeName: 'yarn-apps', + }, { + text: "Long Running Services", + routeName: 'yarn-services', + }] + +}); http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/cluster-metric.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/cluster-metric.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/cluster-metric.js index 981375a..bc6e27a 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/cluster-metric.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/cluster-metric.js @@ -125,7 +125,7 @@ export default DS.Model.extend({ }); arr.push({ label: "Available", - value: this.get("available" + type) + value: Math.max(this.get("available" + type), 0) }); return arr; http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app-attempt.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app-attempt.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app-attempt.js index b913a33..f30d143 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app-attempt.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app-attempt.js @@ -30,6 +30,17 @@ export default DS.Model.extend({ hosts: DS.attr('string'), logsLink: DS.attr('string'), state: DS.attr('string'), + appAttemptId: DS.attr('string'), + + appId: Ember.computed("id",function () { + var id = this.get("id"); + id = id.split("_"); + + id[0] = "application"; + id.pop(); + + return id.join("_"); + }), attemptStartedTime: function() { var startTime = this.get("startTime"); http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app.js index a96c17c..0a5df87 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app.js @@ -36,6 +36,7 @@ export default DS.Model.extend({ unmanagedApplication: DS.attr('string'), amNodeLabelExpression: DS.attr('string'), applicationTags: DS.attr('string'), + applicationType: DS.attr('string'), priority: DS.attr('number'), allocatedMB: DS.attr('number'), allocatedVCores: DS.attr('number'), @@ -46,6 +47,9 @@ export default DS.Model.extend({ preemptedResourceVCores: DS.attr('number'), numNonAMContainerPreempted: DS.attr('number'), numAMContainerPreempted: DS.attr('number'), + clusterUsagePercentage: DS.attr('number'), + queueUsagePercentage: DS.attr('number'), + currentAppAttemptId: DS.attr('string'), isFailed: function() { return this.get('finalStatus') == "FAILED" http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-rm-node.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-rm-node.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-rm-node.js index 9a1082c..a15a20f 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-rm-node.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-rm-node.js @@ -89,4 +89,11 @@ export default DS.Model.extend({ }); return arr; }.property("availableVirtualCores", "usedVirtualCores"), + + toolTipText: function() { + return "<p>Rack: " + this.get("rack") + '</p>' + + "<p>Host: " + this.get("nodeHostName") + '</p>' + + "<p>Used Memory: " + Math.round(this.get("usedMemoryMB")) + ' MB</p>' + + "<p>Available Memory: " + Math.round(this.get("availMemoryMB")) + ' MB</p>'; + }.property(), }); http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js index 8f7ce5f..87a018d 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js @@ -24,8 +24,15 @@ var Router = Ember.Router.extend({ }); Router.map(function() { - this.route('yarn-apps'); - this.route('yarn-nodes'); + this.route('yarn-apps', function () { + this.route('apps'); + this.route('services'); + }); + this.route('yarn-nodes', function(){ + this.route('table'); + this.route('heatmap'); + }); + this.route('yarn-nodes-heatmap'); this.route('yarn-node', { path: '/yarn-node/:node_id/:node_addr' }); this.route('yarn-node-apps', { path: '/yarn-node-apps/:node_id/:node_addr' }); this.route('yarn-node-app', @@ -37,11 +44,15 @@ Router.map(function() { this.route('yarn-container-log', { path: '/yarn-container-log/:node_id/:node_addr/:container_id/:filename' }); this.route('yarn-queue', { path: '/yarn-queue/:queue_name' }); + this.route('cluster-overview'); this.route('yarn-app', { path: '/yarn-app/:app_id' }); this.route('yarn-app-attempt', { path: '/yarn-app-attempt/:app_attempt_id'}); this.route('error'); this.route('notfound', { path: '*:' }); + this.route('yarn-app-attempts', { path: '/yarn-app-attempts/:app_id' }); + this.route('yarn-queues', { path: '/yarn-queues/:queue_name' }); + this.route('yarn-queue-apps', { path: '/yarn-queue-apps/:queue_name' }); }); export default Router; http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/application.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/application.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/application.js index b7a5754..07b3792 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/application.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/application.js @@ -27,6 +27,8 @@ export default Ember.Route.extend({ * error handler page. */ error: function (error) { + Ember.Logger.log(error.stack); + if (error && error.errors[0] && error.errors[0].status == 404) { this.intermediateTransitionTo('/notfound'); http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/cluster-overview.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/cluster-overview.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/cluster-overview.js index 4b4e554..3689274 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/cluster-overview.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/cluster-overview.js @@ -20,7 +20,14 @@ import Ember from 'ember'; export default Ember.Route.extend({ model() { - return this.store.findAll('ClusterMetric'); + return Ember.RSVP.hash({ + clusterMetrics: this.store.findAll('ClusterMetric'), + apps: this.store.query('yarn-app', + { + state: "RUNNING" + }), + queues: this.store.findAll('yarn-queue'), + }); }, afterModel() { http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempts.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempts.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempts.js new file mode 100644 index 0000000..1a526c7 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempts.js @@ -0,0 +1,30 @@ +/** + * 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'; + +export default Ember.Route.extend({ + model(param) { + return this.store.query('yarn-app-attempt', { appId: param.app_id}).then(function (attempts) { + return { + appId: param.app_id, + attempts: attempts + }; + }); + } +}); http://git-wip-us.apache.org/repos/asf/hadoop/blob/d0ccf6f9/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app.js index f5384b8..ab84632 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app.js @@ -22,7 +22,22 @@ export default Ember.Route.extend({ model(param) { return Ember.RSVP.hash({ app: this.store.find('yarn-app', param.app_id), - attempts: this.store.query('yarn-app-attempt', { appId: param.app_id}) + + rmContainers: this.store.find('yarn-app', param.app_id).then(function(app) { + return this.store.query('yarn-app-attempt', {appId: param.app_id}).then(function (attempts) { + if (attempts && attempts.get('firstObject')) { + var appAttemptId = attempts.get('firstObject').get('appAttemptId'); + var rmContainers = this.store.query('yarn-container', + { + app_attempt_id: appAttemptId, + is_rm: true + }); + return rmContainers; + } + }.bind(this)); + }.bind(this)), + + nodes: this.store.findAll('yarn-rm-node'), }); } }); --------------------------------------------------------------------- To unsubscribe, e-mail: common-commits-unsubscr...@hadoop.apache.org For additional commands, e-mail: common-commits-h...@hadoop.apache.org