From 179d3ae586589d474372065a6efc7c93f6f500cb Mon Sep 17 00:00:00 2001 From: Alaa El Helw Date: Thu, 13 Aug 2020 22:36:14 +0200 Subject: [PATCH 1/4] Adding custom suffix for json --- dist/express-middleware.js | 102 ++++++++++++++++++++ dist/express-middleware.js.map | 1 + dist/index.js | 11 +++ dist/index.js.map | 1 + dist/koa-middleware.js | 127 +++++++++++++++++++++++++ dist/koa-middleware.js.map | 1 + dist/metrics-middleware.js | 69 ++++++++++++++ dist/metrics-middleware.js.map | 1 + dist/request-response-collector.js | 76 +++++++++++++++ dist/request-response-collector.js.map | 1 + dist/utils.js | 18 ++++ dist/utils.js.map | 1 + src/express-middleware.js | 2 +- src/index.d.ts | 1 + src/metrics-middleware.js | 3 +- 15 files changed, 413 insertions(+), 2 deletions(-) create mode 100644 dist/express-middleware.js create mode 100644 dist/express-middleware.js.map create mode 100644 dist/index.js create mode 100644 dist/index.js.map create mode 100644 dist/koa-middleware.js create mode 100644 dist/koa-middleware.js.map create mode 100644 dist/metrics-middleware.js create mode 100644 dist/metrics-middleware.js.map create mode 100644 dist/request-response-collector.js create mode 100644 dist/request-response-collector.js.map create mode 100644 dist/utils.js create mode 100644 dist/utils.js.map diff --git a/dist/express-middleware.js b/dist/express-middleware.js new file mode 100644 index 0000000..3939ded --- /dev/null +++ b/dist/express-middleware.js @@ -0,0 +1,102 @@ +const Prometheus = require('prom-client'); +require('pkginfo')(module, ['name']); +const debug = require('debug')(module.exports.name); +const utils = require('./utils'); +class ExpressMiddleware { + constructor(setupOptions) { + this.setupOptions = setupOptions || {}; + } + _collectDefaultServerMetrics(timeout) { + const NUMBER_OF_CONNECTIONS_METRICS_NAME = 'expressjs_number_of_open_connections'; + this.setupOptions.numberOfConnectionsGauge = Prometheus.register.getSingleMetric(NUMBER_OF_CONNECTIONS_METRICS_NAME) || new Prometheus.Gauge({ + name: NUMBER_OF_CONNECTIONS_METRICS_NAME, + help: 'Number of open connections to the Express.js server' + }); + if (this.setupOptions.server) { + setInterval(this._getConnections.bind(this), timeout).unref(); + } + } + _getConnections() { + if (this.setupOptions && this.setupOptions.server) { + this.setupOptions.server.getConnections((error, count) => { + if (error) { + debug('Error while collection number of open connections', error); + } + else { + this.setupOptions.numberOfConnectionsGauge.set(count); + } + }); + } + } + _handleResponse(req, res) { + const responseLength = parseInt(res.get('Content-Length')) || 0; + const route = this._getRoute(req); + if (route && utils.shouldLogMetrics(this.setupOptions.excludeRoutes, route)) { + this.setupOptions.requestSizeHistogram.observe({ method: req.method, route: route, code: res.statusCode }, req.metrics.contentLength); + req.metrics.timer({ route: route, code: res.statusCode }); + this.setupOptions.responseSizeHistogram.observe({ method: req.method, route: route, code: res.statusCode }, responseLength); + debug(`metrics updated, request length: ${req.metrics.contentLength}, response length: ${responseLength}`); + } + } + _getRoute(req) { + let route = req.baseUrl; + if (req.route) { + if (req.route.path !== '/') { + route = route ? route + req.route.path : req.route.path; + } + if (!route || route === '') { + route = req.originalUrl.split('?')[0]; + } + else { + const splittedRoute = route.split('/'); + const splittedUrl = req.originalUrl.split('?')[0].split('/'); + const routeIndex = splittedUrl.length - splittedRoute.length + 1; + const baseUrl = splittedUrl.slice(0, routeIndex).join('/'); + route = baseUrl + route; + } + if (this.setupOptions.includeQueryParams === true && Object.keys(req.query).length > 0) { + route = `${route}?${Object.keys(req.query).sort().map((queryParam) => `${queryParam}=`).join('&')}`; + } + } + if (typeof req.params === 'object') { + Object.keys(req.params).forEach((paramName) => { + route = route.replace(req.params[paramName], ':' + paramName); + }); + } + if (!route || route === '') { + route = 'N/A'; + } + return route; + } + middleware(req, res, next) { + if (!this.setupOptions.server && req.socket) { + this.setupOptions.server = req.socket.server; + this._collectDefaultServerMetrics(this.setupOptions.defaultMetricsInterval); + } + const routeUrl = req.originalUrl || req.url; + if (routeUrl === this.setupOptions.metricsRoute) { + debug('Request to /metrics endpoint'); + res.set('Content-Type', Prometheus.register.contentType); + return res.end(Prometheus.register.metrics()); + } + if (routeUrl === `${this.setupOptions.metricsRoute}${this.setupOptions.metricsJsonSuffix}`) { + debug('Request to /metrics endpoint'); + return res.json(Prometheus.register.getMetricsAsJSON()); + } + req.metrics = { + timer: this.setupOptions.responseTimeHistogram.startTimer({ + method: req.method + }), + contentLength: parseInt(req.get('content-length')) || 0 + }; + debug(`Set start time and content length for request. url: ${routeUrl}, method: ${req.method}`); + res.once('finish', () => { + debug('on finish.'); + this._handleResponse(req, res); + }); + return next(); + } + ; +} +module.exports = ExpressMiddleware; +//# sourceMappingURL=express-middleware.js.map \ No newline at end of file diff --git a/dist/express-middleware.js.map b/dist/express-middleware.js.map new file mode 100644 index 0000000..a17f435 --- /dev/null +++ b/dist/express-middleware.js.map @@ -0,0 +1 @@ +{"version":3,"file":"express-middleware.js","sourceRoot":"","sources":["../src/express-middleware.js"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..2fdf3b3 --- /dev/null +++ b/dist/index.js @@ -0,0 +1,11 @@ +'use strict'; +const Path = require('path'); +const metricsMiddleware = { exports: {} }; +require('pkginfo')(metricsMiddleware, { dir: Path.dirname(module.parent.filename), include: ['name', 'version'] }); +const appVersion = metricsMiddleware.exports.version; +const projectName = metricsMiddleware.exports.name.replace(/-/g, '_'); +module.exports = require('./metrics-middleware')(appVersion, projectName); +module.exports.HttpMetricsCollector = require('./request-response-collector')(projectName); +module.exports.koaMiddleware = require('./metrics-middleware')(appVersion, projectName, 'koa'); +module.exports.expressMiddleware = require('./metrics-middleware')(appVersion, projectName, 'express'); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/index.js.map b/dist/index.js.map new file mode 100644 index 0000000..4ad66b7 --- /dev/null +++ b/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAC7B,MAAM,iBAAiB,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AAC1C,OAAO,CAAC,SAAS,CAAC,CAAC,iBAAiB,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC;AACnH,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,OAAO,CAAC;AACrD,MAAM,WAAW,GAAG,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAEtE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;AAC1E,MAAM,CAAC,OAAO,CAAC,oBAAoB,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC,WAAW,CAAC,CAAC;AAC3F,MAAM,CAAC,OAAO,CAAC,aAAa,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;AAC/F,MAAM,CAAC,OAAO,CAAC,iBAAiB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC"} \ No newline at end of file diff --git a/dist/koa-middleware.js b/dist/koa-middleware.js new file mode 100644 index 0000000..eff89db --- /dev/null +++ b/dist/koa-middleware.js @@ -0,0 +1,127 @@ +const Prometheus = require('prom-client'); +require('pkginfo')(module, ['name']); +const debug = require('debug')(module.exports.name); +const utils = require('./utils'); +const WILDCARD_ROUTE_ENDING = '(.*)'; +class KoaMiddleware { + constructor(setupOptions) { + this.setupOptions = setupOptions; + } + _collectDefaultServerMetrics(timeout) { + const NUMBER_OF_CONNECTIONS_METRICS_NAME = 'koajs_number_of_open_connections'; + this.setupOptions.numberOfConnectionsGauge = Prometheus.register.getSingleMetric(NUMBER_OF_CONNECTIONS_METRICS_NAME) || new Prometheus.Gauge({ + name: NUMBER_OF_CONNECTIONS_METRICS_NAME, + help: 'Number of open connections to the Koa.js server' + }); + if (this.setupOptions.server) { + setInterval(this._getConnections.bind(this), timeout).unref(); + } + } + _getConnections() { + if (this.setupOptions.server) { + this.setupOptions.server.getConnections((error, count) => { + if (error) { + debug('Error while collection number of open connections', error); + } + else { + this.setupOptions.numberOfConnectionsGauge.set(count); + } + }); + } + } + _handleResponse(ctx) { + const responseLength = parseInt(ctx.response.get('Content-Length')) || 0; + const route = this._getRoute(ctx) || 'N/A'; + if (route && utils.shouldLogMetrics(this.setupOptions.excludeRoutes, route)) { + this.setupOptions.requestSizeHistogram.observe({ + method: ctx.req.method, + route: route, + code: ctx.res.statusCode + }, ctx.req.metrics.contentLength); + ctx.req.metrics.timer({ route: route, code: ctx.res.statusCode }); + this.setupOptions.responseSizeHistogram.observe({ + method: ctx.req.method, + route: route, + code: ctx.res.statusCode + }, responseLength); + debug(`metrics updated, request length: ${ctx.req.metrics.contentLength}, response length: ${responseLength}`); + } + } + _getRoute(ctx) { + let route; + if (ctx._matchedRoute && !ctx._matchedRoute.endsWith(WILDCARD_ROUTE_ENDING)) { + route = ctx._matchedRoute; + route = route.endsWith('/') ? route.substring(0, route.length - 1) : route; + } + else if (ctx._matchedRoute) { + route = this._handleSubRoutes(ctx._matchedRoute, ctx.originalUrl, ctx.request.method, ctx.router); + } + if (this.setupOptions.includeQueryParams === true && Object.keys(ctx.query).length > 0) { + route = `${route || '/'}?${Object.keys(ctx.query).sort().map((queryParam) => `${queryParam}=`).join('&')}`; + } + return route; + } + _handleSubRoutes(matchedRoute, originalUrl, method, router) { + let route; + const routeStart = matchedRoute.substring(0, matchedRoute.length - WILDCARD_ROUTE_ENDING.length); + let url = this._removeQueryFromUrl(originalUrl).substring(routeStart.length); + let matchedRoutes = router.match(url, method); + if (matchedRoutes.path.length > 0) { + route = this._findFirstProperRoute(matchedRoutes.path); + return routeStart + route; + } + else { + url = this._removeQueryFromUrl(originalUrl); + matchedRoutes = router.match(url, method); + if (matchedRoutes.path.length > 0) { + route = this._findFirstProperRoute(matchedRoutes.path); + return route; + } + } + } + _findFirstProperRoute(routes) { + const properRoute = routes.find(route => { + if (!route.path.endsWith('(.*)')) { + return route; + } + }); + let route = properRoute.path; + route = route.endsWith('/') ? route.substring(0, route.length - 1) : route; + return route; + } + _removeQueryFromUrl(url) { + return url.split('?')[0]; + } + middleware(ctx, next) { + if (!this.setupOptions.server && ctx.req.socket) { + this.setupOptions.server = ctx.req.socket.server; + this._collectDefaultServerMetrics(this.setupOptions.defaultMetricsInterval); + } + if (ctx.req.url === this.setupOptions.metricsRoute) { + debug('Request to /metrics endpoint'); + ctx.set('Content-Type', Prometheus.register.contentType); + ctx.body = Prometheus.register.metrics(); + return next(); + } + if (ctx.req.url === `${this.setupOptions.metricsRoute}.json`) { + debug('Request to /metrics endpoint'); + ctx.body = Prometheus.register.getMetricsAsJSON(); + return next(); + } + ctx.req.metrics = { + timer: this.setupOptions.responseTimeHistogram.startTimer({ + method: ctx.req.method + }), + contentLength: parseInt(ctx.request.get('content-length')) || 0 + }; + debug(`Set start time and content length for request. url: ${ctx.req.url}, method: ${ctx.req.method}`); + ctx.res.once('finish', () => { + debug('on finish.'); + this._handleResponse(ctx); + }); + return next(); + } + ; +} +module.exports = KoaMiddleware; +//# sourceMappingURL=koa-middleware.js.map \ No newline at end of file diff --git a/dist/koa-middleware.js.map b/dist/koa-middleware.js.map new file mode 100644 index 0000000..c24a570 --- /dev/null +++ b/dist/koa-middleware.js.map @@ -0,0 +1 @@ +{"version":3,"file":"koa-middleware.js","sourceRoot":"","sources":["../src/koa-middleware.js"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/metrics-middleware.js b/dist/metrics-middleware.js new file mode 100644 index 0000000..a152abd --- /dev/null +++ b/dist/metrics-middleware.js @@ -0,0 +1,69 @@ +'use strict'; +const Prometheus = require('prom-client'); +require('pkginfo')(module, ['name']); +const debug = require('debug')(module.exports.name); +const utils = require('./utils'); +const ExpressMiddleware = require('./express-middleware'); +const KoaMiddleware = require('./koa-middleware'); +const setupOptions = {}; +module.exports = (appVersion, projectName, framework = 'express') => { + return (options = {}) => { + const { metricsPath, metricsJsonSuffix, defaultMetricsInterval = 10000, durationBuckets, requestSizeBuckets, responseSizeBuckets, useUniqueHistogramName, metricsPrefix, excludeRoutes, includeQueryParams } = options; + debug(`Init metrics middleware with options: ${JSON.stringify(options)}`); + setupOptions.metricsRoute = metricsPath || '/metrics'; + setupOptions.metricsJsonSuffix = metricsJsonSuffix || '.json'; + setupOptions.excludeRoutes = excludeRoutes || []; + setupOptions.includeQueryParams = includeQueryParams; + setupOptions.defaultMetricsInterval = defaultMetricsInterval; + let metricNames = { + http_request_duration_seconds: 'http_request_duration_seconds', + app_version: 'app_version', + http_request_size_bytes: 'http_request_size_bytes', + http_response_size_bytes: 'http_response_size_bytes', + defaultMetricsPrefix: '' + }; + metricNames = utils.getMetricNames(metricNames, useUniqueHistogramName, metricsPrefix, projectName); + Prometheus.collectDefaultMetrics({ timeout: defaultMetricsInterval, prefix: `${metricNames.defaultMetricsPrefix}` }); + if (!Prometheus.register.getSingleMetric(metricNames.app_version)) { + const version = new Prometheus.Gauge({ + name: metricNames.app_version, + help: 'The service version by package.json', + labelNames: ['version', 'major', 'minor', 'patch'] + }); + const versionSegments = appVersion.split('.').map(Number); + version.labels(appVersion, versionSegments[0], versionSegments[1], versionSegments[2]).set(1); + } + setupOptions.responseTimeHistogram = Prometheus.register.getSingleMetric(metricNames.http_request_duration_seconds) || new Prometheus.Histogram({ + name: metricNames.http_request_duration_seconds, + help: 'Duration of HTTP requests in seconds', + labelNames: ['method', 'route', 'code'], + buckets: durationBuckets || [0.001, 0.005, 0.015, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5] + }); + setupOptions.requestSizeHistogram = Prometheus.register.getSingleMetric(metricNames.http_request_size_bytes) || new Prometheus.Histogram({ + name: metricNames.http_request_size_bytes, + help: 'Size of HTTP requests in bytes', + labelNames: ['method', 'route', 'code'], + buckets: requestSizeBuckets || [5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000] + }); + setupOptions.responseSizeHistogram = Prometheus.register.getSingleMetric(metricNames.http_response_size_bytes) || new Prometheus.Histogram({ + name: metricNames.http_response_size_bytes, + help: 'Size of HTTP response in bytes', + labelNames: ['method', 'route', 'code'], + buckets: responseSizeBuckets || [5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000] + }); + return frameworkMiddleware(framework); + }; +}; +function frameworkMiddleware(framework) { + switch (framework) { + case 'koa': { + const middleware = new KoaMiddleware(setupOptions); + return middleware.middleware.bind(middleware); + } + default: { + const middleware = new ExpressMiddleware(setupOptions); + return middleware.middleware.bind(middleware); + } + } +} +//# sourceMappingURL=metrics-middleware.js.map \ No newline at end of file diff --git a/dist/metrics-middleware.js.map b/dist/metrics-middleware.js.map new file mode 100644 index 0000000..8d20736 --- /dev/null +++ b/dist/metrics-middleware.js.map @@ -0,0 +1 @@ +{"version":3,"file":"metrics-middleware.js","sourceRoot":"","sources":["../src/metrics-middleware.js"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/request-response-collector.js b/dist/request-response-collector.js new file mode 100644 index 0000000..e2f72f5 --- /dev/null +++ b/dist/request-response-collector.js @@ -0,0 +1,76 @@ +const Prometheus = require('prom-client'); +const utils = require('./utils'); +let southboundResponseTimeHistogram, southboundClientErrors = null; +let projectName; +module.exports = (name) => { + projectName = name; + const httpMetricsCollector = HttpMetricsCollector; + httpMetricsCollector.init = init; + httpMetricsCollector.collect = collect; + return httpMetricsCollector; +}; +class HttpMetricsCollector { + constructor(options) { + const setup = _init(options); + this.southboundResponseTimeHistogram = setup.southboundResponseTimeHistogram; + this.southboundClientErrors = setup.southboundClientErrors; + } + ; + collect(res) { + _collectHttpTiming(res, this.southboundResponseTimeHistogram, this.southboundClientErrors); + } +} +function _collectHttpTiming(res, southboundResponseTimeHistogram, southboundClientErrors) { + if (res instanceof Error && !res.response && southboundClientErrors) { + const error = res.error || res; + southboundClientErrors.inc({ target: error.hostname, error: error.code }); + } + else { + const response = res.response || res; + 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); + 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); + 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); + } + } +} +function _init(options = {}) { + let metricNames = { + southbound_request_duration_seconds: 'southbound_request_duration_seconds', + southbound_client_errors_count: 'southbound_client_errors_count' + }; + const { durationBuckets, countClientErrors, useUniqueHistogramName, prefix } = options; + metricNames = utils.getMetricNames(metricNames, useUniqueHistogramName, prefix, projectName); + southboundResponseTimeHistogram = Prometheus.register.getSingleMetric(metricNames.southbound_request_duration_seconds) || + new Prometheus.Histogram({ + name: metricNames.southbound_request_duration_seconds, + help: 'Duration of Southbound queries in seconds', + labelNames: ['method', 'route', 'status_code', 'target', 'type'], + buckets: durationBuckets || [0.001, 0.005, 0.015, 0.03, 0.05, 0.1, 0.15, 0.3, 0.5] + }); + if (countClientErrors !== false) { + southboundClientErrors = Prometheus.register.getSingleMetric(metricNames.southbound_client_errors_count) || new Prometheus.Counter({ + name: metricNames.southbound_client_errors_count, + help: 'Southbound http client error counter', + labelNames: ['target', 'error'] + }); + } + return { + southboundClientErrors: southboundClientErrors, + southboundResponseTimeHistogram: southboundResponseTimeHistogram + }; +} +; +function init(options) { + const setup = _init(options); + southboundResponseTimeHistogram = setup.southboundResponseTimeHistogram; + southboundClientErrors = setup.southboundClientErrors; +} +; +function collect(res) { + _collectHttpTiming(res, southboundResponseTimeHistogram, southboundClientErrors); +} +; +//# sourceMappingURL=request-response-collector.js.map \ No newline at end of file diff --git a/dist/request-response-collector.js.map b/dist/request-response-collector.js.map new file mode 100644 index 0000000..4466e30 --- /dev/null +++ b/dist/request-response-collector.js.map @@ -0,0 +1 @@ +{"version":3,"file":"request-response-collector.js","sourceRoot":"","sources":["../src/request-response-collector.js"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils.js b/dist/utils.js new file mode 100644 index 0000000..58563be --- /dev/null +++ b/dist/utils.js @@ -0,0 +1,18 @@ +'use strict'; +function getMetricNames(metricNames, useUniqueHistogramName, metricsPrefix, projectName) { + const prefix = useUniqueHistogramName === true ? projectName : metricsPrefix; + if (prefix) { + Object.keys(metricNames).forEach(key => { + metricNames[key] = `${prefix}_${metricNames[key]}`; + }); + } + return metricNames; +} +function shouldLogMetrics(excludeRoutes, route) { + return excludeRoutes.every((path) => { + return !route.includes(path); + }); +} +module.exports.getMetricNames = getMetricNames; +module.exports.shouldLogMetrics = shouldLogMetrics; +//# sourceMappingURL=utils.js.map \ No newline at end of file diff --git a/dist/utils.js.map b/dist/utils.js.map new file mode 100644 index 0000000..077e5a8 --- /dev/null +++ b/dist/utils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,SAAS,cAAc,CAAC,WAAW,EAAE,sBAAsB,EAAE,aAAa,EAAE,WAAW;IACnF,MAAM,MAAM,GAAG,sBAAsB,KAAK,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC;IAE7E,IAAI,MAAM,EAAE;QACR,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YACnC,WAAW,CAAC,GAAG,CAAC,GAAG,GAAG,MAAM,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;QACvD,CAAC,CAAC,CAAC;KACN;IAED,OAAO,WAAW,CAAC;AACvB,CAAC;AAED,SAAS,gBAAgB,CAAC,aAAa,EAAE,KAAK;IAC1C,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE;QAChC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,CAAC,OAAO,CAAC,cAAc,GAAG,cAAc,CAAC;AAC/C,MAAM,CAAC,OAAO,CAAC,gBAAgB,GAAG,gBAAgB,CAAC"} \ No newline at end of file diff --git a/src/express-middleware.js b/src/express-middleware.js index e9876b6..da3e79b 100644 --- a/src/express-middleware.js +++ b/src/express-middleware.js @@ -98,7 +98,7 @@ class ExpressMiddleware { res.set('Content-Type', Prometheus.register.contentType); return res.end(Prometheus.register.metrics()); } - if (routeUrl === `${this.setupOptions.metricsRoute}.json`) { + if (routeUrl === `${this.setupOptions.metricsRoute}${this.setupOptions.metricsJsonSuffix}`) { debug('Request to /metrics endpoint'); return res.json(Prometheus.register.getMetricsAsJSON()); } diff --git a/src/index.d.ts b/src/index.d.ts index 8783e7d..01d3924 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -12,6 +12,7 @@ export class HttpMetricsCollector { export interface ApiMetricsOpts { metricsPath?: string; + metricsJsonSuffix?: string, defaultMetricsInterval?: number; durationBuckets?: number[]; requestSizeBuckets?: number[]; diff --git a/src/metrics-middleware.js b/src/metrics-middleware.js index b9f2780..0bdd48f 100644 --- a/src/metrics-middleware.js +++ b/src/metrics-middleware.js @@ -10,9 +10,10 @@ const setupOptions = {}; module.exports = (appVersion, projectName, framework = 'express') => { return (options = {}) => { - const { metricsPath, defaultMetricsInterval = 10000, durationBuckets, requestSizeBuckets, responseSizeBuckets, useUniqueHistogramName, metricsPrefix, excludeRoutes, includeQueryParams } = options; + const { metricsPath, metricsJsonSuffix, defaultMetricsInterval = 10000, durationBuckets, requestSizeBuckets, responseSizeBuckets, useUniqueHistogramName, metricsPrefix, excludeRoutes, includeQueryParams } = options; debug(`Init metrics middleware with options: ${JSON.stringify(options)}`); setupOptions.metricsRoute = metricsPath || '/metrics'; + setupOptions.metricsJsonSuffix = metricsJsonSuffix || '.json'; setupOptions.excludeRoutes = excludeRoutes || []; setupOptions.includeQueryParams = includeQueryParams; setupOptions.defaultMetricsInterval = defaultMetricsInterval; From bbfd34b055236ba8c0d49904bd8eb32f144cfe72 Mon Sep 17 00:00:00 2001 From: Alaa El Helw Date: Mon, 17 Aug 2020 12:19:20 +0200 Subject: [PATCH 2/4] Adding custom suffix for json Removing dist --- dist/express-middleware.js | 102 -------------------- dist/express-middleware.js.map | 1 - dist/index.js | 11 --- dist/index.js.map | 1 - dist/koa-middleware.js | 127 ------------------------- dist/koa-middleware.js.map | 1 - dist/metrics-middleware.js | 69 -------------- dist/metrics-middleware.js.map | 1 - dist/request-response-collector.js | 76 --------------- dist/request-response-collector.js.map | 1 - dist/utils.js | 18 ---- dist/utils.js.map | 1 - 12 files changed, 409 deletions(-) delete mode 100644 dist/express-middleware.js delete mode 100644 dist/express-middleware.js.map delete mode 100644 dist/index.js delete mode 100644 dist/index.js.map delete mode 100644 dist/koa-middleware.js delete mode 100644 dist/koa-middleware.js.map delete mode 100644 dist/metrics-middleware.js delete mode 100644 dist/metrics-middleware.js.map delete mode 100644 dist/request-response-collector.js delete mode 100644 dist/request-response-collector.js.map delete mode 100644 dist/utils.js delete mode 100644 dist/utils.js.map diff --git a/dist/express-middleware.js b/dist/express-middleware.js deleted file mode 100644 index 3939ded..0000000 --- a/dist/express-middleware.js +++ /dev/null @@ -1,102 +0,0 @@ -const Prometheus = require('prom-client'); -require('pkginfo')(module, ['name']); -const debug = require('debug')(module.exports.name); -const utils = require('./utils'); -class ExpressMiddleware { - constructor(setupOptions) { - this.setupOptions = setupOptions || {}; - } - _collectDefaultServerMetrics(timeout) { - const NUMBER_OF_CONNECTIONS_METRICS_NAME = 'expressjs_number_of_open_connections'; - this.setupOptions.numberOfConnectionsGauge = Prometheus.register.getSingleMetric(NUMBER_OF_CONNECTIONS_METRICS_NAME) || new Prometheus.Gauge({ - name: NUMBER_OF_CONNECTIONS_METRICS_NAME, - help: 'Number of open connections to the Express.js server' - }); - if (this.setupOptions.server) { - setInterval(this._getConnections.bind(this), timeout).unref(); - } - } - _getConnections() { - if (this.setupOptions && this.setupOptions.server) { - this.setupOptions.server.getConnections((error, count) => { - if (error) { - debug('Error while collection number of open connections', error); - } - else { - this.setupOptions.numberOfConnectionsGauge.set(count); - } - }); - } - } - _handleResponse(req, res) { - const responseLength = parseInt(res.get('Content-Length')) || 0; - const route = this._getRoute(req); - if (route && utils.shouldLogMetrics(this.setupOptions.excludeRoutes, route)) { - this.setupOptions.requestSizeHistogram.observe({ method: req.method, route: route, code: res.statusCode }, req.metrics.contentLength); - req.metrics.timer({ route: route, code: res.statusCode }); - this.setupOptions.responseSizeHistogram.observe({ method: req.method, route: route, code: res.statusCode }, responseLength); - debug(`metrics updated, request length: ${req.metrics.contentLength}, response length: ${responseLength}`); - } - } - _getRoute(req) { - let route = req.baseUrl; - if (req.route) { - if (req.route.path !== '/') { - route = route ? route + req.route.path : req.route.path; - } - if (!route || route === '') { - route = req.originalUrl.split('?')[0]; - } - else { - const splittedRoute = route.split('/'); - const splittedUrl = req.originalUrl.split('?')[0].split('/'); - const routeIndex = splittedUrl.length - splittedRoute.length + 1; - const baseUrl = splittedUrl.slice(0, routeIndex).join('/'); - route = baseUrl + route; - } - if (this.setupOptions.includeQueryParams === true && Object.keys(req.query).length > 0) { - route = `${route}?${Object.keys(req.query).sort().map((queryParam) => `${queryParam}=`).join('&')}`; - } - } - if (typeof req.params === 'object') { - Object.keys(req.params).forEach((paramName) => { - route = route.replace(req.params[paramName], ':' + paramName); - }); - } - if (!route || route === '') { - route = 'N/A'; - } - return route; - } - middleware(req, res, next) { - if (!this.setupOptions.server && req.socket) { - this.setupOptions.server = req.socket.server; - this._collectDefaultServerMetrics(this.setupOptions.defaultMetricsInterval); - } - const routeUrl = req.originalUrl || req.url; - if (routeUrl === this.setupOptions.metricsRoute) { - debug('Request to /metrics endpoint'); - res.set('Content-Type', Prometheus.register.contentType); - return res.end(Prometheus.register.metrics()); - } - if (routeUrl === `${this.setupOptions.metricsRoute}${this.setupOptions.metricsJsonSuffix}`) { - debug('Request to /metrics endpoint'); - return res.json(Prometheus.register.getMetricsAsJSON()); - } - req.metrics = { - timer: this.setupOptions.responseTimeHistogram.startTimer({ - method: req.method - }), - contentLength: parseInt(req.get('content-length')) || 0 - }; - debug(`Set start time and content length for request. url: ${routeUrl}, method: ${req.method}`); - res.once('finish', () => { - debug('on finish.'); - this._handleResponse(req, res); - }); - return next(); - } - ; -} -module.exports = ExpressMiddleware; -//# sourceMappingURL=express-middleware.js.map \ No newline at end of file diff --git a/dist/express-middleware.js.map b/dist/express-middleware.js.map deleted file mode 100644 index a17f435..0000000 --- a/dist/express-middleware.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"express-middleware.js","sourceRoot":"","sources":["../src/express-middleware.js"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js deleted file mode 100644 index 2fdf3b3..0000000 --- a/dist/index.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; -const Path = require('path'); -const metricsMiddleware = { exports: {} }; -require('pkginfo')(metricsMiddleware, { dir: Path.dirname(module.parent.filename), include: ['name', 'version'] }); -const appVersion = metricsMiddleware.exports.version; -const projectName = metricsMiddleware.exports.name.replace(/-/g, '_'); -module.exports = require('./metrics-middleware')(appVersion, projectName); -module.exports.HttpMetricsCollector = require('./request-response-collector')(projectName); -module.exports.koaMiddleware = require('./metrics-middleware')(appVersion, projectName, 'koa'); -module.exports.expressMiddleware = require('./metrics-middleware')(appVersion, projectName, 'express'); -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/index.js.map b/dist/index.js.map deleted file mode 100644 index 4ad66b7..0000000 --- a/dist/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAC7B,MAAM,iBAAiB,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AAC1C,OAAO,CAAC,SAAS,CAAC,CAAC,iBAAiB,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC;AACnH,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,OAAO,CAAC;AACrD,MAAM,WAAW,GAAG,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAEtE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;AAC1E,MAAM,CAAC,OAAO,CAAC,oBAAoB,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC,WAAW,CAAC,CAAC;AAC3F,MAAM,CAAC,OAAO,CAAC,aAAa,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;AAC/F,MAAM,CAAC,OAAO,CAAC,iBAAiB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC"} \ No newline at end of file diff --git a/dist/koa-middleware.js b/dist/koa-middleware.js deleted file mode 100644 index eff89db..0000000 --- a/dist/koa-middleware.js +++ /dev/null @@ -1,127 +0,0 @@ -const Prometheus = require('prom-client'); -require('pkginfo')(module, ['name']); -const debug = require('debug')(module.exports.name); -const utils = require('./utils'); -const WILDCARD_ROUTE_ENDING = '(.*)'; -class KoaMiddleware { - constructor(setupOptions) { - this.setupOptions = setupOptions; - } - _collectDefaultServerMetrics(timeout) { - const NUMBER_OF_CONNECTIONS_METRICS_NAME = 'koajs_number_of_open_connections'; - this.setupOptions.numberOfConnectionsGauge = Prometheus.register.getSingleMetric(NUMBER_OF_CONNECTIONS_METRICS_NAME) || new Prometheus.Gauge({ - name: NUMBER_OF_CONNECTIONS_METRICS_NAME, - help: 'Number of open connections to the Koa.js server' - }); - if (this.setupOptions.server) { - setInterval(this._getConnections.bind(this), timeout).unref(); - } - } - _getConnections() { - if (this.setupOptions.server) { - this.setupOptions.server.getConnections((error, count) => { - if (error) { - debug('Error while collection number of open connections', error); - } - else { - this.setupOptions.numberOfConnectionsGauge.set(count); - } - }); - } - } - _handleResponse(ctx) { - const responseLength = parseInt(ctx.response.get('Content-Length')) || 0; - const route = this._getRoute(ctx) || 'N/A'; - if (route && utils.shouldLogMetrics(this.setupOptions.excludeRoutes, route)) { - this.setupOptions.requestSizeHistogram.observe({ - method: ctx.req.method, - route: route, - code: ctx.res.statusCode - }, ctx.req.metrics.contentLength); - ctx.req.metrics.timer({ route: route, code: ctx.res.statusCode }); - this.setupOptions.responseSizeHistogram.observe({ - method: ctx.req.method, - route: route, - code: ctx.res.statusCode - }, responseLength); - debug(`metrics updated, request length: ${ctx.req.metrics.contentLength}, response length: ${responseLength}`); - } - } - _getRoute(ctx) { - let route; - if (ctx._matchedRoute && !ctx._matchedRoute.endsWith(WILDCARD_ROUTE_ENDING)) { - route = ctx._matchedRoute; - route = route.endsWith('/') ? route.substring(0, route.length - 1) : route; - } - else if (ctx._matchedRoute) { - route = this._handleSubRoutes(ctx._matchedRoute, ctx.originalUrl, ctx.request.method, ctx.router); - } - if (this.setupOptions.includeQueryParams === true && Object.keys(ctx.query).length > 0) { - route = `${route || '/'}?${Object.keys(ctx.query).sort().map((queryParam) => `${queryParam}=`).join('&')}`; - } - return route; - } - _handleSubRoutes(matchedRoute, originalUrl, method, router) { - let route; - const routeStart = matchedRoute.substring(0, matchedRoute.length - WILDCARD_ROUTE_ENDING.length); - let url = this._removeQueryFromUrl(originalUrl).substring(routeStart.length); - let matchedRoutes = router.match(url, method); - if (matchedRoutes.path.length > 0) { - route = this._findFirstProperRoute(matchedRoutes.path); - return routeStart + route; - } - else { - url = this._removeQueryFromUrl(originalUrl); - matchedRoutes = router.match(url, method); - if (matchedRoutes.path.length > 0) { - route = this._findFirstProperRoute(matchedRoutes.path); - return route; - } - } - } - _findFirstProperRoute(routes) { - const properRoute = routes.find(route => { - if (!route.path.endsWith('(.*)')) { - return route; - } - }); - let route = properRoute.path; - route = route.endsWith('/') ? route.substring(0, route.length - 1) : route; - return route; - } - _removeQueryFromUrl(url) { - return url.split('?')[0]; - } - middleware(ctx, next) { - if (!this.setupOptions.server && ctx.req.socket) { - this.setupOptions.server = ctx.req.socket.server; - this._collectDefaultServerMetrics(this.setupOptions.defaultMetricsInterval); - } - if (ctx.req.url === this.setupOptions.metricsRoute) { - debug('Request to /metrics endpoint'); - ctx.set('Content-Type', Prometheus.register.contentType); - ctx.body = Prometheus.register.metrics(); - return next(); - } - if (ctx.req.url === `${this.setupOptions.metricsRoute}.json`) { - debug('Request to /metrics endpoint'); - ctx.body = Prometheus.register.getMetricsAsJSON(); - return next(); - } - ctx.req.metrics = { - timer: this.setupOptions.responseTimeHistogram.startTimer({ - method: ctx.req.method - }), - contentLength: parseInt(ctx.request.get('content-length')) || 0 - }; - debug(`Set start time and content length for request. url: ${ctx.req.url}, method: ${ctx.req.method}`); - ctx.res.once('finish', () => { - debug('on finish.'); - this._handleResponse(ctx); - }); - return next(); - } - ; -} -module.exports = KoaMiddleware; -//# sourceMappingURL=koa-middleware.js.map \ No newline at end of file diff --git a/dist/koa-middleware.js.map b/dist/koa-middleware.js.map deleted file mode 100644 index c24a570..0000000 --- a/dist/koa-middleware.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"koa-middleware.js","sourceRoot":"","sources":["../src/koa-middleware.js"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/metrics-middleware.js b/dist/metrics-middleware.js deleted file mode 100644 index a152abd..0000000 --- a/dist/metrics-middleware.js +++ /dev/null @@ -1,69 +0,0 @@ -'use strict'; -const Prometheus = require('prom-client'); -require('pkginfo')(module, ['name']); -const debug = require('debug')(module.exports.name); -const utils = require('./utils'); -const ExpressMiddleware = require('./express-middleware'); -const KoaMiddleware = require('./koa-middleware'); -const setupOptions = {}; -module.exports = (appVersion, projectName, framework = 'express') => { - return (options = {}) => { - const { metricsPath, metricsJsonSuffix, defaultMetricsInterval = 10000, durationBuckets, requestSizeBuckets, responseSizeBuckets, useUniqueHistogramName, metricsPrefix, excludeRoutes, includeQueryParams } = options; - debug(`Init metrics middleware with options: ${JSON.stringify(options)}`); - setupOptions.metricsRoute = metricsPath || '/metrics'; - setupOptions.metricsJsonSuffix = metricsJsonSuffix || '.json'; - setupOptions.excludeRoutes = excludeRoutes || []; - setupOptions.includeQueryParams = includeQueryParams; - setupOptions.defaultMetricsInterval = defaultMetricsInterval; - let metricNames = { - http_request_duration_seconds: 'http_request_duration_seconds', - app_version: 'app_version', - http_request_size_bytes: 'http_request_size_bytes', - http_response_size_bytes: 'http_response_size_bytes', - defaultMetricsPrefix: '' - }; - metricNames = utils.getMetricNames(metricNames, useUniqueHistogramName, metricsPrefix, projectName); - Prometheus.collectDefaultMetrics({ timeout: defaultMetricsInterval, prefix: `${metricNames.defaultMetricsPrefix}` }); - if (!Prometheus.register.getSingleMetric(metricNames.app_version)) { - const version = new Prometheus.Gauge({ - name: metricNames.app_version, - help: 'The service version by package.json', - labelNames: ['version', 'major', 'minor', 'patch'] - }); - const versionSegments = appVersion.split('.').map(Number); - version.labels(appVersion, versionSegments[0], versionSegments[1], versionSegments[2]).set(1); - } - setupOptions.responseTimeHistogram = Prometheus.register.getSingleMetric(metricNames.http_request_duration_seconds) || new Prometheus.Histogram({ - name: metricNames.http_request_duration_seconds, - help: 'Duration of HTTP requests in seconds', - labelNames: ['method', 'route', 'code'], - buckets: durationBuckets || [0.001, 0.005, 0.015, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5] - }); - setupOptions.requestSizeHistogram = Prometheus.register.getSingleMetric(metricNames.http_request_size_bytes) || new Prometheus.Histogram({ - name: metricNames.http_request_size_bytes, - help: 'Size of HTTP requests in bytes', - labelNames: ['method', 'route', 'code'], - buckets: requestSizeBuckets || [5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000] - }); - setupOptions.responseSizeHistogram = Prometheus.register.getSingleMetric(metricNames.http_response_size_bytes) || new Prometheus.Histogram({ - name: metricNames.http_response_size_bytes, - help: 'Size of HTTP response in bytes', - labelNames: ['method', 'route', 'code'], - buckets: responseSizeBuckets || [5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000] - }); - return frameworkMiddleware(framework); - }; -}; -function frameworkMiddleware(framework) { - switch (framework) { - case 'koa': { - const middleware = new KoaMiddleware(setupOptions); - return middleware.middleware.bind(middleware); - } - default: { - const middleware = new ExpressMiddleware(setupOptions); - return middleware.middleware.bind(middleware); - } - } -} -//# sourceMappingURL=metrics-middleware.js.map \ No newline at end of file diff --git a/dist/metrics-middleware.js.map b/dist/metrics-middleware.js.map deleted file mode 100644 index 8d20736..0000000 --- a/dist/metrics-middleware.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"metrics-middleware.js","sourceRoot":"","sources":["../src/metrics-middleware.js"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/request-response-collector.js b/dist/request-response-collector.js deleted file mode 100644 index e2f72f5..0000000 --- a/dist/request-response-collector.js +++ /dev/null @@ -1,76 +0,0 @@ -const Prometheus = require('prom-client'); -const utils = require('./utils'); -let southboundResponseTimeHistogram, southboundClientErrors = null; -let projectName; -module.exports = (name) => { - projectName = name; - const httpMetricsCollector = HttpMetricsCollector; - httpMetricsCollector.init = init; - httpMetricsCollector.collect = collect; - return httpMetricsCollector; -}; -class HttpMetricsCollector { - constructor(options) { - const setup = _init(options); - this.southboundResponseTimeHistogram = setup.southboundResponseTimeHistogram; - this.southboundClientErrors = setup.southboundClientErrors; - } - ; - collect(res) { - _collectHttpTiming(res, this.southboundResponseTimeHistogram, this.southboundClientErrors); - } -} -function _collectHttpTiming(res, southboundResponseTimeHistogram, southboundClientErrors) { - if (res instanceof Error && !res.response && southboundClientErrors) { - const error = res.error || res; - southboundClientErrors.inc({ target: error.hostname, error: error.code }); - } - else { - const response = res.response || res; - 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); - 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); - 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); - } - } -} -function _init(options = {}) { - let metricNames = { - southbound_request_duration_seconds: 'southbound_request_duration_seconds', - southbound_client_errors_count: 'southbound_client_errors_count' - }; - const { durationBuckets, countClientErrors, useUniqueHistogramName, prefix } = options; - metricNames = utils.getMetricNames(metricNames, useUniqueHistogramName, prefix, projectName); - southboundResponseTimeHistogram = Prometheus.register.getSingleMetric(metricNames.southbound_request_duration_seconds) || - new Prometheus.Histogram({ - name: metricNames.southbound_request_duration_seconds, - help: 'Duration of Southbound queries in seconds', - labelNames: ['method', 'route', 'status_code', 'target', 'type'], - buckets: durationBuckets || [0.001, 0.005, 0.015, 0.03, 0.05, 0.1, 0.15, 0.3, 0.5] - }); - if (countClientErrors !== false) { - southboundClientErrors = Prometheus.register.getSingleMetric(metricNames.southbound_client_errors_count) || new Prometheus.Counter({ - name: metricNames.southbound_client_errors_count, - help: 'Southbound http client error counter', - labelNames: ['target', 'error'] - }); - } - return { - southboundClientErrors: southboundClientErrors, - southboundResponseTimeHistogram: southboundResponseTimeHistogram - }; -} -; -function init(options) { - const setup = _init(options); - southboundResponseTimeHistogram = setup.southboundResponseTimeHistogram; - southboundClientErrors = setup.southboundClientErrors; -} -; -function collect(res) { - _collectHttpTiming(res, southboundResponseTimeHistogram, southboundClientErrors); -} -; -//# sourceMappingURL=request-response-collector.js.map \ No newline at end of file diff --git a/dist/request-response-collector.js.map b/dist/request-response-collector.js.map deleted file mode 100644 index 4466e30..0000000 --- a/dist/request-response-collector.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"request-response-collector.js","sourceRoot":"","sources":["../src/request-response-collector.js"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils.js b/dist/utils.js deleted file mode 100644 index 58563be..0000000 --- a/dist/utils.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict'; -function getMetricNames(metricNames, useUniqueHistogramName, metricsPrefix, projectName) { - const prefix = useUniqueHistogramName === true ? projectName : metricsPrefix; - if (prefix) { - Object.keys(metricNames).forEach(key => { - metricNames[key] = `${prefix}_${metricNames[key]}`; - }); - } - return metricNames; -} -function shouldLogMetrics(excludeRoutes, route) { - return excludeRoutes.every((path) => { - return !route.includes(path); - }); -} -module.exports.getMetricNames = getMetricNames; -module.exports.shouldLogMetrics = shouldLogMetrics; -//# sourceMappingURL=utils.js.map \ No newline at end of file diff --git a/dist/utils.js.map b/dist/utils.js.map deleted file mode 100644 index 077e5a8..0000000 --- a/dist/utils.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,SAAS,cAAc,CAAC,WAAW,EAAE,sBAAsB,EAAE,aAAa,EAAE,WAAW;IACnF,MAAM,MAAM,GAAG,sBAAsB,KAAK,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC;IAE7E,IAAI,MAAM,EAAE;QACR,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YACnC,WAAW,CAAC,GAAG,CAAC,GAAG,GAAG,MAAM,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;QACvD,CAAC,CAAC,CAAC;KACN;IAED,OAAO,WAAW,CAAC;AACvB,CAAC;AAED,SAAS,gBAAgB,CAAC,aAAa,EAAE,KAAK;IAC1C,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE;QAChC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,CAAC,OAAO,CAAC,cAAc,GAAG,cAAc,CAAC;AAC/C,MAAM,CAAC,OAAO,CAAC,gBAAgB,GAAG,gBAAgB,CAAC"} \ No newline at end of file From fcb3ae8fc5e64a4bd1c572d9374d4d298e28f3f4 Mon Sep 17 00:00:00 2001 From: Alaa El Helw Date: Fri, 21 Aug 2020 10:49:08 +0200 Subject: [PATCH 3/4] Adding an optional params for json formatted metrics : "metricsJsonPath" defaults to ``${setupOptions.metricsRoute}.json` --- src/express-middleware.js | 6 +++--- src/index.d.ts | 2 +- src/metrics-middleware.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/express-middleware.js b/src/express-middleware.js index 5a80ba0..6a8146b 100644 --- a/src/express-middleware.js +++ b/src/express-middleware.js @@ -98,8 +98,8 @@ class ExpressMiddleware { res.set('Content-Type', Prometheus.register.contentType); return res.end(Prometheus.register.metrics()); } - if (routeUrl === `${this.setupOptions.metricsRoute}${this.setupOptions.metricsJsonSuffix}`) { - debug('Request to /metrics endpoint'); + if (routeUrl === this.setupOptions.metricsJsonRoute) { + debug('Request to /metrics/json endpoint'); return res.json(Prometheus.register.getMetricsAsJSON()); } @@ -121,4 +121,4 @@ class ExpressMiddleware { }; } -module.exports = ExpressMiddleware; +module.exports = ExpressMiddleware; \ No newline at end of file diff --git a/src/index.d.ts b/src/index.d.ts index 01d3924..b54475a 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -12,7 +12,7 @@ export class HttpMetricsCollector { export interface ApiMetricsOpts { metricsPath?: string; - metricsJsonSuffix?: string, + metricsJsonPath?: string, defaultMetricsInterval?: number; durationBuckets?: number[]; requestSizeBuckets?: number[]; diff --git a/src/metrics-middleware.js b/src/metrics-middleware.js index b99263e..c4905f6 100644 --- a/src/metrics-middleware.js +++ b/src/metrics-middleware.js @@ -10,10 +10,10 @@ const setupOptions = {}; module.exports = (appVersion, projectName, framework = 'express') => { return (options = {}) => { - const { metricsPath, metricsJsonSuffix, defaultMetricsInterval = 10000, durationBuckets, requestSizeBuckets, responseSizeBuckets, useUniqueHistogramName, metricsPrefix, excludeRoutes, includeQueryParams } = options; + const { metricsPath, metricsJsonPath, defaultMetricsInterval = 10000, durationBuckets, requestSizeBuckets, responseSizeBuckets, useUniqueHistogramName, metricsPrefix, excludeRoutes, includeQueryParams } = options; debug(`Init metrics middleware with options: ${JSON.stringify(options)}`); setupOptions.metricsRoute = metricsPath || '/metrics'; - setupOptions.metricsJsonSuffix = metricsJsonSuffix || '.json'; + setupOptions.metricsJsonRoute = metricsJsonPath || `${setupOptions.metricsRoute}.json`; setupOptions.excludeRoutes = excludeRoutes || []; setupOptions.includeQueryParams = includeQueryParams; setupOptions.defaultMetricsInterval = defaultMetricsInterval; From 7389c17aafa521a377be9243a30c740e1d32ebd1 Mon Sep 17 00:00:00 2001 From: Alaa El Helw Date: Mon, 7 Sep 2020 15:16:09 +0200 Subject: [PATCH 4/4] Adding an optional params for json formatted metrics : "metricsJsonPath" defaults to ``${setupOptions.metricsRoute}.json` --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ca3a84e..7d69bfa 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ API and process monitoring with [Prometheus](https://prometheus.io) for Node.js - Process Metrics as recommended by Prometheus [itself](https://prometheus.io/docs/instrumenting/writing_clientlibs/#standard-and-runtime-collectors) - Endpoint to retrieve the metrics - used for Prometheus scraping - Prometheus format - - JSON format (`${path}.json`) + - JSON format (default to `${path}.json`, can be changed in options) - Support custom metrics - [Http function to collect request.js HTTP request duration](#requestjs-http-request-duration-collector) @@ -60,6 +60,7 @@ app.use(apiMetrics()) ### Options - metricsPath - Path to access the metrics. `default: /metrics` +- metricsJsonPath - Path to access the json formatted metrics. `default: {metricsPath}.json` - defaultMetricsInterval - the interval to collect the process metrics in milliseconds. `default: 10000` - durationBuckets - Buckets for response time in seconds. `default: [0.001, 0.005, 0.015, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5]` - requestSizeBuckets - Buckets for request size in bytes. `default: [5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000]` @@ -87,6 +88,7 @@ curl http[s]://:[port]/metrics.json 2. If you are using express framework and no route was found for the request (e.g: 404 status code), the request will not be collected. that's because we'll risk memory leak since the route is not a pattern but a hardcoded string. +3. You can specify your own metrics path via options. see : `metricsJsonPath` ## Custom Metrics