apitally 0.11.5 → 0.12.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 +2 -2
- package/dist/common/client.cjs +116 -105
- package/dist/common/client.cjs.map +1 -1
- package/dist/common/client.js +111 -100
- package/dist/common/client.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/express/index.cjs +117 -106
- package/dist/express/index.cjs.map +1 -1
- package/dist/express/index.js +112 -101
- package/dist/express/index.js.map +1 -1
- package/dist/express/middleware.cjs +117 -106
- package/dist/express/middleware.cjs.map +1 -1
- package/dist/express/middleware.js +112 -101
- package/dist/express/middleware.js.map +1 -1
- package/dist/fastify/index.cjs +117 -106
- package/dist/fastify/index.cjs.map +1 -1
- package/dist/fastify/index.js +112 -101
- package/dist/fastify/index.js.map +1 -1
- package/dist/fastify/plugin.cjs +117 -106
- package/dist/fastify/plugin.cjs.map +1 -1
- package/dist/fastify/plugin.js +112 -101
- package/dist/fastify/plugin.js.map +1 -1
- package/dist/hono/index.cjs +117 -106
- package/dist/hono/index.cjs.map +1 -1
- package/dist/hono/index.js +112 -101
- package/dist/hono/index.js.map +1 -1
- package/dist/hono/middleware.cjs +117 -106
- package/dist/hono/middleware.cjs.map +1 -1
- package/dist/hono/middleware.js +112 -101
- package/dist/hono/middleware.js.map +1 -1
- package/dist/koa/index.cjs +119 -106
- package/dist/koa/index.cjs.map +1 -1
- package/dist/koa/index.js +114 -101
- package/dist/koa/index.js.map +1 -1
- package/dist/koa/middleware.cjs +119 -106
- package/dist/koa/middleware.cjs.map +1 -1
- package/dist/koa/middleware.js +114 -101
- package/dist/koa/middleware.js.map +1 -1
- package/dist/nestjs/index.cjs +117 -106
- package/dist/nestjs/index.cjs.map +1 -1
- package/dist/nestjs/index.js +112 -101
- package/dist/nestjs/index.js.map +1 -1
- package/package.json +1 -1
package/dist/express/index.js
CHANGED
|
@@ -190,6 +190,108 @@ import { unlinkSync as unlinkSync2, writeFileSync } from "fs";
|
|
|
190
190
|
import { tmpdir as tmpdir2 } from "os";
|
|
191
191
|
import { join as join2 } from "path";
|
|
192
192
|
|
|
193
|
+
// src/common/sentry.ts
|
|
194
|
+
var sentry;
|
|
195
|
+
(async () => {
|
|
196
|
+
try {
|
|
197
|
+
sentry = await import("@sentry/node");
|
|
198
|
+
} catch (e) {
|
|
199
|
+
}
|
|
200
|
+
})();
|
|
201
|
+
function getSentryEventId() {
|
|
202
|
+
if (sentry && sentry.lastEventId) {
|
|
203
|
+
return sentry.lastEventId();
|
|
204
|
+
}
|
|
205
|
+
return void 0;
|
|
206
|
+
}
|
|
207
|
+
__name(getSentryEventId, "getSentryEventId");
|
|
208
|
+
|
|
209
|
+
// src/common/serverErrorCounter.ts
|
|
210
|
+
import { createHash } from "crypto";
|
|
211
|
+
var MAX_MSG_LENGTH = 2048;
|
|
212
|
+
var MAX_STACKTRACE_LENGTH = 65536;
|
|
213
|
+
var _ServerErrorCounter = class _ServerErrorCounter {
|
|
214
|
+
errorCounts;
|
|
215
|
+
errorDetails;
|
|
216
|
+
sentryEventIds;
|
|
217
|
+
constructor() {
|
|
218
|
+
this.errorCounts = /* @__PURE__ */ new Map();
|
|
219
|
+
this.errorDetails = /* @__PURE__ */ new Map();
|
|
220
|
+
this.sentryEventIds = /* @__PURE__ */ new Map();
|
|
221
|
+
}
|
|
222
|
+
addServerError(serverError) {
|
|
223
|
+
const key = this.getKey(serverError);
|
|
224
|
+
if (!this.errorDetails.has(key)) {
|
|
225
|
+
this.errorDetails.set(key, serverError);
|
|
226
|
+
}
|
|
227
|
+
this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);
|
|
228
|
+
const sentryEventId = getSentryEventId();
|
|
229
|
+
if (sentryEventId) {
|
|
230
|
+
this.sentryEventIds.set(key, sentryEventId);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
getAndResetServerErrors() {
|
|
234
|
+
const data = [];
|
|
235
|
+
this.errorCounts.forEach((count, key) => {
|
|
236
|
+
const serverError = this.errorDetails.get(key);
|
|
237
|
+
if (serverError) {
|
|
238
|
+
data.push({
|
|
239
|
+
consumer: serverError.consumer || null,
|
|
240
|
+
method: serverError.method,
|
|
241
|
+
path: serverError.path,
|
|
242
|
+
type: serverError.type,
|
|
243
|
+
msg: truncateExceptionMessage(serverError.msg),
|
|
244
|
+
traceback: truncateExceptionStackTrace(serverError.traceback),
|
|
245
|
+
sentry_event_id: this.sentryEventIds.get(key) || null,
|
|
246
|
+
error_count: count
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
this.errorCounts.clear();
|
|
251
|
+
this.errorDetails.clear();
|
|
252
|
+
return data;
|
|
253
|
+
}
|
|
254
|
+
getKey(serverError) {
|
|
255
|
+
const hashInput = [
|
|
256
|
+
serverError.consumer || "",
|
|
257
|
+
serverError.method.toUpperCase(),
|
|
258
|
+
serverError.path,
|
|
259
|
+
serverError.type,
|
|
260
|
+
serverError.msg.trim(),
|
|
261
|
+
serverError.traceback.trim()
|
|
262
|
+
].join("|");
|
|
263
|
+
return createHash("md5").update(hashInput).digest("hex");
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
__name(_ServerErrorCounter, "ServerErrorCounter");
|
|
267
|
+
var ServerErrorCounter = _ServerErrorCounter;
|
|
268
|
+
function truncateExceptionMessage(msg) {
|
|
269
|
+
if (msg.length <= MAX_MSG_LENGTH) {
|
|
270
|
+
return msg;
|
|
271
|
+
}
|
|
272
|
+
const suffix = "... (truncated)";
|
|
273
|
+
const cutoff = MAX_MSG_LENGTH - suffix.length;
|
|
274
|
+
return msg.substring(0, cutoff) + suffix;
|
|
275
|
+
}
|
|
276
|
+
__name(truncateExceptionMessage, "truncateExceptionMessage");
|
|
277
|
+
function truncateExceptionStackTrace(stack) {
|
|
278
|
+
const suffix = "... (truncated) ...";
|
|
279
|
+
const cutoff = MAX_STACKTRACE_LENGTH - suffix.length;
|
|
280
|
+
const lines = stack.trim().split("\n");
|
|
281
|
+
const truncatedLines = [];
|
|
282
|
+
let length = 0;
|
|
283
|
+
for (const line of lines) {
|
|
284
|
+
if (length + line.length + 1 > cutoff) {
|
|
285
|
+
truncatedLines.push(suffix);
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
truncatedLines.push(line);
|
|
289
|
+
length += line.length + 1;
|
|
290
|
+
}
|
|
291
|
+
return truncatedLines.join("\n");
|
|
292
|
+
}
|
|
293
|
+
__name(truncateExceptionStackTrace, "truncateExceptionStackTrace");
|
|
294
|
+
|
|
193
295
|
// src/common/tempGzipFile.ts
|
|
194
296
|
import { Buffer as Buffer2 } from "buffer";
|
|
195
297
|
import { randomUUID } from "crypto";
|
|
@@ -312,6 +414,7 @@ var DEFAULT_CONFIG = {
|
|
|
312
414
|
logRequestBody: false,
|
|
313
415
|
logResponseHeaders: true,
|
|
314
416
|
logResponseBody: false,
|
|
417
|
+
logException: true,
|
|
315
418
|
maskQueryParams: [],
|
|
316
419
|
maskHeaders: [],
|
|
317
420
|
excludePaths: []
|
|
@@ -384,7 +487,7 @@ var _RequestLogger = class _RequestLogger {
|
|
|
384
487
|
this.shouldMaskHeader(k) ? MASKED : v
|
|
385
488
|
]);
|
|
386
489
|
}
|
|
387
|
-
logRequest(request, response) {
|
|
490
|
+
logRequest(request, response, error) {
|
|
388
491
|
var _a2, _b, _c;
|
|
389
492
|
if (!this.enabled || this.suspendUntil !== null) return;
|
|
390
493
|
const url = new URL(request.url);
|
|
@@ -432,7 +535,13 @@ var _RequestLogger = class _RequestLogger {
|
|
|
432
535
|
const item = {
|
|
433
536
|
uuid: randomUUID2(),
|
|
434
537
|
request: skipEmptyValues(request),
|
|
435
|
-
response: skipEmptyValues(response)
|
|
538
|
+
response: skipEmptyValues(response),
|
|
539
|
+
exception: error && this.config.logException ? {
|
|
540
|
+
type: error.name,
|
|
541
|
+
message: truncateExceptionMessage(error.message),
|
|
542
|
+
stacktrace: truncateExceptionStackTrace(error.stack || ""),
|
|
543
|
+
sentryEventId: getSentryEventId()
|
|
544
|
+
} : null
|
|
436
545
|
};
|
|
437
546
|
[
|
|
438
547
|
item.request.body,
|
|
@@ -594,104 +703,6 @@ function checkWritableFs() {
|
|
|
594
703
|
}
|
|
595
704
|
__name(checkWritableFs, "checkWritableFs");
|
|
596
705
|
|
|
597
|
-
// src/common/serverErrorCounter.ts
|
|
598
|
-
import { createHash } from "crypto";
|
|
599
|
-
var MAX_MSG_LENGTH = 2048;
|
|
600
|
-
var MAX_STACKTRACE_LENGTH = 65536;
|
|
601
|
-
var _ServerErrorCounter = class _ServerErrorCounter {
|
|
602
|
-
errorCounts;
|
|
603
|
-
errorDetails;
|
|
604
|
-
sentryEventIds;
|
|
605
|
-
sentry;
|
|
606
|
-
constructor() {
|
|
607
|
-
this.errorCounts = /* @__PURE__ */ new Map();
|
|
608
|
-
this.errorDetails = /* @__PURE__ */ new Map();
|
|
609
|
-
this.sentryEventIds = /* @__PURE__ */ new Map();
|
|
610
|
-
this.tryImportSentry();
|
|
611
|
-
}
|
|
612
|
-
addServerError(serverError) {
|
|
613
|
-
const key = this.getKey(serverError);
|
|
614
|
-
if (!this.errorDetails.has(key)) {
|
|
615
|
-
this.errorDetails.set(key, serverError);
|
|
616
|
-
}
|
|
617
|
-
this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);
|
|
618
|
-
this.captureSentryEventId(key);
|
|
619
|
-
}
|
|
620
|
-
getAndResetServerErrors() {
|
|
621
|
-
const data = [];
|
|
622
|
-
this.errorCounts.forEach((count, key) => {
|
|
623
|
-
const serverError = this.errorDetails.get(key);
|
|
624
|
-
if (serverError) {
|
|
625
|
-
data.push({
|
|
626
|
-
consumer: serverError.consumer || null,
|
|
627
|
-
method: serverError.method,
|
|
628
|
-
path: serverError.path,
|
|
629
|
-
type: serverError.type,
|
|
630
|
-
msg: this.getTruncatedMessage(serverError.msg),
|
|
631
|
-
traceback: this.getTruncatedStack(serverError.traceback),
|
|
632
|
-
sentry_event_id: this.sentryEventIds.get(key) || null,
|
|
633
|
-
error_count: count
|
|
634
|
-
});
|
|
635
|
-
}
|
|
636
|
-
});
|
|
637
|
-
this.errorCounts.clear();
|
|
638
|
-
this.errorDetails.clear();
|
|
639
|
-
return data;
|
|
640
|
-
}
|
|
641
|
-
getKey(serverError) {
|
|
642
|
-
const hashInput = [
|
|
643
|
-
serverError.consumer || "",
|
|
644
|
-
serverError.method.toUpperCase(),
|
|
645
|
-
serverError.path,
|
|
646
|
-
serverError.type,
|
|
647
|
-
serverError.msg.trim(),
|
|
648
|
-
serverError.traceback.trim()
|
|
649
|
-
].join("|");
|
|
650
|
-
return createHash("md5").update(hashInput).digest("hex");
|
|
651
|
-
}
|
|
652
|
-
getTruncatedMessage(msg) {
|
|
653
|
-
msg = msg.trim();
|
|
654
|
-
if (msg.length <= MAX_MSG_LENGTH) {
|
|
655
|
-
return msg;
|
|
656
|
-
}
|
|
657
|
-
const suffix = "... (truncated)";
|
|
658
|
-
const cutoff = MAX_MSG_LENGTH - suffix.length;
|
|
659
|
-
return msg.substring(0, cutoff) + suffix;
|
|
660
|
-
}
|
|
661
|
-
getTruncatedStack(stack) {
|
|
662
|
-
const suffix = "... (truncated) ...";
|
|
663
|
-
const cutoff = MAX_STACKTRACE_LENGTH - suffix.length;
|
|
664
|
-
const lines = stack.trim().split("\n");
|
|
665
|
-
const truncatedLines = [];
|
|
666
|
-
let length = 0;
|
|
667
|
-
for (const line of lines) {
|
|
668
|
-
if (length + line.length + 1 > cutoff) {
|
|
669
|
-
truncatedLines.push(suffix);
|
|
670
|
-
break;
|
|
671
|
-
}
|
|
672
|
-
truncatedLines.push(line);
|
|
673
|
-
length += line.length + 1;
|
|
674
|
-
}
|
|
675
|
-
return truncatedLines.join("\n");
|
|
676
|
-
}
|
|
677
|
-
captureSentryEventId(serverErrorKey) {
|
|
678
|
-
if (this.sentry && this.sentry.lastEventId) {
|
|
679
|
-
const eventId = this.sentry.lastEventId();
|
|
680
|
-
if (eventId) {
|
|
681
|
-
this.sentryEventIds.set(serverErrorKey, eventId);
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
async tryImportSentry() {
|
|
686
|
-
try {
|
|
687
|
-
this.sentry = await import("@sentry/node");
|
|
688
|
-
} catch (e) {
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
};
|
|
692
|
-
__name(_ServerErrorCounter, "ServerErrorCounter");
|
|
693
|
-
var ServerErrorCounter = _ServerErrorCounter;
|
|
694
|
-
|
|
695
706
|
// src/common/validationErrorCounter.ts
|
|
696
707
|
import { createHash as createHash2 } from "crypto";
|
|
697
708
|
var _ValidationErrorCounter = class _ValidationErrorCounter {
|
|
@@ -1262,7 +1273,7 @@ var getMiddleware = /* @__PURE__ */ __name((app, client) => {
|
|
|
1262
1273
|
headers: convertHeaders(res.getHeaders()),
|
|
1263
1274
|
size: Number(res.get("content-length")),
|
|
1264
1275
|
body: convertBody(res.locals.body, res.get("content-type"))
|
|
1265
|
-
});
|
|
1276
|
+
}, res.locals.serverError);
|
|
1266
1277
|
}
|
|
1267
1278
|
} catch (error) {
|
|
1268
1279
|
client.logger.error("Error while logging request in Apitally middleware.", {
|