Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

swagger-stats

Package Overview
Dependencies
Maintainers
1
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

swagger-stats - npm Package Compare versions

Comparing version 0.91.0 to 0.92.0

dashboards/prometheus/swagger-stats API Operation dashboard.json

33

examples/spectest/spectest.js

@@ -7,2 +7,8 @@ 'use strict';

// Prometheus Client
const promClient = require('prom-client');
const collectDefaultMetrics = promClient.collectDefaultMetrics;
// Probe every 1 second
collectDefaultMetrics({ timeout: 1000 });
// Server

@@ -42,2 +48,9 @@ var server = null;

// Return Prometheus metrics from prom-client
app.get('/metrics', function(req,res) {
res.status(200).set('Content-Type', 'text/plain');
res.end(promClient.register.metrics());
});
// Testing validation of 3rd-party API spec

@@ -51,4 +64,2 @@ var swaggerSpec = null;

specLocation = process.env.SWS_SPECTEST_URL;
}else{
debug('Use SWS_SPECTEST_URL environment variable to specify swagger spec');
}

@@ -69,16 +80,14 @@

//app.use(swStats.getMiddleware());
// Track statistics on API request / responses
// Enable swagger-stats middleware with all options
app.use(swStats.getMiddleware({
name: 'swagger-stats-testapp',
version: '0.90.3',
name: 'swagger-stats-spectest',
version: '0.92.0',
hostname: "hostname",
ip: "127.0.0.1",
timelineBucketDuration: tlBucket,
swaggerSpec:swaggerSpec
// Override duration buckets
//durationBuckets: [100, 1000, 5000, 20000],
//requestSizeBuckets: [500, 5000, 15000, 50000],
//responseSizeBuckets: [600, 6000, 6000, 60000]
swaggerSpec:swaggerSpec,
uriPath: '/swagger-stats',
durationBuckets: [5, 10, 25],
requestSizeBuckets: [5, 10, 25],
responseSizeBuckets: [5, 10, 25]
}));

@@ -85,0 +94,0 @@

@@ -112,6 +112,10 @@ 'use strict';

name: 'swagger-stats-testapp',
version: '0.90.3',
version: '0.92.0',
timelineBucketDuration: tlBucket,
uriPath: '/swagger-stats',
swaggerSpec:swaggerSpec
swaggerSpec:swaggerSpec,
promClient: false,
onResponseFinish: function(req,res,rrr){
debug('onResponseFinish: %s', JSON.stringify(rrr));
}
}));

@@ -118,0 +122,0 @@

@@ -72,3 +72,4 @@ 'use strict';

{ type: 'lcov' },
{ type: 'text' }
{ type: 'text' },
{ type: 'json' }
]

@@ -75,0 +76,0 @@ },

