-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathindex.js
104 lines (90 loc) · 2.94 KB
/
index.js
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
'use strict'
var loopbench = require('loopbench')
var frameworks = {
express: require('./lib/express'),
http: require('./lib/http'),
koa: require('./lib/koa'),
restify: require('./lib/restify')
}
var defaults = {
production: process.env.NODE_ENV === 'production',
errorPropagationMode: false,
clientRetrySecs: 1,
sampleInterval: 5,
maxEventLoopDelay: 42,
maxHeapUsedBytes: 0,
maxRssBytes: 0,
logging: false,
logStatsOnReq: false
}
function protect (framework, opts) {
opts = Object.assign({}, defaults, opts)
if (typeof framework === 'undefined') {
throw Error('Please specify a framework')
}
if (!(framework in frameworks)) {
throw Error(opts.integrate + ' not supported.')
}
if (opts.maxRssBytes <= 0 && opts.maxHeapUsedBytes <= 0 && opts.eventLoopDelay <= 0) {
throw Error('At least one threshold (eventLoopDelay, maxHeapUsedBytes, maxRssBytes) should be above 0')
}
if (opts.logStatsOnReq && opts.logging === false) {
throw Error('logStatsOnReq cannot be enabled unless logging is also enabled')
}
var update = (opts.maxEventLoopDelay > 0)
? function update () {
profiler.eventLoopOverload = eventLoopProfiler.overLimit
profiler.eventLoopDelay = eventLoopProfiler.delay
profiler.overload = profiler.eventLoopOverload ||
profiler.heapUsedOverload ||
profiler.rssOverload
}
: function update () {
profiler.overload = profiler.heapUsedOverload || profiler.rssOverload
}
if (opts.maxEventLoopDelay > 0) {
var eventLoopProfiler = loopbench({
sampleInterval: opts.sampleInterval,
limit: opts.maxEventLoopDelay
})
eventLoopProfiler.on('load', update)
eventLoopProfiler.on('unload', update)
}
var maxHeapUsedBytes = opts.maxHeapUsedBytes
var maxRssBytes = opts.maxRssBytes
var timer = (maxHeapUsedBytes > 0 || maxRssBytes > 0) &&
setInterval(checkMemory, opts.sampleInterval).unref()
var profiler = {
overload: false,
eventLoopOverload: false,
heapUsedOverload: false,
rssOverload: false,
eventLoopDelay: 0,
maxEventLoopDelay: opts.maxEventLoopDelay,
maxHeapUsedBytes: opts.maxHeapUsedBytes,
maxRssBytes: opts.maxRssBytes,
stop: stop
}
var integrate = frameworks[framework](opts, profiler)
if (Object.setPrototypeOf) {
Object.setPrototypeOf(profiler, Function.prototype)
Object.setPrototypeOf(integrate, profiler)
} else {
profiler.__proto__ = Function.prototype // eslint-disable-line
integrate.__proto__ = profiler // eslint-disable-line
}
return integrate
function checkMemory () {
var mem = process.memoryUsage()
var heapUsed = mem.heapUsed
var rss = mem.rss
profiler.heapUsedOverload = (maxHeapUsedBytes > 0 && heapUsed > maxHeapUsedBytes)
profiler.rssOverload = (maxRssBytes > 0 && rss > maxRssBytes)
update()
}
function stop () {
if (eventLoopProfiler) eventLoopProfiler.stop()
clearInterval(timer)
}
}
module.exports = protect