You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ea...@apache.org on 2018/09/25 16:40:41 UTC

qpid-dispatch git commit: DISPATCH-1128 Added rates to connection popup on console's topology page

Repository: qpid-dispatch
Updated Branches:
  refs/heads/master d5bbd422c -> 15c46db55


DISPATCH-1128 Added rates to connection popup on console's topology page


Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/15c46db5
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/15c46db5
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/15c46db5

Branch: refs/heads/master
Commit: 15c46db55bed4d5d7e88bd24fd1ccf255453e629
Parents: d5bbd42
Author: Ernest Allen <ea...@redhat.com>
Authored: Tue Sep 25 12:40:20 2018 -0400
Committer: Ernest Allen <ea...@redhat.com>
Committed: Tue Sep 25 12:40:20 2018 -0400

----------------------------------------------------------------------
 console/stand-alone/plugin/js/amqp/topology.js  |  1 +
 console/stand-alone/plugin/js/amqp/utilities.js | 35 +++++++++++++--
 console/stand-alone/plugin/js/chord/data.js     |  2 +-
 .../plugin/js/topology/qdrTopology.js           |  1 +
 .../stand-alone/plugin/js/topology/topoUtils.js | 47 ++++++++++++++++----
 5 files changed, 72 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/15c46db5/console/stand-alone/plugin/js/amqp/topology.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/amqp/topology.js b/console/stand-alone/plugin/js/amqp/topology.js
