1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
const { MetricTypes } = require('./Metric');
const Histogram = require('./Histogram');
const Meter = require('./Meter');
const Stopwatch = require('../util/Stopwatch');
/**
*
* Timers are a combination of Meters and Histograms. They measure the rate as well as distribution of scalar events.
* <p>
* Since they are frequently used for tracking how long certain things take, they expose an API for that: See example 1.
* <p>
* But you can also use them as generic histograms that also track the rate of events: See example 2.
*
* @example
* var Measured = require('measured')
* var timer = new Measured.Timer();
* http.createServer(function(req, res) {
* var stopwatch = timer.start();
* req.on('end', function() {
* stopwatch.end();
* });
* });
*
*
* @example
* var Measured = require('measured')
* var timer = new Measured.Timer();
* http.createServer(function(req, res) {
* if (req.headers['content-length']) {
* timer.update(parseInt(req.headers['content-length'], 10));
* }
* });
*
* @implements {Metric}
*/
class Timer {
/**
* @param {TimerProperties} [properties] See {@link TimerProperties}.
*/
constructor(properties) {
properties = properties || {};
this._meter = properties.meter || new Meter({});
this._histogram = properties.histogram || new Histogram({});
this._getTime = properties.getTime;
this._keepAlive = !!properties.keepAlive;
if (!properties.keepAlive) {
this.unref();
}
}
/**
* @return {Stopwatch} Returns a Stopwatch that has been started.
*/
start() {
const self = this;
const watch = new Stopwatch({ getTime: this._getTime });
watch.once('end', elapsed => {
self.update(elapsed);
});
return watch;
}
/**
* Updates the internal histogram with value and marks one event on the internal meter.
* @param {number} value
*/
update(value) {
this._meter.mark();
this._histogram.update(value);
}
/**
* Resets all values. Timers initialized with custom options will be reset to the default settings.
*/
reset() {
this._meter.reset();
this._histogram.reset();
}
end() {
this._meter.end();
}
/**
* Refs the backing timer again. Idempotent.
*/
ref() {
this._meter.ref();
}
/**
* Unrefs the backing timer. The meter will not keep the event loop alive. Idempotent.
*/
unref() {
this._meter.unref();
}
/**
* toJSON output:
*
* <li> meter: See <a href="#meter">Meter</a>#toJSON output docs above.</li>
* <li> histogram: See <a href="#histogram">Histogram</a>#toJSON output docs above.</a></li>
*
* @return {any}
*/
toJSON() {
return {
meter: this._meter.toJSON(),
histogram: this._histogram.toJSON()
};
}
/**
* The type of the Metric Impl. {@link MetricTypes}.
* @return {string} The type of the Metric Impl.
*/
getType() {
return MetricTypes.TIMER;
}
}
module.exports = Timer;
/**
* @interface TimerProperties
* @typedef TimerProperties
* @type {Object}
* @property {Meter} meter The internal meter to use. Defaults to a new {@link Meter}.
* @property {Histogram} histogram The internal histogram to use. Defaults to a new {@link Histogram}.
* @property {function} getTime optional function override for supplying time to the {@link Stopwatch}
* @property {boolean} keepAlive Optional flag to unref the associated timer. Defaults to `false`.
*/