changeset 268:597d7d7e0aff

Add data age limit to jvm-memory Reviewed-by: jkang Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-October/025371.html
author Andrew Azores <aazores@redhat.com>
date Wed, 11 Oct 2017 15:38:34 -0400
parents 8fea191dbff0
children a0ae36ed4a9a
files src/app/components/jvm-info/jvm-memory/en.locale.yaml src/app/components/jvm-info/jvm-memory/jvm-memory.controller.js src/app/components/jvm-info/jvm-memory/jvm-memory.controller.spec.js src/app/components/jvm-info/jvm-memory/jvm-memory.html
diffstat 4 files changed, 110 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/app/components/jvm-info/jvm-memory/en.locale.yaml	Wed Oct 11 14:59:09 2017 -0400
+++ b/src/app/components/jvm-info/jvm-memory/en.locale.yaml	Wed Oct 11 15:38:34 2017 -0400
@@ -1,5 +1,8 @@
 jvmMemory:
+
   REFRESH_RATE_LABEL: Refresh Rate
+  MAX_DATA_AGE_LABEL: Max Data Age
+
   METASPACE: Metaspace
   COLLECTOR: '{{name}} generation ({{collector}} collector)'
   SPACE: Space {{index}}
@@ -9,3 +12,7 @@
   refresh:
     DISABLED: Disabled
     SECONDS: '{SECONDS, plural, =0{0 Seconds} one{1 Second} other{# Seconds}}{DEFAULT, select, true{ (Default)} other{}}'
+
+  dataAge:
+    SECONDS: '{SECONDS, plural, =0{0 Seconds} one{1 Second} other{# Seconds}}{DEFAULT, select, true{ (Default)} other{}}'
+    MINUTES: '{MINUTES, plural, =0{0 Minutes} one{1 Minute} other{# Minutes}}{DEFAULT, select, true{ (Default)} other{}}'
--- a/src/app/components/jvm-info/jvm-memory/jvm-memory.controller.js	Wed Oct 11 14:59:09 2017 -0400
+++ b/src/app/components/jvm-info/jvm-memory/jvm-memory.controller.js	Wed Oct 11 15:38:34 2017 -0400
@@ -109,6 +109,7 @@
     this.generationLineConfigs = new Map();
 
     this._refreshRate = 2000;
+    this._dataAgeLimit = 10 * 60 * 1000;
   }
 
   getLineConfig (genIndex, spaceIndex) {
@@ -181,6 +182,15 @@
     return this._refreshRate.toString();
   }
 
+  set dataAgeLimit (val) {
+    this._dataAgeLimit = val;
+    this._trimData();
+  }
+
+  get dataAgeLimit () {
+    return this._dataAgeLimit.toString();
+  }
+
   multichartMetaspace () {
     return new Promise(resolve =>
       this._jvmMemoryService.getJvmMemory(this.jvmId).then(resp =>
@@ -239,13 +249,39 @@
           });
         });
       });
+      this._trimData();
       this._updateLineCharts(keys);
       this._updateBarCharts(resp[0]);
     });
   }
 
-  _getKey (genIndex, spaceIndex) {
-    return `${genIndex}:${spaceIndex}`;
+  _trimData () {
+    let now = Date.now();
+    let limit = now - this._dataAgeLimit;
+
+    let metaspaceSpliceCount = 0;
+    for (; metaspaceSpliceCount < this._metaspaceData.timestamps.length; metaspaceSpliceCount++) {
+      let sample = this._metaspaceData.timestamps[metaspaceSpliceCount];
+      if (sample >= limit) {
+        break;
+      }
+    }
+    this._metaspaceData.timestamps.splice(0, metaspaceSpliceCount);
+    this._metaspaceData.used.splice(0, metaspaceSpliceCount);
+    this._metaspaceData.capacity.splice(0, metaspaceSpliceCount);
+
+    this._generationData.forEach(sampleSet => {
+      let sampleSpliceCount = 0;
+      for (; sampleSpliceCount < sampleSet.timestamps.length; sampleSpliceCount++) {
+        let sample = sampleSet.timestamps[sampleSpliceCount];
+        if (sample >= limit) {
+          break;
+        }
+      }
+      sampleSet.timestamps.splice(0, sampleSpliceCount);
+      sampleSet.used.splice(0, sampleSpliceCount);
+      sampleSet.capacity.splice(0, sampleSpliceCount);
+    });
   }
 
   _updateLineCharts (keys) {
@@ -322,6 +358,10 @@
     }
   }
 
