You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

prometheus-api-metrics

Package Overview
Dependencies
Maintainers
3
Versions
35
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

prometheus-api-metrics - npm Package Compare versions

Comparing version

to
3.1.0

4

CHANGELOG.md
# Master
# 3.1.0 - 3 September, 2020
- Added support for axios responses while using axios-time plugin
# 3.0.0 - 2 September, 2020

@@ -4,0 +8,0 @@

42

package.json
{
"name": "prometheus-api-metrics",
"version": "3.0.0",
"version": "3.1.0",
"description": "API and process monitoring with Prometheus for Node.js micro-service",

@@ -36,6 +36,7 @@ "author": "Idan Tovi",

"dependencies": {
"@types/express": "^4.17.6",
"@types/express-serve-static-core": "^4.17.5",
"@types/koa": "^2.11.3",
"@types/express": "^4.17.8",
"@types/express-serve-static-core": "^4.17.12",
"@types/koa": "^2.11.4",
"debug": "^3.2.6",
"lodash.get": "^4.4.2",
"pkginfo": "^0.4.1"

@@ -47,11 +48,15 @@ },

"devDependencies": {
"@nestjs/common": "^4.6.4",
"@nestjs/core": "^4.6.4",
"@nestjs/testing": "^4.6.4",
"@nestjs/common": "^7.4.4",
"@nestjs/core": "^7.4.4",
"@nestjs/platform-express": "^7.4.4",
"@nestjs/testing": "^7.4.4",
"@types/mocha": "^5.2.6",
"@types/node": "^9.6.50",
"@types/supertest": "^2.0.7",
"@types/node": "^9.6.57",
"@types/supertest": "^2.0.10",
"axios": "^0.20.0",
"axios-time": "^1.0.0",
"body-parser": "^1.18.3",
"chai": "^4.2.0",
"coveralls": "^3.0.0",
"chai-as-promised": "^7.1.1",
"coveralls": "^3.1.0",
"doctoc": "^1.4.0",

@@ -61,3 +66,3 @@ "eslint": "^6.8.0",

"eslint-plugin-chai-friendly": "^0.5.0",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-mocha": "^6.3.0",

@@ -68,18 +73,17 @@ "eslint-plugin-node": "^11.1.0",

"express": "^4.16.4",
"koa": "^2.7.0",
"koa": "^2.13.0",
"koa-bodyparser": "^4.2.1",
"koa-router": "^7.4.0",
"lodash.clonedeep": "^4.5.0",
"mocha": "^5.2.0",
"mocha": "^8.1.3",
"nock": "^10.0.6",
"node-mocks-http": "^1.7.3",
"nyc": "^15.0.1",
"node-mocks-http": "^1.9.0",
"nyc": "^15.1.0",
"prom-client": "^12.0.0",
"reflect-metadata": "0.1.10",
"reflect-metadata": "^0.1.13",
"request": "^2.88.0",
"request-promise-native": "^1.0.7",
"request-promise-native": "^1.0.9",
"rewire": "^4.0.1",
"rxjs": "^5.5.12",
"sinon": "^5.0.10",
"sleep": "^6.1.0",
"stryker": "^0.30.1",

@@ -92,3 +96,3 @@ "stryker-api": "^0.21.5",

"ts-node": "^7.0.1",
"typescript": "^3.3.3"
"typescript": "^3.9.7"
},

@@ -95,0 +99,0 @@ "repository": {

@@ -25,2 +25,3 @@ # Prometheus API Monitoring

- [request-promise-native](#request-promise-native)
- [axios](#axios)
- [Test](#test)

@@ -170,2 +171,3 @@ - [Usage in koa](#usage-in-koa)

**Notes:**

@@ -180,2 +182,20 @@ 1. In order to use this feature you must use `{ time: true }` as part of your request configuration and then pass to the collector the response or error you got.

#### axios
```js
const axios = require('axios');
const axiosTime = require('axios-time');
axiosTime(axios);
try {
const response = await axios({ baseURL: 'http://www.google.com', method: 'get', url: '/' });
Collector.collect(response);
} catch (error) {
Collector.collect(error);
}
```
**Notes:**
* In order to collect metrics from axios client the [`axios-time`](https://www.npmjs.com/package/axios-time) package is required.
## Usage in koa

@@ -182,0 +202,0 @@ This package supports koa server that uses [`koa-router`](https://www.npmjs.com/package/koa-router) and [`koa-bodyparser`](https://www.npmjs.com/package/koa-bodyparser)

const Prometheus = require('prom-client');
const utils = require('./utils');
const get = require('lodash.get');
let southboundResponseTimeHistogram, southboundClientErrors = null;

@@ -15,2 +17,4 @@ let projectName;

const OBSERVER_TYPES = ['total', 'socket', 'lookup', 'connect'];
class HttpMetricsCollector {

@@ -35,7 +39,4 @@ constructor(options){

if (response.timings) {
response.request.metrics = response.request.metrics || {};
southboundResponseTimeHistogram.observe({ target: response.request.metrics.target || response.request.originalHost, method: response.request.method, route: response.request.metrics.route || response.request.path, status_code: response.statusCode, type: 'total' }, response.timingPhases.total / 1000);
southboundResponseTimeHistogram.observe({ target: response.request.metrics.target || response.request.originalHost, method: response.request.method, route: response.request.metrics.route || response.request.path, status_code: response.statusCode, type: 'socket' }, response.timingPhases.wait / 1000); // timings.socket
southboundResponseTimeHistogram.observe({ target: response.request.metrics.target || response.request.originalHost, method: response.request.method, route: response.request.metrics.route || response.request.path, status_code: response.statusCode, type: 'lookup' }, response.timingPhases.dns / 1000); // timings.lookup - timings.socket
southboundResponseTimeHistogram.observe({ target: response.request.metrics.target || response.request.originalHost, method: response.request.method, route: response.request.metrics.route || response.request.path, status_code: response.statusCode, type: 'connect' }, response.timingPhases.tcp / 1000); // timings.connect - timings.socket
const responseData = extractResponseData(response);
addObservers(southboundResponseTimeHistogram, responseData);
}

@@ -45,2 +46,50 @@ }

function addObservers(southboundResponseTimeHistogram, responseData) {
const { target, method, route, status_code, timings } = responseData;
OBSERVER_TYPES.forEach(type => {
if (typeof responseData.timings[type] !== 'undefined') {
southboundResponseTimeHistogram.observe({ target, method, route, status_code, type }, timings[type]);
}
});
}
function extractResponseData(response) {
let status_code, route, method, target, timings;
// check if response client is axios
if (isAxiosResponse(response)) {
status_code = response.status;
method = response.config.method.toUpperCase();
route = get(response, 'config.metrics.route', response.config.url);
target = get(response, 'config.metrics.target', response.config.baseURL);
timings = {
total: response.timings.elapsedTime / 1000
};
} else { // response is request-promise
status_code = response.statusCode;
method = response.request.method;
route = get(response, 'request.metrics.route', response.request.path);
target = get(response, 'request.metrics.target', response.request.originalHost);
timings = {
total: response.timingPhases.total / 1000,
socket: response.timingPhases.wait / 1000,
lookup: response.timingPhases.dns / 1000,
connect: response.timingPhases.tcp / 1000
};
}
return {
target,
method,
route,
status_code,
timings
};
}
function isAxiosResponse(response) {
return response.config && response.hasOwnProperty('data');
}
function _init(options = {}) {

@@ -84,2 +133,2 @@ let metricNames = {

_collectHttpTiming(res, southboundResponseTimeHistogram, southboundClientErrors);
};
};