node-server-engine 1.10.10 → 1.10.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/const/metrics.js +7 -0
- package/dist/const/metrics.js.map +1 -1
- package/dist/entities/Server/Server.const.js +2 -2
- package/dist/entities/Server/Server.const.js.map +1 -1
- package/dist/metrics/request.d.ts +4 -1
- package/dist/metrics/request.js +31 -4
- package/dist/metrics/request.js.map +1 -1
- package/dist/middleware/requestMetrics/requestMetrics.d.ts +3 -2
- package/dist/middleware/requestMetrics/requestMetrics.js +73 -10
- package/dist/middleware/requestMetrics/requestMetrics.js.map +1 -1
- package/package.json +1 -1
package/dist/const/metrics.js
CHANGED
|
@@ -7,6 +7,13 @@ exports.serviceRegistry = exports.instanceRegistry = void 0;
|
|
|
7
7
|
var _promClient = require("prom-client");
|
|
8
8
|
// Registry for metrics that apply to this specific instance of the service
|
|
9
9
|
const instanceRegistry = exports.instanceRegistry = new _promClient.Registry();
|
|
10
|
+
|
|
10
11
|
// Registry for metrics that apply to the service as a whole
|
|
11
12
|
const serviceRegistry = exports.serviceRegistry = new _promClient.Registry();
|
|
13
|
+
|
|
14
|
+
// Collect default Node.js process metrics (includes process_start_time_seconds)
|
|
15
|
+
(0, _promClient.collectDefaultMetrics)({
|
|
16
|
+
register: instanceRegistry,
|
|
17
|
+
prefix: ''
|
|
18
|
+
});
|
|
12
19
|
//# sourceMappingURL=metrics.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.js","names":["_promClient","require","instanceRegistry","exports","Registry","serviceRegistry"],"sources":["../../src/const/metrics.ts"],"sourcesContent":["import { Registry } from 'prom-client';\n\n// Registry for metrics that apply to this specific instance of the service\nexport const instanceRegistry = new Registry();\n// Registry for metrics that apply to the service as a whole\nexport const serviceRegistry = new Registry();\n"],"mappings":";;;;;;AAAA,IAAAA,WAAA,GAAAC,OAAA;AAEA;AACO,MAAMC,gBAAgB,GAAAC,OAAA,CAAAD,gBAAA,GAAG,IAAIE,oBAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"metrics.js","names":["_promClient","require","instanceRegistry","exports","Registry","serviceRegistry","collectDefaultMetrics","register","prefix"],"sources":["../../src/const/metrics.ts"],"sourcesContent":["import { Registry, collectDefaultMetrics } from 'prom-client';\n\n// Registry for metrics that apply to this specific instance of the service\nexport const instanceRegistry = new Registry();\n\n// Registry for metrics that apply to the service as a whole\nexport const serviceRegistry = new Registry();\n\n// Collect default Node.js process metrics (includes process_start_time_seconds)\ncollectDefaultMetrics({\n register: instanceRegistry,\n prefix: '',\n});\n"],"mappings":";;;;;;AAAA,IAAAA,WAAA,GAAAC,OAAA;AAEA;AACO,MAAMC,gBAAgB,GAAAC,OAAA,CAAAD,gBAAA,GAAG,IAAIE,oBAAQ,CAAC,CAAC;;AAE9C;AACO,MAAMC,eAAe,GAAAF,OAAA,CAAAE,eAAA,GAAG,IAAID,oBAAQ,CAAC,CAAC;;AAE7C;AACA,IAAAE,iCAAqB,EAAC;EACpBC,QAAQ,EAAEL,gBAAgB;EAC1BM,MAAM,EAAE;AACV,CAAC,CAAC","ignoreList":[]}
|
|
@@ -12,13 +12,13 @@ const defaultMiddleware = exports.defaultMiddleware = [(0, _middleware.healthChe
|
|
|
12
12
|
}), (0, _express.urlencoded)({
|
|
13
13
|
extended: true,
|
|
14
14
|
limit: process.env.REQUEST_SIZE_LIMIT ?? '1mb'
|
|
15
|
-
}), (0, _middleware.metrics)(), (0, _middleware.version)()].filter(val => val);
|
|
15
|
+
}), _middleware.requestMetrics, (0, _middleware.metrics)(), (0, _middleware.version)()].filter(val => val);
|
|
16
16
|
|
|
17
17
|
// Error handling middleware that are run after the main business logic endpoints
|
|
18
18
|
const defaultErrorMiddleware = exports.defaultErrorMiddleware = [_middleware.error, _middleware.fourOhFour];
|
|
19
19
|
|
|
20
20
|
// Middleware that are served on the secondary port
|
|
21
|
-
const secondaryMiddleware = exports.secondaryMiddleware = [(0, _middleware.metrics)(), (0, _middleware.version)(), (0, _middleware.swaggerDocs)()];
|
|
21
|
+
const secondaryMiddleware = exports.secondaryMiddleware = [_middleware.requestMetrics, (0, _middleware.metrics)(), (0, _middleware.version)(), (0, _middleware.swaggerDocs)()];
|
|
22
22
|
|
|
23
23
|
// Add request logging to middleware chain when reporting is not silenced
|
|
24
24
|
if (!process.env.SILENCE_REPORT) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Server.const.js","names":["_express","require","_middleware","defaultMiddleware","exports","healthCheck","json","limit","process","env","REQUEST_SIZE_LIMIT","urlencoded","extended","metrics","version","filter","val","defaultErrorMiddleware","error","fourOhFour","secondaryMiddleware","swaggerDocs","SILENCE_REPORT","unshift","requestLogger","shutdownSignals"],"sources":["../../../src/entities/Server/Server.const.ts"],"sourcesContent":["import { json, urlencoded, ErrorRequestHandler, RequestHandler } from 'express';\nimport {\n metrics,\n error,\n fourOhFour,\n healthCheck,\n version,\n swaggerDocs,\n requestLogger\n} from 'middleware';\n\n// Default middleware that are applied first thing on the primary port, before the business logic endpoints\nexport const defaultMiddleware: Array<RequestHandler> = [\n healthCheck(),\n json({ limit: process.env.REQUEST_SIZE_LIMIT ?? '1mb' }),\n urlencoded({\n extended: true,\n limit: process.env.REQUEST_SIZE_LIMIT ?? '1mb'\n }),\n metrics(),\n version()\n].filter((val) => val);\n\n// Error handling middleware that are run after the main business logic endpoints\nexport const defaultErrorMiddleware: Array<\n RequestHandler | ErrorRequestHandler\n> = [error, fourOhFour];\n\n// Middleware that are served on the secondary port\nexport const secondaryMiddleware: Array<RequestHandler> = [\n metrics(),\n version(),\n swaggerDocs()\n];\n\n// Add request logging to middleware chain when reporting is not silenced\nif (!process.env.SILENCE_REPORT) {\n defaultMiddleware.unshift(requestLogger());\n secondaryMiddleware.unshift(requestLogger());\n}\n\nexport const shutdownSignals = ['SIGTERM', 'SIGUSR2', 'SIGINT'];\n"],"mappings":";;;;;;AAAA,IAAAA,QAAA,GAAAC,OAAA;AACA,IAAAC,WAAA,GAAAD,OAAA;
|
|
1
|
+
{"version":3,"file":"Server.const.js","names":["_express","require","_middleware","defaultMiddleware","exports","healthCheck","json","limit","process","env","REQUEST_SIZE_LIMIT","urlencoded","extended","requestMetrics","metrics","version","filter","val","defaultErrorMiddleware","error","fourOhFour","secondaryMiddleware","swaggerDocs","SILENCE_REPORT","unshift","requestLogger","shutdownSignals"],"sources":["../../../src/entities/Server/Server.const.ts"],"sourcesContent":["import { json, urlencoded, ErrorRequestHandler, RequestHandler } from 'express';\nimport {\n metrics,\n error,\n fourOhFour,\n healthCheck,\n version,\n swaggerDocs,\n requestLogger,\n requestMetrics\n} from 'middleware';\n\n// Default middleware that are applied first thing on the primary port, before the business logic endpoints\nexport const defaultMiddleware: Array<RequestHandler> = [\n healthCheck(),\n json({ limit: process.env.REQUEST_SIZE_LIMIT ?? '1mb' }),\n urlencoded({\n extended: true,\n limit: process.env.REQUEST_SIZE_LIMIT ?? '1mb'\n }),\n requestMetrics,\n metrics(),\n version()\n].filter((val) => val);\n\n// Error handling middleware that are run after the main business logic endpoints\nexport const defaultErrorMiddleware: Array<\n RequestHandler | ErrorRequestHandler\n> = [error, fourOhFour];\n\n// Middleware that are served on the secondary port\nexport const secondaryMiddleware: Array<RequestHandler> = [\n requestMetrics,\n metrics(),\n version(),\n swaggerDocs()\n];\n\n// Add request logging to middleware chain when reporting is not silenced\nif (!process.env.SILENCE_REPORT) {\n defaultMiddleware.unshift(requestLogger());\n secondaryMiddleware.unshift(requestLogger());\n}\n\nexport const shutdownSignals = ['SIGTERM', 'SIGUSR2', 'SIGINT'];\n"],"mappings":";;;;;;AAAA,IAAAA,QAAA,GAAAC,OAAA;AACA,IAAAC,WAAA,GAAAD,OAAA;AAWA;AACO,MAAME,iBAAwC,GAAAC,OAAA,CAAAD,iBAAA,GAAG,CACtD,IAAAE,uBAAW,EAAC,CAAC,EACb,IAAAC,aAAI,EAAC;EAAEC,KAAK,EAAEC,OAAO,CAACC,GAAG,CAACC,kBAAkB,IAAI;AAAM,CAAC,CAAC,EACxD,IAAAC,mBAAU,EAAC;EACTC,QAAQ,EAAE,IAAI;EACdL,KAAK,EAAEC,OAAO,CAACC,GAAG,CAACC,kBAAkB,IAAI;AAC3C,CAAC,CAAC,EACFG,0BAAc,EACd,IAAAC,mBAAO,EAAC,CAAC,EACT,IAAAC,mBAAO,EAAC,CAAC,CACV,CAACC,MAAM,CAAEC,GAAG,IAAKA,GAAG,CAAC;;AAEtB;AACO,MAAMC,sBAEZ,GAAAd,OAAA,CAAAc,sBAAA,GAAG,CAACC,iBAAK,EAAEC,sBAAU,CAAC;;AAEvB;AACO,MAAMC,mBAA0C,GAAAjB,OAAA,CAAAiB,mBAAA,GAAG,CACxDR,0BAAc,EACd,IAAAC,mBAAO,EAAC,CAAC,EACT,IAAAC,mBAAO,EAAC,CAAC,EACT,IAAAO,uBAAW,EAAC,CAAC,CACd;;AAED;AACA,IAAI,CAACd,OAAO,CAACC,GAAG,CAACc,cAAc,EAAE;EAC/BpB,iBAAiB,CAACqB,OAAO,CAAC,IAAAC,yBAAa,EAAC,CAAC,CAAC;EAC1CJ,mBAAmB,CAACG,OAAO,CAAC,IAAAC,yBAAa,EAAC,CAAC,CAAC;AAC9C;AAEO,MAAMC,eAAe,GAAAtB,OAAA,CAAAsB,eAAA,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC","ignoreList":[]}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import { Counter, Histogram } from 'prom-client';
|
|
1
|
+
import { Counter, Histogram, Gauge } from 'prom-client';
|
|
2
2
|
export declare const httpRequestCount: Counter<"method" | "path" | "service" | "status">;
|
|
3
3
|
export declare const httpRequestDuration: Histogram<"method" | "path" | "service" | "status">;
|
|
4
|
+
export declare const httpInFlight: Gauge<string>;
|
|
5
|
+
export declare const httpErrorCount: Counter<"method" | "service" | "status">;
|
|
6
|
+
export declare const httpResponseSize: Histogram<"method" | "path" | "service" | "status">;
|
package/dist/metrics/request.js
CHANGED
|
@@ -3,20 +3,47 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.httpRequestDuration = exports.httpRequestCount = void 0;
|
|
6
|
+
exports.httpResponseSize = exports.httpRequestDuration = exports.httpRequestCount = exports.httpInFlight = exports.httpErrorCount = void 0;
|
|
7
7
|
var _promClient = require("prom-client");
|
|
8
8
|
var _const = require("../const");
|
|
9
|
+
// Register metrics to both the instance-level registry and the service-level
|
|
10
|
+
// registry so `/metrics/service` can expose aggregated/service-wide metrics.
|
|
9
11
|
const httpRequestCount = exports.httpRequestCount = new _promClient.Counter({
|
|
10
12
|
name: 'http_requests_total',
|
|
11
13
|
help: 'Total count of request received',
|
|
12
|
-
registers: [_const.instanceRegistry],
|
|
14
|
+
registers: [_const.instanceRegistry, _const.serviceRegistry],
|
|
13
15
|
labelNames: ['service', 'path', 'method', 'status']
|
|
14
16
|
});
|
|
15
17
|
const httpRequestDuration = exports.httpRequestDuration = new _promClient.Histogram({
|
|
16
18
|
name: 'http_requests_duration',
|
|
17
19
|
help: 'Duration of the request received',
|
|
18
|
-
registers: [_const.instanceRegistry],
|
|
20
|
+
registers: [_const.instanceRegistry, _const.serviceRegistry],
|
|
19
21
|
labelNames: ['service', 'path', 'method', 'status'],
|
|
20
|
-
|
|
22
|
+
// Reduced buckets to lower cardinality while keeping useful latency ranges
|
|
23
|
+
buckets: [0.01, 0.05, 0.1, 0.5, 1, 5]
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Gauge for currently in-flight requests (simple, no labels to reduce cardinality)
|
|
27
|
+
const httpInFlight = exports.httpInFlight = new _promClient.Gauge({
|
|
28
|
+
name: 'http_requests_in_flight',
|
|
29
|
+
help: 'Number of requests currently being processed by this instance',
|
|
30
|
+
registers: [_const.instanceRegistry]
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Counter for errors (4xx/5xx) — aggregated by status class and method
|
|
34
|
+
const httpErrorCount = exports.httpErrorCount = new _promClient.Counter({
|
|
35
|
+
name: 'http_requests_errors_total',
|
|
36
|
+
help: 'Total count of error responses',
|
|
37
|
+
registers: [_const.instanceRegistry, _const.serviceRegistry],
|
|
38
|
+
labelNames: ['service', 'status', 'method']
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Response size histogram (bytes). Uses instance + service registries.
|
|
42
|
+
const httpResponseSize = exports.httpResponseSize = new _promClient.Histogram({
|
|
43
|
+
name: 'http_response_size_bytes',
|
|
44
|
+
help: 'Size of HTTP responses in bytes',
|
|
45
|
+
registers: [_const.instanceRegistry, _const.serviceRegistry],
|
|
46
|
+
labelNames: ['service', 'path', 'method', 'status'],
|
|
47
|
+
buckets: [200, 500, 1500, 5000]
|
|
21
48
|
});
|
|
22
49
|
//# sourceMappingURL=request.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.js","names":["_promClient","require","_const","httpRequestCount","exports","Counter","name","help","registers","instanceRegistry","labelNames","httpRequestDuration","Histogram","buckets"],"sources":["../../src/metrics/request.ts"],"sourcesContent":["import { Counter, Histogram } from 'prom-client';\nimport { instanceRegistry } from 'const';\n\nexport const httpRequestCount = new Counter({\n name: 'http_requests_total',\n help: 'Total count of request received',\n registers: [instanceRegistry],\n labelNames: ['service', 'path', 'method', 'status']\n});\n\nexport const httpRequestDuration = new Histogram({\n name: 'http_requests_duration',\n help: 'Duration of the request received',\n registers: [instanceRegistry],\n labelNames: ['service', 'path', 'method', 'status'],\n buckets: [0.
|
|
1
|
+
{"version":3,"file":"request.js","names":["_promClient","require","_const","httpRequestCount","exports","Counter","name","help","registers","instanceRegistry","serviceRegistry","labelNames","httpRequestDuration","Histogram","buckets","httpInFlight","Gauge","httpErrorCount","httpResponseSize"],"sources":["../../src/metrics/request.ts"],"sourcesContent":["import { Counter, Histogram, Gauge } from 'prom-client';\nimport { instanceRegistry, serviceRegistry } from 'const';\n\n// Register metrics to both the instance-level registry and the service-level\n// registry so `/metrics/service` can expose aggregated/service-wide metrics.\nexport const httpRequestCount = new Counter({\n name: 'http_requests_total',\n help: 'Total count of request received',\n registers: [instanceRegistry, serviceRegistry],\n labelNames: ['service', 'path', 'method', 'status']\n});\n\nexport const httpRequestDuration = new Histogram({\n name: 'http_requests_duration',\n help: 'Duration of the request received',\n registers: [instanceRegistry, serviceRegistry],\n labelNames: ['service', 'path', 'method', 'status'],\n // Reduced buckets to lower cardinality while keeping useful latency ranges\n buckets: [0.01, 0.05, 0.1, 0.5, 1, 5]\n});\n\n// Gauge for currently in-flight requests (simple, no labels to reduce cardinality)\nexport const httpInFlight = new Gauge({\n name: 'http_requests_in_flight',\n help: 'Number of requests currently being processed by this instance',\n registers: [instanceRegistry]\n});\n\n// Counter for errors (4xx/5xx) — aggregated by status class and method\nexport const httpErrorCount = new Counter({\n name: 'http_requests_errors_total',\n help: 'Total count of error responses',\n registers: [instanceRegistry, serviceRegistry],\n labelNames: ['service', 'status', 'method']\n});\n\n// Response size histogram (bytes). Uses instance + service registries.\nexport const httpResponseSize = new Histogram({\n name: 'http_response_size_bytes',\n help: 'Size of HTTP responses in bytes',\n registers: [instanceRegistry, serviceRegistry],\n labelNames: ['service', 'path', 'method', 'status'],\n buckets: [200, 500, 1500, 5000]\n});\n"],"mappings":";;;;;;AAAA,IAAAA,WAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AAEA;AACA;AACO,MAAME,gBAAgB,GAAAC,OAAA,CAAAD,gBAAA,GAAG,IAAIE,mBAAO,CAAC;EAC1CC,IAAI,EAAE,qBAAqB;EAC3BC,IAAI,EAAE,iCAAiC;EACvCC,SAAS,EAAE,CAACC,uBAAgB,EAAEC,sBAAe,CAAC;EAC9CC,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ;AACpD,CAAC,CAAC;AAEK,MAAMC,mBAAmB,GAAAR,OAAA,CAAAQ,mBAAA,GAAG,IAAIC,qBAAS,CAAC;EAC/CP,IAAI,EAAE,wBAAwB;EAC9BC,IAAI,EAAE,kCAAkC;EACxCC,SAAS,EAAE,CAACC,uBAAgB,EAAEC,sBAAe,CAAC;EAC9CC,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC;EACnD;EACAG,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;AACtC,CAAC,CAAC;;AAEF;AACO,MAAMC,YAAY,GAAAX,OAAA,CAAAW,YAAA,GAAG,IAAIC,iBAAK,CAAC;EACpCV,IAAI,EAAE,yBAAyB;EAC/BC,IAAI,EAAE,+DAA+D;EACrEC,SAAS,EAAE,CAACC,uBAAgB;AAC9B,CAAC,CAAC;;AAEF;AACO,MAAMQ,cAAc,GAAAb,OAAA,CAAAa,cAAA,GAAG,IAAIZ,mBAAO,CAAC;EACxCC,IAAI,EAAE,4BAA4B;EAClCC,IAAI,EAAE,gCAAgC;EACtCC,SAAS,EAAE,CAACC,uBAAgB,EAAEC,sBAAe,CAAC;EAC9CC,UAAU,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ;AAC5C,CAAC,CAAC;;AAEF;AACO,MAAMO,gBAAgB,GAAAd,OAAA,CAAAc,gBAAA,GAAG,IAAIL,qBAAS,CAAC;EAC5CP,IAAI,EAAE,0BAA0B;EAChCC,IAAI,EAAE,iCAAiC;EACvCC,SAAS,EAAE,CAACC,uBAAgB,EAAEC,sBAAe,CAAC;EAC9CC,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC;EACnDG,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI;AAChC,CAAC,CAAC","ignoreList":[]}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { Request, Response, NextFunction } from 'express';
|
|
2
|
+
/** Composite middleware that tracks in-flight requests, errors, response size and timings */
|
|
3
|
+
export declare const requestMetrics: (request: Request, response: Response, next: NextFunction) => void;
|
|
@@ -7,15 +7,78 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.requestMetrics = void 0;
|
|
8
8
|
var _responseTime = _interopRequireDefault(require("response-time"));
|
|
9
9
|
var _metrics = require("../../metrics");
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
const excludedPrefixes = ['/swagger', '/docs', '/api-docs', '/metrics', '/favicon.ico', '/.well-known'];
|
|
11
|
+
|
|
12
|
+
/** Composite middleware that tracks in-flight requests, errors, response size and timings */
|
|
13
|
+
const requestMetrics = (request, response, next) => {
|
|
14
|
+
const path = request.route?.path ?? request.path;
|
|
15
|
+
|
|
16
|
+
// Skip operational/static routes
|
|
17
|
+
for (const prefix of excludedPrefixes) {
|
|
18
|
+
if (path.startsWith(prefix)) return next();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Increment in-flight
|
|
22
|
+
try {
|
|
23
|
+
_metrics.httpInFlight.inc();
|
|
24
|
+
} catch {}
|
|
25
|
+
|
|
26
|
+
// Ensure we decrement on finish/close (only once)
|
|
27
|
+
let inflightDecremented = false;
|
|
28
|
+
const cleanup = () => {
|
|
29
|
+
if (inflightDecremented) return;
|
|
30
|
+
inflightDecremented = true;
|
|
31
|
+
try {
|
|
32
|
+
_metrics.httpInFlight.dec();
|
|
33
|
+
} catch {}
|
|
17
34
|
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
35
|
+
response.once('finish', () => {
|
|
36
|
+
// record errors
|
|
37
|
+
const statusCode = response.statusCode ?? 0;
|
|
38
|
+
const statusClass = statusCode ? `${statusCode.toString().substring(0, 1)}XX` : '';
|
|
39
|
+
if (statusCode >= 400) {
|
|
40
|
+
try {
|
|
41
|
+
_metrics.httpErrorCount.inc({
|
|
42
|
+
service: process.env.CHART,
|
|
43
|
+
status: statusClass,
|
|
44
|
+
method: request.method
|
|
45
|
+
});
|
|
46
|
+
} catch {}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// observe response size if content-length header available
|
|
50
|
+
const lenHeader = response.getHeader('content-length');
|
|
51
|
+
const len = lenHeader ? parseInt(String(lenHeader), 10) : NaN;
|
|
52
|
+
if (!Number.isNaN(len)) {
|
|
53
|
+
try {
|
|
54
|
+
_metrics.httpResponseSize.observe({
|
|
55
|
+
service: process.env.CHART,
|
|
56
|
+
path,
|
|
57
|
+
method: request.method,
|
|
58
|
+
status: statusClass
|
|
59
|
+
}, len);
|
|
60
|
+
} catch {}
|
|
61
|
+
}
|
|
62
|
+
cleanup();
|
|
63
|
+
});
|
|
64
|
+
response.once('close', cleanup);
|
|
65
|
+
|
|
66
|
+
// Use response-time to record duration and request counts
|
|
67
|
+
const rt = (0, _responseTime.default)((req, res, time) => {
|
|
68
|
+
const labels = {
|
|
69
|
+
path,
|
|
70
|
+
method: request.method,
|
|
71
|
+
status: res.statusCode ? `${res.statusCode.toString().substring(0, 1)}XX` : '',
|
|
72
|
+
service: process.env.CHART || 'unknown'
|
|
73
|
+
};
|
|
74
|
+
try {
|
|
75
|
+
_metrics.httpRequestCount.inc(labels);
|
|
76
|
+
_metrics.httpRequestDuration.observe(labels, time / 1000);
|
|
77
|
+
} catch {}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Call the response-time middleware which will call next when done
|
|
81
|
+
rt(request, response, next);
|
|
82
|
+
};
|
|
83
|
+
exports.requestMetrics = requestMetrics;
|
|
21
84
|
//# sourceMappingURL=requestMetrics.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requestMetrics.js","names":["_responseTime","_interopRequireDefault","require","_metrics","requestMetrics","
|
|
1
|
+
{"version":3,"file":"requestMetrics.js","names":["_responseTime","_interopRequireDefault","require","_metrics","excludedPrefixes","requestMetrics","request","response","next","path","route","prefix","startsWith","httpInFlight","inc","inflightDecremented","cleanup","dec","once","statusCode","statusClass","toString","substring","httpErrorCount","service","process","env","CHART","status","method","lenHeader","getHeader","len","parseInt","String","NaN","Number","isNaN","httpResponseSize","observe","rt","responseTime","req","res","time","labels","httpRequestCount","httpRequestDuration","exports"],"sources":["../../../src/middleware/requestMetrics/requestMetrics.ts"],"sourcesContent":["import { Request, Response, NextFunction } from 'express';\nimport responseTime from 'response-time';\nimport {\n httpRequestCount,\n httpRequestDuration,\n httpInFlight,\n httpErrorCount,\n httpResponseSize\n} from 'metrics';\n\nconst excludedPrefixes = ['/swagger', '/docs', '/api-docs', '/metrics', '/favicon.ico', '/.well-known'];\n\n/** Composite middleware that tracks in-flight requests, errors, response size and timings */\nexport const requestMetrics = (request: Request, response: Response, next: NextFunction) => {\n const path = (request.route?.path ?? request.path) as string;\n\n // Skip operational/static routes\n for (const prefix of excludedPrefixes) {\n if (path.startsWith(prefix)) return next();\n }\n\n // Increment in-flight\n try {\n httpInFlight.inc();\n } catch {}\n\n // Ensure we decrement on finish/close (only once)\n let inflightDecremented = false;\n const cleanup = () => {\n if (inflightDecremented) return;\n inflightDecremented = true;\n try {\n httpInFlight.dec();\n } catch {}\n };\n\n response.once('finish', () => {\n // record errors\n const statusCode = response.statusCode ?? 0;\n const statusClass = statusCode ? `${statusCode.toString().substring(0, 1)}XX` : '';\n if (statusCode >= 400) {\n try {\n httpErrorCount.inc({ service: process.env.CHART, status: statusClass, method: request.method });\n } catch {}\n }\n\n // observe response size if content-length header available\n const lenHeader = response.getHeader('content-length');\n const len = lenHeader ? parseInt(String(lenHeader), 10) : NaN;\n if (!Number.isNaN(len)) {\n try {\n httpResponseSize.observe({ service: process.env.CHART, path, method: request.method, status: statusClass }, len);\n } catch {}\n }\n\n cleanup();\n });\n\n response.once('close', cleanup);\n\n // Use response-time to record duration and request counts\n const rt = responseTime((req: Request, res: Response, time: number) => {\n const labels = {\n path,\n method: request.method,\n status: res.statusCode ? `${res.statusCode.toString().substring(0, 1)}XX` : '',\n service: process.env.CHART || 'unknown'\n };\n\n try {\n httpRequestCount.inc(labels);\n httpRequestDuration.observe(labels, time / 1000);\n } catch {}\n });\n\n // Call the response-time middleware which will call next when done\n rt(request as Request, response as Response, next as NextFunction);\n};\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-server-engine",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.12",
|
|
4
4
|
"description": "Framework used to develop backend services. This package ships with a lot of features to standardize the creation of services, letting you focus on the business logic.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|