mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
102 lines
3.7 KiB
JavaScript
102 lines
3.7 KiB
JavaScript
|
const _ = require('underscore');
|
||
|
const metricConfig = require('./metricConfig');
|
||
|
const metricTools = require('./metricTools');
|
||
|
const gutil = require('app/common/gutil');
|
||
|
|
||
|
/**
|
||
|
* Base class for metrics collection used by both the server metrics collector, ServerMetrics.js,
|
||
|
* and the client metrics collector, ClientMetrics.js. Should not be instantiated.
|
||
|
* Establishes interval attempts to push metrics to the server on creation.
|
||
|
*/
|
||
|
function MetricsCollector() {
|
||
|
this.startTime = metricTools.getBucketStartTime(Date.now());
|
||
|
this.readyToExport = [];
|
||
|
// used (as a protected member) by the derived ServerMetrics class.
|
||
|
this._collect = setTimeout(() => this.scheduleBucketPreparation(), metricTools.getDeltaMs(Date.now()));
|
||
|
}
|
||
|
|
||
|
// Should return a map from metric names (as entered in metricConfig.js) to their metricTools.
|
||
|
MetricsCollector.prototype.getMetrics = function() {
|
||
|
throw new Error("Not implemented");
|
||
|
};
|
||
|
|
||
|
// Should return a promise that is resolved when the metrics have been pushed.
|
||
|
MetricsCollector.prototype.pushMetrics = function() {
|
||
|
throw new Error("Not implemented");
|
||
|
};
|
||
|
|
||
|
// Should return a bucket of metric data, formatted for either the client or server.
|
||
|
MetricsCollector.prototype.createBucket = function(bucketStart) {
|
||
|
throw new Error("Not implemented");
|
||
|
};
|
||
|
|
||
|
// Takes a list of metrics specifications and creates an object mapping metric names to
|
||
|
// a new instance of the metric gathering tool matching that metric's type.
|
||
|
MetricsCollector.prototype.initMetricTools = function(metricsList) {
|
||
|
var metrics = {};
|
||
|
metricsList.forEach(metricInfo => {
|
||
|
metrics[metricInfo.name] = new metricTools[metricInfo.type](metricInfo.name);
|
||
|
});
|
||
|
return metrics;
|
||
|
};
|
||
|
|
||
|
// Called each push interval.
|
||
|
MetricsCollector.prototype.attemptPush = function() {
|
||
|
this.pushMetrics(this.readyToExport);
|
||
|
this.readyToExport = [];
|
||
|
};
|
||
|
|
||
|
// Pushes bucket to the end of the readyToExport queue. Should be called sequentially, since it
|
||
|
// handles deletion of buckets older than the export memory limit.
|
||
|
MetricsCollector.prototype.queueBucket = function(bucket) {
|
||
|
// If readyToExport is at maximum length, delete the oldest element
|
||
|
this.readyToExport.push(bucket);
|
||
|
var length = this.readyToExport.length;
|
||
|
if (length > metricConfig.MAX_PENDING_BUCKETS) {
|
||
|
this.readyToExport.splice(0, length - metricConfig.MAX_PENDING_BUCKETS);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
MetricsCollector.prototype.scheduleBucketPreparation = function() {
|
||
|
this.prepareCompletedBuckets(Date.now());
|
||
|
this._collect = setTimeout(() => this.scheduleBucketPreparation(), metricTools.getDeltaMs(Date.now()));
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Checks if each bucket since the last update is completed and for each one adds all data and
|
||
|
* pushes it to the export ready array.
|
||
|
*/
|
||
|
MetricsCollector.prototype.prepareCompletedBuckets = function(now) {
|
||
|
var bucketStart = metricTools.getBucketStartTime(now);
|
||
|
while (bucketStart > this.startTime) {
|
||
|
this.queueBucket(this.createBucket(this.startTime));
|
||
|
this.startTime += metricConfig.BUCKET_SIZE;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Collects primitive metrics tools into a list.
|
||
|
*/
|
||
|
MetricsCollector.prototype.collectPrimitiveMetrics = function() {
|
||
|
var metricTools = [];
|
||
|
_.forEach(this.getMetrics(), metricTool => {
|
||
|
gutil.arrayExtend(metricTools, metricTool.getPrimitiveMetrics());
|
||
|
});
|
||
|
return metricTools;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Loops through metric tools for a chosen bucket and performs the provided callback on each.
|
||
|
* Resets each tool after the callback is performed.
|
||
|
* @param {Number} bucketStart - The desired bucket's start time in milliseconds
|
||
|
* @param {Function} callback - The callback to perform on each metric tool.
|
||
|
*/
|
||
|
MetricsCollector.prototype.forEachBucketMetric = function(bucketEnd, callback) {
|
||
|
this.collectPrimitiveMetrics().forEach(tool => {
|
||
|
callback(tool);
|
||
|
tool.reset(bucketEnd);
|
||
|
});
|
||
|
};
|
||
|
|
||
|
module.exports = MetricsCollector;
|