+  _getKey (genIndex, spaceIndex) {
+    return `${genIndex}:${spaceIndex}`;
+  }
+
   convertMemStat (stat, scale) {
     let bigInt = this._metricToBigInt(stat, scale);
     let str = this._bigIntToString(bigInt);
--- a/src/app/components/jvm-info/jvm-memory/jvm-memory.controller.spec.js	Wed Oct 11 14:59:09 2017 -0400
+++ b/src/app/components/jvm-info/jvm-memory/jvm-memory.controller.spec.js	Wed Oct 11 15:38:34 2017 -0400
@@ -208,7 +208,7 @@
       data = [{
         agentId: 'foo-agentId',
         jvmId: 'foo-jvmId',
-        timeStamp: 100,
+        timeStamp: Date.now(),
         metaspaceMaxCapacity: { $numberLong: '0' },
         metaspaceMinCapacity: { $numberLong: '0' },
         metaspaceCapacity: { $numberLong: (40 * 1024 * 1024).toString() },
@@ -290,6 +290,54 @@
     });
   });
 
+  describe('_trimData', () => {
+    it('should trim old metaspace data', () => {
+      let now = Date.now();
+      ctrl._metaspaceData = {
+        timestamps: [now - 120 * 60 * 1000, now],
+        used: [100, 200],
+        capacity: [200, 400]
+      };
+      ctrl._trimData();
+      ctrl._metaspaceData.should.deepEqual({
+        timestamps: [now],
+        used: [200],
+        capacity: [400]
+      });
+    });
+
+    it('should trim old generational data', () => {
+      let now = Date.now();
+      ctrl._generationData.set('foo-key', {
+        timestamps: [now - 120 * 60 * 1000, now],
+        used: [100, 200],
+        capacity: [200, 400]
+      });
+      ctrl._trimData();
+      ctrl._generationData.get('foo-key').should.deepEqual({
+        timestamps: [now],
+        used: [200],
+        capacity: [400]
+      });
+    });
+  });
+
+  describe('dataAgeLimit', () => {
+    it('should cause a data trim on change', () => {
+      sinon.spy(ctrl, '_trimData');
+      ctrl._trimData.should.not.be.called;
+      ctrl.dataAgeLimit = 10000;
+      ctrl._trimData.should.be.calledOnce();
+      ctrl._trimData.restore();
+    });
+
+    it('should reflect changes in getter', () => {
+      ctrl.dataAgeLimit.should.equal('600000');
+      ctrl.dataAgeLimit = 10000;
+      ctrl.dataAgeLimit.should.equal('10000');
+    });
+  });
+
   describe('multichartMetaspace', () => {
     it('should return a promise', () => {
       let res = ctrl.multichartMetaspace();
--- a/src/app/components/jvm-info/jvm-memory/jvm-memory.html	Wed Oct 11 14:59:09 2017 -0400
+++ b/src/app/components/jvm-info/jvm-memory/jvm-memory.html	Wed Oct 11 15:38:34 2017 -0400
@@ -12,6 +12,18 @@
         <option value="30000" translate="jvmMemory.refresh.SECONDS" translate-values="{ SECONDS: 30 }" translate-interpolation="messageformat"></option>
       </select>
     </div>
+
+    <div class="col-xs-12 col-md-3">
+      <label for="dataAgeCombo" class="label label-info" translate>jvmMemory.MAX_DATA_AGE_LABEL</label>
+      <select name="dataAgeCombo" class="combobox form-control" ng-model="$ctrl.dataAgeLimit">
+        <option value="30000" translate="jvmMemory.dataAge.SECONDS" translate-values="{ SECONDS: 30 }" translate-interpolation="messageformat"></option>
+        <option value="60000" translate="jvmMemory.dataAge.MINUTES" translate-values="{ MINUTES: 1 }" translate-interpolation="messageformat"></option>
+        <option value="300000" translate="jvmMemory.dataAge.MINUTES" translate-values="{ MINUTES: 5 }" translate-interpolation="messageformat"></option>
+        <option value="600000" selected translate="jvmMemory.dataAge.MINUTES" translate-values="{ MINUTES: 10, DEFAULT: true }" translate-interpolation="messageformat"></option>
+        <option value="900000" translate="jvmMemory.dataAge.MINUTES" translate-values="{ MINUTES: 15 }" translate-interpolation="messageformat"></option>
+        <option value="1800000" translate="jvmMemory.dataAge.MINUTES" translate-values="{ MINUTES: 30 }" translate-interpolation="messageformat"></option>
+      </select>
+    </div>
   </div>
 
   <div class="row row-cards-pf">