index e208a6f..ec45e3b 100644
--- a/console/stand-alone/plugin/js/amqp/topology.js
+++ b/console/stand-alone/plugin/js/amqp/topology.js
@@ -212,6 +212,7 @@ class Topology {
   }
   // ensure these nodes have all these entities. don't fetch unless forced to
   ensureEntities(nodes, entityAttribs, callback, extra) {
+    let self = this;
     if (Object.prototype.toString.call(entityAttribs) !== '[object Array]') {
       entityAttribs = [entityAttribs];
     }

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/15c46db5/console/stand-alone/plugin/js/amqp/utilities.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/amqp/utilities.js b/console/stand-alone/plugin/js/amqp/utilities.js
index 328da38..7b10c57 100644
--- a/console/stand-alone/plugin/js/amqp/utilities.js
+++ b/console/stand-alone/plugin/js/amqp/utilities.js
@@ -85,8 +85,8 @@ var utils = {
     var t = s.charAt(0).toUpperCase() + s.substr(1).replace(/[A-Z]/g, ' $&');
     return t.replace('.', ' ');
   },
-  pretty: function (v) {
-    var formatComma = ddd.format(',');
+  pretty: function (v, format = ',') {
+    var formatComma = ddd.format(format);
     if (!isNaN(parseFloat(v)) && isFinite(v))
       return formatComma(v);
     return v;
@@ -103,13 +103,40 @@ var utils = {
   },
   // extract the name of the router from the router id
   nameFromId: function (id) {
-    // the router id looks like 'amqp:/topo/0/routerName/$managemrnt'
+    // the router id looks like 'amqp:/topo/0/routerName/$management'
     var parts = id.split('/');
     // handle cases where the router name contains a /
     parts.splice(0, 3); // remove amqp, topo, 0
     parts.pop(); // remove $management
     return parts.join('/');
+  },
+  // calculate the average rate of change per second for a list of fields on the given obj
+  // store the historical raw values in storage[key] for future rate calcs
+  // keep 'history' number of historical values
+  rates: function (obj, fields, storage, key, history = 1) {
+    let list = storage[key];
+    if (!list) {
+      list = storage[key] = [];
+    }
+    // expire old entries
+    while (list.length > history) {
+      list.shift();
+    }
+    let rates = {};
+    list.push({date: new Date(), val: Object.assign({}, obj)});
+
+    for (let i=0; i<fields.length; i++) {
+      let cumulative = 0;
+      let field = fields[i];
+      for (let j=0; j<list.length-1; j++) {
+        let elapsed = list[j+1].date - list[j].date;
+        let diff = list[j+1].val[field] - list[j].val[field];
+        if (elapsed > 100)
+          cumulative += diff/(elapsed / 1000);
+      }
+      rates[field] = list.length > 1 ? cumulative / (list.length-1) : 0;
+    }
+    return rates;
   }
-  
 };
 export { utils };
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/15c46db5/console/stand-alone/plugin/js/chord/data.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/chord/data.js b/console/stand-alone/plugin/js/chord/data.js
index 491b42b..d9625aa 100644
--- a/console/stand-alone/plugin/js/chord/data.js
+++ b/console/stand-alone/plugin/js/chord/data.js
@@ -108,7 +108,7 @@ class ChordData { // eslint-disable-line no-unused-vars
           let egressRouter = self.QDRService.utilities.nameFromId(nodeId);
           // loop through the router links for this router looking for out/endpoint/non-console links
           let routerLinks = results[nodeId]['router.link'];
-          for (let i = 0; i < routerLinks.results.length; i++) {
+          for (let i = 0; routerLinks && (i < routerLinks.results.length); i++) {
             let link = self.QDRService.utilities.flatten(routerLinks.attributeNames, routerLinks.results[i]);
             // if the link is an outbound/enpoint/non console
             if (link.linkType === 'endpoint' && link.linkDir === 'out' && !link.owningAddr.startsWith('Ltemp.')) {

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/15c46db5/console/stand-alone/plugin/js/topology/qdrTopology.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/topology/qdrTopology.js b/console/stand-alone/plugin/js/topology/qdrTopology.js
index 1ac1011..ed85f74 100644
--- a/console/stand-alone/plugin/js/topology/qdrTopology.js
+++ b/console/stand-alone/plugin/js/topology/qdrTopology.js
@@ -523,6 +523,7 @@ export class TopologyController {
           d3.select('#popover-div')
             .style('display', 'none');
           selected_link = null;
+          connectionPopupHTML();
           restart();
         })
         // left click a path

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/15c46db5/console/stand-alone/plugin/js/topology/topoUtils.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/topology/topoUtils.js b/console/stand-alone/plugin/js/topology/topoUtils.js
index 48d4cf8..4163e94 100644
--- a/console/stand-alone/plugin/js/topology/topoUtils.js
+++ b/console/stand-alone/plugin/js/topology/topoUtils.js
@@ -60,7 +60,12 @@ export function nextHop(thisNode, d, nodes, links, QDRService, selected_node, cb
   }
 }
 
+let linkRateHistory = {};
 export function connectionPopupHTML (d, QDRService) {
+  if (!d) {
+    linkRateHistory = {};
+    return;
+  }
   let getConnsArray = function (d, conn) {
     let conns = [conn];
     if (d.cls === 'small') {
@@ -79,7 +84,7 @@ export function connectionPopupHTML (d, QDRService) {
   // The HTML is sanitized elsewhere before it is displayed
   let linksHTML = function (onode, conn, d) {
     const max_links = 10;
-    const fields = ['undelivered', 'unsettled', 'rejected', 'released', 'modified'];
+    const fields = ['deliveryCount', 'undeliveredCount', 'unsettledCount', 'rejectedCount', 'releasedCount', 'modifiedCount'];
     // local function to determine if a link's connectionId is in any of the connections
     let isLinkFor = function (connectionId, conns) {
       for (let c=0; c<conns.length; c++) {
@@ -111,22 +116,36 @@ export function connectionPopupHTML (d, QDRService) {
         if (isLinkFor(link.connectionId, conns)) {
           if (link.owningAddr)
             hasAddress = true;
+          if (link.name) {
+            let rate = QDRService.utilities.rates(link, fields, linkRateHistory, link.name, 1);
+            // replace the raw value with the rate
+            for (let i=0; i<fields.length; i++) {
+              link[fields[i]] = rate[fields[i]];
+            }
+          }
           links.push(link);
         }
       }
     }
     // we may need to limit the number of links displayed, so sort descending by the sum of the field values
+    let sum = function (a) {
+      let s = 0;
+      for (let i=0; i<fields.length; i++) {
+        s += a[fields[i]];
+      }
+      return s;
+    };
     links.sort( function (a, b) {
-      let asum = a.undeliveredCount + a.unsettledCount + a.rejectedCount + a.releasedCount + a.modifiedCount;
-      let bsum = b.undeliveredCount + b.unsettledCount + b.rejectedCount + b.releasedCount + b.modifiedCount;
+      let asum = sum(a);
+      let bsum = sum(b);
       return asum < bsum ? 1 : asum > bsum ? -1 : 0;
     });
-    let HTMLHeading = '<h5>Links</h5>';
+
+    let HTMLHeading = '<h5>Rates (per second) for links</h5>';
     let HTML = '<table class="popupTable">';
     // copy of fields since we may be prepending an address
     let th = fields.slice();
-    // convert to actual attribute names
-    let td = fields.map( function (f) {return f + 'Count';});
+    let td = fields;
     th.unshift('dir');
     td.unshift('linkDir');
     // add an address field if any of the links had an owningAddress
@@ -134,11 +153,20 @@ export function connectionPopupHTML (d, QDRService) {
       th.unshift('address');
       td.unshift('owningAddr');
     }
-    HTML += ('<tr class="header"><td>' + th.join('</td><td>') + '</td></tr>');
+
+    let rate_th = function (th) {
+      let rth = th.map( function (t) {
+        if (t.endsWith('Count'))
+          t = t.replace('Count', 'Rate');
+        return QDRService.utilities.humanify(t);
+      });
+      return rth;
+    };
+    HTML += ('<tr class="header"><td>' + rate_th(th).join('</td><td>') + '</td></tr>');
     // add rows to the table for each link
     for (let l=0; l<links.length; l++) {
       if (l>=max_links) {
-        HTMLHeading = `<h4>Top ${max_links} Links</h4>`;
+        HTMLHeading = `<h5>Rates (per second) for top ${max_links} links</h5>`;
         break;
       }
       let link = links[l];
@@ -150,13 +178,14 @@ export function connectionPopupHTML (d, QDRService) {
         return link[f];
       });
       let joinedVals = fnJoin(vals, function (v1) {
-        return ['</td><td' + (isNaN(+v1) ? '': ' align="right"') + '>', QDRService.utilities.pretty(v1 || '0')];
+        return ['</td><td' + (isNaN(+v1) ? '': ' align="right"') + '>', QDRService.utilities.pretty(v1 || '0', ',.2f')];
       });
       HTML += `<tr><td> ${joinedVals} </td></tr>`;
     }
     HTML += '</table>';
     return HTMLHeading + HTML;
   };
+
   let left = d.left ? d.source : d.target;
   // left is the connection with dir 'in'
   let right = d.left ? d.target : d.source;


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org