From d58d0f8fd876907c1712bf0725ccaf3f3884ea92 Mon Sep 17 00:00:00 2001 From: ocket8888 Date: Thu, 2 Dec 2021 19:29:35 -0700 Subject: [PATCH 1/5] Switch Cache Stats view to AG-Grid --- .../cacheStats/CacheStatsController.js | 240 +++++++++++++++--- .../private/cacheStats/cacheStats.tpl.html | 40 +-- 2 files changed, 202 insertions(+), 78 deletions(-) diff --git a/traffic_portal/app/src/modules/private/cacheStats/CacheStatsController.js b/traffic_portal/app/src/modules/private/cacheStats/CacheStatsController.js index 7fc4c86a85..454cb3baf0 100644 --- a/traffic_portal/app/src/modules/private/cacheStats/CacheStatsController.js +++ b/traffic_portal/app/src/modules/private/cacheStats/CacheStatsController.js @@ -17,60 +17,218 @@ * under the License. */ -var CacheStatsController = function(cacheStats, $scope, $state, $interval, numberUtils, serverUtils) { +/** + * @typedef CacheStat + * @property {string} cachegroup + * @property {number} connections + * @property {boolean} healthy + * @property {string} hostname + * @property {string | null} ip + * @property {number} kbps + * @property {string} profile + * @property {string} status + */ - var cacheStatsInterval, - autoRefresh = false, - refreshRateInMS = 10000; - var createInterval = function() { - killInterval(); - cacheStatsInterval = $interval(function() { $scope.refresh() }, refreshRateInMS ); - }; +class CacheStatsHealthyCellRenderer { + /** @type HTMLSpanElement */ + eGui; - var killInterval = function() { - if (angular.isDefined(cacheStatsInterval)) { - $interval.cancel(cacheStatsInterval); - cacheStatsInterval = undefined; - } - }; + /** + * Called by AG-Grid as a pseudo constructor, used when a renderer is + * instantiated. + * + * @param {{ + * api: any; + * colDef: any; + * column: any; + * columnApi: any; + * context: any; + * data: CacheStat + * eGridCell: HTMLElement; + * eParentOfValue: HTMLElement; + * formatValue: function; + * fullWidth: boolean; + * getValue: function; + * node: any; + * pinned: string | null; + * refreshCell: function; + * registerRowDragger: function; + * rowIndex: number; + * setValue: function; + * value: boolean; + * valueFormatted: null; + * $scope: null; + * }} params + */ + init(params) { + this.eGui = document.createElement("span"); + this.eGui.setAttribute("class", params.value ? "green" : "red"); + this.eGui.textContent = String(params.value); + } - $scope.cacheStats = cacheStats; + /** + * Gets a rendered cell. Parameters are available, but not currently used. + * + * @returns {HTMLElement | Text} A rendered cell element. + */ + getGui() { + return this.eGui; + } +} - $scope.ssh = serverUtils.ssh; +/** + * + * @param {CacheStat[]} cacheStats + * @param {{user: {username: string}}} userModel + */ +var CacheStatsController = function(cacheStats, $scope, userModel) { - $scope.bandwidth = function(kbps, unit) { - return numberUtils.addCommas(numberUtils.convertTo(kbps, unit)); - }; + class CacheStatsSSHCellRenderer { + /** @type HTMLAnchorElement | Text */ + eGui; - $scope.connections = function(amt) { - return numberUtils.addCommas(amt); - }; + /** + * Called by AG-Grid as a pseudo constructor, used when a renderer is + * instantiated. + * + * @param {{ + * api: any; + * colDef: any; + * column: any; + * columnApi: any; + * context: any; + * data: CacheStat + * eGridCell: HTMLElement; + * eParentOfValue: HTMLElement; + * formatValue: function; + * fullWidth: boolean; + * getValue: function; + * node: any; + * pinned: string | null; + * refreshCell: function; + * registerRowDragger: function; + * rowIndex: number; + * setValue: function; + * value: string; + * valueFormatted: null; + * $scope: null; + * }} params + */ + init(params) { + if (params.data.ip === null) { + this.eGui = document.createTextNode(params.value); + return; + } + this.eGui = document.createElement("a"); + this.eGui.href = `ssh://${userModel.user.username}@${params.data.ip}`; + this.eGui.setAttribute("class", "link"); + this.eGui.textContent = params.value; + } - $scope.refresh = function() { - $state.reload(); // reloads all the resolves for the view - }; + /** + * Gets a rendered cell. Parameters are available, but not currently used. + * + * @returns {HTMLElement | Text} A rendered cell element. + */ + getGui() { + return this.eGui; + } + } - $scope.$on("$destroy", function() { - killInterval(); - }); + /** The columns of the ag-grid table */ + $scope.columns = [ + { + headerName: "Cache Group", + field: "cachegroup", + hide: false + }, + { + headerName: "Connections", + field: "connections", + hide: false, + filter: "agNumberColumnFilter" + }, + { + cellRenderer: CacheStatsHealthyCellRenderer, + headerName: "Healthy", + field: "healthy", + hide: false + }, + { + cellRenderer: CacheStatsSSHCellRenderer, + headerName: "Host", + field: "hostname", + hide: false + }, + { + cellRenderer: CacheStatsSSHCellRenderer, + headerName: "IP", + field: "ip", + hide: true, + }, + { + headerName: "Data out rate", + field: "kbps", + filter: "agNumberColumnFilter", + hide: false, + /** + * Formats the kbps metric. + * @param {{value: number}} value Some AG Grid params containing the raw value to be formatted. + * @returns {string} The formatted value. + */ + valueFormatter: ({value}) => { + console.log("formatting a kbps:", value); + if (!value || value <= 0 || !isFinite(value)) { + return "0bps"; + } + if (value >= 1e9) { + return `${(value/1e9).toFixed(3)}Tb/s`; + } + if (value >= 1e6) { + return `${(value/1e6).toFixed(3)}Gb/s`; + } + if (value >= 1000) { + return `${(value/1000).toFixed(3)}Mb/s`; + } + if (value >= 1) { + return `${value.toFixed(3)}kb/s`; + } + return `${(value*1000).toFixed(0)}b/s`; + } + }, + { + headerName: "Profile", + field: "profile", + hide: false, + }, + { + headerName: "Status", + field: "status", + hide: false, + } + ]; - angular.element(document).ready(function () { - $('#cacheStatsTable').dataTable({ - "aLengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]], - "iDisplayLength": 25, - "order": [ [ 6, "desc" ] ] // sort by bandwidth, descending - }); - }); + $scope.data = cacheStats; - var init = function () { - if (autoRefresh) { - createInterval(); - } + /** Options, configuration, data and callbacks for the ag-grid table. */ + /** @type CGC.GridSettings */ + $scope.gridOptions = { + refreshable: true, + }; + + $scope.defaultData = { + cachegroup: "ALL", + connections: -1, + healthy: false, + hostname: "ALL", + ip: null, + kbps: -1, + profile: "ALL", + status: "ALL" }; - init(); }; -CacheStatsController.$inject = ['cacheStats', '$scope', '$state', '$interval', 'numberUtils', 'serverUtils']; +CacheStatsController.$inject = ["cacheStats", "$scope", "userModel"]; module.exports = CacheStatsController; diff --git a/traffic_portal/app/src/modules/private/cacheStats/cacheStats.tpl.html b/traffic_portal/app/src/modules/private/cacheStats/cacheStats.tpl.html index 50d810b3e6..b13d971310 100644 --- a/traffic_portal/app/src/modules/private/cacheStats/cacheStats.tpl.html +++ b/traffic_portal/app/src/modules/private/cacheStats/cacheStats.tpl.html @@ -18,41 +18,7 @@ -->
-
- -
- -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - -
ProfileHostCache GroupHealthyStatusConnectionsMbps Out
{{::cs.profile}}{{::cs.hostname}}{{::cs.cachegroup}}{{::cs.healthy}}{{::cs.status}}{{::connections(cs.connections)}}{{::bandwidth(cs.kbps, 'Mb')}}
-
+ +
- From a158727aadb16d8fde05273bfcffbf1d9a97b622 Mon Sep 17 00:00:00 2001 From: ocket8888 Date: Thu, 2 Dec 2021 19:30:33 -0700 Subject: [PATCH 2/5] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c032448a90..d33b4eef71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Added Rocky Linux 8 support - Traffic Monitors now peer with other Traffic Monitors of the same status (e.g. ONLINE with ONLINE, OFFLINE with OFFLINE), instead of all peering with ONLINE. - Added permissions to the role form in traffic portal +- Updated the Cache Stats Traffic Portal page to use a more performant AG-Grid-based table. ## [6.1.0] - 2022-01-18 ### Added From d550192a50c25c950320d322ff5a10f6ba38d1db Mon Sep 17 00:00:00 2001 From: ocket8888 Date: Fri, 3 Dec 2021 09:31:00 -0700 Subject: [PATCH 3/5] Remove log line from valueFormatter --- .../app/src/modules/private/cacheStats/CacheStatsController.js | 1 - 1 file changed, 1 deletion(-) diff --git a/traffic_portal/app/src/modules/private/cacheStats/CacheStatsController.js b/traffic_portal/app/src/modules/private/cacheStats/CacheStatsController.js index 454cb3baf0..d920155563 100644 --- a/traffic_portal/app/src/modules/private/cacheStats/CacheStatsController.js +++ b/traffic_portal/app/src/modules/private/cacheStats/CacheStatsController.js @@ -178,7 +178,6 @@ var CacheStatsController = function(cacheStats, $scope, userModel) { * @returns {string} The formatted value. */ valueFormatter: ({value}) => { - console.log("formatting a kbps:", value); if (!value || value <= 0 || !isFinite(value)) { return "0bps"; } From 53e20903d468b81e023a71f18e0a07f2bc2c7ba0 Mon Sep 17 00:00:00 2001 From: ocket8888 Date: Fri, 3 Dec 2021 09:36:45 -0700 Subject: [PATCH 4/5] Add missing semicolon to JSDoc typing --- .../src/modules/private/cacheStats/CacheStatsController.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/traffic_portal/app/src/modules/private/cacheStats/CacheStatsController.js b/traffic_portal/app/src/modules/private/cacheStats/CacheStatsController.js index d920155563..3e7090ad00 100644 --- a/traffic_portal/app/src/modules/private/cacheStats/CacheStatsController.js +++ b/traffic_portal/app/src/modules/private/cacheStats/CacheStatsController.js @@ -44,7 +44,7 @@ class CacheStatsHealthyCellRenderer { * column: any; * columnApi: any; * context: any; - * data: CacheStat + * data: CacheStat; * eGridCell: HTMLElement; * eParentOfValue: HTMLElement; * formatValue: function; @@ -98,7 +98,7 @@ var CacheStatsController = function(cacheStats, $scope, userModel) { * column: any; * columnApi: any; * context: any; - * data: CacheStat + * data: CacheStat; * eGridCell: HTMLElement; * eParentOfValue: HTMLElement; * formatValue: function; From 9ec384b9edb0547e921a7799d6e4f9cf7c22d8dc Mon Sep 17 00:00:00 2001 From: ocket8888 Date: Sat, 4 Dec 2021 00:03:46 -0700 Subject: [PATCH 5/5] Add column type --- .../src/modules/private/cacheStats/CacheStatsController.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/traffic_portal/app/src/modules/private/cacheStats/CacheStatsController.js b/traffic_portal/app/src/modules/private/cacheStats/CacheStatsController.js index 3e7090ad00..02a23f61a9 100644 --- a/traffic_portal/app/src/modules/private/cacheStats/CacheStatsController.js +++ b/traffic_portal/app/src/modules/private/cacheStats/CacheStatsController.js @@ -136,7 +136,10 @@ var CacheStatsController = function(cacheStats, $scope, userModel) { } } - /** The columns of the ag-grid table */ + /** + * The columns of the ag-grid table. + * @type CGC.ColumnDefinition[] + */ $scope.columns = [ { headerName: "Cache Group",