swagger-stats
Advanced tools
Comparing version 0.95.11 to 0.95.15
# Changelog | ||
All notable changes to this project will be documented in this file. | ||
## v0.95.15 | ||
* [feature] New User eXperience is enabled at `/swagger-stats/ux` | ||
New UX is optional and can be used in parallel with leagcy UI. | ||
Will keep it optional for several releases, and then make default. | ||
Send your feedback ! | ||
## v0.95.11 | ||
* [feature] Support for Fastify Framework [#62](https://github.com/slanatech/swagger-stats/issues/62) | ||
## v0.95.10 | ||
@@ -5,0 +19,0 @@ |
@@ -67,3 +67,3 @@ 'use strict'; | ||
name: 'swagger-stats-authtest', | ||
version: '0.95.11', | ||
version: '0.95.15', | ||
hostname: "hostname", | ||
@@ -70,0 +70,0 @@ ip: "127.0.0.1", |
@@ -41,3 +41,3 @@ 'use strict'; | ||
name: 'swagger-stats-fastify', | ||
version: '0.95.11', | ||
version: '0.95.15', | ||
timelineBucketDuration: 1000, | ||
@@ -44,0 +44,0 @@ swaggerSpec:swaggerSpec, |
@@ -71,3 +71,3 @@ 'use strict'; | ||
name: 'swagger-stats-hapitest', | ||
version: '0.95.11', | ||
version: '0.95.15', | ||
hostname: "hostname", | ||
@@ -74,0 +74,0 @@ ip: "127.0.0.1", |
@@ -7,2 +7,4 @@ 'use strict'; | ||
//http.globalAgent.keepAlive = true; | ||
// Prometheus Client | ||
@@ -80,3 +82,3 @@ const promClient = require('prom-client'); | ||
name: 'swagger-stats-spectest', | ||
version: '0.95.11', | ||
version: '0.95.15', | ||
hostname: "hostname", | ||
@@ -137,2 +139,4 @@ ip: "127.0.0.1", | ||
server.listen(app.get('port')); | ||
server.keepAliveTimeout = 61 * 1000; | ||
server.headersTimeout = 65 * 1000; | ||
debug('Server started on port ' + app.get('port') + ' http://localhost:'+app.get('port')); | ||
@@ -139,0 +143,0 @@ } |
@@ -112,3 +112,3 @@ 'use strict'; | ||
name: 'swagger-stats-testapp', | ||
version: '0.95.11', | ||
version: '0.95.15', | ||
timelineBucketDuration: tlBucket, | ||
@@ -115,0 +115,0 @@ uriPath: '/swagger-stats', |
@@ -105,3 +105,22 @@ /* swagger-stats Hapi plugin */ | ||
} | ||
}) | ||
}); | ||
// Return UX | ||
server.route({ | ||
method: 'GET', | ||
path: swsSettings.pathUX+'/{file*}', | ||
handler: function (request, h) { | ||
let fileName = request.params.file; | ||
if(!fileName){ | ||
fileName = 'index.html'; | ||
} | ||
var options = { | ||
root: path.join(__dirname,'..','ux'), | ||
dotfiles: 'deny' | ||
// TODO Caching | ||
}; | ||
request.raw.res.setHeader('Content-Type', send.mime.lookup(path.basename(fileName))); | ||
send(request.raw.req, fileName, options).pipe(request.raw.res); | ||
return h.abandon; | ||
} | ||
}); | ||
} | ||
@@ -108,0 +127,0 @@ } |
@@ -260,2 +260,21 @@ /** | ||
return; | ||
} else if(req.url.startsWith(swsSettings.pathUX)) { | ||
let filename = null; | ||
if(req.url === swsSettings.pathUX){ | ||
fileName = 'index.html'; | ||
}else { | ||
fileName = req.url.replace(swsSettings.pathUX+'/', ''); | ||
let qidx = fileName.indexOf('?'); | ||
if ( qidx != -1 ) { | ||
fileName = fileName.substring(0, qidx); | ||
} | ||
} | ||
let options = { | ||
root: path.join(__dirname,'..','ux'), | ||
dotfiles: 'deny' | ||
// TODO Caching | ||
}; | ||
res.setHeader('Content-Type', send.mime.lookup(path.basename(fileName))); | ||
send(req, fileName, options).pipe(res); | ||
return; | ||
} | ||
@@ -262,0 +281,0 @@ |
@@ -176,7 +176,5 @@ /** | ||
// Response Headers | ||
if ("_headers" in res){ | ||
rrr.http.response.headers = {}; | ||
for(var hdr in res['_headers']){ | ||
rrr.http.response.headers[hdr] = res['_headers'][hdr]; | ||
} | ||
var responseHeaders = res.getHeaders(); | ||
if (responseHeaders){ | ||
rrr.http.response.headers = responseHeaders; | ||
} | ||
@@ -183,0 +181,0 @@ |
@@ -115,2 +115,3 @@ /* swagger-stats Settings */ | ||
this.pathDist = '/swagger-stats/dist'; | ||
this.pathUX = '/swagger-stats/ux'; | ||
this.pathStats = '/swagger-stats/stats'; | ||
@@ -151,2 +152,3 @@ this.pathMetrics = '/swagger-stats/metrics'; | ||
this.pathDist = this.uriPath+'/dist'; | ||
this.pathUX = this.uriPath+'/ux'; | ||
this.pathStats = this.uriPath+'/stats'; | ||
@@ -153,0 +155,0 @@ this.pathMetrics = this.uriPath+'/metrics'; |
@@ -40,4 +40,5 @@ /** | ||
external: 0, | ||
cpu: 0 | ||
// TODO event loop delays | ||
cpu: 0, | ||
lag: 0, | ||
maxlag: 0 | ||
}; | ||
@@ -61,2 +62,12 @@ | ||
setEventLoopLag(start, sys) { | ||
const delta = process.hrtime(start); | ||
const nanosec = delta[0] * 1e9 + delta[1]; | ||
const mseconds = nanosec / 1e6; | ||
sys.lag = mseconds; | ||
if( mseconds > sys.maxlag ) { | ||
sys.maxlag = mseconds; | ||
} | ||
} | ||
getStats() { | ||
@@ -87,6 +98,7 @@ return this.sys; | ||
this.startTimeAndUsage.push( { hrtime: process.hrtime(), cpuUsage: process.cpuUsage() } ); | ||
let startTime = process.hrtime(); | ||
setImmediate(this.setEventLoopLag, startTime, this.sys); | ||
//this.startTime = process.hrtime(); | ||
//this.startUsage = process.cpuUsage(); | ||
let startUsage = process.cpuUsage(); | ||
this.startTimeAndUsage.push( { hrtime: startTime, cpuUsage: startUsage } ); | ||
@@ -93,0 +105,0 @@ this.sys.cpu = cpuPercent; |
@@ -35,2 +35,5 @@ /** | ||
this.memoryMeasurements = 1; | ||
// current max event loop lag | ||
this.lag = 0; | ||
} | ||
@@ -78,4 +81,14 @@ | ||
this.setMemoryStats(currBucket); | ||
let start = process.hrtime(); | ||
setImmediate(this.setMaxEvenLoopLag,start,this); | ||
}; | ||
swsTimeline.prototype.setMaxEvenLoopLag = function (start, dest) { | ||
const delta = process.hrtime(start); | ||
const nanosec = delta[0] * 1e9 + delta[1]; | ||
const mseconds = nanosec / 1e6; | ||
if( mseconds > dest.lag ){ | ||
dest.lag = mseconds; | ||
} | ||
} | ||
@@ -102,2 +115,3 @@ swsTimeline.prototype.getTimelineBucket = function (timelineid) { | ||
// TODO Carry over rates, SYS from prev bucket - so it would be aways 0 on refresh with short buckets | ||
swsTimeline.prototype.closeTimelineBucket = function(timelineid) { | ||
@@ -128,3 +142,9 @@ | ||
// Lag | ||
this.data[timelineid].sys.lag = this.lag; | ||
this.lag=0; | ||
this.startTime = process.hrtime(); | ||
setImmediate(this.setMaxEvenLoopLag,this.startTime,this.data[timelineid]); | ||
this.startUsage = process.cpuUsage(); | ||
@@ -131,0 +151,0 @@ |
{ | ||
"name": "swagger-stats", | ||
"version": "0.95.11", | ||
"version": "0.95.15", | ||
"description": "API Telemetry and APM. Trace API calls and Monitor API performance, health and usage statistics in Node.js Microservices, based on express routes and Swagger (Open API) specification", | ||
"main": "lib/index.js", | ||
"scripts": { | ||
"build": "npm run copy:ux", | ||
"copy:ux": "cp -r node_modules/swagger-stats-ux/dist/* ux", | ||
"start": "node example/app.js", | ||
@@ -45,6 +47,7 @@ "testonly": "mocha -S --delay", | ||
"karma-ci": "cross-env NODE_ENV=ci DEBUG=sws:* karma start karma.conf.js", | ||
"quickload": "artillery quick --duration 120 --rate 10 -n 20 http://localhost:3030/api/v1/tester/200" | ||
"quickload": "artillery quick --duration 120 --rate 70 -n 20 http://localhost:3040/v2/paramstest/200/and/OK" | ||
}, | ||
"keywords": [ | ||
"api", | ||
"observability", | ||
"telemetry", | ||
@@ -94,2 +97,3 @@ "node", | ||
"devDependencies": { | ||
"swagger-stats-ux": "^0.95.20", | ||
"artillery": "^1.6.0-26", | ||
@@ -96,0 +100,0 @@ "body-parser": "^1.18.2", |
@@ -33,7 +33,7 @@ <p align="center"> | ||
> **swagger-stats** provides built-in Telemetry UI, so you may enable **swagger-stats** in your app, and start monitoring immediately, with no infrastructure requirements. | ||
> Navigate to `http://<your app host:port>/swagger-stats/ui` | ||
> **swagger-stats** provides built-in Telemetry UX, so you may enable **swagger-stats** in your app, and start monitoring immediately, with no infrastructure requirements. | ||
> Navigate to `http://<your app host:port>/swagger-stats/ux` | ||
![swagger-stats Built-In Monitoring](screenshots/ui0950.gif?raw=true) | ||
![swagger-stats Built-In Telemetry](screenshots/swsux.gif?raw=true) | ||
@@ -40,0 +40,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
Network access
Supply chain riskThis module accesses the network.
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
8257082
99
41456
61
8