apitally 0.11.5 → 0.13.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/README.md +43 -2
- package/dist/adonisjs/index.cjs +41 -0
- package/dist/adonisjs/index.cjs.map +1 -0
- package/dist/adonisjs/index.d.cts +14 -0
- package/dist/adonisjs/index.d.ts +14 -0
- package/dist/adonisjs/index.js +17 -0
- package/dist/adonisjs/index.js.map +1 -0
- package/dist/adonisjs/middleware.cjs +214 -0
- package/dist/adonisjs/middleware.cjs.map +1 -0
- package/dist/adonisjs/middleware.d.cts +21 -0
- package/dist/adonisjs/middleware.d.ts +21 -0
- package/dist/adonisjs/middleware.js +185 -0
- package/dist/adonisjs/middleware.js.map +1 -0
- package/dist/adonisjs/provider.cjs +1083 -0
- package/dist/adonisjs/provider.cjs.map +1 -0
- package/dist/adonisjs/provider.d.cts +28 -0
- package/dist/adonisjs/provider.d.ts +28 -0
- package/dist/adonisjs/provider.js +1057 -0
- package/dist/adonisjs/provider.js.map +1 -0
- package/dist/common/client.cjs +117 -106
- package/dist/common/client.cjs.map +1 -1
- package/dist/common/client.js +112 -101
- package/dist/common/client.js.map +1 -1
- package/dist/common/consumerRegistry.cjs.map +1 -1
- package/dist/common/consumerRegistry.js.map +1 -1
- package/dist/common/logging.cjs.map +1 -1
- package/dist/common/logging.js.map +1 -1
- package/dist/common/packageVersions.cjs.map +1 -1
- package/dist/common/packageVersions.js.map +1 -1
- package/dist/common/paramValidation.cjs.map +1 -1
- package/dist/common/paramValidation.js.map +1 -1
- package/dist/common/requestCounter.cjs.map +1 -1
- package/dist/common/requestCounter.js.map +1 -1
- package/dist/common/requestLogger.cjs +55 -2
- package/dist/common/requestLogger.cjs.map +1 -1
- package/dist/common/requestLogger.d.cts +2 -1
- package/dist/common/requestLogger.d.ts +2 -1
- package/dist/common/requestLogger.js +55 -2
- package/dist/common/requestLogger.js.map +1 -1
- package/dist/common/sentry.cjs +55 -0
- package/dist/common/sentry.cjs.map +1 -0
- package/dist/common/sentry.d.cts +6 -0
- package/dist/common/sentry.d.ts +6 -0
- package/dist/common/sentry.js +22 -0
- package/dist/common/sentry.js.map +1 -0
- package/dist/common/serverErrorCounter.cjs +58 -45
- package/dist/common/serverErrorCounter.cjs.map +1 -1
- package/dist/common/serverErrorCounter.d.cts +3 -6
- package/dist/common/serverErrorCounter.d.ts +3 -6
- package/dist/common/serverErrorCounter.js +53 -45
- package/dist/common/serverErrorCounter.js.map +1 -1
- package/dist/common/tempGzipFile.cjs.map +1 -1
- package/dist/common/tempGzipFile.js.map +1 -1
- package/dist/common/types.cjs.map +1 -1
- package/dist/common/utils.cjs +48 -0
- package/dist/common/utils.cjs.map +1 -0
- package/dist/common/utils.d.cts +5 -0
- package/dist/common/utils.d.ts +5 -0
- package/dist/common/utils.js +25 -0
- package/dist/common/utils.js.map +1 -0
- package/dist/common/validationErrorCounter.cjs.map +1 -1
- package/dist/common/validationErrorCounter.js.map +1 -1
- package/dist/express/index.cjs +143 -111
- package/dist/express/index.cjs.map +1 -1
- package/dist/express/index.js +138 -106
- package/dist/express/index.js.map +1 -1
- package/dist/express/middleware.cjs +143 -111
- package/dist/express/middleware.cjs.map +1 -1
- package/dist/express/middleware.js +138 -106
- package/dist/express/middleware.js.map +1 -1
- package/dist/express/utils.cjs.map +1 -1
- package/dist/express/utils.js.map +1 -1
- package/dist/fastify/index.cjs +139 -112
- package/dist/fastify/index.cjs.map +1 -1
- package/dist/fastify/index.js +134 -107
- package/dist/fastify/index.js.map +1 -1
- package/dist/fastify/plugin.cjs +139 -112
- package/dist/fastify/plugin.cjs.map +1 -1
- package/dist/fastify/plugin.js +134 -107
- package/dist/fastify/plugin.js.map +1 -1
- package/dist/hono/index.cjs +138 -108
- package/dist/hono/index.cjs.map +1 -1
- package/dist/hono/index.js +133 -103
- package/dist/hono/index.js.map +1 -1
- package/dist/hono/middleware.cjs +138 -108
- package/dist/hono/middleware.cjs.map +1 -1
- package/dist/hono/middleware.js +133 -103
- package/dist/hono/middleware.js.map +1 -1
- package/dist/koa/index.cjs +122 -109
- package/dist/koa/index.cjs.map +1 -1
- package/dist/koa/index.js +117 -104
- package/dist/koa/index.js.map +1 -1
- package/dist/koa/middleware.cjs +122 -109
- package/dist/koa/middleware.cjs.map +1 -1
- package/dist/koa/middleware.js +117 -104
- package/dist/koa/middleware.js.map +1 -1
- package/dist/nestjs/index.cjs +143 -111
- package/dist/nestjs/index.cjs.map +1 -1
- package/dist/nestjs/index.js +138 -106
- package/dist/nestjs/index.js.map +1 -1
- package/package.json +46 -1
package/dist/hono/middleware.js
CHANGED
|
@@ -191,6 +191,108 @@ import { unlinkSync as unlinkSync2, writeFileSync } from "fs";
|
|
|
191
191
|
import { tmpdir as tmpdir2 } from "os";
|
|
192
192
|
import { join as join2 } from "path";
|
|
193
193
|
|
|
194
|
+
// src/common/sentry.ts
|
|
195
|
+
var sentry;
|
|
196
|
+
(async () => {
|
|
197
|
+
try {
|
|
198
|
+
sentry = await import("@sentry/node");
|
|
199
|
+
} catch (e) {
|
|
200
|
+
}
|
|
201
|
+
})();
|
|
202
|
+
function getSentryEventId() {
|
|
203
|
+
if (sentry && sentry.lastEventId) {
|
|
204
|
+
return sentry.lastEventId();
|
|
205
|
+
}
|
|
206
|
+
return void 0;
|
|
207
|
+
}
|
|
208
|
+
__name(getSentryEventId, "getSentryEventId");
|
|
209
|
+
|
|
210
|
+
// src/common/serverErrorCounter.ts
|
|
211
|
+
import { createHash } from "crypto";
|
|
212
|
+
var MAX_MSG_LENGTH = 2048;
|
|
213
|
+
var MAX_STACKTRACE_LENGTH = 65536;
|
|
214
|
+
var _ServerErrorCounter = class _ServerErrorCounter {
|
|
215
|
+
errorCounts;
|
|
216
|
+
errorDetails;
|
|
217
|
+
sentryEventIds;
|
|
218
|
+
constructor() {
|
|
219
|
+
this.errorCounts = /* @__PURE__ */ new Map();
|
|
220
|
+
this.errorDetails = /* @__PURE__ */ new Map();
|
|
221
|
+
this.sentryEventIds = /* @__PURE__ */ new Map();
|
|
222
|
+
}
|
|
223
|
+
addServerError(serverError) {
|
|
224
|
+
const key = this.getKey(serverError);
|
|
225
|
+
if (!this.errorDetails.has(key)) {
|
|
226
|
+
this.errorDetails.set(key, serverError);
|
|
227
|
+
}
|
|
228
|
+
this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);
|
|
229
|
+
const sentryEventId = getSentryEventId();
|
|
230
|
+
if (sentryEventId) {
|
|
231
|
+
this.sentryEventIds.set(key, sentryEventId);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
getAndResetServerErrors() {
|
|
235
|
+
const data = [];
|
|
236
|
+
this.errorCounts.forEach((count, key) => {
|
|
237
|
+
const serverError = this.errorDetails.get(key);
|
|
238
|
+
if (serverError) {
|
|
239
|
+
data.push({
|
|
240
|
+
consumer: serverError.consumer || null,
|
|
241
|
+
method: serverError.method,
|
|
242
|
+
path: serverError.path,
|
|
243
|
+
type: serverError.type,
|
|
244
|
+
msg: truncateExceptionMessage(serverError.msg),
|
|
245
|
+
traceback: truncateExceptionStackTrace(serverError.traceback),
|
|
246
|
+
sentry_event_id: this.sentryEventIds.get(key) || null,
|
|
247
|
+
error_count: count
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
this.errorCounts.clear();
|
|
252
|
+
this.errorDetails.clear();
|
|
253
|
+
return data;
|
|
254
|
+
}
|
|
255
|
+
getKey(serverError) {
|
|
256
|
+
const hashInput = [
|
|
257
|
+
serverError.consumer || "",
|
|
258
|
+
serverError.method.toUpperCase(),
|
|
259
|
+
serverError.path,
|
|
260
|
+
serverError.type,
|
|
261
|
+
serverError.msg.trim(),
|
|
262
|
+
serverError.traceback.trim()
|
|
263
|
+
].join("|");
|
|
264
|
+
return createHash("md5").update(hashInput).digest("hex");
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
__name(_ServerErrorCounter, "ServerErrorCounter");
|
|
268
|
+
var ServerErrorCounter = _ServerErrorCounter;
|
|
269
|
+
function truncateExceptionMessage(msg) {
|
|
270
|
+
if (msg.length <= MAX_MSG_LENGTH) {
|
|
271
|
+
return msg;
|
|
272
|
+
}
|
|
273
|
+
const suffix = "... (truncated)";
|
|
274
|
+
const cutoff = MAX_MSG_LENGTH - suffix.length;
|
|
275
|
+
return msg.substring(0, cutoff) + suffix;
|
|
276
|
+
}
|
|
277
|
+
__name(truncateExceptionMessage, "truncateExceptionMessage");
|
|
278
|
+
function truncateExceptionStackTrace(stack) {
|
|
279
|
+
const suffix = "... (truncated) ...";
|
|
280
|
+
const cutoff = MAX_STACKTRACE_LENGTH - suffix.length;
|
|
281
|
+
const lines = stack.trim().split("\n");
|
|
282
|
+
const truncatedLines = [];
|
|
283
|
+
let length = 0;
|
|
284
|
+
for (const line of lines) {
|
|
285
|
+
if (length + line.length + 1 > cutoff) {
|
|
286
|
+
truncatedLines.push(suffix);
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
truncatedLines.push(line);
|
|
290
|
+
length += line.length + 1;
|
|
291
|
+
}
|
|
292
|
+
return truncatedLines.join("\n");
|
|
293
|
+
}
|
|
294
|
+
__name(truncateExceptionStackTrace, "truncateExceptionStackTrace");
|
|
295
|
+
|
|
194
296
|
// src/common/tempGzipFile.ts
|
|
195
297
|
import { Buffer as Buffer2 } from "buffer";
|
|
196
298
|
import { randomUUID } from "crypto";
|
|
@@ -313,6 +415,7 @@ var DEFAULT_CONFIG = {
|
|
|
313
415
|
logRequestBody: false,
|
|
314
416
|
logResponseHeaders: true,
|
|
315
417
|
logResponseBody: false,
|
|
418
|
+
logException: true,
|
|
316
419
|
maskQueryParams: [],
|
|
317
420
|
maskHeaders: [],
|
|
318
421
|
excludePaths: []
|
|
@@ -385,7 +488,7 @@ var _RequestLogger = class _RequestLogger {
|
|
|
385
488
|
this.shouldMaskHeader(k) ? MASKED : v
|
|
386
489
|
]);
|
|
387
490
|
}
|
|
388
|
-
logRequest(request, response) {
|
|
491
|
+
logRequest(request, response, error) {
|
|
389
492
|
var _a2, _b, _c;
|
|
390
493
|
if (!this.enabled || this.suspendUntil !== null) return;
|
|
391
494
|
const url = new URL(request.url);
|
|
@@ -433,7 +536,13 @@ var _RequestLogger = class _RequestLogger {
|
|
|
433
536
|
const item = {
|
|
434
537
|
uuid: randomUUID2(),
|
|
435
538
|
request: skipEmptyValues(request),
|
|
436
|
-
response: skipEmptyValues(response)
|
|
539
|
+
response: skipEmptyValues(response),
|
|
540
|
+
exception: error && this.config.logException ? {
|
|
541
|
+
type: error.name,
|
|
542
|
+
message: truncateExceptionMessage(error.message),
|
|
543
|
+
stacktrace: truncateExceptionStackTrace(error.stack || ""),
|
|
544
|
+
sentryEventId: getSentryEventId()
|
|
545
|
+
} : null
|
|
437
546
|
};
|
|
438
547
|
[
|
|
439
548
|
item.request.body,
|
|
@@ -563,104 +672,6 @@ function checkWritableFs() {
|
|
|
563
672
|
}
|
|
564
673
|
__name(checkWritableFs, "checkWritableFs");
|
|
565
674
|
|
|
566
|
-
// src/common/serverErrorCounter.ts
|
|
567
|
-
import { createHash } from "crypto";
|
|
568
|
-
var MAX_MSG_LENGTH = 2048;
|
|
569
|
-
var MAX_STACKTRACE_LENGTH = 65536;
|
|
570
|
-
var _ServerErrorCounter = class _ServerErrorCounter {
|
|
571
|
-
errorCounts;
|
|
572
|
-
errorDetails;
|
|
573
|
-
sentryEventIds;
|
|
574
|
-
sentry;
|
|
575
|
-
constructor() {
|
|
576
|
-
this.errorCounts = /* @__PURE__ */ new Map();
|
|
577
|
-
this.errorDetails = /* @__PURE__ */ new Map();
|
|
578
|
-
this.sentryEventIds = /* @__PURE__ */ new Map();
|
|
579
|
-
this.tryImportSentry();
|
|
580
|
-
}
|
|
581
|
-
addServerError(serverError) {
|
|
582
|
-
const key = this.getKey(serverError);
|
|
583
|
-
if (!this.errorDetails.has(key)) {
|
|
584
|
-
this.errorDetails.set(key, serverError);
|
|
585
|
-
}
|
|
586
|
-
this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);
|
|
587
|
-
this.captureSentryEventId(key);
|
|
588
|
-
}
|
|
589
|
-
getAndResetServerErrors() {
|
|
590
|
-
const data = [];
|
|
591
|
-
this.errorCounts.forEach((count, key) => {
|
|
592
|
-
const serverError = this.errorDetails.get(key);
|
|
593
|
-
if (serverError) {
|
|
594
|
-
data.push({
|
|
595
|
-
consumer: serverError.consumer || null,
|
|
596
|
-
method: serverError.method,
|
|
597
|
-
path: serverError.path,
|
|
598
|
-
type: serverError.type,
|
|
599
|
-
msg: this.getTruncatedMessage(serverError.msg),
|
|
600
|
-
traceback: this.getTruncatedStack(serverError.traceback),
|
|
601
|
-
sentry_event_id: this.sentryEventIds.get(key) || null,
|
|
602
|
-
error_count: count
|
|
603
|
-
});
|
|
604
|
-
}
|
|
605
|
-
});
|
|
606
|
-
this.errorCounts.clear();
|
|
607
|
-
this.errorDetails.clear();
|
|
608
|
-
return data;
|
|
609
|
-
}
|
|
610
|
-
getKey(serverError) {
|
|
611
|
-
const hashInput = [
|
|
612
|
-
serverError.consumer || "",
|
|
613
|
-
serverError.method.toUpperCase(),
|
|
614
|
-
serverError.path,
|
|
615
|
-
serverError.type,
|
|
616
|
-
serverError.msg.trim(),
|
|
617
|
-
serverError.traceback.trim()
|
|
618
|
-
].join("|");
|
|
619
|
-
return createHash("md5").update(hashInput).digest("hex");
|
|
620
|
-
}
|
|
621
|
-
getTruncatedMessage(msg) {
|
|
622
|
-
msg = msg.trim();
|
|
623
|
-
if (msg.length <= MAX_MSG_LENGTH) {
|
|
624
|
-
return msg;
|
|
625
|
-
}
|
|
626
|
-
const suffix = "... (truncated)";
|
|
627
|
-
const cutoff = MAX_MSG_LENGTH - suffix.length;
|
|
628
|
-
return msg.substring(0, cutoff) + suffix;
|
|
629
|
-
}
|
|
630
|
-
getTruncatedStack(stack) {
|
|
631
|
-
const suffix = "... (truncated) ...";
|
|
632
|
-
const cutoff = MAX_STACKTRACE_LENGTH - suffix.length;
|
|
633
|
-
const lines = stack.trim().split("\n");
|
|
634
|
-
const truncatedLines = [];
|
|
635
|
-
let length = 0;
|
|
636
|
-
for (const line of lines) {
|
|
637
|
-
if (length + line.length + 1 > cutoff) {
|
|
638
|
-
truncatedLines.push(suffix);
|
|
639
|
-
break;
|
|
640
|
-
}
|
|
641
|
-
truncatedLines.push(line);
|
|
642
|
-
length += line.length + 1;
|
|
643
|
-
}
|
|
644
|
-
return truncatedLines.join("\n");
|
|
645
|
-
}
|
|
646
|
-
captureSentryEventId(serverErrorKey) {
|
|
647
|
-
if (this.sentry && this.sentry.lastEventId) {
|
|
648
|
-
const eventId = this.sentry.lastEventId();
|
|
649
|
-
if (eventId) {
|
|
650
|
-
this.sentryEventIds.set(serverErrorKey, eventId);
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
async tryImportSentry() {
|
|
655
|
-
try {
|
|
656
|
-
this.sentry = await import("@sentry/node");
|
|
657
|
-
} catch (e) {
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
};
|
|
661
|
-
__name(_ServerErrorCounter, "ServerErrorCounter");
|
|
662
|
-
var ServerErrorCounter = _ServerErrorCounter;
|
|
663
|
-
|
|
664
675
|
// src/common/validationErrorCounter.ts
|
|
665
676
|
import { createHash as createHash2 } from "crypto";
|
|
666
677
|
var _ValidationErrorCounter = class _ValidationErrorCounter {
|
|
@@ -746,7 +757,7 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
746
757
|
throw new Error("Apitally client is already initialized");
|
|
747
758
|
}
|
|
748
759
|
if (!isValidClientId(clientId)) {
|
|
749
|
-
throw new Error(`Invalid client ID '${clientId}' (expecting
|
|
760
|
+
throw new Error(`Invalid Apitally client ID '${clientId}' (expecting hexadecimal UUID format)`);
|
|
750
761
|
}
|
|
751
762
|
if (!isValidEnv(env)) {
|
|
752
763
|
throw new Error(`Invalid env '${env}' (expecting 1-32 alphanumeric lowercase characters and hyphens only)`);
|
|
@@ -1001,6 +1012,25 @@ function getPackageVersion(name) {
|
|
|
1001
1012
|
}
|
|
1002
1013
|
__name(getPackageVersion, "getPackageVersion");
|
|
1003
1014
|
|
|
1015
|
+
// src/common/utils.ts
|
|
1016
|
+
function parseContentLength(contentLength) {
|
|
1017
|
+
if (contentLength === void 0 || contentLength === null) {
|
|
1018
|
+
return void 0;
|
|
1019
|
+
}
|
|
1020
|
+
if (typeof contentLength === "number") {
|
|
1021
|
+
return contentLength;
|
|
1022
|
+
}
|
|
1023
|
+
if (typeof contentLength === "string") {
|
|
1024
|
+
const parsed = parseInt(contentLength);
|
|
1025
|
+
return isNaN(parsed) ? void 0 : parsed;
|
|
1026
|
+
}
|
|
1027
|
+
if (Array.isArray(contentLength)) {
|
|
1028
|
+
return parseContentLength(contentLength[0]);
|
|
1029
|
+
}
|
|
1030
|
+
return void 0;
|
|
1031
|
+
}
|
|
1032
|
+
__name(parseContentLength, "parseContentLength");
|
|
1033
|
+
|
|
1004
1034
|
// src/hono/middleware.ts
|
|
1005
1035
|
var useApitally = /* @__PURE__ */ __name((app, config) => {
|
|
1006
1036
|
const client = new ApitallyClient(config);
|
|
@@ -1021,7 +1051,7 @@ var getMiddleware = /* @__PURE__ */ __name((client) => {
|
|
|
1021
1051
|
let response;
|
|
1022
1052
|
const responseTime = performance.now() - startTime;
|
|
1023
1053
|
const [responseSize, newResponse] = await measureResponseSize(c.res);
|
|
1024
|
-
const requestSize = c.req.header("
|
|
1054
|
+
const requestSize = parseContentLength(c.req.header("content-length"));
|
|
1025
1055
|
const consumer = getConsumer(c);
|
|
1026
1056
|
client.consumerRegistry.addOrUpdateConsumer(consumer);
|
|
1027
1057
|
client.requestCounter.addRequest({
|
|
@@ -1084,7 +1114,7 @@ var getMiddleware = /* @__PURE__ */ __name((client) => {
|
|
|
1084
1114
|
headers: convertHeaders(c.res.headers),
|
|
1085
1115
|
size: responseSize,
|
|
1086
1116
|
body: responseBody
|
|
1087
|
-
});
|
|
1117
|
+
}, c.error);
|
|
1088
1118
|
}
|
|
1089
1119
|
c.res = response;
|
|
1090
1120
|
};
|