mirror of
https://github.com/nodejs/node.git
synced 2025-08-15 13:48:44 +02:00
perf_hooks: implement histogram based api
Add a sampling-based event loop delay monitor. ```js const { monitorEventLoopDelay } = require('perf_hooks'); const h = monitorEventLoopDelay(); h.enable(); h.disable(); console.log(h.percentiles); console.log(h.min); console.log(h.max); console.log(h.mean); console.log(h.stddev); console.log(h.percentile(50)); ``` PR-URL: https://github.com/nodejs/node/pull/25378 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Stephen Belanger <admin@stephenbelanger.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
This commit is contained in:
parent
679c23f2ae
commit
bcdd228f90
18 changed files with 2207 additions and 3 deletions
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const {
|
||||
ELDHistogram: _ELDHistogram,
|
||||
PerformanceEntry,
|
||||
mark: _mark,
|
||||
clearMark: _clearMark,
|
||||
|
@ -35,6 +36,8 @@ const { AsyncResource } = require('async_hooks');
|
|||
const L = require('internal/linkedlist');
|
||||
const kInspect = require('internal/util').customInspectSymbol;
|
||||
|
||||
const kHandle = Symbol('handle');
|
||||
const kMap = Symbol('map');
|
||||
const kCallback = Symbol('callback');
|
||||
const kTypes = Symbol('types');
|
||||
const kEntries = Symbol('entries');
|
||||
|
@ -545,9 +548,73 @@ function sortedInsert(list, entry) {
|
|||
list.splice(location, 0, entry);
|
||||
}
|
||||
|
||||
class ELDHistogram {
|
||||
constructor(handle) {
|
||||
this[kHandle] = handle;
|
||||
this[kMap] = new Map();
|
||||
}
|
||||
|
||||
reset() { this[kHandle].reset(); }
|
||||
enable() { return this[kHandle].enable(); }
|
||||
disable() { return this[kHandle].disable(); }
|
||||
|
||||
get exceeds() { return this[kHandle].exceeds(); }
|
||||
get min() { return this[kHandle].min(); }
|
||||
get max() { return this[kHandle].max(); }
|
||||
get mean() { return this[kHandle].mean(); }
|
||||
get stddev() { return this[kHandle].stddev(); }
|
||||
percentile(percentile) {
|
||||
if (typeof percentile !== 'number') {
|
||||
const errors = lazyErrors();
|
||||
throw new errors.ERR_INVALID_ARG_TYPE('percentile', 'number', percentile);
|
||||
}
|
||||
if (percentile <= 0 || percentile > 100) {
|
||||
const errors = lazyErrors();
|
||||
throw new errors.ERR_INVALID_ARG_VALUE.RangeError('percentile',
|
||||
percentile);
|
||||
}
|
||||
return this[kHandle].percentile(percentile);
|
||||
}
|
||||
get percentiles() {
|
||||
this[kMap].clear();
|
||||
this[kHandle].percentiles(this[kMap]);
|
||||
return this[kMap];
|
||||
}
|
||||
|
||||
[kInspect]() {
|
||||
return {
|
||||
min: this.min,
|
||||
max: this.max,
|
||||
mean: this.mean,
|
||||
stddev: this.stddev,
|
||||
percentiles: this.percentiles,
|
||||
exceeds: this.exceeds
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function monitorEventLoopDelay(options = {}) {
|
||||
if (typeof options !== 'object' || options === null) {
|
||||
const errors = lazyErrors();
|
||||
throw new errors.ERR_INVALID_ARG_TYPE('options', 'Object', options);
|
||||
}
|
||||
const { resolution = 10 } = options;
|
||||
if (typeof resolution !== 'number') {
|
||||
const errors = lazyErrors();
|
||||
throw new errors.ERR_INVALID_ARG_TYPE('options.resolution',
|
||||
'number', resolution);
|
||||
}
|
||||
if (resolution <= 0 || !Number.isSafeInteger(resolution)) {
|
||||
const errors = lazyErrors();
|
||||
throw new errors.ERR_INVALID_OPT_VALUE.RangeError('resolution', resolution);
|
||||
}
|
||||
return new ELDHistogram(new _ELDHistogram(resolution));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
performance,
|
||||
PerformanceObserver
|
||||
PerformanceObserver,
|
||||
monitorEventLoopDelay
|
||||
};
|
||||
|
||||
Object.defineProperty(module.exports, 'constants', {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue