@vtex/api 6.51.3 → 6.53.0-beta.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/CHANGELOG.md +33 -1
- package/lib/constants.d.ts +15 -0
- package/lib/constants.js +18 -1
- package/lib/metrics/DiagnosticsMetrics.d.ts +189 -0
- package/lib/metrics/DiagnosticsMetrics.js +342 -0
- package/lib/service/logger/client.js +0 -5
- package/lib/service/master.d.ts +2 -0
- package/lib/service/master.js +15 -3
- package/lib/service/metrics/client.d.ts +2 -0
- package/lib/service/metrics/client.js +38 -0
- package/lib/service/metrics/clusterMetricsAggregator.d.ts +72 -0
- package/lib/service/metrics/clusterMetricsAggregator.js +181 -0
- package/lib/service/metrics/instruments/hostMetrics.d.ts +14 -0
- package/lib/service/metrics/instruments/hostMetrics.js +33 -0
- package/lib/service/metrics/requestHandlerLabel.d.ts +26 -0
- package/lib/service/metrics/requestHandlerLabel.js +30 -0
- package/lib/service/metrics/requestMetricsMiddleware.js +5 -4
- package/lib/service/telemetry/client.d.ts +9 -1
- package/lib/service/telemetry/client.js +93 -27
- package/lib/service/telemetry/resourceAttributes.d.ts +1 -0
- package/lib/service/telemetry/resourceAttributes.js +21 -0
- package/lib/service/worker/index.d.ts +1 -0
- package/lib/service/worker/index.js +16 -4
- package/lib/service/worker/runtime/builtIn/middlewares.d.ts +1 -1
- package/lib/service/worker/runtime/builtIn/middlewares.js +7 -2
- package/lib/service/worker/runtime/statusTrack.js +4 -1
- package/package.json +7 -2
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getClusterResourceAttributes = void 0;
|
|
4
|
+
const constants_1 = require("../../constants");
|
|
5
|
+
const normalizeAttribute = (value) => {
|
|
6
|
+
const normalized = value === null || value === void 0 ? void 0 : value.trim();
|
|
7
|
+
return normalized || undefined;
|
|
8
|
+
};
|
|
9
|
+
const getClusterResourceAttributes = (clusterId, clusterRole) => {
|
|
10
|
+
const attributes = {};
|
|
11
|
+
const normalizedClusterId = normalizeAttribute(clusterId);
|
|
12
|
+
const normalizedClusterRole = normalizeAttribute(clusterRole);
|
|
13
|
+
if (normalizedClusterId) {
|
|
14
|
+
attributes[constants_1.AttributeKeys.VTEX_IO_CLUSTER_ID] = normalizedClusterId;
|
|
15
|
+
}
|
|
16
|
+
if (normalizedClusterRole) {
|
|
17
|
+
attributes[constants_1.AttributeKeys.VTEX_IO_CLUSTER_ROLE] = normalizedClusterRole;
|
|
18
|
+
}
|
|
19
|
+
return attributes;
|
|
20
|
+
};
|
|
21
|
+
exports.getClusterResourceAttributes = getClusterResourceAttributes;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Koa from 'koa';
|
|
2
2
|
import { MetricsAccumulator } from '../../metrics/MetricsAccumulator';
|
|
3
3
|
import { ServiceJSON } from './runtime/typings';
|
|
4
|
+
export declare const onMessage: (service: ServiceJSON) => (message: any) => void;
|
|
4
5
|
export declare const startWorker: (serviceJSON: ServiceJSON) => Koa<Koa.DefaultState, Koa.DefaultContext>;
|
|
5
6
|
declare global {
|
|
6
7
|
namespace NodeJS {
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.startWorker = void 0;
|
|
6
|
+
exports.startWorker = exports.onMessage = void 0;
|
|
7
7
|
const http_1 = require("http");
|
|
8
8
|
const koa_1 = __importDefault(require("koa"));
|
|
9
9
|
const koa_compress_1 = __importDefault(require("koa-compress"));
|
|
@@ -14,6 +14,7 @@ const MetricsAccumulator_1 = require("../../metrics/MetricsAccumulator");
|
|
|
14
14
|
const loaders_1 = require("../loaders");
|
|
15
15
|
const console_1 = require("../logger/console");
|
|
16
16
|
const loggerTypes_1 = require("../logger/loggerTypes");
|
|
17
|
+
const clusterMetricsAggregator_1 = require("../metrics/clusterMetricsAggregator");
|
|
17
18
|
const requestMetricsMiddleware_1 = require("../metrics/requestMetricsMiddleware");
|
|
18
19
|
const TracerSingleton_1 = require("../tracing/TracerSingleton");
|
|
19
20
|
const tracingMiddlewares_1 = require("../tracing/tracingMiddlewares");
|
|
@@ -54,7 +55,12 @@ const onMessage = (service) => (message) => {
|
|
|
54
55
|
else if ((0, statusTrack_1.isStatusTrack)(message)) {
|
|
55
56
|
(0, statusTrack_1.trackStatus)();
|
|
56
57
|
}
|
|
57
|
-
else {
|
|
58
|
+
else if ((0, clusterMetricsAggregator_1.isAggMetricsResponse)(message)) {
|
|
59
|
+
(0, clusterMetricsAggregator_1.handleMasterMetricsResponse)(message);
|
|
60
|
+
}
|
|
61
|
+
else if (!(0, clusterMetricsAggregator_1.isPromClientMessage)(message)) {
|
|
62
|
+
// prom-client's own cluster messages are handled by its worker listener;
|
|
63
|
+
// anything else that reaches here is genuinely unexpected.
|
|
58
64
|
listeners_1.logger.warn({
|
|
59
65
|
content: message,
|
|
60
66
|
message: 'Master sent message',
|
|
@@ -62,6 +68,7 @@ const onMessage = (service) => (message) => {
|
|
|
62
68
|
});
|
|
63
69
|
}
|
|
64
70
|
};
|
|
71
|
+
exports.onMessage = onMessage;
|
|
65
72
|
const createAppHttpHandlers = ({ config: { routes, clients } }, serviceJSON, globalLimiter) => {
|
|
66
73
|
if (routes && clients) {
|
|
67
74
|
return Object.keys(routes).reduce((acc, routeId) => {
|
|
@@ -153,11 +160,16 @@ const startWorker = (serviceJSON) => {
|
|
|
153
160
|
var _a, _b;
|
|
154
161
|
(0, listeners_1.addProcessListeners)();
|
|
155
162
|
const tracer = TracerSingleton_1.TracerSingleton.getTracer();
|
|
163
|
+
// In multi-worker mode install prom-client's worker-side cluster responder so
|
|
164
|
+
// the master can collect this worker's registry for the aggregated /metrics.
|
|
165
|
+
if (serviceJSON.workers > 1) {
|
|
166
|
+
(0, clusterMetricsAggregator_1.ensureWorkerAggregatorRegistry)();
|
|
167
|
+
}
|
|
156
168
|
const app = new koa_1.default();
|
|
157
169
|
app.proxy = true;
|
|
158
170
|
app
|
|
159
171
|
.use(error_1.error)
|
|
160
|
-
.use((0, middlewares_1.prometheusLoggerMiddleware)())
|
|
172
|
+
.use((0, middlewares_1.prometheusLoggerMiddleware)(serviceJSON.workers))
|
|
161
173
|
.use((0, tracingMiddlewares_1.addTracingMiddleware)(tracer))
|
|
162
174
|
.use((0, requestMetricsMiddleware_1.addRequestMetricsMiddleware)())
|
|
163
175
|
.use((0, middlewares_1.addMetricsLoggerMiddleware)())
|
|
@@ -190,7 +202,7 @@ const startWorker = (serviceJSON) => {
|
|
|
190
202
|
const privateHandlersRouter = routerFromPrivateHttpHandlers(httpHandlers.pvt);
|
|
191
203
|
app.use(privateHandlersRouter.routes());
|
|
192
204
|
}
|
|
193
|
-
process.on('message', onMessage(serviceJSON));
|
|
205
|
+
process.on('message', (0, exports.onMessage)(serviceJSON));
|
|
194
206
|
return app;
|
|
195
207
|
};
|
|
196
208
|
exports.startWorker = startWorker;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { ServiceContext } from '../typings';
|
|
2
2
|
export declare function recorderMiddleware(ctx: ServiceContext, next: () => Promise<void>): Promise<void>;
|
|
3
3
|
export declare const addMetricsLoggerMiddleware: () => (ctx: ServiceContext, next: () => Promise<void>) => Promise<void>;
|
|
4
|
-
export declare const prometheusLoggerMiddleware: () => (ctx: ServiceContext, next: () => Promise<void>) => Promise<void>;
|
|
4
|
+
export declare const prometheusLoggerMiddleware: (workers?: number) => (ctx: ServiceContext, next: () => Promise<void>) => Promise<void>;
|
|
@@ -4,6 +4,7 @@ exports.prometheusLoggerMiddleware = exports.addMetricsLoggerMiddleware = export
|
|
|
4
4
|
const prom_client_1 = require("prom-client");
|
|
5
5
|
const constants_1 = require("../../../../constants");
|
|
6
6
|
const metricsLogger_1 = require("../../../logger/metricsLogger");
|
|
7
|
+
const clusterMetricsAggregator_1 = require("../../../metrics/clusterMetricsAggregator");
|
|
7
8
|
const EventLoopLagMeasurer_1 = require("../../../tracing/metrics/measurers/EventLoopLagMeasurer");
|
|
8
9
|
const recorder_1 = require("../utils/recorder");
|
|
9
10
|
async function recorderMiddleware(ctx, next) {
|
|
@@ -22,10 +23,14 @@ const addMetricsLoggerMiddleware = () => {
|
|
|
22
23
|
};
|
|
23
24
|
};
|
|
24
25
|
exports.addMetricsLoggerMiddleware = addMetricsLoggerMiddleware;
|
|
25
|
-
const prometheusLoggerMiddleware = () => {
|
|
26
|
+
const prometheusLoggerMiddleware = (workers = 1) => {
|
|
26
27
|
(0, prom_client_1.collectDefaultMetrics)();
|
|
27
28
|
const eventLoopLagMeasurer = new EventLoopLagMeasurer_1.EventLoopLagMeasurer();
|
|
28
29
|
eventLoopLagMeasurer.start();
|
|
30
|
+
// In multi-worker mode each worker holds only its own registry, so /metrics
|
|
31
|
+
// must serve the cluster-wide aggregate requested from the master over IPC.
|
|
32
|
+
// In single-worker mode (LINKED / workers:1) the local registry is complete.
|
|
33
|
+
const isMultiWorker = workers > 1;
|
|
29
34
|
return async (ctx, next) => {
|
|
30
35
|
if (ctx.request.path !== '/metrics') {
|
|
31
36
|
return next();
|
|
@@ -36,7 +41,7 @@ const prometheusLoggerMiddleware = () => {
|
|
|
36
41
|
}
|
|
37
42
|
await eventLoopLagMeasurer.updateInstrumentsAndReset();
|
|
38
43
|
ctx.set('Content-Type', prom_client_1.register.contentType);
|
|
39
|
-
ctx.body = await prom_client_1.register.metrics();
|
|
44
|
+
ctx.body = isMultiWorker ? await (0, clusterMetricsAggregator_1.requestAggregatedMetrics)() : await prom_client_1.register.metrics();
|
|
40
45
|
ctx.status = 200;
|
|
41
46
|
};
|
|
42
47
|
};
|
|
@@ -14,7 +14,10 @@ const isStatusTrackBroadcast = (message) => message === BROADCAST_STATUS_TRACK;
|
|
|
14
14
|
exports.isStatusTrackBroadcast = isStatusTrackBroadcast;
|
|
15
15
|
const statusTrackHandler = async (ctx) => {
|
|
16
16
|
var _a, _b, _c;
|
|
17
|
-
|
|
17
|
+
// Parity with the other builtin handlers: name the request so its samples don't
|
|
18
|
+
// land in the catch-all `handler="undefined"` bucket.
|
|
19
|
+
ctx.requestHandlerName = 'builtin:status-track';
|
|
20
|
+
(_b = (_a = ctx.tracing) === null || _a === void 0 ? void 0 : _a.currentSpan) === null || _b === void 0 ? void 0 : _b.setOperationName(ctx.requestHandlerName);
|
|
18
21
|
if (!constants_1.LINKED) {
|
|
19
22
|
(_c = process.send) === null || _c === void 0 ? void 0 : _c.call(process, BROADCAST_STATUS_TRACK);
|
|
20
23
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vtex/api",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.53.0-beta.0",
|
|
4
4
|
"description": "VTEX I/O API client",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
@@ -47,9 +47,14 @@
|
|
|
47
47
|
},
|
|
48
48
|
"license": "MIT",
|
|
49
49
|
"dependencies": {
|
|
50
|
+
"@opentelemetry/api": "^1.9.0",
|
|
51
|
+
"@opentelemetry/host-metrics": "0.35.5",
|
|
52
|
+
"@opentelemetry/instrumentation": "0.57.2",
|
|
53
|
+
"@opentelemetry/instrumentation-koa": "0.47.1",
|
|
50
54
|
"@types/koa": "^2.11.0",
|
|
51
55
|
"@types/koa-compose": "^3.2.3",
|
|
52
|
-
"@vtex/diagnostics-nodejs": "0.1.
|
|
56
|
+
"@vtex/diagnostics-nodejs": "0.1.8-io",
|
|
57
|
+
"@vtex/diagnostics-semconv": "5.5.2",
|
|
53
58
|
"@vtex/node-error-report": "^0.0.3",
|
|
54
59
|
"@wry/equality": "^0.1.9",
|
|
55
60
|
"agentkeepalive": "^4.0.2",
|