view src/app/components/jvm-info/jvm-gc/jvm-gc.controller.js @ 263:87a683af97e8

Use jvm-gc /delta Reviewed-by: jkang Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-October/025439.html
author Andrew Azores <aazores@redhat.com>
date Tue, 24 Oct 2017 15:51:36 -0400
parents 9f3ee8157ac6
children
line wrap: on
line source

/**
 * Copyright 2012-2017 Red Hat, Inc.
 *
 * Thermostat is distributed under the GNU General Public License,
 * version 2 or any later version (with a special exception described
 * below, commonly known as the "Classpath Exception").
 *
 * A copy of GNU General Public License (GPL) is included in this
 * distribution, in the file COPYING.
 *
 * Linking Thermostat code with other modules is making a combined work
 * based on Thermostat.  Thus, the terms and conditions of the GPL
 * cover the whole combination.
 *
 * As a special exception, the copyright holders of Thermostat give you
 * permission to link this code with independent modules to produce an
 * executable, regardless of the license terms of these independent
 * modules, and to copy and distribute the resulting executable under
 * terms of your choice, provided that you also meet, for each linked
 * independent module, the terms and conditions of the license of that
 * module.  An independent module is a module which is not derived from
 * or based on Thermostat code.  If you modify Thermostat, you may
 * extend this exception to your version of the software, but you are
 * not obligated to do so.  If you do not wish to do so, delete this
 * exception statement from your version.
 */

import 'c3';
import filters from 'shared/filters/filters.module.js';
import service from './jvm-gc.service.js';

class JvmGcController {
  constructor ($stateParams, $interval, dateFilter, DATE_FORMAT,
    metricToNumberFilter, jvmGcService, sanitizeService, $translate) {
    'ngInject';
    this.jvmId = $stateParams.jvmId;
    this._interval = $interval;
    this._dateFilter = dateFilter;
    this._dateFormat = DATE_FORMAT;
    this._metricToNumber = metricToNumberFilter;
    this._svc = jvmGcService;
    this._sanitize = sanitizeService;
    this._translate = $translate;
  }

  $onInit () {
    this.collectors = [];
    this.chartConfigs = {};
    this.chartData = {};
    this._collectorData = new Map();
    this._constructChartData();

    this._refreshRate = 1000;
    this._dataAgeLimit = 30000;

    this._start();
  }

  $onDestroy () {
    this._stop();
  }

  _start () {
    this._stop();
    this._update();
    this._refresh = this._interval(() => this._update(), this.refreshRate);
  }

  _stop () {
    if (angular.isDefined(this._refresh)) {
      this._interval.cancel(this._refresh);
      delete this._refresh;
    }
  }

  set refreshRate (val) {
    this._stop();
    this._refreshRate = parseInt(val);
    if (this._refreshRate > 0) {
      this._start();
    }
  }

  get refreshRate () {
    return this._refreshRate.toString();
  }

  set dataAgeLimit (val) {
    this._dataAgeLimit = val;
    this._trimData();
  }

  get dataAgeLimit () {
    return this._dataAgeLimit.toString();
  }

  _makeConfig (collector) {
    if (_.includes(this.collectors, collector)) {
      return;
    }
    this.collectors.push(collector);
    this.collectors.sort();
    this._translate([
      'jvmGc.chart.UNITS',
      'jvmGc.chart.X_AXIS_LABEL',
      'jvmGc.chart.Y_AXIS_LABEL'
    ]).then(translations => {
      let config = {
        chartId: 'chart-' + collector,
        units: translations['jvmGc.chart.UNITS'],
        axis: {
          x: {
            label: translations['jvmGc.chart.X_AXIS_LABEL'],
            type: 'timeseries',
            localtime: false,
            tick: {
              format: timestamp => this._dateFilter(timestamp, this._dateFormat.time.medium),
              count: 5
            }
          },
          y: {
            label: translations['jvmGc.chart.Y_AXIS_LABEL'],
            tick: {
              format: d => d
            }
          }
        },
        tooltip: {
          format: {
            title: x => x,
            value: y => y
          }
        },
        transition: {
          duration: 0
        },
        point: {
          r: 0
        },
        onmouseover: () => this._stop(),
        onmouseout: () => this._start()
      };
      this.chartConfigs[collector] = config;
    });
  }

  _trimData () {
    let now = Date.now();
    let oldestLimit = now - parseInt(this.dataAgeLimit);

    for (let entry of this._collectorData) {
      let collector = entry[0];
      let samples = entry[1];

      let spliceCount = 0;
      for (; spliceCount < samples.length; spliceCount++) {
        let sample = samples[spliceCount];
        if (sample.timestamp >= oldestLimit) {
          break;
        }
      }
      samples.splice(0, spliceCount);
      this._collectorData.set(collector, samples);
    }
  }

  _constructChartData () {
    for (let entry of this._collectorData) {
      let collector = entry[0];
      let samples = entry[1];

      let data = {
        xData: ['timestamps'],
        yData: [collector]
      };

      for (let i = 0; i < samples.length; i++) {
        let sample = samples[i];
        data.xData.push(sample.timestamp);
        data.yData.push(sample.micros);
      }

      this.chartData[collector] = data;
    }
  }

  _update () {
    this._svc.getJvmGcData(this.jvmId).then(resp => this._processData(resp));
  }

  _processData (resp) {
    resp.forEach(update => {
      let timestamp = this._metricToNumber(update.timeStamp);
      let collectorName = update.collectorName;
      let micros = this._metricToNumber(update.wallTimeDelta);

      this._makeConfig(collectorName, micros);

      if (!this._collectorData.has(collectorName)) {
        this._collectorData.set(collectorName, []);
      }

      let collectorData = this._collectorData.get(collectorName);
      collectorData.push({
        timestamp: timestamp,
        micros: micros
      });
    });

    this._trimData();

    this._constructChartData();
  }

  sanitize (input) {
    return this._sanitize.sanitize(input);
  }

  multichartFn (collector) {
    return new Promise(resolve => {
      this._svc.getSnapshot(this.jvmId, collector).then(resp => {
        resolve(this._metricToNumber(resp));
      });
    });
  }

}

export default angular
  .module('jvmGc.controller', [
    'patternfly',
    'patternfly.charts',
    service,
    filters
  ])
  .controller('JvmGcController', JvmGcController)
  .name;