overload-protection
Advanced tools
Comparing version 1.1.0 to 1.2.0
@@ -20,3 +20,4 @@ 'use strict' | ||
maxRssBytes: 0, | ||
logging: false | ||
logging: false, | ||
logStatsOnReq: false | ||
} | ||
@@ -35,2 +36,5 @@ | ||
} | ||
if (opts.logStatsOnReq && opts.logging === false) { | ||
throw Error('logStatsOnReq cannot be enabled unless logging is also enabled') | ||
} | ||
var update = (opts.maxEventLoopDelay > 0) | ||
@@ -37,0 +41,0 @@ ? function update () { |
'use strict' | ||
var explain = require('./explain') | ||
var OverloadProtectionStats = require('./stats') | ||
Error.stackTraceLimit = Infinity | ||
module.exports = http | ||
@@ -12,2 +11,3 @@ | ||
var sendRetryHeader = clientRetrySecs > 0 | ||
var logStatsOnReq = opts.logStatsOnReq | ||
var logging = opts.logging | ||
@@ -23,2 +23,16 @@ var loggingOn = typeof logging === 'string' || typeof logging === 'function' | ||
function overloadProtection (req, res, next) { | ||
if (logStatsOnReq) { | ||
const stats = new OverloadProtectionStats( | ||
protect.overload, | ||
protect.eventLoopOverload, | ||
protect.heapUsedOverload, | ||
protect.rssOverload, | ||
protect.eventLoopDelay, | ||
protect.maxEventLoopDelay, | ||
protect.maxHeapUsedBytes, | ||
protect.maxRssBytes | ||
) | ||
if (log4jLogging) req.log && req.log[logging] && req.log[logging](stats) | ||
else logging(stats) | ||
} | ||
if (protect.overload === true) { | ||
@@ -25,0 +39,0 @@ res.statusCode = 503 |
@@ -5,2 +5,3 @@ 'use strict' | ||
var explain = require('./explain') | ||
var OverloadProtectionStats = require('./stats') | ||
@@ -10,2 +11,3 @@ function koa (opts, protect) { | ||
var sendRetryHeader = clientRetrySecs > 0 | ||
var logStatsOnReq = opts.logStatsOnReq | ||
var logging = opts.logging | ||
@@ -21,2 +23,16 @@ var loggingOn = typeof logging === 'string' || typeof logging === 'function' | ||
function overloadProtection (ctx, next) { | ||
if (logStatsOnReq) { | ||
const stats = new OverloadProtectionStats( | ||
protect.overload, | ||
protect.eventLoopOverload, | ||
protect.heapUsedOverload, | ||
protect.rssOverload, | ||
protect.eventLoopDelay, | ||
protect.maxEventLoopDelay, | ||
protect.maxHeapUsedBytes, | ||
protect.maxRssBytes | ||
) | ||
if (log4jLogging) ctx.log && ctx.log[logging] && ctx.log[logging](stats) | ||
else logging(stats) | ||
} | ||
if (protect.overload === true) { | ||
@@ -23,0 +39,0 @@ if (sendRetryHeader) ctx.set('Retry-After', clientRetrySecs) |
{ | ||
"name": "overload-protection", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"main": "index.js", | ||
@@ -38,8 +38,7 @@ "scripts": { | ||
"devDependencies": { | ||
"autocannon": "^0.16.5", | ||
"express": "^4.16.2", | ||
"koa": "^2.3.0", | ||
"koa-router": "^7.2.1", | ||
"express": "^4.17.1", | ||
"koa": "^2.11.0", | ||
"koa-router": "^7.4.0", | ||
"pre-commit": "^1.2.2", | ||
"restify": "^6.3.1", | ||
"restify": "^8.5.1", | ||
"standard": "^10.0.3", | ||
@@ -49,2 +48,3 @@ "tap": "^10.7.2" | ||
"dependencies": { | ||
"autocannon": "^4.4.1", | ||
"loopbench": "^1.2.0" | ||
@@ -51,0 +51,0 @@ }, |
@@ -43,2 +43,4 @@ # overload-protection | ||
// or propagate an error to the framework [default false] | ||
logging: false, // set to string for log level or function to pass data to | ||
logStatsOnReq: false // set to true to log stats on every requests | ||
} | ||
@@ -228,2 +230,7 @@ ``` | ||
#### logStatsOnReq: false | ||
Set `logStatsOnReq` to `true` log the profiled stats on every request. In order to use this option, the `logging` option must not be `false`. Bear in mind that using this option will | ||
add extra pressure on the event loop in itself, so use with caution. | ||
### instance.overload | ||
@@ -238,3 +245,3 @@ | ||
### profiler.eventLoopOverload | ||
### instance.eventLoopOverload | ||
@@ -248,3 +255,3 @@ The returned instance (which in many cases is passed as middleware to `app.use`), | ||
### profiler.heapUsedOverload | ||
### instance.heapUsedOverload | ||
@@ -258,3 +265,3 @@ The returned instance (which in many cases is passed as middleware to `app.use`), | ||
### profiler.rssOverload | ||
### instance.rssOverload | ||
@@ -261,0 +268,0 @@ The returned instance (which in many cases is passed as middleware to `app.use`), |
@@ -30,2 +30,11 @@ 'use strict' | ||
test('throws if logStatsOnReq is true but logging is false', function (t) { | ||
t.throws(function () { | ||
protect('http', { | ||
logStatsOnReq: true | ||
}) | ||
}) | ||
t.end() | ||
}) | ||
test('instance.stop ceases sampling', function (t) { | ||
@@ -32,0 +41,0 @@ var sI = global.setInterval |
@@ -540,1 +540,71 @@ 'use strict' | ||
}) | ||
test('if logStatsOnReq is true and if logging option is a string, writes log message using req.log as per level in string for every request', function (t) { | ||
var protect = protection('express', { | ||
logging: 'info', | ||
logStatsOnReq: true | ||
}) | ||
t.plan(1) | ||
var app = express() | ||
app.use(function (req, res, next) { | ||
req.log = { | ||
info: function (msg) { | ||
t.same(Object.keys(msg), [ | ||
'overload', | ||
'eventLoopOverload', | ||
'heapUsedOverload', | ||
'rssOverload', | ||
'eventLoopDelay', | ||
'maxEventLoopDelay', | ||
'maxHeapUsedBytes', | ||
'maxRssBytes' | ||
]) | ||
server.close() | ||
protect.stop() | ||
t.end() | ||
} | ||
} | ||
next() | ||
}) | ||
app.use(protect) | ||
app.get('/', function (req, res) { res.end('content') }) | ||
var server = http.createServer(app) | ||
server.listen(3000, function () { | ||
setTimeout(function () { | ||
http.get('http://localhost:3000').end() | ||
}, 6) | ||
}) | ||
}) | ||
test('if logStatsOnReq is true and logging option is a function, calls the function with stats on every request', function (t) { | ||
var protect = protection('express', { | ||
logStatsOnReq: true, | ||
logging: function (msg) { | ||
t.same(Object.keys(msg), [ | ||
'overload', | ||
'eventLoopOverload', | ||
'heapUsedOverload', | ||
'rssOverload', | ||
'eventLoopDelay', | ||
'maxEventLoopDelay', | ||
'maxHeapUsedBytes', | ||
'maxRssBytes' | ||
]) | ||
server.close() | ||
protect.stop() | ||
t.end() | ||
} | ||
}) | ||
var app = express() | ||
app.use(protect) | ||
app.get('/', function (req, res) { res.end('content') }) | ||
var server = http.createServer(app) | ||
server.listen(3001, function () { | ||
setTimeout(function () { | ||
http.get('http://localhost:3001').end() | ||
}, 6) | ||
}) | ||
}) |
@@ -591,1 +591,70 @@ 'use strict' | ||
}) | ||
test('if logStatsOnReq is true and if logging option is a string, writes log message using req.log as per level in string for every request', function (t) { | ||
var protect = protection('http', { | ||
logging: 'info', | ||
logStatsOnReq: true | ||
}) | ||
t.plan(1) | ||
var server = http.createServer(function serve (req, res) { | ||
req = { | ||
log: { | ||
info: function (msg) { | ||
t.same(Object.keys(msg), [ | ||
'overload', | ||
'eventLoopOverload', | ||
'heapUsedOverload', | ||
'rssOverload', | ||
'eventLoopDelay', | ||
'maxEventLoopDelay', | ||
'maxHeapUsedBytes', | ||
'maxRssBytes' | ||
]) | ||
server.close() | ||
protect.stop() | ||
t.end() | ||
} | ||
} | ||
} | ||
if (protect(req, res) === true) return | ||
res.end('content') | ||
}) | ||
server.listen(3000, function () { | ||
setTimeout(function () { | ||
http.get('http://localhost:3000').end() | ||
}, 6) | ||
}) | ||
}) | ||
test('if logStatsOnReq is true and logging option is a function, calls the function with stats on every request', function (t) { | ||
var protect = protection('http', { | ||
logStatsOnReq: true, | ||
logging: function (msg) { | ||
t.same(Object.keys(msg), [ | ||
'overload', | ||
'eventLoopOverload', | ||
'heapUsedOverload', | ||
'rssOverload', | ||
'eventLoopDelay', | ||
'maxEventLoopDelay', | ||
'maxHeapUsedBytes', | ||
'maxRssBytes' | ||
]) | ||
server.close() | ||
protect.stop() | ||
t.end() | ||
} | ||
}) | ||
var server = http.createServer(function serve (req, res) { | ||
if (protect(req, res) === true) return | ||
res.end('content') | ||
}) | ||
server.listen(3002, function () { | ||
setTimeout(function () { | ||
http.get('http://localhost:3002').end() | ||
}, 6) | ||
}) | ||
}) |
@@ -539,1 +539,67 @@ 'use strict' | ||
}) | ||
test('if logStatsOnReq is true and if logging option is a string, writes log message using req.log as per level in string for every request', function (t) { | ||
var protect = protection('koa', { | ||
logging: 'info', | ||
logStatsOnReq: true | ||
}) | ||
t.plan(1) | ||
var app = new Koa() | ||
app.use(function (ctx, next) { | ||
ctx.log = ctx.req.log = { | ||
info: function (msg) { | ||
t.same(Object.keys(msg), [ | ||
'overload', | ||
'eventLoopOverload', | ||
'heapUsedOverload', | ||
'rssOverload', | ||
'eventLoopDelay', | ||
'maxEventLoopDelay', | ||
'maxHeapUsedBytes', | ||
'maxRssBytes' | ||
]) | ||
server.close() | ||
protect.stop() | ||
t.end() | ||
} | ||
} | ||
return next() | ||
}) | ||
app.use(protect) | ||
var server = app.listen(3000, function () { | ||
setTimeout(function () { | ||
http.get('http://localhost:3000').end() | ||
}, 6) | ||
}) | ||
}) | ||
test('if logStatsOnReq is true and logging option is a function, calls the function with stats on every request', function (t) { | ||
var protect = protection('koa', { | ||
logStatsOnReq: true, | ||
logging: function (msg) { | ||
t.same(Object.keys(msg), [ | ||
'overload', | ||
'eventLoopOverload', | ||
'heapUsedOverload', | ||
'rssOverload', | ||
'eventLoopDelay', | ||
'maxEventLoopDelay', | ||
'maxHeapUsedBytes', | ||
'maxRssBytes' | ||
]) | ||
server.close() | ||
protect.stop() | ||
t.end() | ||
} | ||
}) | ||
var app = new Koa() | ||
app.use(protect) | ||
var server = app.listen(3001, function () { | ||
setTimeout(function () { | ||
http.get('http://localhost:3001').end() | ||
}, 6) | ||
}) | ||
}) |
@@ -534,1 +534,68 @@ 'use strict' | ||
}) | ||
test('if logStatsOnReq is true and if logging option is a string, writes log message using req.log as per level in string for every request', function (t) { | ||
var protect = protection('restify', { | ||
logging: 'info', | ||
logStatsOnReq: true | ||
}) | ||
t.plan(1) | ||
var server = restify.createServer({name: 'myapp', version: '1.0.0'}) | ||
server.use(function (req, res, next) { | ||
req.log = { | ||
info: function (msg) { | ||
t.same(Object.keys(msg), [ | ||
'overload', | ||
'eventLoopOverload', | ||
'heapUsedOverload', | ||
'rssOverload', | ||
'eventLoopDelay', | ||
'maxEventLoopDelay', | ||
'maxHeapUsedBytes', | ||
'maxRssBytes' | ||
]) | ||
server.close() | ||
protect.stop() | ||
t.end() | ||
} | ||
} | ||
next() | ||
}) | ||
server.use(protect) | ||
server.get('/', function (req, res) { res.end('content') }) | ||
server.listen(3000, function () { | ||
setTimeout(function () { | ||
http.get('http://localhost:3000').end() | ||
}, 6) | ||
}) | ||
}) | ||
test('if logStatsOnReq is true and logging option is a function, calls the function with stats on every request', function (t) { | ||
var protect = protection('restify', { | ||
logStatsOnReq: true, | ||
logging: function (msg) { | ||
t.same(Object.keys(msg), [ | ||
'overload', | ||
'eventLoopOverload', | ||
'heapUsedOverload', | ||
'rssOverload', | ||
'eventLoopDelay', | ||
'maxEventLoopDelay', | ||
'maxHeapUsedBytes', | ||
'maxRssBytes' | ||
]) | ||
server.close() | ||
protect.stop() | ||
t.end() | ||
} | ||
}) | ||
var server = restify.createServer({name: 'myapp', version: '1.0.0'}) | ||
server.use(protect) | ||
server.get('/', function (req, res) { res.end('content') }) | ||
server.listen(3001, function () { | ||
setTimeout(function () { | ||
http.get('http://localhost:3001').end() | ||
}, 6) | ||
}) | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
102684
7
32
3214
310
2
+ Addedautocannon@^4.4.1
+ Addedansi-regex@3.0.1(transitive)
+ Addedansi-styles@4.3.0(transitive)
+ Addedasynckit@0.4.0(transitive)
+ Addedautocannon@4.6.0(transitive)
+ Addedbase64-js@1.5.1(transitive)
+ Addedchalk@3.0.0(transitive)
+ Addedcli-table3@0.5.1(transitive)
+ Addedclone@2.1.2(transitive)
+ Addedcolor-convert@2.0.1(transitive)
+ Addedcolor-name@1.1.4(transitive)
+ Addedcolor-support@1.1.3(transitive)
+ Addedcolors@1.4.0(transitive)
+ Addedcombined-stream@1.0.8(transitive)
+ Addedcross-argv@1.0.0(transitive)
+ Addeddelayed-stream@1.0.0(transitive)
+ Addedform-data@2.5.2(transitive)
+ Addedhas-async-hooks@1.0.0(transitive)
+ Addedhas-flag@4.0.0(transitive)
+ Addedhdr-histogram-js@1.2.0(transitive)
+ Addedhdr-histogram-percentiles-obj@2.0.1(transitive)
+ Addedhttp-parser-js@0.5.8(transitive)
+ Addedhyperid@2.3.1(transitive)
+ Addedis-fullwidth-code-point@2.0.0(transitive)
+ Addedmanage-path@2.0.0(transitive)
+ Addedmime-db@1.52.0(transitive)
+ Addedmime-types@2.1.35(transitive)
+ Addedminimist@1.2.8(transitive)
+ Addedobject-assign@4.1.1(transitive)
+ Addedon-net-listen@1.1.2(transitive)
+ Addedpako@1.0.11(transitive)
+ Addedpretty-bytes@5.6.0(transitive)
+ Addedprogress@2.0.3(transitive)
+ Addedreinterval@1.1.0(transitive)
+ Addedretimer@2.0.0(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedstring-width@2.1.1(transitive)
+ Addedstrip-ansi@4.0.0(transitive)
+ Addedsupports-color@7.2.0(transitive)
+ Addedtimestring@6.0.0(transitive)
+ Addeduuid@8.3.2(transitive)
+ Addeduuid-parse@1.1.0(transitive)