apitally 0.21.2 → 0.21.4
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/adonisjs/configure.cjs +6 -21
- package/dist/adonisjs/configure.cjs.map +1 -1
- package/dist/adonisjs/configure.js +3 -18
- package/dist/adonisjs/configure.js.map +1 -1
- package/dist/adonisjs/index.cjs +2 -70
- package/dist/adonisjs/index.cjs.map +1 -1
- package/dist/adonisjs/index.js +1 -66
- package/dist/adonisjs/index.js.map +1 -1
- package/dist/adonisjs/middleware.cjs +11 -116
- package/dist/adonisjs/middleware.cjs.map +1 -1
- package/dist/adonisjs/middleware.js +6 -101
- package/dist/adonisjs/middleware.js.map +1 -1
- package/dist/adonisjs/provider.cjs +15 -5663
- package/dist/adonisjs/provider.cjs.map +1 -1
- package/dist/adonisjs/provider.js +7 -5671
- package/dist/adonisjs/provider.js.map +1 -1
- package/dist/common/client.cjs +39 -800
- package/dist/common/client.cjs.map +1 -1
- package/dist/common/client.d.cts +1 -1
- package/dist/common/client.d.ts +1 -1
- package/dist/common/client.js +33 -794
- package/dist/common/client.js.map +1 -1
- package/dist/common/consumerRegistry.cjs +3 -5
- package/dist/common/consumerRegistry.cjs.map +1 -1
- package/dist/common/consumerRegistry.js +3 -5
- package/dist/common/consumerRegistry.js.map +1 -1
- package/dist/common/headers.cjs +0 -2
- package/dist/common/headers.cjs.map +1 -1
- package/dist/common/headers.js +0 -2
- package/dist/common/headers.js.map +1 -1
- package/dist/common/logging.cjs +0 -2
- package/dist/common/logging.cjs.map +1 -1
- package/dist/common/logging.js +0 -2
- package/dist/common/logging.js.map +1 -1
- package/dist/common/packageVersions.cjs +2 -4
- package/dist/common/packageVersions.cjs.map +1 -1
- package/dist/common/packageVersions.js +2 -10
- package/dist/common/packageVersions.js.map +1 -1
- package/dist/common/paramValidation.cjs +0 -2
- package/dist/common/paramValidation.cjs.map +1 -1
- package/dist/common/paramValidation.js +0 -2
- package/dist/common/paramValidation.js.map +1 -1
- package/dist/common/requestCounter.cjs +2 -4
- package/dist/common/requestCounter.cjs.map +1 -1
- package/dist/common/requestCounter.js +2 -4
- package/dist/common/requestCounter.js.map +1 -1
- package/dist/common/requestLogger.cjs +39 -162
- package/dist/common/requestLogger.cjs.map +1 -1
- package/dist/common/requestLogger.js +33 -156
- package/dist/common/requestLogger.js.map +1 -1
- package/dist/common/response.cjs +21 -4
- package/dist/common/response.cjs.map +1 -1
- package/dist/common/response.d.cts +2 -1
- package/dist/common/response.d.ts +2 -1
- package/dist/common/response.js +19 -3
- package/dist/common/response.js.map +1 -1
- package/dist/common/sentry.cjs +1 -3
- package/dist/common/sentry.cjs.map +1 -1
- package/dist/common/sentry.js +1 -3
- package/dist/common/sentry.js.map +1 -1
- package/dist/common/serverErrorCounter.cjs +7 -36
- package/dist/common/serverErrorCounter.cjs.map +1 -1
- package/dist/common/serverErrorCounter.js +6 -25
- package/dist/common/serverErrorCounter.js.map +1 -1
- package/dist/common/tempGzipFile.cjs +9 -11
- package/dist/common/tempGzipFile.cjs.map +1 -1
- package/dist/common/tempGzipFile.js +9 -11
- package/dist/common/tempGzipFile.js.map +1 -1
- package/dist/common/types.cjs +0 -2
- package/dist/common/types.cjs.map +1 -1
- package/dist/common/validationErrorCounter.cjs +3 -5
- package/dist/common/validationErrorCounter.cjs.map +1 -1
- package/dist/common/validationErrorCounter.js +3 -5
- package/dist/common/validationErrorCounter.js.map +1 -1
- package/dist/elysia/index.cjs +2 -1549
- package/dist/elysia/index.cjs.map +1 -1
- package/dist/elysia/index.js +2 -1553
- package/dist/elysia/index.js.map +1 -1
- package/dist/elysia/plugin.cjs +33 -1415
- package/dist/elysia/plugin.cjs.map +1 -1
- package/dist/elysia/plugin.js +22 -1399
- package/dist/elysia/plugin.js.map +1 -1
- package/dist/elysia/utils.cjs +3 -24
- package/dist/elysia/utils.cjs.map +1 -1
- package/dist/elysia/utils.js +1 -25
- package/dist/elysia/utils.js.map +1 -1
- package/dist/express/index.cjs +3 -6348
- package/dist/express/index.cjs.map +1 -1
- package/dist/express/index.js +1 -6361
- package/dist/express/index.js.map +1 -1
- package/dist/express/middleware.cjs +39 -6065
- package/dist/express/middleware.cjs.map +1 -1
- package/dist/express/middleware.js +14 -6056
- package/dist/express/middleware.js.map +1 -1
- package/dist/express/utils.cjs +17 -19
- package/dist/express/utils.cjs.map +1 -1
- package/dist/express/utils.js +17 -19
- package/dist/express/utils.js.map +1 -1
- package/dist/fastify/index.cjs +3 -6118
- package/dist/fastify/index.cjs.map +1 -1
- package/dist/fastify/index.js +2 -6142
- package/dist/fastify/index.js.map +1 -1
- package/dist/fastify/plugin.cjs +36 -5884
- package/dist/fastify/plugin.cjs.map +1 -1
- package/dist/fastify/plugin.js +14 -5888
- package/dist/fastify/plugin.js.map +1 -1
- package/dist/h3/index.cjs +3 -1539
- package/dist/h3/index.cjs.map +1 -1
- package/dist/h3/index.js +1 -1531
- package/dist/h3/index.js.map +1 -1
- package/dist/h3/plugin.cjs +28 -1418
- package/dist/h3/plugin.cjs.map +1 -1
- package/dist/h3/plugin.js +16 -1401
- package/dist/h3/plugin.js.map +1 -1
- package/dist/h3/utils.cjs +3 -24
- package/dist/h3/utils.cjs.map +1 -1
- package/dist/h3/utils.js +1 -25
- package/dist/h3/utils.js.map +1 -1
- package/dist/hapi/index.cjs +3 -5982
- package/dist/hapi/index.cjs.map +1 -1
- package/dist/hapi/index.js +2 -6006
- package/dist/hapi/index.js.map +1 -1
- package/dist/hapi/plugin.cjs +28 -5842
- package/dist/hapi/plugin.cjs.map +1 -1
- package/dist/hapi/plugin.js +16 -5846
- package/dist/hapi/plugin.js.map +1 -1
- package/dist/hapi/utils.cjs +3 -24
- package/dist/hapi/utils.cjs.map +1 -1
- package/dist/hapi/utils.js +1 -25
- package/dist/hapi/utils.js.map +1 -1
- package/dist/hono/index.cjs +3 -1565
- package/dist/hono/index.cjs.map +1 -1
- package/dist/hono/index.js +1 -1557
- package/dist/hono/index.js.map +1 -1
- package/dist/hono/middleware.cjs +22 -1455
- package/dist/hono/middleware.cjs.map +1 -1
- package/dist/hono/middleware.js +10 -1438
- package/dist/hono/middleware.js.map +1 -1
- package/dist/hono/utils.cjs +3 -24
- package/dist/hono/utils.cjs.map +1 -1
- package/dist/hono/utils.js +1 -27
- package/dist/hono/utils.js.map +1 -1
- package/dist/koa/index.cjs +3 -1478
- package/dist/koa/index.cjs.map +1 -1
- package/dist/koa/index.js +1 -1470
- package/dist/koa/index.js.map +1 -1
- package/dist/koa/middleware.cjs +20 -1308
- package/dist/koa/middleware.cjs.map +1 -1
- package/dist/koa/middleware.js +9 -1292
- package/dist/koa/middleware.js.map +1 -1
- package/dist/loggers/console.cjs +4 -6
- package/dist/loggers/console.cjs.map +1 -1
- package/dist/loggers/console.js +4 -6
- package/dist/loggers/console.js.map +1 -1
- package/dist/loggers/hapi.cjs +3 -5
- package/dist/loggers/hapi.cjs.map +1 -1
- package/dist/loggers/hapi.js +3 -5
- package/dist/loggers/hapi.js.map +1 -1
- package/dist/loggers/index.cjs +10 -4732
- package/dist/loggers/index.cjs.map +1 -1
- package/dist/loggers/index.js +5 -4743
- package/dist/loggers/index.js.map +1 -1
- package/dist/loggers/nestjs.cjs +5 -39
- package/dist/loggers/nestjs.cjs.map +1 -1
- package/dist/loggers/nestjs.js +4 -36
- package/dist/loggers/nestjs.js.map +1 -1
- package/dist/loggers/pino.cjs +29 -4448
- package/dist/loggers/pino.cjs.map +1 -1
- package/dist/loggers/pino.js +7 -4451
- package/dist/loggers/pino.js.map +1 -1
- package/dist/loggers/utils.cjs +1 -3
- package/dist/loggers/utils.cjs.map +1 -1
- package/dist/loggers/utils.js +1 -3
- package/dist/loggers/utils.js.map +1 -1
- package/dist/loggers/winston.cjs +6 -44
- package/dist/loggers/winston.cjs.map +1 -1
- package/dist/loggers/winston.js +4 -40
- package/dist/loggers/winston.js.map +1 -1
- package/dist/nestjs/index.cjs +17 -17779
- package/dist/nestjs/index.cjs.map +1 -1
- package/dist/nestjs/index.js +20 -17807
- package/dist/nestjs/index.js.map +1 -1
- package/package.json +1 -1
package/dist/common/client.cjs
CHANGED
|
@@ -29,792 +29,26 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
29
29
|
));
|
|
30
30
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
31
31
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
32
|
-
|
|
33
|
-
// src/common/client.ts
|
|
34
32
|
var client_exports = {};
|
|
35
33
|
__export(client_exports, {
|
|
36
34
|
ApitallyClient: () => ApitallyClient
|
|
37
35
|
});
|
|
38
36
|
module.exports = __toCommonJS(client_exports);
|
|
39
37
|
var import_fetch_retry = __toESM(require("fetch-retry"), 1);
|
|
40
|
-
var
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
var
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
this.updated = /* @__PURE__ */ new Set();
|
|
49
|
-
}
|
|
50
|
-
addOrUpdateConsumer(consumer) {
|
|
51
|
-
if (!consumer || !consumer.name && !consumer.group) {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
const existing = this.consumers.get(consumer.identifier);
|
|
55
|
-
if (!existing) {
|
|
56
|
-
this.consumers.set(consumer.identifier, consumer);
|
|
57
|
-
this.updated.add(consumer.identifier);
|
|
58
|
-
} else {
|
|
59
|
-
if (consumer.name && consumer.name !== existing.name) {
|
|
60
|
-
existing.name = consumer.name;
|
|
61
|
-
this.updated.add(consumer.identifier);
|
|
62
|
-
}
|
|
63
|
-
if (consumer.group && consumer.group !== existing.group) {
|
|
64
|
-
existing.group = consumer.group;
|
|
65
|
-
this.updated.add(consumer.identifier);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
getAndResetUpdatedConsumers() {
|
|
70
|
-
const data = [];
|
|
71
|
-
this.updated.forEach((identifier) => {
|
|
72
|
-
const consumer = this.consumers.get(identifier);
|
|
73
|
-
if (consumer) {
|
|
74
|
-
data.push(consumer);
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
this.updated.clear();
|
|
78
|
-
return data;
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
__name(_ConsumerRegistry, "ConsumerRegistry");
|
|
82
|
-
var ConsumerRegistry = _ConsumerRegistry;
|
|
83
|
-
|
|
84
|
-
// src/common/logging.ts
|
|
85
|
-
var import_winston = require("winston");
|
|
86
|
-
function getLogger() {
|
|
87
|
-
return (0, import_winston.createLogger)({
|
|
88
|
-
level: process.env.APITALLY_DEBUG ? "debug" : "warn",
|
|
89
|
-
format: import_winston.format.combine(import_winston.format.colorize(), import_winston.format.timestamp(), import_winston.format.printf((info) => `${info.timestamp} ${info.level}: ${info.message}`)),
|
|
90
|
-
transports: [
|
|
91
|
-
new import_winston.transports.Console()
|
|
92
|
-
]
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
__name(getLogger, "getLogger");
|
|
96
|
-
|
|
97
|
-
// src/common/paramValidation.ts
|
|
98
|
-
function isValidClientId(clientId) {
|
|
99
|
-
const regexExp = /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
100
|
-
return regexExp.test(clientId);
|
|
101
|
-
}
|
|
102
|
-
__name(isValidClientId, "isValidClientId");
|
|
103
|
-
function isValidEnv(env) {
|
|
104
|
-
const regexExp = /^[\w-]{1,32}$/;
|
|
105
|
-
return regexExp.test(env);
|
|
106
|
-
}
|
|
107
|
-
__name(isValidEnv, "isValidEnv");
|
|
108
|
-
|
|
109
|
-
// src/common/requestCounter.ts
|
|
110
|
-
var _RequestCounter = class _RequestCounter {
|
|
111
|
-
requestCounts;
|
|
112
|
-
requestSizeSums;
|
|
113
|
-
responseSizeSums;
|
|
114
|
-
responseTimes;
|
|
115
|
-
requestSizes;
|
|
116
|
-
responseSizes;
|
|
117
|
-
constructor() {
|
|
118
|
-
this.requestCounts = /* @__PURE__ */ new Map();
|
|
119
|
-
this.requestSizeSums = /* @__PURE__ */ new Map();
|
|
120
|
-
this.responseSizeSums = /* @__PURE__ */ new Map();
|
|
121
|
-
this.responseTimes = /* @__PURE__ */ new Map();
|
|
122
|
-
this.requestSizes = /* @__PURE__ */ new Map();
|
|
123
|
-
this.responseSizes = /* @__PURE__ */ new Map();
|
|
124
|
-
}
|
|
125
|
-
getKey(requestInfo) {
|
|
126
|
-
return [
|
|
127
|
-
requestInfo.consumer || "",
|
|
128
|
-
requestInfo.method.toUpperCase(),
|
|
129
|
-
requestInfo.path,
|
|
130
|
-
requestInfo.statusCode
|
|
131
|
-
].join("|");
|
|
132
|
-
}
|
|
133
|
-
addRequest(requestInfo) {
|
|
134
|
-
const key = this.getKey(requestInfo);
|
|
135
|
-
this.requestCounts.set(key, (this.requestCounts.get(key) || 0) + 1);
|
|
136
|
-
if (!this.responseTimes.has(key)) {
|
|
137
|
-
this.responseTimes.set(key, /* @__PURE__ */ new Map());
|
|
138
|
-
}
|
|
139
|
-
const responseTimeMap = this.responseTimes.get(key);
|
|
140
|
-
const responseTimeMsBin = Math.floor(requestInfo.responseTime / 10) * 10;
|
|
141
|
-
responseTimeMap.set(responseTimeMsBin, (responseTimeMap.get(responseTimeMsBin) || 0) + 1);
|
|
142
|
-
if (requestInfo.requestSize !== void 0) {
|
|
143
|
-
requestInfo.requestSize = Number(requestInfo.requestSize);
|
|
144
|
-
this.requestSizeSums.set(key, (this.requestSizeSums.get(key) || 0) + requestInfo.requestSize);
|
|
145
|
-
if (!this.requestSizes.has(key)) {
|
|
146
|
-
this.requestSizes.set(key, /* @__PURE__ */ new Map());
|
|
147
|
-
}
|
|
148
|
-
const requestSizeMap = this.requestSizes.get(key);
|
|
149
|
-
const requestSizeKbBin = Math.floor(requestInfo.requestSize / 1e3);
|
|
150
|
-
requestSizeMap.set(requestSizeKbBin, (requestSizeMap.get(requestSizeKbBin) || 0) + 1);
|
|
151
|
-
}
|
|
152
|
-
if (requestInfo.responseSize !== void 0) {
|
|
153
|
-
requestInfo.responseSize = Number(requestInfo.responseSize);
|
|
154
|
-
this.responseSizeSums.set(key, (this.responseSizeSums.get(key) || 0) + requestInfo.responseSize);
|
|
155
|
-
if (!this.responseSizes.has(key)) {
|
|
156
|
-
this.responseSizes.set(key, /* @__PURE__ */ new Map());
|
|
157
|
-
}
|
|
158
|
-
const responseSizeMap = this.responseSizes.get(key);
|
|
159
|
-
const responseSizeKbBin = Math.floor(requestInfo.responseSize / 1e3);
|
|
160
|
-
responseSizeMap.set(responseSizeKbBin, (responseSizeMap.get(responseSizeKbBin) || 0) + 1);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
getAndResetRequests() {
|
|
164
|
-
const data = [];
|
|
165
|
-
this.requestCounts.forEach((count, key) => {
|
|
166
|
-
const [consumer, method, path, statusCodeStr] = key.split("|");
|
|
167
|
-
const responseTimes = this.responseTimes.get(key) || /* @__PURE__ */ new Map();
|
|
168
|
-
const requestSizes = this.requestSizes.get(key) || /* @__PURE__ */ new Map();
|
|
169
|
-
const responseSizes = this.responseSizes.get(key) || /* @__PURE__ */ new Map();
|
|
170
|
-
data.push({
|
|
171
|
-
consumer: consumer || null,
|
|
172
|
-
method,
|
|
173
|
-
path,
|
|
174
|
-
status_code: parseInt(statusCodeStr),
|
|
175
|
-
request_count: count,
|
|
176
|
-
request_size_sum: this.requestSizeSums.get(key) || 0,
|
|
177
|
-
response_size_sum: this.responseSizeSums.get(key) || 0,
|
|
178
|
-
response_times: Object.fromEntries(responseTimes),
|
|
179
|
-
request_sizes: Object.fromEntries(requestSizes),
|
|
180
|
-
response_sizes: Object.fromEntries(responseSizes)
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
this.requestCounts.clear();
|
|
184
|
-
this.requestSizeSums.clear();
|
|
185
|
-
this.responseSizeSums.clear();
|
|
186
|
-
this.responseTimes.clear();
|
|
187
|
-
this.requestSizes.clear();
|
|
188
|
-
this.responseSizes.clear();
|
|
189
|
-
return data;
|
|
190
|
-
}
|
|
191
|
-
};
|
|
192
|
-
__name(_RequestCounter, "RequestCounter");
|
|
193
|
-
var RequestCounter = _RequestCounter;
|
|
194
|
-
|
|
195
|
-
// src/common/requestLogger.ts
|
|
196
|
-
var import_async_lock = __toESM(require("async-lock"), 1);
|
|
197
|
-
var import_node_buffer2 = require("buffer");
|
|
198
|
-
var import_node_crypto3 = require("crypto");
|
|
199
|
-
var import_node_fs2 = require("fs");
|
|
200
|
-
var import_node_os2 = require("os");
|
|
201
|
-
var import_node_path2 = require("path");
|
|
202
|
-
|
|
203
|
-
// src/common/sentry.ts
|
|
204
|
-
var sentry;
|
|
205
|
-
(async () => {
|
|
206
|
-
try {
|
|
207
|
-
sentry = await import("@sentry/node");
|
|
208
|
-
} catch (e) {
|
|
209
|
-
}
|
|
210
|
-
})();
|
|
211
|
-
function getSentryEventId() {
|
|
212
|
-
if (sentry && sentry.lastEventId) {
|
|
213
|
-
return sentry.lastEventId();
|
|
214
|
-
}
|
|
215
|
-
return void 0;
|
|
216
|
-
}
|
|
217
|
-
__name(getSentryEventId, "getSentryEventId");
|
|
218
|
-
|
|
219
|
-
// src/common/serverErrorCounter.ts
|
|
220
|
-
var import_node_crypto = require("crypto");
|
|
221
|
-
var MAX_MSG_LENGTH = 2048;
|
|
222
|
-
var MAX_STACKTRACE_LENGTH = 65536;
|
|
223
|
-
var _ServerErrorCounter = class _ServerErrorCounter {
|
|
224
|
-
errorCounts;
|
|
225
|
-
errorDetails;
|
|
226
|
-
sentryEventIds;
|
|
227
|
-
constructor() {
|
|
228
|
-
this.errorCounts = /* @__PURE__ */ new Map();
|
|
229
|
-
this.errorDetails = /* @__PURE__ */ new Map();
|
|
230
|
-
this.sentryEventIds = /* @__PURE__ */ new Map();
|
|
231
|
-
}
|
|
232
|
-
addServerError(serverError) {
|
|
233
|
-
const key = this.getKey(serverError);
|
|
234
|
-
if (!this.errorDetails.has(key)) {
|
|
235
|
-
this.errorDetails.set(key, serverError);
|
|
236
|
-
}
|
|
237
|
-
this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);
|
|
238
|
-
const sentryEventId = getSentryEventId();
|
|
239
|
-
if (sentryEventId) {
|
|
240
|
-
this.sentryEventIds.set(key, sentryEventId);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
getAndResetServerErrors() {
|
|
244
|
-
const data = [];
|
|
245
|
-
this.errorCounts.forEach((count, key) => {
|
|
246
|
-
const serverError = this.errorDetails.get(key);
|
|
247
|
-
if (serverError) {
|
|
248
|
-
data.push({
|
|
249
|
-
consumer: serverError.consumer || null,
|
|
250
|
-
method: serverError.method,
|
|
251
|
-
path: serverError.path,
|
|
252
|
-
type: serverError.type,
|
|
253
|
-
msg: truncateExceptionMessage(serverError.msg),
|
|
254
|
-
traceback: truncateExceptionStackTrace(serverError.traceback),
|
|
255
|
-
sentry_event_id: this.sentryEventIds.get(key) || null,
|
|
256
|
-
error_count: count
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
});
|
|
260
|
-
this.errorCounts.clear();
|
|
261
|
-
this.errorDetails.clear();
|
|
262
|
-
this.sentryEventIds.clear();
|
|
263
|
-
return data;
|
|
264
|
-
}
|
|
265
|
-
getKey(serverError) {
|
|
266
|
-
const hashInput = [
|
|
267
|
-
serverError.consumer || "",
|
|
268
|
-
serverError.method.toUpperCase(),
|
|
269
|
-
serverError.path,
|
|
270
|
-
serverError.type,
|
|
271
|
-
serverError.msg.trim(),
|
|
272
|
-
serverError.traceback.trim()
|
|
273
|
-
].join("|");
|
|
274
|
-
return (0, import_node_crypto.createHash)("md5").update(hashInput).digest("hex");
|
|
275
|
-
}
|
|
276
|
-
};
|
|
277
|
-
__name(_ServerErrorCounter, "ServerErrorCounter");
|
|
278
|
-
var ServerErrorCounter = _ServerErrorCounter;
|
|
279
|
-
function truncateExceptionMessage(msg) {
|
|
280
|
-
if (msg.length <= MAX_MSG_LENGTH) {
|
|
281
|
-
return msg;
|
|
282
|
-
}
|
|
283
|
-
const suffix = "... (truncated)";
|
|
284
|
-
const cutoff = MAX_MSG_LENGTH - suffix.length;
|
|
285
|
-
return msg.substring(0, cutoff) + suffix;
|
|
286
|
-
}
|
|
287
|
-
__name(truncateExceptionMessage, "truncateExceptionMessage");
|
|
288
|
-
function truncateExceptionStackTrace(stack) {
|
|
289
|
-
const suffix = "... (truncated) ...";
|
|
290
|
-
const cutoff = MAX_STACKTRACE_LENGTH - suffix.length;
|
|
291
|
-
const lines = stack.trim().split("\n");
|
|
292
|
-
const truncatedLines = [];
|
|
293
|
-
let length = 0;
|
|
294
|
-
for (const line of lines) {
|
|
295
|
-
if (length + line.length + 1 > cutoff) {
|
|
296
|
-
truncatedLines.push(suffix);
|
|
297
|
-
break;
|
|
298
|
-
}
|
|
299
|
-
truncatedLines.push(line);
|
|
300
|
-
length += line.length + 1;
|
|
301
|
-
}
|
|
302
|
-
return truncatedLines.join("\n");
|
|
303
|
-
}
|
|
304
|
-
__name(truncateExceptionStackTrace, "truncateExceptionStackTrace");
|
|
305
|
-
|
|
306
|
-
// src/common/tempGzipFile.ts
|
|
307
|
-
var import_node_buffer = require("buffer");
|
|
308
|
-
var import_node_crypto2 = require("crypto");
|
|
309
|
-
var import_node_fs = require("fs");
|
|
310
|
-
var import_promises = require("fs/promises");
|
|
311
|
-
var import_node_os = require("os");
|
|
312
|
-
var import_node_path = require("path");
|
|
313
|
-
var import_node_zlib = require("zlib");
|
|
314
|
-
var _TempGzipFile = class _TempGzipFile {
|
|
315
|
-
uuid;
|
|
316
|
-
filePath;
|
|
317
|
-
gzip;
|
|
318
|
-
writeStream;
|
|
319
|
-
readyPromise;
|
|
320
|
-
closedPromise;
|
|
321
|
-
constructor() {
|
|
322
|
-
this.uuid = (0, import_node_crypto2.randomUUID)();
|
|
323
|
-
this.filePath = (0, import_node_path.join)((0, import_node_os.tmpdir)(), `apitally-${this.uuid}.gz`);
|
|
324
|
-
this.writeStream = (0, import_node_fs.createWriteStream)(this.filePath);
|
|
325
|
-
this.readyPromise = new Promise((resolve, reject) => {
|
|
326
|
-
this.writeStream.once("ready", resolve);
|
|
327
|
-
this.writeStream.once("error", reject);
|
|
328
|
-
});
|
|
329
|
-
this.closedPromise = new Promise((resolve, reject) => {
|
|
330
|
-
this.writeStream.once("close", resolve);
|
|
331
|
-
this.writeStream.once("error", reject);
|
|
332
|
-
});
|
|
333
|
-
this.gzip = (0, import_node_zlib.createGzip)();
|
|
334
|
-
this.gzip.pipe(this.writeStream);
|
|
335
|
-
}
|
|
336
|
-
get size() {
|
|
337
|
-
return this.writeStream.bytesWritten;
|
|
338
|
-
}
|
|
339
|
-
async writeLine(data) {
|
|
340
|
-
await this.readyPromise;
|
|
341
|
-
return new Promise((resolve, reject) => {
|
|
342
|
-
this.gzip.write(import_node_buffer.Buffer.concat([
|
|
343
|
-
data,
|
|
344
|
-
import_node_buffer.Buffer.from("\n")
|
|
345
|
-
]), (error) => {
|
|
346
|
-
if (error) {
|
|
347
|
-
reject(error);
|
|
348
|
-
} else {
|
|
349
|
-
resolve();
|
|
350
|
-
}
|
|
351
|
-
});
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
async getContent() {
|
|
355
|
-
return new Promise((resolve, reject) => {
|
|
356
|
-
(0, import_node_fs.readFile)(this.filePath, (error, data) => {
|
|
357
|
-
if (error) {
|
|
358
|
-
reject(error);
|
|
359
|
-
} else {
|
|
360
|
-
resolve(data);
|
|
361
|
-
}
|
|
362
|
-
});
|
|
363
|
-
});
|
|
364
|
-
}
|
|
365
|
-
async close() {
|
|
366
|
-
await new Promise((resolve) => {
|
|
367
|
-
this.gzip.end(() => {
|
|
368
|
-
resolve();
|
|
369
|
-
});
|
|
370
|
-
});
|
|
371
|
-
await this.closedPromise;
|
|
372
|
-
}
|
|
373
|
-
async delete() {
|
|
374
|
-
await this.close();
|
|
375
|
-
await (0, import_promises.unlink)(this.filePath);
|
|
376
|
-
}
|
|
377
|
-
};
|
|
378
|
-
__name(_TempGzipFile, "TempGzipFile");
|
|
379
|
-
var TempGzipFile = _TempGzipFile;
|
|
380
|
-
|
|
381
|
-
// src/common/requestLogger.ts
|
|
382
|
-
var MAX_BODY_SIZE = 5e4;
|
|
383
|
-
var MAX_FILE_SIZE = 1e6;
|
|
384
|
-
var MAX_FILES = 50;
|
|
385
|
-
var MAX_PENDING_WRITES = 100;
|
|
386
|
-
var MAX_LOG_MSG_LENGTH = 2048;
|
|
387
|
-
var BODY_TOO_LARGE = import_node_buffer2.Buffer.from("<body too large>");
|
|
388
|
-
var BODY_MASKED = import_node_buffer2.Buffer.from("<masked>");
|
|
389
|
-
var MASKED = "******";
|
|
390
|
-
var ALLOWED_CONTENT_TYPES = [
|
|
391
|
-
"application/json",
|
|
392
|
-
"application/problem+json",
|
|
393
|
-
"application/vnd.api+json",
|
|
394
|
-
"text/plain",
|
|
395
|
-
"text/html"
|
|
396
|
-
];
|
|
397
|
-
var EXCLUDE_PATH_PATTERNS = [
|
|
398
|
-
/\/_?healthz?$/i,
|
|
399
|
-
/\/_?health[_-]?checks?$/i,
|
|
400
|
-
/\/_?heart[_-]?beats?$/i,
|
|
401
|
-
/\/ping$/i,
|
|
402
|
-
/\/ready$/i,
|
|
403
|
-
/\/live$/i
|
|
404
|
-
];
|
|
405
|
-
var EXCLUDE_USER_AGENT_PATTERNS = [
|
|
406
|
-
/health[-_ ]?check/i,
|
|
407
|
-
/microsoft-azure-application-lb/i,
|
|
408
|
-
/googlehc/i,
|
|
409
|
-
/kube-probe/i
|
|
410
|
-
];
|
|
411
|
-
var MASK_QUERY_PARAM_PATTERNS = [
|
|
412
|
-
/auth/i,
|
|
413
|
-
/api-?key/i,
|
|
414
|
-
/secret/i,
|
|
415
|
-
/token/i,
|
|
416
|
-
/password/i,
|
|
417
|
-
/pwd/i
|
|
418
|
-
];
|
|
419
|
-
var MASK_HEADER_PATTERNS = [
|
|
420
|
-
/auth/i,
|
|
421
|
-
/api-?key/i,
|
|
422
|
-
/secret/i,
|
|
423
|
-
/token/i,
|
|
424
|
-
/cookie/i
|
|
425
|
-
];
|
|
426
|
-
var MASK_BODY_FIELD_PATTERNS = [
|
|
427
|
-
/password/i,
|
|
428
|
-
/pwd/i,
|
|
429
|
-
/token/i,
|
|
430
|
-
/secret/i,
|
|
431
|
-
/auth/i,
|
|
432
|
-
/card[-_ ]?number/i,
|
|
433
|
-
/ccv/i,
|
|
434
|
-
/ssn/i
|
|
435
|
-
];
|
|
436
|
-
var DEFAULT_CONFIG = {
|
|
437
|
-
enabled: false,
|
|
438
|
-
logQueryParams: true,
|
|
439
|
-
logRequestHeaders: false,
|
|
440
|
-
logRequestBody: false,
|
|
441
|
-
logResponseHeaders: true,
|
|
442
|
-
logResponseBody: false,
|
|
443
|
-
logException: true,
|
|
444
|
-
captureLogs: false,
|
|
445
|
-
maskQueryParams: [],
|
|
446
|
-
maskHeaders: [],
|
|
447
|
-
maskBodyFields: [],
|
|
448
|
-
excludePaths: []
|
|
449
|
-
};
|
|
450
|
-
var _RequestLogger = class _RequestLogger {
|
|
451
|
-
config;
|
|
452
|
-
enabled;
|
|
453
|
-
suspendUntil = null;
|
|
454
|
-
pendingWrites = [];
|
|
455
|
-
currentFile = null;
|
|
456
|
-
files = [];
|
|
457
|
-
maintainIntervalId;
|
|
458
|
-
lock = new import_async_lock.default();
|
|
459
|
-
constructor(config) {
|
|
460
|
-
this.config = {
|
|
461
|
-
...DEFAULT_CONFIG,
|
|
462
|
-
...config
|
|
463
|
-
};
|
|
464
|
-
this.enabled = this.config.enabled && checkWritableFs();
|
|
465
|
-
if (this.enabled) {
|
|
466
|
-
this.maintainIntervalId = setInterval(() => {
|
|
467
|
-
this.maintain();
|
|
468
|
-
}, 1e3);
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
get maxBodySize() {
|
|
472
|
-
return MAX_BODY_SIZE;
|
|
473
|
-
}
|
|
474
|
-
shouldExcludePath(urlPath) {
|
|
475
|
-
const patterns = [
|
|
476
|
-
...this.config.excludePaths,
|
|
477
|
-
...EXCLUDE_PATH_PATTERNS
|
|
478
|
-
];
|
|
479
|
-
return matchPatterns(urlPath, patterns);
|
|
480
|
-
}
|
|
481
|
-
shouldExcludeUserAgent(userAgent) {
|
|
482
|
-
return userAgent ? matchPatterns(userAgent, EXCLUDE_USER_AGENT_PATTERNS) : false;
|
|
483
|
-
}
|
|
484
|
-
shouldMaskQueryParam(name) {
|
|
485
|
-
const patterns = [
|
|
486
|
-
...this.config.maskQueryParams,
|
|
487
|
-
...MASK_QUERY_PARAM_PATTERNS
|
|
488
|
-
];
|
|
489
|
-
return matchPatterns(name, patterns);
|
|
490
|
-
}
|
|
491
|
-
shouldMaskHeader(name) {
|
|
492
|
-
const patterns = [
|
|
493
|
-
...this.config.maskHeaders,
|
|
494
|
-
...MASK_HEADER_PATTERNS
|
|
495
|
-
];
|
|
496
|
-
return matchPatterns(name, patterns);
|
|
497
|
-
}
|
|
498
|
-
shouldMaskBodyField(name) {
|
|
499
|
-
const patterns = [
|
|
500
|
-
...this.config.maskBodyFields,
|
|
501
|
-
...MASK_BODY_FIELD_PATTERNS
|
|
502
|
-
];
|
|
503
|
-
return matchPatterns(name, patterns);
|
|
504
|
-
}
|
|
505
|
-
hasSupportedContentType(headers) {
|
|
506
|
-
var _a2;
|
|
507
|
-
const contentType = (_a2 = headers.find(([k]) => k.toLowerCase() === "content-type")) == null ? void 0 : _a2[1];
|
|
508
|
-
return this.isSupportedContentType(contentType);
|
|
509
|
-
}
|
|
510
|
-
hasJsonContentType(headers) {
|
|
511
|
-
var _a2;
|
|
512
|
-
const contentType = (_a2 = headers.find(([k]) => k.toLowerCase() === "content-type")) == null ? void 0 : _a2[1];
|
|
513
|
-
return contentType ? /\bjson\b/i.test(contentType) : null;
|
|
514
|
-
}
|
|
515
|
-
isSupportedContentType(contentType) {
|
|
516
|
-
return typeof contentType === "string" && ALLOWED_CONTENT_TYPES.some((t) => contentType.startsWith(t));
|
|
517
|
-
}
|
|
518
|
-
maskQueryParams(search) {
|
|
519
|
-
const params = new URLSearchParams(search);
|
|
520
|
-
for (const [key] of params) {
|
|
521
|
-
if (this.shouldMaskQueryParam(key)) {
|
|
522
|
-
params.set(key, MASKED);
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
return params.toString();
|
|
526
|
-
}
|
|
527
|
-
maskHeaders(headers) {
|
|
528
|
-
return headers.map(([k, v]) => [
|
|
529
|
-
k,
|
|
530
|
-
this.shouldMaskHeader(k) ? MASKED : v
|
|
531
|
-
]);
|
|
532
|
-
}
|
|
533
|
-
maskBody(data) {
|
|
534
|
-
if (typeof data === "object" && data !== null && !Array.isArray(data)) {
|
|
535
|
-
const result = {};
|
|
536
|
-
for (const [key, value] of Object.entries(data)) {
|
|
537
|
-
if (typeof value === "string" && this.shouldMaskBodyField(key)) {
|
|
538
|
-
result[key] = MASKED;
|
|
539
|
-
} else {
|
|
540
|
-
result[key] = this.maskBody(value);
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
return result;
|
|
544
|
-
}
|
|
545
|
-
if (Array.isArray(data)) {
|
|
546
|
-
return data.map((item) => this.maskBody(item));
|
|
547
|
-
}
|
|
548
|
-
return data;
|
|
549
|
-
}
|
|
550
|
-
applyMasking(item) {
|
|
551
|
-
if (this.config.maskRequestBodyCallback && item.request.body && item.request.body !== BODY_TOO_LARGE) {
|
|
552
|
-
try {
|
|
553
|
-
const maskedBody = this.config.maskRequestBodyCallback(item.request);
|
|
554
|
-
item.request.body = maskedBody ?? BODY_MASKED;
|
|
555
|
-
} catch {
|
|
556
|
-
item.request.body = void 0;
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
if (this.config.maskResponseBodyCallback && item.response.body && item.response.body !== BODY_TOO_LARGE) {
|
|
560
|
-
try {
|
|
561
|
-
const maskedBody = this.config.maskResponseBodyCallback(item.request, item.response);
|
|
562
|
-
item.response.body = maskedBody ?? BODY_MASKED;
|
|
563
|
-
} catch {
|
|
564
|
-
item.response.body = void 0;
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
if (item.request.body && item.request.body.length > MAX_BODY_SIZE) {
|
|
568
|
-
item.request.body = BODY_TOO_LARGE;
|
|
569
|
-
}
|
|
570
|
-
if (item.response.body && item.response.body.length > MAX_BODY_SIZE) {
|
|
571
|
-
item.response.body = BODY_TOO_LARGE;
|
|
572
|
-
}
|
|
573
|
-
for (const key of [
|
|
574
|
-
"request",
|
|
575
|
-
"response"
|
|
576
|
-
]) {
|
|
577
|
-
const bodyData = item[key].body;
|
|
578
|
-
if (!bodyData || bodyData === BODY_TOO_LARGE || bodyData === BODY_MASKED) {
|
|
579
|
-
continue;
|
|
580
|
-
}
|
|
581
|
-
const headers = item[key].headers;
|
|
582
|
-
const hasJsonContent = this.hasJsonContentType(headers);
|
|
583
|
-
if (hasJsonContent === null || hasJsonContent) {
|
|
584
|
-
try {
|
|
585
|
-
const parsedBody = JSON.parse(bodyData.toString());
|
|
586
|
-
const maskedBody = this.maskBody(parsedBody);
|
|
587
|
-
item[key].body = import_node_buffer2.Buffer.from(JSON.stringify(maskedBody));
|
|
588
|
-
} catch {
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
item.request.headers = this.config.logRequestHeaders ? this.maskHeaders(item.request.headers) : [];
|
|
593
|
-
item.response.headers = this.config.logResponseHeaders ? this.maskHeaders(item.response.headers) : [];
|
|
594
|
-
const url = new URL(item.request.url);
|
|
595
|
-
url.search = this.config.logQueryParams ? this.maskQueryParams(url.search) : "";
|
|
596
|
-
item.request.url = url.toString();
|
|
597
|
-
return item;
|
|
598
|
-
}
|
|
599
|
-
logRequest(request, response, error, logs) {
|
|
600
|
-
var _a2, _b, _c;
|
|
601
|
-
if (!this.enabled || this.suspendUntil !== null) return;
|
|
602
|
-
const url = new URL(request.url);
|
|
603
|
-
const path = request.path ?? url.pathname;
|
|
604
|
-
const userAgent = (_a2 = request.headers.find(([k]) => k.toLowerCase() === "user-agent")) == null ? void 0 : _a2[1];
|
|
605
|
-
if (this.shouldExcludePath(path) || this.shouldExcludeUserAgent(userAgent) || (((_c = (_b = this.config).excludeCallback) == null ? void 0 : _c.call(_b, request, response)) ?? false)) {
|
|
606
|
-
return;
|
|
607
|
-
}
|
|
608
|
-
if (!this.config.logRequestBody || !this.hasSupportedContentType(request.headers)) {
|
|
609
|
-
request.body = void 0;
|
|
610
|
-
}
|
|
611
|
-
if (!this.config.logResponseBody || !this.hasSupportedContentType(response.headers)) {
|
|
612
|
-
response.body = void 0;
|
|
613
|
-
}
|
|
614
|
-
if (request.size !== void 0 && request.size < 0) {
|
|
615
|
-
request.size = void 0;
|
|
616
|
-
}
|
|
617
|
-
if (response.size !== void 0 && response.size < 0) {
|
|
618
|
-
response.size = void 0;
|
|
619
|
-
}
|
|
620
|
-
const item = {
|
|
621
|
-
uuid: (0, import_node_crypto3.randomUUID)(),
|
|
622
|
-
request,
|
|
623
|
-
response,
|
|
624
|
-
exception: error && this.config.logException ? {
|
|
625
|
-
type: error.name,
|
|
626
|
-
message: truncateExceptionMessage(error.message),
|
|
627
|
-
stacktrace: truncateExceptionStackTrace(error.stack || ""),
|
|
628
|
-
sentryEventId: getSentryEventId()
|
|
629
|
-
} : void 0
|
|
630
|
-
};
|
|
631
|
-
if (logs && logs.length > 0) {
|
|
632
|
-
item.logs = logs.map((log) => ({
|
|
633
|
-
timestamp: log.timestamp,
|
|
634
|
-
logger: log.logger,
|
|
635
|
-
level: log.level,
|
|
636
|
-
message: truncateLogMessage(log.message)
|
|
637
|
-
}));
|
|
638
|
-
}
|
|
639
|
-
this.pendingWrites.push(item);
|
|
640
|
-
if (this.pendingWrites.length > MAX_PENDING_WRITES) {
|
|
641
|
-
this.pendingWrites.shift();
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
async writeToFile() {
|
|
645
|
-
if (!this.enabled || this.pendingWrites.length === 0) {
|
|
646
|
-
return;
|
|
647
|
-
}
|
|
648
|
-
return this.lock.acquire("file", async () => {
|
|
649
|
-
if (!this.currentFile) {
|
|
650
|
-
this.currentFile = new TempGzipFile();
|
|
651
|
-
}
|
|
652
|
-
while (this.pendingWrites.length > 0) {
|
|
653
|
-
let item = this.pendingWrites.shift();
|
|
654
|
-
if (item) {
|
|
655
|
-
item = this.applyMasking(item);
|
|
656
|
-
const finalItem = {
|
|
657
|
-
uuid: item.uuid,
|
|
658
|
-
request: skipEmptyValues(item.request),
|
|
659
|
-
response: skipEmptyValues(item.response),
|
|
660
|
-
exception: item.exception,
|
|
661
|
-
logs: item.logs
|
|
662
|
-
};
|
|
663
|
-
[
|
|
664
|
-
finalItem.request.body,
|
|
665
|
-
finalItem.response.body
|
|
666
|
-
].forEach((body) => {
|
|
667
|
-
if (body) {
|
|
668
|
-
body.toJSON = function() {
|
|
669
|
-
return this.toString("base64");
|
|
670
|
-
};
|
|
671
|
-
}
|
|
672
|
-
});
|
|
673
|
-
await this.currentFile.writeLine(import_node_buffer2.Buffer.from(JSON.stringify(finalItem)));
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
});
|
|
677
|
-
}
|
|
678
|
-
getFile() {
|
|
679
|
-
return this.files.shift();
|
|
680
|
-
}
|
|
681
|
-
retryFileLater(file) {
|
|
682
|
-
this.files.unshift(file);
|
|
683
|
-
}
|
|
684
|
-
async rotateFile() {
|
|
685
|
-
return this.lock.acquire("file", async () => {
|
|
686
|
-
if (this.currentFile) {
|
|
687
|
-
await this.currentFile.close();
|
|
688
|
-
this.files.push(this.currentFile);
|
|
689
|
-
this.currentFile = null;
|
|
690
|
-
}
|
|
691
|
-
});
|
|
692
|
-
}
|
|
693
|
-
async maintain() {
|
|
694
|
-
await this.writeToFile();
|
|
695
|
-
if (this.currentFile && this.currentFile.size > MAX_FILE_SIZE) {
|
|
696
|
-
await this.rotateFile();
|
|
697
|
-
}
|
|
698
|
-
while (this.files.length > MAX_FILES) {
|
|
699
|
-
const file = this.files.shift();
|
|
700
|
-
file == null ? void 0 : file.delete();
|
|
701
|
-
}
|
|
702
|
-
if (this.suspendUntil !== null && this.suspendUntil < Date.now()) {
|
|
703
|
-
this.suspendUntil = null;
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
async clear() {
|
|
707
|
-
this.pendingWrites = [];
|
|
708
|
-
await this.rotateFile();
|
|
709
|
-
this.files.forEach((file) => {
|
|
710
|
-
file.delete();
|
|
711
|
-
});
|
|
712
|
-
this.files = [];
|
|
713
|
-
}
|
|
714
|
-
async close() {
|
|
715
|
-
this.enabled = false;
|
|
716
|
-
await this.clear();
|
|
717
|
-
if (this.maintainIntervalId) {
|
|
718
|
-
clearInterval(this.maintainIntervalId);
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
};
|
|
722
|
-
__name(_RequestLogger, "RequestLogger");
|
|
723
|
-
var RequestLogger = _RequestLogger;
|
|
724
|
-
function matchPatterns(value, patterns) {
|
|
725
|
-
return patterns.some((pattern) => {
|
|
726
|
-
return pattern.test(value);
|
|
727
|
-
});
|
|
728
|
-
}
|
|
729
|
-
__name(matchPatterns, "matchPatterns");
|
|
730
|
-
function skipEmptyValues(data) {
|
|
731
|
-
return Object.fromEntries(Object.entries(data).filter(([_, v]) => {
|
|
732
|
-
if (v == null || Number.isNaN(v)) return false;
|
|
733
|
-
if (Array.isArray(v) || import_node_buffer2.Buffer.isBuffer(v) || typeof v === "string") {
|
|
734
|
-
return v.length > 0;
|
|
735
|
-
}
|
|
736
|
-
return true;
|
|
737
|
-
}));
|
|
738
|
-
}
|
|
739
|
-
__name(skipEmptyValues, "skipEmptyValues");
|
|
740
|
-
function truncateLogMessage(msg) {
|
|
741
|
-
if (msg.length > MAX_LOG_MSG_LENGTH) {
|
|
742
|
-
const suffix = "... (truncated)";
|
|
743
|
-
return msg.slice(0, MAX_LOG_MSG_LENGTH - suffix.length) + suffix;
|
|
744
|
-
}
|
|
745
|
-
return msg;
|
|
746
|
-
}
|
|
747
|
-
__name(truncateLogMessage, "truncateLogMessage");
|
|
748
|
-
function checkWritableFs() {
|
|
749
|
-
try {
|
|
750
|
-
const testPath = (0, import_node_path2.join)((0, import_node_os2.tmpdir)(), `apitally-${(0, import_node_crypto3.randomUUID)()}`);
|
|
751
|
-
(0, import_node_fs2.writeFileSync)(testPath, "test");
|
|
752
|
-
(0, import_node_fs2.unlinkSync)(testPath);
|
|
753
|
-
return true;
|
|
754
|
-
} catch (error) {
|
|
755
|
-
return false;
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
__name(checkWritableFs, "checkWritableFs");
|
|
759
|
-
|
|
760
|
-
// src/common/validationErrorCounter.ts
|
|
761
|
-
var import_node_crypto4 = require("crypto");
|
|
762
|
-
var _ValidationErrorCounter = class _ValidationErrorCounter {
|
|
763
|
-
errorCounts;
|
|
764
|
-
errorDetails;
|
|
765
|
-
constructor() {
|
|
766
|
-
this.errorCounts = /* @__PURE__ */ new Map();
|
|
767
|
-
this.errorDetails = /* @__PURE__ */ new Map();
|
|
768
|
-
}
|
|
769
|
-
addValidationError(validationError) {
|
|
770
|
-
const key = this.getKey(validationError);
|
|
771
|
-
if (!this.errorDetails.has(key)) {
|
|
772
|
-
this.errorDetails.set(key, validationError);
|
|
773
|
-
}
|
|
774
|
-
this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);
|
|
775
|
-
}
|
|
776
|
-
getAndResetValidationErrors() {
|
|
777
|
-
const data = [];
|
|
778
|
-
this.errorCounts.forEach((count, key) => {
|
|
779
|
-
const validationError = this.errorDetails.get(key);
|
|
780
|
-
if (validationError) {
|
|
781
|
-
data.push({
|
|
782
|
-
consumer: validationError.consumer || null,
|
|
783
|
-
method: validationError.method,
|
|
784
|
-
path: validationError.path,
|
|
785
|
-
loc: validationError.loc.split(".").filter(Boolean),
|
|
786
|
-
msg: validationError.msg,
|
|
787
|
-
type: validationError.type,
|
|
788
|
-
error_count: count
|
|
789
|
-
});
|
|
790
|
-
}
|
|
791
|
-
});
|
|
792
|
-
this.errorCounts.clear();
|
|
793
|
-
this.errorDetails.clear();
|
|
794
|
-
return data;
|
|
795
|
-
}
|
|
796
|
-
getKey(validationError) {
|
|
797
|
-
const hashInput = [
|
|
798
|
-
validationError.consumer || "",
|
|
799
|
-
validationError.method.toUpperCase(),
|
|
800
|
-
validationError.path,
|
|
801
|
-
validationError.loc.split(".").filter(Boolean),
|
|
802
|
-
validationError.msg.trim(),
|
|
803
|
-
validationError.type
|
|
804
|
-
].join("|");
|
|
805
|
-
return (0, import_node_crypto4.createHash)("md5").update(hashInput).digest("hex");
|
|
806
|
-
}
|
|
807
|
-
};
|
|
808
|
-
__name(_ValidationErrorCounter, "ValidationErrorCounter");
|
|
809
|
-
var ValidationErrorCounter = _ValidationErrorCounter;
|
|
810
|
-
|
|
811
|
-
// src/common/client.ts
|
|
812
|
-
var SYNC_INTERVAL = 6e4;
|
|
813
|
-
var INITIAL_SYNC_INTERVAL = 1e4;
|
|
814
|
-
var INITIAL_SYNC_INTERVAL_DURATION = 36e5;
|
|
815
|
-
var MAX_QUEUE_TIME = 36e5;
|
|
38
|
+
var import_node_crypto = require("node:crypto");
|
|
39
|
+
var import_consumerRegistry = __toESM(require("./consumerRegistry.js"), 1);
|
|
40
|
+
var import_logging = require("./logging.js");
|
|
41
|
+
var import_paramValidation = require("./paramValidation.js");
|
|
42
|
+
var import_requestCounter = __toESM(require("./requestCounter.js"), 1);
|
|
43
|
+
var import_requestLogger = __toESM(require("./requestLogger.js"), 1);
|
|
44
|
+
var import_serverErrorCounter = __toESM(require("./serverErrorCounter.js"), 1);
|
|
45
|
+
var import_validationErrorCounter = __toESM(require("./validationErrorCounter.js"), 1);
|
|
816
46
|
var _a;
|
|
817
|
-
|
|
47
|
+
const SYNC_INTERVAL = 6e4;
|
|
48
|
+
const INITIAL_SYNC_INTERVAL = 1e4;
|
|
49
|
+
const INITIAL_SYNC_INTERVAL_DURATION = 36e5;
|
|
50
|
+
const MAX_QUEUE_TIME = 36e5;
|
|
51
|
+
let HTTPError = (_a = class extends Error {
|
|
818
52
|
response;
|
|
819
53
|
constructor(response) {
|
|
820
54
|
const reason = response.status ? `status code ${response.status}` : "an unknown error";
|
|
@@ -822,7 +56,7 @@ var HTTPError = (_a = class extends Error {
|
|
|
822
56
|
this.response = response;
|
|
823
57
|
}
|
|
824
58
|
}, __name(_a, "HTTPError"), _a);
|
|
825
|
-
|
|
59
|
+
const _ApitallyClient = class _ApitallyClient {
|
|
826
60
|
clientId;
|
|
827
61
|
env;
|
|
828
62
|
instanceUuid;
|
|
@@ -841,11 +75,14 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
841
75
|
if (_ApitallyClient.instance) {
|
|
842
76
|
throw new Error("Apitally client is already initialized");
|
|
843
77
|
}
|
|
844
|
-
|
|
845
|
-
|
|
78
|
+
this.logger = logger ?? (0, import_logging.getLogger)();
|
|
79
|
+
if (!(0, import_paramValidation.isValidClientId)(clientId)) {
|
|
80
|
+
this.logger.error(`Invalid Apitally client ID '${clientId}' (expecting hexadecimal UUID format)`);
|
|
81
|
+
this.enabled = false;
|
|
846
82
|
}
|
|
847
|
-
if (!isValidEnv(env)) {
|
|
848
|
-
|
|
83
|
+
if (!(0, import_paramValidation.isValidEnv)(env)) {
|
|
84
|
+
this.logger.error(`Invalid Apitally env '${env}' (expecting 1-32 alphanumeric characters and hyphens only)`);
|
|
85
|
+
this.enabled = false;
|
|
849
86
|
}
|
|
850
87
|
if (requestLoggingConfig && !requestLogging) {
|
|
851
88
|
console.warn("requestLoggingConfig is deprecated, use requestLogging instead.");
|
|
@@ -853,15 +90,13 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
853
90
|
_ApitallyClient.instance = this;
|
|
854
91
|
this.clientId = clientId;
|
|
855
92
|
this.env = env;
|
|
856
|
-
this.instanceUuid = (0,
|
|
93
|
+
this.instanceUuid = (0, import_node_crypto.randomUUID)();
|
|
857
94
|
this.syncDataQueue = [];
|
|
858
|
-
this.requestCounter = new
|
|
859
|
-
this.requestLogger = new
|
|
860
|
-
this.validationErrorCounter = new
|
|
861
|
-
this.serverErrorCounter = new
|
|
862
|
-
this.consumerRegistry = new
|
|
863
|
-
this.logger = logger ?? getLogger();
|
|
864
|
-
this.startSync();
|
|
95
|
+
this.requestCounter = new import_requestCounter.default();
|
|
96
|
+
this.requestLogger = new import_requestLogger.default(requestLogging ?? requestLoggingConfig);
|
|
97
|
+
this.validationErrorCounter = new import_validationErrorCounter.default();
|
|
98
|
+
this.serverErrorCounter = new import_serverErrorCounter.default();
|
|
99
|
+
this.consumerRegistry = new import_consumerRegistry.default();
|
|
865
100
|
this.handleShutdown = this.handleShutdown.bind(this);
|
|
866
101
|
}
|
|
867
102
|
static getInstance() {
|
|
@@ -916,15 +151,20 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
916
151
|
}
|
|
917
152
|
}
|
|
918
153
|
startSync() {
|
|
154
|
+
if (!this.enabled) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
919
157
|
this.sync();
|
|
920
158
|
this.syncIntervalId = setInterval(() => {
|
|
921
159
|
this.sync();
|
|
922
160
|
}, INITIAL_SYNC_INTERVAL);
|
|
923
161
|
setTimeout(() => {
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
this.
|
|
927
|
-
|
|
162
|
+
if (this.syncIntervalId) {
|
|
163
|
+
clearInterval(this.syncIntervalId);
|
|
164
|
+
this.syncIntervalId = setInterval(() => {
|
|
165
|
+
this.sync();
|
|
166
|
+
}, SYNC_INTERVAL);
|
|
167
|
+
}
|
|
928
168
|
}, INITIAL_SYNC_INTERVAL_DURATION);
|
|
929
169
|
}
|
|
930
170
|
async sync() {
|
|
@@ -952,14 +192,13 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
952
192
|
setStartupData(data) {
|
|
953
193
|
this.startupData = data;
|
|
954
194
|
this.startupDataSent = false;
|
|
955
|
-
this.sendStartupData();
|
|
956
195
|
}
|
|
957
196
|
async sendStartupData() {
|
|
958
197
|
if (this.startupData) {
|
|
959
198
|
this.logger.debug("Sending startup data to Apitally Hub");
|
|
960
199
|
const payload = {
|
|
961
200
|
instance_uuid: this.instanceUuid,
|
|
962
|
-
message_uuid: (0,
|
|
201
|
+
message_uuid: (0, import_node_crypto.randomUUID)(),
|
|
963
202
|
...this.startupData
|
|
964
203
|
};
|
|
965
204
|
try {
|
|
@@ -981,7 +220,7 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
981
220
|
const newPayload = {
|
|
982
221
|
timestamp: Date.now() / 1e3,
|
|
983
222
|
instance_uuid: this.instanceUuid,
|
|
984
|
-
message_uuid: (0,
|
|
223
|
+
message_uuid: (0, import_node_crypto.randomUUID)(),
|
|
985
224
|
requests: this.requestCounter.getAndResetRequests(),
|
|
986
225
|
validation_errors: this.validationErrorCounter.getAndResetValidationErrors(),
|
|
987
226
|
server_errors: this.serverErrorCounter.getAndResetServerErrors(),
|
|
@@ -1081,7 +320,7 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
1081
320
|
};
|
|
1082
321
|
__name(_ApitallyClient, "ApitallyClient");
|
|
1083
322
|
__publicField(_ApitallyClient, "instance");
|
|
1084
|
-
|
|
323
|
+
let ApitallyClient = _ApitallyClient;
|
|
1085
324
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1086
325
|
0 && (module.exports = {
|
|
1087
326
|
ApitallyClient
|