@@ -12,2 +12,5 @@ /**

// Prometheus Client library will be required, if exists in the application
var promClient = null;
var swsUtil = require('./swsUtil');

@@ -48,2 +51,5 @@ var swsReqResStats = require('./swsReqResStats');

// prom-client metrics
this.promClientMetrics = null;
}

@@ -246,3 +252,41 @@

if(swsOptions.promClientAvailable) {
try {
promClient = require("prom-client");
// Create metrics
this.promClientMetrics = {};
this.promClientMetrics.api_request_total = new promClient.Counter({
name: swsUtil.swsMetrics.api_request_total.name,
help: swsUtil.swsMetrics.api_request_total.help,
labelNames: ['method','path','code'] });
this.promClientMetrics.api_request_duration_milliseconds = new promClient.Histogram({
name: swsUtil.swsMetrics.api_request_duration_milliseconds.name,
help: swsUtil.swsMetrics.api_request_duration_milliseconds.help,
labelNames: ['method','path'],
buckets: this.durationBuckets });
this.promClientMetrics.api_request_size_bytes = new promClient.Histogram({
name: swsUtil.swsMetrics.api_request_size_bytes.name,
help: swsUtil.swsMetrics.api_request_size_bytes.help,
labelNames: ['method','path'],
buckets: this.requestSizeBuckets });
this.promClientMetrics.api_response_size_bytes = new promClient.Histogram({
name: swsUtil.swsMetrics.api_response_size_bytes.name,
help: swsUtil.swsMetrics.api_response_size_bytes.help,
labelNames: ['method','path'],
buckets: this.responseSizeBuckets });
this.usePromClient = true;
} catch (e) {}
}
if(!('swaggerSpec' in swsOptions)) return;

@@ -607,4 +651,13 @@ if(swsOptions.swaggerSpec === null) return;

// prm-client metrics update
// Add prom-client metrics, if prom-client is available
if(this.promClientMetrics !== null){
this.promClientMetrics.api_request_total.labels(req.method,req.sws.api_path,res.statusCode).inc();
this.promClientMetrics.api_request_duration_milliseconds.labels(req.method,req.sws.api_path).observe(req.sws.duration);
this.promClientMetrics.api_request_size_bytes.labels(req.method,req.sws.api_path).observe(req.sws.req_clength);
this.promClientMetrics.api_response_size_bytes.labels(req.method,req.sws.api_path).observe(req.sws.res_clength);
}
};
module.exports = swsAPIStats;

@@ -11,2 +11,5 @@ /**

// Prometheus Client library will be required, if exists in the application
var promClient = null;
var swsUtil = require('./swsUtil');

@@ -55,2 +58,6 @@ var swsReqResStats = require('./swsReqResStats');

];
// prom-client metrics
this.promClientMetrics = null;
}

@@ -60,2 +67,50 @@

swsCoreStats.prototype.initialize = function (swsOptions) {
if(swsOptions.promClientAvailable){
// Will use prom-client
promClient = require("prom-client");
// Create metrics
this.promClientMetrics = {};
// Register all provided metrics in prom-client
this.promClientMetrics.api_all_request_total = new promClient.Counter({
name: swsUtil.swsMetrics.api_all_request_total.name,
help: swsUtil.swsMetrics.api_all_request_total.help });
this.promClientMetrics.api_all_success_total = new promClient.Counter({
name: swsUtil.swsMetrics.api_all_success_total.name,
help: swsUtil.swsMetrics.api_all_success_total.help });
this.promClientMetrics.api_all_errors_total = new promClient.Counter({
name: swsUtil.swsMetrics.api_all_errors_total.name,
help: swsUtil.swsMetrics.api_all_errors_total.help });
this.promClientMetrics.api_all_client_error_total = new promClient.Counter({
name: swsUtil.swsMetrics.api_all_client_error_total.name,
help: swsUtil.swsMetrics.api_all_client_error_total.help });
this.promClientMetrics.api_all_server_error_total = new promClient.Counter({
name: swsUtil.swsMetrics.api_all_server_error_total.name,
help: swsUtil.swsMetrics.api_all_server_error_total.help });
this.promClientMetrics.api_all_request_in_processing_total = new promClient.Gauge({
name: swsUtil.swsMetrics.api_all_request_in_processing_total.name,
help: swsUtil.swsMetrics.api_all_request_in_processing_total.help });
this.promClientMetrics.nodejs_process_memory_rss_bytes = new promClient.Gauge({
name: swsUtil.swsMetrics.nodejs_process_memory_rss_bytes.name,
help: swsUtil.swsMetrics.nodejs_process_memory_rss_bytes.help });
this.promClientMetrics.nodejs_process_memory_heap_total_bytes = new promClient.Gauge({
name: swsUtil.swsMetrics.nodejs_process_memory_heap_total_bytes.name,
help: swsUtil.swsMetrics.nodejs_process_memory_heap_total_bytes.help });
this.promClientMetrics.nodejs_process_memory_heap_used_bytes = new promClient.Gauge({
name: swsUtil.swsMetrics.nodejs_process_memory_heap_used_bytes.name,
help: swsUtil.swsMetrics.nodejs_process_memory_heap_used_bytes.help });
this.promClientMetrics.nodejs_process_memory_external_bytes = new promClient.Gauge({
name: swsUtil.swsMetrics.nodejs_process_memory_external_bytes.name,
help: swsUtil.swsMetrics.nodejs_process_memory_external_bytes.help });
this.promClientMetrics.nodejs_process_cpu_usage_percentage = new promClient.Gauge({
name: swsUtil.swsMetrics.nodejs_process_cpu_usage_percentage.name,
help: swsUtil.swsMetrics.nodejs_process_cpu_usage_percentage.help });
}
};

@@ -124,2 +179,11 @@

this.sys.cpu = cpuPercent;
// Update prom-client metrics
if(this.promClientMetrics !== null) {
this.promClientMetrics.nodejs_process_memory_rss_bytes.set(this.sys.rss);
this.promClientMetrics.nodejs_process_memory_heap_total_bytes.set(this.sys.heapTotal);
this.promClientMetrics.nodejs_process_memory_heap_used_bytes.set(this.sys.heapUsed);
this.promClientMetrics.nodejs_process_memory_external_bytes.set(this.sys.external);
this.promClientMetrics.nodejs_process_cpu_usage_percentage.set(this.sys.cpu);
}
};

@@ -139,2 +203,8 @@

this.method[method].countRequest(req.sws.req_clength);
// Update prom-client metrics
if(this.promClientMetrics !== null){
this.promClientMetrics.api_all_request_total.inc();
this.promClientMetrics.api_all_request_in_processing_total.inc();
}
};

@@ -189,4 +259,24 @@

}
// Update prom-client metrics
if(this.promClientMetrics !== null){
switch(codeclass){
case "success":
this.promClientMetrics.api_all_success_total.inc();
break;
case "redirect":
this.promClientMetrics.api_all_errors_total.inc();
break;
case "client_error":
this.promClientMetrics.api_all_client_error_total.inc();
break;
case "server_error":
this.promClientMetrics.api_all_server_error_total.inc();
break;
}
this.promClientMetrics.api_all_request_in_processing_total.dec();
}
};
module.exports = swsCoreStats;

@@ -13,2 +13,5 @@ /**

// Prometheus Client library will be required, if exists in the application
var promClient = null;
var swsUtil = require('./swsUtil');

@@ -27,3 +30,7 @@ var swsProcessor = require('./swsProcessor');

requestSizeBuckets: [5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000],
responseSizeBuckets: [5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000]
responseSizeBuckets: [5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000],
promClient: true,
onResponseFinish: null,
// internal option: Will be set to true if prom-client module is available in the application
promClientAvailable: false
};

@@ -37,2 +44,3 @@

var pathMetrics = swsOptions.uriPath+'/metrics';
var pathMetricsInt = swsOptions.uriPath+'/metrics-int';

@@ -73,2 +81,14 @@ // Request hanlder

// Check for prom-client
if( swsOptions.promClient ) {
try {
var a = require.resolve("prom-client");
swsOptions.promClientAvailable = true;
promClient = require("prom-client");
} catch (e) {
debug("prom-client module is not found, using embedded metrics");
swsOptions.promClientAvailable = true;
}
}
// update standard path

@@ -79,2 +99,3 @@ pathUI = swsOptions.uriPath+'/ui';

pathMetrics = swsOptions.uriPath+'/metrics';
pathMetricsInt = swsOptions.uriPath+'/metrics-int';
}

@@ -94,10 +115,12 @@

//res.status(200)
// .set('Content-Type', 'text/plain')
// .send( processor.getMetrics( req.query ) );
res.status(200).set('Content-Type', 'text/plain');
var usePromClient = ((promClient !== null) && !(req.url.startsWith(pathMetricsInt)));
processor.writeMetrics(req.query, res);
res.end();
if( usePromClient ){
res.status(200).set('Content-Type', 'text/plain');
res.end(promClient.register.metrics());
}else {
res.status(200).set('Content-Type', 'text/plain');
processor.writeMetrics(req.query, res);
res.end();
}
}

@@ -104,0 +127,0 @@

@@ -19,3 +19,3 @@ /**

// Lowest duration from all stored requests
this.lowest = -1;
this.lowest = -1; // will be updated by first request

@@ -59,3 +59,3 @@ // Max number of requests to keep.

for(var i=0;(i<this.longest_requests.length) && (idx==-1);i++){
if( duration < this.longest_requests[i].duration ){
if( duration < this.longest_requests[i].responsetime ){
idx = i;

@@ -89,3 +89,3 @@ }

// First entry duration is now the smallest one
this.lowest = this.longest_requests[0].duration;
this.lowest = this.longest_requests[0].responsetime;

@@ -92,0 +92,0 @@ this.placeReqResData(rrr);

@@ -45,2 +45,4 @@ /**

// onResponseFinish callback, if specified in options
this.onResponseFinish = null;

@@ -124,2 +126,6 @@ // Core statistics

if( swsOptions.onResponseFinish && (typeof swsOptions.onResponseFinish === 'function') ){
this.onResponseFinish = swsOptions.onResponseFinish;
}
};

@@ -348,5 +354,10 @@

// Pass to app if callback is specified
if(this.onResponseFinish !== null ){
this.onResponseFinish(req,res,rrr);
}
// TODO Push Request/Response Data to Emitter(s)
debugrrr('%s', JSON.stringify(rrr));
//debugrrr('%s', JSON.stringify(rrr));
};

@@ -408,10 +419,2 @@

// Return all available metrics for Prometheus
swsProcessor.prototype.getMetrics = function ( query ) {
var metrics = '';
metrics += this.coreStats.getMetrics();
//metrics += this.apiStats.getMetrics();
return metrics;
};
// Write prometheus metrics to stream

@@ -418,0 +421,0 @@ swsProcessor.prototype.writeMetrics = function ( query, stream ) {

@@ -41,3 +41,3 @@ /*

// The default buckets are tailored to broadly measure API response time.
// Most likely needs to be defined per to account for application specifics.
// Most likely needs to be defined per app to account for application specifics.
durationBuckets : "durationBuckets",

@@ -49,11 +49,27 @@

// The default buckets are tailored to broadly measure API request size.
// Most likely needs to be defined per to account for application specifics.
// Most likely needs to be defined per app to account for application specifics.
requestSizeBuckets : "requestSizeBuckets",
// Buckets for request size histogram metric, in Bytes
// Buckets for response size histogram metric, in Bytes
// Optional. Default value:
// [5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000]
// The default buckets are tailored to broadly measure API request size.
// Most likely needs to be defined per to account for application specifics.
responseSizeBuckets : "responseSizeBuckets"
// The default buckets are tailored to broadly measure API response size.
// Most likely needs to be defined per app to account for application specifics.
responseSizeBuckets : "responseSizeBuckets",
// Whether to use prom-client Prometheus client library from the application
// If set to true (default), swagger-stats will attempt to detect if prom-client module is available
// in the application, and if yes, use it
// If set to false, prom-client will not be used
promClient : "promClient",
// Callback to invoke when response is finished - https://github.com/slanatech/swagger-stats/issues/5
// Application may implement it to trace Request Response Record (RRR), which is passed as parameter
// the following parameters are passed to this callback:
// OnResponseFinish(req,res,rrr)
// - req - request
// - res - response
// - rrr - Request Response Record (RRR)
onResponseFinish : "onResponseFinish"
};

@@ -60,0 +76,0 @@

{
"name": "swagger-stats",
"version": "0.91.0",
"version": "0.92.0",
"description": "Telemetry for your APIs. Trace API calls and Monitor API performance, health and usage statistics in Node.js Microservices, based on express routes and Swagger (Open API) specification",

@@ -9,5 +9,10 @@ "main": "lib/index.js",

"testonly": "mocha -S --delay",
"test": "npm run coverage && npm run karma-ci",
"test-old": "npm run coverage && npm run karma-ci",
"coverage": "nyc --reporter=lcov --reporter=html --reporter=text --report-dir=coverage/mocha mocha -S --delay",
"coverage-report": "nyc report",
"test": "npm run cov000 && npm run cov100 && npm run cov200 && npm run cov300 && npm run karma-ci && npm run coverage-report",
"cov000": "nyc --reporter=lcov --reporter=html --reporter=json --reporter=text --report-dir=coverage/000 mocha --delay test/000_baseline.js",
"cov100": "nyc --reporter=lcov --reporter=html --reporter=json --reporter=text --report-dir=coverage/100 mocha --delay test/100_method.js",
"cov200": "nyc --reporter=lcov --reporter=html --reporter=json --reporter=text --report-dir=coverage/200 mocha --delay test/200_apicore.js",
"cov300": "nyc --reporter=lcov --reporter=html --reporter=json --reporter=text --report-dir=coverage/300 mocha --delay test/300_timeline.js",
"coverage-report": "node_modules/.bin/istanbul report --root ./coverage --dir ./coverage-report lcov",
"specstest": "mocha test/specstest/swaggerspecstest.js",

@@ -93,2 +98,3 @@ "karma": "NODE_ENV=test karma start karma.conf.js",

"postcss-loader": "^2.0.5",
"prom-client": "^10.1.1",
"q": "^1.5.0",

@@ -95,0 +101,0 @@ "serve-favicon": "^2.4.5",

@@ -186,2 +186,9 @@ <p align="center">

#### v0.92.0
* [feature] Support providing Prometheus metrics via [prom-client](https://www.npmjs.com/package/prom-client) library [#20](https://github.com/slanatech/swagger-stats/issues/20)
* [feature] OnResponseFinish hook: pass request/response record to callback so app can post proceses it add it to the log [#5](https://github.com/slanatech/swagger-stats/issues/5)
#### v0.91.0

@@ -188,0 +195,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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc