@tramvai/module-metrics 1.61.0 → 1.62.0
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/lib/request/types.d.ts +3 -1
- package/lib/server.es.js +40 -6
- package/lib/server.js +40 -6
- package/package.json +8 -8
package/lib/request/types.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type httpsType from 'https';
|
|
|
5
5
|
import type { Counter, Histogram } from 'prom-client';
|
|
6
6
|
import type { METRICS_MODULE_TOKEN, METRICS_SERVICES_REGISTRY_TOKEN } from '@tramvai/tokens-metrics';
|
|
7
7
|
export declare type ModuleConfig = {
|
|
8
|
-
|
|
8
|
+
enableConnectionResolveMetrics: boolean;
|
|
9
9
|
};
|
|
10
10
|
export declare type MetricsModule = typeof METRICS_MODULE_TOKEN;
|
|
11
11
|
export declare type HttpModule = typeof httpType;
|
|
@@ -16,6 +16,8 @@ export declare type MetricsInstances = {
|
|
|
16
16
|
requestsErrors: Counter<'status' | 'method' | 'service'>;
|
|
17
17
|
requestsDuration: Histogram<'status' | 'method' | 'service'>;
|
|
18
18
|
dnsResolveDuration: Histogram<'service'>;
|
|
19
|
+
tcpConnectDuration: Histogram<'service'>;
|
|
20
|
+
tlsHandshakeDuration: Histogram<'service'>;
|
|
19
21
|
};
|
|
20
22
|
export declare type GetServiceName = typeof METRICS_SERVICES_REGISTRY_TOKEN['getServiceName'];
|
|
21
23
|
export declare type Args = [RequestOptions | string | URL, (res: IncomingMessage) => void] | [string | URL, RequestOptions, (res: IncomingMessage) => void];
|
package/lib/server.es.js
CHANGED
|
@@ -68,7 +68,11 @@ const getUrlAndOptions = (args) => {
|
|
|
68
68
|
const urlWOQuery = parsedUrl.origin + parsedUrl.pathname;
|
|
69
69
|
return [urlWOQuery, options || {}];
|
|
70
70
|
};
|
|
71
|
-
|
|
71
|
+
// in seconds
|
|
72
|
+
const getDuration = (current, prev) =>
|
|
73
|
+
// max to avoid negative values and turn that into zero
|
|
74
|
+
prev === 0 ? 0 : Math.max((current - prev) / 1000, 0);
|
|
75
|
+
const createRequestWithMetrics = ({ metricsInstances: { requestsTotal, requestsErrors, requestsDuration, dnsResolveDuration, tcpConnectDuration, tlsHandshakeDuration, }, getServiceName, config, }) => function requestWithMetrics(originalRequest, ...args) {
|
|
72
76
|
const [url, options] = getUrlAndOptions(args);
|
|
73
77
|
const serviceName = getServiceName(url);
|
|
74
78
|
const req = originalRequest.apply(this, args);
|
|
@@ -94,17 +98,33 @@ const createRequestWithMetrics = ({ metricsInstances: { requestsTotal, requestsE
|
|
|
94
98
|
requestsErrors.inc(labelsValues);
|
|
95
99
|
timerDone(labelsValues);
|
|
96
100
|
});
|
|
97
|
-
if (config.
|
|
101
|
+
if (config.enableConnectionResolveMetrics) {
|
|
98
102
|
req.on('socket', (socket) => {
|
|
99
|
-
const
|
|
103
|
+
const timings = {
|
|
104
|
+
start: Date.now(),
|
|
105
|
+
lookupEnd: 0,
|
|
106
|
+
connectEnd: 0,
|
|
107
|
+
secureConnectEnd: 0,
|
|
108
|
+
};
|
|
109
|
+
const { service } = labelsValues;
|
|
100
110
|
socket.on('lookup', () => {
|
|
101
|
-
|
|
111
|
+
timings.lookupEnd = Date.now();
|
|
112
|
+
dnsResolveDuration.observe({ service }, getDuration(timings.lookupEnd, timings.start));
|
|
113
|
+
});
|
|
114
|
+
socket.on('connect', () => {
|
|
115
|
+
timings.connectEnd = Date.now();
|
|
116
|
+
tcpConnectDuration.observe({ service }, getDuration(timings.connectEnd, timings.lookupEnd));
|
|
117
|
+
});
|
|
118
|
+
socket.on('secureConnect', () => {
|
|
119
|
+
timings.secureConnectEnd = Date.now();
|
|
120
|
+
tlsHandshakeDuration.observe({ service }, getDuration(timings.secureConnectEnd, timings.connectEnd));
|
|
102
121
|
});
|
|
103
122
|
});
|
|
104
123
|
}
|
|
105
124
|
return req;
|
|
106
125
|
};
|
|
107
126
|
|
|
127
|
+
const DEFAULT_BUCKETS = [0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 20, 40, 60];
|
|
108
128
|
const initRequestsMetrics = ({ metrics, getServiceName, http, https, createRequestWithMetrics, config, }) => {
|
|
109
129
|
const metricsInstances = {
|
|
110
130
|
requestsTotal: metrics.counter({
|
|
@@ -121,11 +141,25 @@ const initRequestsMetrics = ({ metrics, getServiceName, http, https, createReque
|
|
|
121
141
|
name: 'http_sent_requests_duration',
|
|
122
142
|
help: 'Execution time of the sent requests',
|
|
123
143
|
labelNames: ['status', 'method', 'service'],
|
|
144
|
+
buckets: DEFAULT_BUCKETS,
|
|
124
145
|
}),
|
|
125
146
|
dnsResolveDuration: metrics.histogram({
|
|
126
147
|
name: 'dns_resolve_duration',
|
|
127
148
|
help: 'Time for dns resolve of the outhgoing requests',
|
|
128
149
|
labelNames: ['service'],
|
|
150
|
+
buckets: DEFAULT_BUCKETS,
|
|
151
|
+
}),
|
|
152
|
+
tcpConnectDuration: metrics.histogram({
|
|
153
|
+
name: 'tcp_connect_duration',
|
|
154
|
+
help: 'Duration of tcp connect of the outgoing requests',
|
|
155
|
+
labelNames: ['service'],
|
|
156
|
+
buckets: DEFAULT_BUCKETS,
|
|
157
|
+
}),
|
|
158
|
+
tlsHandshakeDuration: metrics.histogram({
|
|
159
|
+
name: 'tls_handshake_duration',
|
|
160
|
+
help: 'Duration of tls handshake of the outgoing requests',
|
|
161
|
+
labelNames: ['service'],
|
|
162
|
+
buckets: DEFAULT_BUCKETS,
|
|
129
163
|
}),
|
|
130
164
|
};
|
|
131
165
|
monkeypatch({
|
|
@@ -402,7 +436,7 @@ const eventLoopMetrics = (metrics) => {
|
|
|
402
436
|
const histogram = metrics.histogram({
|
|
403
437
|
name: NODEJS_EVENTLOOP_LAG,
|
|
404
438
|
help: 'Lag of event loop in seconds (setInterval based).',
|
|
405
|
-
buckets: [0.02, 0.1, 0.2, 0.5, 1, 3, 5],
|
|
439
|
+
buckets: [0.02, 0.1, 0.2, 0.5, 1, 3, 5, 7.5, 10],
|
|
406
440
|
});
|
|
407
441
|
startEventLoopLagMeasure(histogram);
|
|
408
442
|
};
|
|
@@ -416,7 +450,7 @@ MetricsModule = __decorate([
|
|
|
416
450
|
provide({
|
|
417
451
|
provide: METRICS_MODULE_CONFIG_TOKEN,
|
|
418
452
|
useValue: {
|
|
419
|
-
|
|
453
|
+
enableConnectionResolveMetrics: false,
|
|
420
454
|
},
|
|
421
455
|
}),
|
|
422
456
|
provide({
|
package/lib/server.js
CHANGED
|
@@ -82,7 +82,11 @@ const getUrlAndOptions = (args) => {
|
|
|
82
82
|
const urlWOQuery = parsedUrl.origin + parsedUrl.pathname;
|
|
83
83
|
return [urlWOQuery, options || {}];
|
|
84
84
|
};
|
|
85
|
-
|
|
85
|
+
// in seconds
|
|
86
|
+
const getDuration = (current, prev) =>
|
|
87
|
+
// max to avoid negative values and turn that into zero
|
|
88
|
+
prev === 0 ? 0 : Math.max((current - prev) / 1000, 0);
|
|
89
|
+
const createRequestWithMetrics = ({ metricsInstances: { requestsTotal, requestsErrors, requestsDuration, dnsResolveDuration, tcpConnectDuration, tlsHandshakeDuration, }, getServiceName, config, }) => function requestWithMetrics(originalRequest, ...args) {
|
|
86
90
|
const [url, options] = getUrlAndOptions(args);
|
|
87
91
|
const serviceName = getServiceName(url);
|
|
88
92
|
const req = originalRequest.apply(this, args);
|
|
@@ -108,17 +112,33 @@ const createRequestWithMetrics = ({ metricsInstances: { requestsTotal, requestsE
|
|
|
108
112
|
requestsErrors.inc(labelsValues);
|
|
109
113
|
timerDone(labelsValues);
|
|
110
114
|
});
|
|
111
|
-
if (config.
|
|
115
|
+
if (config.enableConnectionResolveMetrics) {
|
|
112
116
|
req.on('socket', (socket) => {
|
|
113
|
-
const
|
|
117
|
+
const timings = {
|
|
118
|
+
start: Date.now(),
|
|
119
|
+
lookupEnd: 0,
|
|
120
|
+
connectEnd: 0,
|
|
121
|
+
secureConnectEnd: 0,
|
|
122
|
+
};
|
|
123
|
+
const { service } = labelsValues;
|
|
114
124
|
socket.on('lookup', () => {
|
|
115
|
-
|
|
125
|
+
timings.lookupEnd = Date.now();
|
|
126
|
+
dnsResolveDuration.observe({ service }, getDuration(timings.lookupEnd, timings.start));
|
|
127
|
+
});
|
|
128
|
+
socket.on('connect', () => {
|
|
129
|
+
timings.connectEnd = Date.now();
|
|
130
|
+
tcpConnectDuration.observe({ service }, getDuration(timings.connectEnd, timings.lookupEnd));
|
|
131
|
+
});
|
|
132
|
+
socket.on('secureConnect', () => {
|
|
133
|
+
timings.secureConnectEnd = Date.now();
|
|
134
|
+
tlsHandshakeDuration.observe({ service }, getDuration(timings.secureConnectEnd, timings.connectEnd));
|
|
116
135
|
});
|
|
117
136
|
});
|
|
118
137
|
}
|
|
119
138
|
return req;
|
|
120
139
|
};
|
|
121
140
|
|
|
141
|
+
const DEFAULT_BUCKETS = [0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 20, 40, 60];
|
|
122
142
|
const initRequestsMetrics = ({ metrics, getServiceName, http, https, createRequestWithMetrics, config, }) => {
|
|
123
143
|
const metricsInstances = {
|
|
124
144
|
requestsTotal: metrics.counter({
|
|
@@ -135,11 +155,25 @@ const initRequestsMetrics = ({ metrics, getServiceName, http, https, createReque
|
|
|
135
155
|
name: 'http_sent_requests_duration',
|
|
136
156
|
help: 'Execution time of the sent requests',
|
|
137
157
|
labelNames: ['status', 'method', 'service'],
|
|
158
|
+
buckets: DEFAULT_BUCKETS,
|
|
138
159
|
}),
|
|
139
160
|
dnsResolveDuration: metrics.histogram({
|
|
140
161
|
name: 'dns_resolve_duration',
|
|
141
162
|
help: 'Time for dns resolve of the outhgoing requests',
|
|
142
163
|
labelNames: ['service'],
|
|
164
|
+
buckets: DEFAULT_BUCKETS,
|
|
165
|
+
}),
|
|
166
|
+
tcpConnectDuration: metrics.histogram({
|
|
167
|
+
name: 'tcp_connect_duration',
|
|
168
|
+
help: 'Duration of tcp connect of the outgoing requests',
|
|
169
|
+
labelNames: ['service'],
|
|
170
|
+
buckets: DEFAULT_BUCKETS,
|
|
171
|
+
}),
|
|
172
|
+
tlsHandshakeDuration: metrics.histogram({
|
|
173
|
+
name: 'tls_handshake_duration',
|
|
174
|
+
help: 'Duration of tls handshake of the outgoing requests',
|
|
175
|
+
labelNames: ['service'],
|
|
176
|
+
buckets: DEFAULT_BUCKETS,
|
|
143
177
|
}),
|
|
144
178
|
};
|
|
145
179
|
monkeypatch__default["default"]({
|
|
@@ -416,7 +450,7 @@ const eventLoopMetrics = (metrics) => {
|
|
|
416
450
|
const histogram = metrics.histogram({
|
|
417
451
|
name: NODEJS_EVENTLOOP_LAG,
|
|
418
452
|
help: 'Lag of event loop in seconds (setInterval based).',
|
|
419
|
-
buckets: [0.02, 0.1, 0.2, 0.5, 1, 3, 5],
|
|
453
|
+
buckets: [0.02, 0.1, 0.2, 0.5, 1, 3, 5, 7.5, 10],
|
|
420
454
|
});
|
|
421
455
|
startEventLoopLagMeasure(histogram);
|
|
422
456
|
};
|
|
@@ -430,7 +464,7 @@ exports.MetricsModule = tslib.__decorate([
|
|
|
430
464
|
core.provide({
|
|
431
465
|
provide: METRICS_MODULE_CONFIG_TOKEN,
|
|
432
466
|
useValue: {
|
|
433
|
-
|
|
467
|
+
enableConnectionResolveMetrics: false,
|
|
434
468
|
},
|
|
435
469
|
}),
|
|
436
470
|
core.provide({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tramvai/module-metrics",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.62.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"browser": "lib/browser.js",
|
|
6
6
|
"main": "lib/server.js",
|
|
@@ -19,13 +19,13 @@
|
|
|
19
19
|
"build-for-publish": "true"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@tramvai/core": "1.
|
|
23
|
-
"@tramvai/tokens-server": "1.
|
|
24
|
-
"@tramvai/tokens-metrics": "1.
|
|
25
|
-
"@tramvai/module-common": "1.
|
|
26
|
-
"@tramvai/tokens-http-client": "1.
|
|
27
|
-
"@tramvai/state": "1.
|
|
28
|
-
"@tramvai/papi": "1.
|
|
22
|
+
"@tramvai/core": "1.62.0",
|
|
23
|
+
"@tramvai/tokens-server": "1.62.0",
|
|
24
|
+
"@tramvai/tokens-metrics": "1.62.0",
|
|
25
|
+
"@tramvai/module-common": "1.62.0",
|
|
26
|
+
"@tramvai/tokens-http-client": "1.62.0",
|
|
27
|
+
"@tramvai/state": "1.62.0",
|
|
28
|
+
"@tramvai/papi": "1.62.0",
|
|
29
29
|
"@tinkoff/measure-express-requests": "1.4.2",
|
|
30
30
|
"@tinkoff/monkeypatch": "1.3.3",
|
|
31
31
|
"@tinkoff/url": "0.7.37",
|