dl
Version:
DreamLab Libs
104 lines (79 loc) • 2.68 kB
JavaScript
var core = require('core');
var HdrHistogram = require('native-hdr-histogram');
var Types = core.common.Types;
var GaugeMetric = require('./GaugeMetric.js').GaugeMetric;
var HistogramMetric = function (name, buckets) {
GaugeMetric.call(this, name);
if (!Types.isArray(buckets)) {
throw new Error('Buckets need to be an array');
}
if (buckets.length < 2) {
throw new Error('Buckets need to have at least two elements');
}
this._buckets = buckets.sort(function (a, b) { return a - b; });
this._values = Array.apply(null, Array(this._buckets.length + 1)).map(function () { return 0; });
var min = this._buckets[0] >= 1 ? this._buckets[0] : 1;
var max = this._buckets[this._buckets.length - 1];
this._histogram = new HdrHistogram(min, max);
};
HistogramMetric.prototype = Object.create(GaugeMetric.prototype);
HistogramMetric.prototype.update = function (value) {
this._histogram.record(value);
var idx = 0;
// [ 1, 3 ]
// -1 -> 0
// 1 -> 1
// 2 -> 1
// 3 -> 2
// 4 -> 2
while (idx < this._buckets.length && value >= this._buckets[idx]) {
idx++;
}
this._values[idx]++;
return GaugeMetric.prototype.update.call(this, value);
};
HistogramMetric.prototype.dump = function () {
var data = {
'p50': this._histogram.percentile(50),
'p95': this._histogram.percentile(95),
'p99': this._histogram.percentile(99),
'stddev': this._histogram.stddev()
};
var keys = Object.keys(data);
var that = this;
keys = keys.map(function (key) {
return {
'key': that._name + '.' + key,
'value': that._dumpValue(1, data[key])
};
});
if (this._values[0] > 0) {
keys.push({
'key': this._name + '.min_to_' + this._buckets[0],
'value': {
'count': this._values[0]
}
});
}
for (var i = 1, l = this._buckets.length; i < l; i++) {
if (this._values[i] > 0) {
keys.push({
'key': this._name + '.' + this._buckets[i - 1] + '_to_' + this._buckets[i],
'value': {
'count': this._values[i]
}
});
}
}
if (this._values[this._buckets.length] > 0) {
keys.push({
'key': this._name + '.' + this._buckets[this._buckets.length - 1] + '_to_max',
'value': {
'count': this._values[this._buckets.length]
}
})
}
keys = keys.concat(GaugeMetric.prototype.dump.call(this));
return keys;
};
exports.HistogramMetric = HistogramMetric;