You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@eagle.apache.org by jj...@apache.org on 2017/04/13 06:20:20 UTC
eagle git commit: [EAGLE-953] Host-level Overview Heatmap Diagram for
Topology Monitoring
Repository: eagle
Updated Branches:
refs/heads/master 4ff4d628f -> 01553a346
[EAGLE-953] Host-level Overview Heatmap Diagram for Topology Monitoring
https://issues.apache.org/jira/browse/EAGLE-953
Author: koone <lu...@126.com>
Closes #907 from koone/heatmap.
Project: http://git-wip-us.apache.org/repos/asf/eagle/repo
Commit: http://git-wip-us.apache.org/repos/asf/eagle/commit/01553a34
Tree: http://git-wip-us.apache.org/repos/asf/eagle/tree/01553a34
Diff: http://git-wip-us.apache.org/repos/asf/eagle/diff/01553a34
Branch: refs/heads/master
Commit: 01553a34639423621b534bc9837dea4cf4c71b4b
Parents: 4ff4d62
Author: koone <lu...@126.com>
Authored: Thu Apr 13 06:20:05 2017 +0000
Committer: r7raul1984 <ta...@yhd.com>
Committed: Thu Apr 13 06:20:05 2017 +0000
----------------------------------------------------------------------
.../apps/hbase/ctrls/backupMasterListCtrl.js | 124 ++++++++++++++++++-
.../app/apps/hbase/ctrls/regionListCtrl.js | 124 ++++++++++++++++++-
.../src/main/webapp/app/apps/hbase/index.js | 18 ++-
.../apps/hbase/partials/backupMasterList.html | 85 ++++++++-----
.../apps/hbase/partials/region/regionList.html | 88 ++++++++-----
.../app/apps/hdfs/ctrl/datanodeListCtrl.js | 118 +++++++++++++++++-
.../app/apps/hdfs/ctrl/namenodeListCtrl.js | 120 +++++++++++++++++-
.../app/apps/hdfs/partials/datanodeList.html | 88 ++++++++-----
.../app/apps/hdfs/partials/namenodeList.html | 88 ++++++++-----
.../webapp/app/apps/hdfs/partials/overview.html | 4 +-
10 files changed, 711 insertions(+), 146 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/eagle/blob/01553a34/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/ctrls/backupMasterListCtrl.js
----------------------------------------------------------------------
diff --git a/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/ctrls/backupMasterListCtrl.js b/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/ctrls/backupMasterListCtrl.js
index ca6c47e..2330885 100644
--- a/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/ctrls/backupMasterListCtrl.js
+++ b/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/ctrls/backupMasterListCtrl.js
@@ -7,7 +7,7 @@
* "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
+ * 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,
@@ -30,6 +30,128 @@
$scope.site = $wrapState.param.siteId;
$scope.searchPathList = [["tags", "hostname"], ["tags", "rack"], ["tags", "site"], ["status"]];
$scope.backupMasterList = METRIC.hbaseMaster($scope.site, "standby", 1000);
+
+ $scope.masterAll = METRIC.hbaseMaster($scope.site);
+
+
+ function getCommonHeatMapSeries(name, data) {
+ return {
+ name: name,
+ type: 'heatmap',
+ data: data,
+ label: {
+ normal: {
+ show: true,
+ formatter: function (point) {
+ if(point.data) {
+ return point.data[3];
+ }
+ return "";
+ }
+ }
+ },
+ itemStyle: {
+ normal: {
+ borderColor: "#FFF"
+ },
+ emphasis: {
+ shadowBlur: 10,
+ shadowColor: 'rgba(0, 0, 0, 0.5)'
+ }
+ }
+ };
+ }
+
+ function getCommonHeatMapOption() {
+ return {
+ animation: false,
+ tooltip: {
+ trigger: 'item'
+ },
+ xAxis: {
+ show: false,
+ data: [0,-1,-2,-3,-4],
+ splitArea: {show: true}
+ },
+ yAxis: [{
+ show: false,
+ splitArea: {show: true},
+ axisTick: {show: false}
+ }],
+ grid: {
+ left: "1%",
+ right: "1%",
+ top: "60",
+ bottom: "60"
+ },
+ visualMap: {
+ categories: ['active', 'standby'],
+ calculable: true,
+ orient: 'horizontal',
+ right: "2%",
+ inRange: {
+ color: ['#00a65a', '#dd4b39']
+ }
+ }
+ };
+ }
+
+
+ // region server heatmap chart
+ $scope.masterAll._promise.then(function () {
+ var master_status = [];
+ var master_status_category = [];
+ var x = -1;
+ var y = 0;
+ var split = 5;
+ $.each($scope.masterAll,
+ /**
+ * @param {number} i
+ * @param {RegionServer} master
+ */
+ function (i, master) {
+ if(x === split){
+ x = 0;
+ y = y - 1;
+ }else{
+ x = x +1;
+ }
+ master_status.push([x, y, 0, master.tags.hostname, master.tags.rack, master.status || "-"])
+ });
+ for(var i = 0;i < split; i++){
+ master_status_category.push(i);
+ }
+ $scope.healthStatusSeries = [getCommonHeatMapSeries("Health", master_status)];
+ console.log($scope.healthStatusSeries);
+ $scope.healthStatusOption = getHealthHeatMapOption();
+ console.log($scope.healthStatusOption);
+ $scope.healthStatusCategory = master_status_category;
+ $scope.heatmapHeight = {
+ 'height': getHeight(y)
+ };
+
+ function getHeight(x){
+ return (Math.abs(x-1)*30 + 140) + "px"
+ }
+
+ function getHealthHeatMapOption() {
+ var option = getCommonHeatMapOption();
+ return common.merge(option, {
+ tooltip: {
+ formatter: function (point) {
+ if(point.data) {
+ return point.data[3] + '<br/>'
+ + 'status: <span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:' + point.color + '"></span> ' + point.data[5] + '<br/>'
+ + 'rack: ' + point.data[4] + '<br/>';
+ }
+ return "";
+ }
+ }
+ });
+ }
+
+ });
+
});
});
})();
http://git-wip-us.apache.org/repos/asf/eagle/blob/01553a34/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/ctrls/regionListCtrl.js
----------------------------------------------------------------------
diff --git a/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/ctrls/regionListCtrl.js b/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/ctrls/regionListCtrl.js
index 6fc9ab0..401ef15 100644
--- a/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/ctrls/regionListCtrl.js
+++ b/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/ctrls/regionListCtrl.js
@@ -7,7 +7,7 @@
* "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
+ * 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,
@@ -33,6 +33,128 @@
$scope.status = $wrapState.param.status;
$scope.searchPathList = [["tags", "hostname"], ["tags", "rack"], ["tags", "site"], ["status"]];
$scope.regionserverList = METRIC.regionserverList($scope.site, $scope.status);
+ $scope.regionserverAll = METRIC.regionserverList($scope.site);
+
+
+ function getCommonHeatMapSeries(name, data) {
+ return {
+ name: name,
+ type: 'heatmap',
+ data: data,
+ label: {
+ normal: {
+ show: true,
+ formatter: function (point) {
+ if(point.data) {
+ return point.data[3];
+ }
+ return "";
+ }
+ }
+ },
+ itemStyle: {
+ normal: {
+ borderColor: "#FFF"
+ },
+ emphasis: {
+ shadowBlur: 10,
+ shadowColor: 'rgba(0, 0, 0, 0.5)'
+ }
+ }
+ };
+ }
+
+ function getCommonHeatMapOption() {
+ return {
+ animation: false,
+ tooltip: {
+ trigger: 'item'
+ },
+ grid: {
+ left: "1%",
+ right: "1%",
+ top: "60",
+ bottom: "60"
+ },
+ xAxis: {
+ show: false,
+ splitArea: {show: true}
+ },
+ yAxis: [{
+ show: false,
+ splitArea: {show: true},
+ axisTick: {show: false}
+ }],
+ visualMap: {
+ categories: ['live', 'dead'],
+ calculable: true,
+ orient: 'horizontal',
+ right: "2%",
+ inRange: {
+ color: ['#00a65a', '#dd4b39']
+ }
+ }
+ };
+ }
+
+
+ // region server heatmap chart
+ $scope.regionserverAll._promise.then(function () {
+ var regionServer_status = [];
+ var regionServer_status_category = [];
+ var regionServer_level = [];
+ var x = -1;
+ var y = 0;
+ var split = 5;
+ $.each($scope.regionserverAll,
+ /**
+ * @param {number} i
+ * @param {RegionServer} regionServer
+ */
+ function (i, regionServer) {
+ if(x === split){
+ x = 0;
+ y = y - 1;
+ }else{
+ x = x +1;
+ }
+ regionServer_status.push([x, y, 0, regionServer.tags.hostname, regionServer.tags.rack, regionServer.usedHeapMB, regionServer.maxHeapMB, regionServer.status || "-"]);
+ });
+
+ for(var i = 0;i < split; i++){
+ regionServer_status_category.push(i);
+ }
+ $scope.healthStatusSeries = [getCommonHeatMapSeries("Health", regionServer_status)];
+ $scope.healthStatusOption = getHealthHeatMapOption();
+ $scope.healthStatusCategory = regionServer_status_category;
+ $scope.heatmapHeight = {
+ 'height': getHeight(y)
+ };
+
+ function getHeight(x){
+ return (Math.abs(x-1)*30 + 140) + "px"
+ }
+
+ function getHealthHeatMapOption() {
+ var option = getCommonHeatMapOption();
+ return common.merge(option, {
+ tooltip: {
+ formatter: function (point) {
+ if(point.data) {
+ return point.data[3] + '<br/>'
+ + 'status: <span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:' + point.color + '"></span> ' + point.data[7] + '<br/>'
+ + 'rack: ' + point.data[4] + '<br/>'
+ + 'heap used: ' + point.data[5] + '/' + point.data[6] + ' MB<br/>';
+ }
+ return "";
+ }
+ }
+ });
+ }
+
+ });
});
+
+
});
})();
http://git-wip-us.apache.org/repos/asf/eagle/blob/01553a34/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/index.js
----------------------------------------------------------------------
diff --git a/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/index.js b/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/index.js
index 8e4ea46..157cded 100644
--- a/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/index.js
+++ b/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/index.js
@@ -283,11 +283,19 @@
};
METRIC.hbaseMaster = function (siteId, status, limit) {
- var condition = {
- site: siteId,
- role: "hmaster",
- status: status
- };
+ var condition = {};
+ if(typeof status === 'undefined') {
+ condition = {
+ site: siteId,
+ role: "hmaster"
+ };
+ } else {
+ condition = {
+ site: siteId,
+ role: "hmaster",
+ status: status
+ };
+ }
return METRIC.hbasehostStatus(condition, limit);
};
http://git-wip-us.apache.org/repos/asf/eagle/blob/01553a34/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/partials/backupMasterList.html
----------------------------------------------------------------------
diff --git a/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/partials/backupMasterList.html b/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/partials/backupMasterList.html
index 13e20c9..e35aae3 100644
--- a/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/partials/backupMasterList.html
+++ b/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/partials/backupMasterList.html
@@ -15,38 +15,57 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<div class="box box-primary">
- <div class="box-header with-border">
- <h3 class="box-title">
- <span ng-show="!backupMasterList._done || isSorting" class="fa fa-refresh fa-spin no-animate"></span>
- </h3>
- </div>
- <div class="box-body">
- <div id="backupMasterList" sort-table="backupMasterList" is-sorting="isSorting"
- search-path-list="searchPathList"
- scope="tableScope">
- <table class="table table-bordered">
- <thead>
- <tr>
- <th sortpath="tags.hostname">Master</th>
- <th sortpath="tags.rack">Rack</th>
- <th sortpath="tags.site">SiteId</th>
- <th sortpath="status">Status</th>
- </tr>
- </thead>
- <tbody>
- <tr ng-repeat="item in backupMasterList">
- <td>
- <a ui-sref="masterDetail({siteId: site, hostname: item.tags.hostname})">{{item.tags.hostname}}</a>
- </td>
- <td>{{item.tags.rack}}</td>
- <td>{{item.tags.site}}</td>
- <td>
- <span>{{item.status}}</span>
- </td>
- </tr>
- </tbody>
- </table>
+<div class="nav-tabs-custom" style="cursor: move;">
+ <ul class="nav nav-tabs pull-right ui-sortable-handle">
+ <li><a href="#heatmap" data-toggle="tab" aria-expanded="false" ng-click="healthHeatMap.resize()">HeatMap</a></li>
+ <li class="active"><a href="#list" data-toggle="tab" aria-expanded="true">List</a></li>
+ </ul>
+
+ <div class="tab-content no-padding keepContent">
+ <div class="box box-primary no-margin tab-pane fade in active" id="list">
+ <div class="box-body">
+ <div id="backupMasterList" sort-table="backupMasterList" is-sorting="isSorting"
+ search-path-list="searchPathList"
+ scope="tableScope">
+ <table class="table table-bordered">
+ <thead>
+ <tr>
+ <th sortpath="tags.hostname">Master</th>
+ <th sortpath="tags.rack">Rack</th>
+ <th sortpath="tags.site">SiteId</th>
+ <th sortpath="status">Status</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="item in backupMasterList">
+ <td>
+ <a ui-sref="masterDetail({siteId: site, hostname: item.tags.hostname})">{{item.tags.hostname}}</a>
+ </td>
+ <td>{{item.tags.rack}}</td>
+ <td>{{item.tags.site}}</td>
+ <td>
+ <span>{{item.status}}</span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+
+
+ <!--region server health chart-->
+ <div class="box box-primary no-margin tab-pane fade" id="heatmap">
+ <div class="box-body">
+ <div class="hadoopMetric-chart">
+ <div chart="healthHeatMap" ng-style="heatmapHeight" series="healthStatusSeries" category="healthStatusCategory" option="healthStatusOption"></div>
+ <div ng-if="(healthStatusSeries || []).length === 0" class="overlay">
+ <i class="fa fa-refresh fa-spin"></i>
+ </div>
+ </div>
+ </div>
</div>
- </div>
+
+ </div>
+
</div>
http://git-wip-us.apache.org/repos/asf/eagle/blob/01553a34/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/partials/region/regionList.html
----------------------------------------------------------------------
diff --git a/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/partials/region/regionList.html b/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/partials/region/regionList.html
index d1a7440..dd78c3b 100644
--- a/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/partials/region/regionList.html
+++ b/eagle-metric/eagle-hbase-web/src/main/webapp/app/apps/hbase/partials/region/regionList.html
@@ -15,39 +15,59 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<div class="box box-primary">
- <div class="box-header with-border">
- <h3 class="box-title">
- <span ng-show="!regionserverList._done || isSorting" class="fa fa-refresh fa-spin no-animate"></span>
- </h3>
- </div>
- <div class="box-body">
- <div id="regionserverList" sort-table="regionserverList" is-sorting="isSorting"
- search-path-list="searchPathList"
- scope="tableScope">
- <table class="table table-bordered">
- <thead>
- <tr>
- <th sortpath="tags.hostname">RegionServer</th>
- <th sortpath="tags.rack">Rack</th>
- <th sortpath="tags.site">SiteId</th>
- <th sortpath="status">Status</th>
- </tr>
- </thead>
- <tbody>
- <tr ng-repeat="item in regionserverList">
- <td>
- <a ui-sref="regionDetail({siteId: site, hostname: item.tags.hostname})">{{item.tags.hostname}}</a>
- </td>
- <td>{{item.tags.rack}}</td>
- <td>{{item.tags.site}}</td>
- <td>
- <span ng-if="item.status===live" class="label label-success">Healthy</span>
- <span ng-if="item.status===dead" class="label label-danger">UnHealthy</span>
- </td>
- </tr>
- </tbody>
- </table>
+<div class="nav-tabs-custom" style="cursor: move;">
+ <ul class="nav nav-tabs pull-right ui-sortable-handle">
+ <li><a href="#heatmap" data-toggle="tab" aria-expanded="false" ng-click="healthHeatMap.resize()">HeatMap</a></li>
+ <li class="active"><a href="#list" data-toggle="tab" aria-expanded="true">List</a></li>
+ </ul>
+
+ <div class="tab-content no-padding keepContent">
+ <div class="box box-primary no-margin tab-pane fade in active" id="list">
+ <div class="box-body">
+ <div id="regionserverList" sort-table="regionserverList" is-sorting="isSorting"
+ search-path-list="searchPathList"
+ scope="tableScope">
+ <table class="table table-bordered">
+ <thead>
+ <tr>
+ <th sortpath="tags.hostname">RegionServer</th>
+ <th sortpath="tags.rack">Rack</th>
+ <th sortpath="tags.site">SiteId</th>
+ <th sortpath="status">Status</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="item in regionserverList">
+ <td>
+ <a ui-sref="regionDetail({siteId: site, hostname: item.tags.hostname})">{{item.tags.hostname}}</a>
+ </td>
+ <td>{{item.tags.rack}}</td>
+ <td>{{item.tags.site}}</td>
+ <td>
+ <span ng-if="item.status===live" class="label label-success">Healthy</span>
+ <span ng-if="item.status===dead" class="label label-danger">UnHealthy</span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+
+
+ <!--region server health chart-->
+ <div class="box box-primary no-margin tab-pane fade" id="heatmap">
+ <div class="box-body">
+ <div class="hadoopMetric-chart">
+ <div chart="healthHeatMap" ng-style="heatmapHeight" series="healthStatusSeries" category="healthStatusCategory" option="healthStatusOption"></div>
+ <div ng-if="(healthStatusSeries || []).length === 0" class="overlay">
+ <i class="fa fa-refresh fa-spin"></i>
+ </div>
+ </div>
+ </div>
</div>
- </div>
+
+ </div>
+
</div>
+
http://git-wip-us.apache.org/repos/asf/eagle/blob/01553a34/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/ctrl/datanodeListCtrl.js
----------------------------------------------------------------------
diff --git a/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/ctrl/datanodeListCtrl.js b/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/ctrl/datanodeListCtrl.js
index 78ea7e1..7664b7c 100644
--- a/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/ctrl/datanodeListCtrl.js
+++ b/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/ctrl/datanodeListCtrl.js
@@ -7,7 +7,7 @@
* "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
+ * 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,
@@ -35,6 +35,122 @@
$scope.datanodeList = (typeof $scope.status === 'undefined') ? HDFSMETRIC.getListByRoleName("HdfsServiceInstance", "datanode", $scope.site)
: HDFSMETRIC.getHadoopHostByStatusAndRole("HdfsServiceInstance", $scope.site, $scope.status, "datanode");
+ $scope.datanodeAll = HDFSMETRIC.getListByRoleName("HdfsServiceInstance", "datanode", $scope.site);
+
+
+ function getCommonHeatMapSeries(name, data) {
+ return {
+ name: name,
+ type: 'heatmap',
+ data: data,
+ label: {
+ normal: {
+ show: true,
+ formatter: function (point) {
+ if(point.data) {
+ return point.data[3];
+ }
+ return "";
+ }
+ }
+ },
+ itemStyle: {
+ normal: {
+ borderColor: "#FFF"
+ },
+ emphasis: {
+ shadowBlur: 10,
+ shadowColor: 'rgba(0, 0, 0, 0.5)'
+ }
+ }
+ };
+ }
+
+ function getCommonHeatMapOption() {
+ return {
+ animation: false,
+ tooltip: {
+ trigger: 'item'
+ },
+ xAxis: {
+ show: false,
+ splitArea: {show: true}
+ },
+ yAxis: [{
+ show: false,
+ splitArea: {show: true},
+ axisTick: {show: false}
+ }],
+ grid: {
+ left: "1%",
+ right: "1%",
+ top: "60",
+ bottom: "60"
+ },
+ visualMap: {
+ categories: ['live', 'dead'],
+ calculable: true,
+ orient: 'horizontal',
+ right: "2%",
+ inRange: {
+ color: ['#00a65a', '#dd4b39']
+ }
+ }
+ };
+ }
+
+
+ // region server heatmap chart
+ $scope.datanodeAll._promise.then(function () {
+ var datanode_status = [];
+ var datanode_status_category = [];
+ var x = -1;
+ var y = 0;
+ var split = 5;
+ $.each($scope.datanodeAll,
+ /**
+ * @param {number} i
+ * @param {RegionServer} datanode
+ */
+ function (i, datanode) {
+ if(x === split){
+ x = 0;
+ y = y - 1;
+ }else{
+ x = x +1;
+ }
+ datanode_status.push([x, y, 0, datanode.tags.hostname, datanode.tags.rack, datanode.status || "-"])
+ });
+ for(var i = 0;i < split; i++){
+ datanode_status_category.push(i);
+ }
+ $scope.healthStatusSeries = [getCommonHeatMapSeries("Health", datanode_status)];
+ $scope.healthStatusOption = getHealthHeatMapOption();
+ $scope.healthStatusCategory = datanode_status_category;
+ $scope.heatmapHeight = {
+ 'height': getHeight(y)
+ };
+ function getHeight(x){
+ return (Math.abs(x-1)*30 + 140) + "px"
+ }
+
+ function getHealthHeatMapOption() {
+ var option = getCommonHeatMapOption();
+ return common.merge(option, {
+ tooltip: {
+ formatter: function (point) {
+ if(point.data) {
+ return point.data[3] + '<br/>'
+ + 'status: <span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:' + point.color + '"></span> ' + point.data[5] + '<br/>'
+ + 'rack: ' + point.data[4] + '<br/>';
+ }
+ return "";
+ }
+ }
+ });
+ }
+
+ });
});
});
})();
http://git-wip-us.apache.org/repos/asf/eagle/blob/01553a34/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/ctrl/namenodeListCtrl.js
----------------------------------------------------------------------
diff --git a/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/ctrl/namenodeListCtrl.js b/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/ctrl/namenodeListCtrl.js
index 8424b8e..d0d41bf 100644
--- a/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/ctrl/namenodeListCtrl.js
+++ b/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/ctrl/namenodeListCtrl.js
@@ -7,7 +7,7 @@
* "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
+ * 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,
@@ -32,6 +32,124 @@
$scope.searchPathList = [["tags", "hostname"], ["tags", "rack"], ["tags", "site"], ["status"]];
$scope.namenodeList = (typeof $scope.status === 'undefined') ? HDFSMETRIC.getListByRoleName("HdfsServiceInstance", "namenode", $scope.site)
: HDFSMETRIC.getHadoopHostByStatusAndRole("HdfsServiceInstance", $scope.site, $scope.status, "namenode");
+
+ $scope.namenodeAll = HDFSMETRIC.getListByRoleName("HdfsServiceInstance", "namenode", $scope.site);
+
+
+ function getCommonHeatMapSeries(name, data) {
+ return {
+ name: name,
+ type: 'heatmap',
+ data: data,
+ label: {
+ normal: {
+ show: true,
+ formatter: function (point) {
+ if(point.data) {
+ return point.data[3];
+ }
+ return "";
+ }
+ }
+ },
+ itemStyle: {
+ normal: {
+ borderColor: "#FFF"
+ },
+ emphasis: {
+ shadowBlur: 10,
+ shadowColor: 'rgba(0, 0, 0, 0.5)'
+ }
+ }
+ };
+ }
+
+ function getCommonHeatMapOption() {
+ return {
+ animation: false,
+ tooltip: {
+ trigger: 'item'
+ },
+ xAxis: {
+ show: false,
+ splitArea: {show: true}
+ },
+ yAxis: [{
+ show: false,
+ splitArea: {show: true},
+ axisTick: {show: false}
+ }],
+ grid: {
+ left: "1%",
+ right: "1%",
+ top: "60",
+ bottom: "60"
+ },
+ visualMap: {
+ categories: ['active', 'standby'],
+ calculable: true,
+ orient: 'horizontal',
+ right: "2%",
+ inRange: {
+ color: ['#00a65a', '#dd4b39']
+ }
+ }
+ };
+ }
+
+
+ // region server heatmap chart
+ $scope.namenodeAll._promise.then(function () {
+ var namenode_status = [];
+ var namenode_status_category = [];
+ var x = -1;
+ var y = 0;
+ var split = 5;
+ $.each($scope.namenodeAll,
+ /**
+ * @param {number} i
+ * @param {RegionServer} namenode
+ */
+ function (i, namenode) {
+ if(x === split){
+ x = 0;
+ y = y - 1;
+ }else{
+ x = x +1;
+ }
+ namenode_status.push([x, y, 0, namenode.tags.hostname, namenode.tags.rack, namenode.usedCapacityTB, namenode.status || "-"])
+ });
+ for(var i = 0;i < split; i++){
+ namenode_status_category.push(i);
+ }
+ $scope.healthStatusSeries = [getCommonHeatMapSeries("Health", namenode_status)];
+ $scope.healthStatusOption = getHealthHeatMapOption();
+ $scope.healthStatusCategory = namenode_status_category;
+ $scope.heatmapHeight = {
+ 'height': getHeight(y)
+ };
+ function getHeight(x){
+ return (Math.abs(x-1)*30 + 140) + "px"
+ }
+
+ function getHealthHeatMapOption() {
+ var option = getCommonHeatMapOption();
+ return common.merge(option, {
+ tooltip: {
+ formatter: function (point) {
+ if(point.data) {
+ return point.data[3] + '<br/>'
+ + 'status: <span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:' + point.color + '"></span> ' + point.data[6] + '<br/>'
+ + 'rack: ' + point.data[4] + '<br/>'
+ + 'usedCapacity: ' + point.data[5] + ' TB<br/>';
+ }
+ return "";
+ }
+ }
+ });
+ }
+
+ });
});
});
})();
http://git-wip-us.apache.org/repos/asf/eagle/blob/01553a34/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/partials/datanodeList.html
----------------------------------------------------------------------
diff --git a/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/partials/datanodeList.html b/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/partials/datanodeList.html
index b76d44d..a53251e 100644
--- a/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/partials/datanodeList.html
+++ b/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/partials/datanodeList.html
@@ -15,39 +15,59 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<div class="box box-primary">
- <div class="box-header with-border">
- <h3 class="box-title">
- <span ng-show="!datanodeList._done || isSorting" class="fa fa-refresh fa-spin no-animate"></span>
- </h3>
- </div>
- <div class="box-body">
- <div id="datanodeList" sort-table="datanodeList" is-sorting="isSorting"
- search-path-list="searchPathList"
- scope="tableScope">
- <table class="table table-bordered">
- <thead>
- <tr>
- <th sortpath="tags.hostname">Datanode</th>
- <th sortpath="tags.rack">Rack</th>
- <th sortpath="tags.site">SiteId</th>
- <th sortpath="status">Status</th>
- </tr>
- </thead>
- <tbody>
- <tr ng-repeat="item in datanodeList">
- <td>
- <a ui-sref="datanodeDetail({siteId: site, hostname: item.tags.hostname})" target="_blank">{{item.tags.hostname}}</a>
- </td>
- <td>{{item.tags.rack}}</td>
- <td>{{item.tags.site}}</td>
- <td>
- <span ng-if="item.status===live" class="label label-success">Healthy</span>
- <span ng-if="item.status===dead" class="label label-danger">UnHealthy</span>
- </td>
- </tr>
- </tbody>
- </table>
+
+<div class="nav-tabs-custom" style="cursor: move;">
+ <ul class="nav nav-tabs pull-right ui-sortable-handle">
+ <li><a href="#heatmap" data-toggle="tab" aria-expanded="false" ng-click="healthHeatMap.resize()">HeatMap</a></li>
+ <li class="active"><a href="#list" data-toggle="tab" aria-expanded="true">List</a></li>
+ </ul>
+
+ <div class="tab-content no-padding keepContent">
+ <div class="box box-primary no-margin tab-pane fade in active" id="list">
+ <div class="box-body">
+ <div id="datanodeList" sort-table="datanodeList" is-sorting="isSorting"
+ search-path-list="searchPathList"
+ scope="tableScope">
+ <table class="table table-bordered">
+ <thead>
+ <tr>
+ <th sortpath="tags.hostname">Datanode</th>
+ <th sortpath="tags.rack">Rack</th>
+ <th sortpath="tags.site">SiteId</th>
+ <th sortpath="status">Status</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="item in datanodeList">
+ <td>
+ <a ui-sref="datanodeDetail({siteId: site, hostname: item.tags.hostname})" target="_blank">{{item.tags.hostname}}</a>
+ </td>
+ <td>{{item.tags.rack}}</td>
+ <td>{{item.tags.site}}</td>
+ <td>
+ <span ng-if="item.status===live" class="label label-success">Healthy</span>
+ <span ng-if="item.status===dead" class="label label-danger">UnHealthy</span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
</div>
- </div>
+
+
+ <!--region server health chart-->
+ <div class="box box-primary no-margin tab-pane fade" id="heatmap">
+ <div class="box-body">
+ <div class="hadoopMetric-chart">
+ <div chart="healthHeatMap" ng-style="heatmapHeight" series="healthStatusSeries" category="healthStatusCategory" option="healthStatusOption"></div>
+ <div ng-if="(healthStatusSeries || []).length === 0" class="overlay">
+ <i class="fa fa-refresh fa-spin"></i>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ </div>
+
</div>
http://git-wip-us.apache.org/repos/asf/eagle/blob/01553a34/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/partials/namenodeList.html
----------------------------------------------------------------------
diff --git a/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/partials/namenodeList.html b/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/partials/namenodeList.html
index d10aa0b..d9bab1a 100644
--- a/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/partials/namenodeList.html
+++ b/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/partials/namenodeList.html
@@ -15,38 +15,58 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<div class="box box-primary">
- <div class="box-header with-border">
- <h3 class="box-title">
- <span ng-show="!namenodeList._done || isSorting" class="fa fa-refresh fa-spin no-animate"></span>
- </h3>
- </div>
- <div class="box-body">
- <div id="namenodeList" sort-table="namenodeList" is-sorting="isSorting"
- search-path-list="searchPathList"
- scope="tableScope">
- <table class="table table-bordered">
- <thead>
- <tr>
- <th sortpath="tags.hostname">Namenode</th>
- <th sortpath="tags.rack">Rack</th>
- <th sortpath="tags.site">SiteId</th>
- <th sortpath="status">Status</th>
- </tr>
- </thead>
- <tbody>
- <tr ng-repeat="item in namenodeList">
- <td>
- <a ui-sref="namenodeDetail({siteId: site, hostname: item.tags.hostname})" target="_blank">{{item.tags.hostname}}</a>
- </td>
- <td>{{item.tags.rack}}</td>
- <td>{{item.tags.site}}</td>
- <td>
- <span>{{item.status}}</span>
- </td>
- </tr>
- </tbody>
- </table>
+
+<div class="nav-tabs-custom" style="cursor: move;">
+ <ul class="nav nav-tabs pull-right ui-sortable-handle">
+ <li><a href="#heatmap" data-toggle="tab" aria-expanded="false" ng-click="healthHeatMap.resize()">HeatMap</a></li>
+ <li class="active"><a href="#list" data-toggle="tab" aria-expanded="true">List</a></li>
+ </ul>
+
+ <div class="tab-content no-padding keepContent">
+ <div class="box box-primary no-margin tab-pane fade in active" id="list">
+ <div class="box-body">
+ <div id="namenodeList" sort-table="namenodeList" is-sorting="isSorting"
+ search-path-list="searchPathList"
+ scope="tableScope">
+ <table class="table table-bordered">
+ <thead>
+ <tr>
+ <th sortpath="tags.hostname">Namenode</th>
+ <th sortpath="tags.rack">Rack</th>
+ <th sortpath="tags.site">SiteId</th>
+ <th sortpath="status">Status</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="item in namenodeList">
+ <td>
+ <a ui-sref="namenodeDetail({siteId: site, hostname: item.tags.hostname})" target="_blank">{{item.tags.hostname}}</a>
+ </td>
+ <td>{{item.tags.rack}}</td>
+ <td>{{item.tags.site}}</td>
+ <td>
+ <span>{{item.status}}</span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
</div>
- </div>
-</div>
+
+
+ <!--region server health chart-->
+ <div class="box box-primary no-margin tab-pane fade" id="heatmap">
+ <div class="box-body">
+ <div class="hadoopMetric-chart">
+ <div chart="healthHeatMap" ng-style="heatmapHeight" series="healthStatusSeries" category="healthStatusCategory" option="healthStatusOption"></div>
+ <div ng-if="(healthStatusSeries || []).length === 0" class="overlay">
+ <i class="fa fa-refresh fa-spin"></i>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ </div>
+
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/eagle/blob/01553a34/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/partials/overview.html
----------------------------------------------------------------------
diff --git a/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/partials/overview.html b/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/partials/overview.html
index 7a6d9ad..52f8e92 100644
--- a/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/partials/overview.html
+++ b/eagle-metric/eagle-hdfs-web/src/main/webapp/app/apps/hdfs/partials/overview.html
@@ -28,7 +28,7 @@
<tr>
<td width="5%">
<span ng-show="!namenodeactivenum">0</span>
- <span ng-show="namenodeactivenum!==-1"><a ui-sref="namenodeList({siteId: site, status: 'active'})" target="_blank">{{namenodeactivenum}}</a></span>
+ <span ng-show="namenodeactivenum!==-1"><a ui-sref="namenodeList({siteId: site, status: 'active'})">{{namenodeactivenum}}</a></span>
<span ng-show="namenodeactivenum===-1">N/A</span>
</td>
<th width="30%">Active Namenode</th>
@@ -46,7 +46,7 @@
</tr>
<tr>
<td>
- <span ng-show="namenodestandbynum!==-1"><a ui-sref="namenodeList({siteId: site, status: 'standby'})" target="_blank">{{namenodestandbynum}}</a></span>
+ <span ng-show="namenodestandbynum!==-1"><a ui-sref="namenodeList({siteId: site, status: 'standby'})">{{namenodestandbynum}}</a></span>
<span ng-show="!namenodestandbynum">0</span>
<span ng-show="namenodestandbynum===-1">N/A</span>
</td>