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/nestjs/index.js
CHANGED
|
@@ -194,6 +194,108 @@ import { unlinkSync as unlinkSync2, writeFileSync } from "fs";
|
|
|
194
194
|
import { tmpdir as tmpdir2 } from "os";
|
|
195
195
|
import { join as join2 } from "path";
|
|
196
196
|
|
|
197
|
+
// src/common/sentry.ts
|
|
198
|
+
var sentry;
|
|
199
|
+
(async () => {
|
|
200
|
+
try {
|
|
201
|
+
sentry = await import("@sentry/node");
|
|
202
|
+
} catch (e) {
|
|
203
|
+
}
|
|
204
|
+
})();
|
|
205
|
+
function getSentryEventId() {
|
|
206
|
+
if (sentry && sentry.lastEventId) {
|
|
207
|
+
return sentry.lastEventId();
|
|
208
|
+
}
|
|
209
|
+
return void 0;
|
|
210
|
+
}
|
|
211
|
+
__name(getSentryEventId, "getSentryEventId");
|
|
212
|
+
|
|
213
|
+
// src/common/serverErrorCounter.ts
|
|
214
|
+
import { createHash } from "crypto";
|
|
215
|
+
var MAX_MSG_LENGTH = 2048;
|
|
216
|
+
var MAX_STACKTRACE_LENGTH = 65536;
|
|
217
|
+
var _ServerErrorCounter = class _ServerErrorCounter {
|
|
218
|
+
errorCounts;
|
|
219
|
+
errorDetails;
|
|
220
|
+
sentryEventIds;
|
|
221
|
+
constructor() {
|
|
222
|
+
this.errorCounts = /* @__PURE__ */ new Map();
|
|
223
|
+
this.errorDetails = /* @__PURE__ */ new Map();
|
|
224
|
+
this.sentryEventIds = /* @__PURE__ */ new Map();
|
|
225
|
+
}
|
|
226
|
+
addServerError(serverError) {
|
|
227
|
+
const key = this.getKey(serverError);
|
|
228
|
+
if (!this.errorDetails.has(key)) {
|
|
229
|
+
this.errorDetails.set(key, serverError);
|
|
230
|
+
}
|
|
231
|
+
this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);
|
|
232
|
+
const sentryEventId = getSentryEventId();
|
|
233
|
+
if (sentryEventId) {
|
|
234
|
+
this.sentryEventIds.set(key, sentryEventId);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
getAndResetServerErrors() {
|
|
238
|
+
const data = [];
|
|
239
|
+
this.errorCounts.forEach((count, key) => {
|
|
240
|
+
const serverError = this.errorDetails.get(key);
|
|
241
|
+
if (serverError) {
|
|
242
|
+
data.push({
|
|
243
|
+
consumer: serverError.consumer || null,
|
|
244
|
+
method: serverError.method,
|
|
245
|
+
path: serverError.path,
|
|
246
|
+
type: serverError.type,
|
|
247
|
+
msg: truncateExceptionMessage(serverError.msg),
|
|
248
|
+
traceback: truncateExceptionStackTrace(serverError.traceback),
|
|
249
|
+
sentry_event_id: this.sentryEventIds.get(key) || null,
|
|
250
|
+
error_count: count
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
this.errorCounts.clear();
|
|
255
|
+
this.errorDetails.clear();
|
|
256
|
+
return data;
|
|
257
|
+
}
|
|
258
|
+
getKey(serverError) {
|
|
259
|
+
const hashInput = [
|
|
260
|
+
serverError.consumer || "",
|
|
261
|
+
serverError.method.toUpperCase(),
|
|
262
|
+
serverError.path,
|
|
263
|
+
serverError.type,
|
|
264
|
+
serverError.msg.trim(),
|
|
265
|
+
serverError.traceback.trim()
|
|
266
|
+
].join("|");
|
|
267
|
+
return createHash("md5").update(hashInput).digest("hex");
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
__name(_ServerErrorCounter, "ServerErrorCounter");
|
|
271
|
+
var ServerErrorCounter = _ServerErrorCounter;
|
|
272
|
+
function truncateExceptionMessage(msg) {
|
|
273
|
+
if (msg.length <= MAX_MSG_LENGTH) {
|
|
274
|
+
return msg;
|
|
275
|
+
}
|
|
276
|
+
const suffix = "... (truncated)";
|
|
277
|
+
const cutoff = MAX_MSG_LENGTH - suffix.length;
|
|
278
|
+
return msg.substring(0, cutoff) + suffix;
|
|
279
|
+
}
|
|
280
|
+
__name(truncateExceptionMessage, "truncateExceptionMessage");
|
|
281
|
+
function truncateExceptionStackTrace(stack) {
|
|
282
|
+
const suffix = "... (truncated) ...";
|
|
283
|
+
const cutoff = MAX_STACKTRACE_LENGTH - suffix.length;
|
|
284
|
+
const lines = stack.trim().split("\n");
|
|
285
|
+
const truncatedLines = [];
|
|
286
|
+
let length = 0;
|
|
287
|
+
for (const line of lines) {
|
|
288
|
+
if (length + line.length + 1 > cutoff) {
|
|
289
|
+
truncatedLines.push(suffix);
|
|
290
|
+
break;
|
|
291
|
+
}
|
|
292
|
+
truncatedLines.push(line);
|
|
293
|
+
length += line.length + 1;
|
|
294
|
+
}
|
|
295
|
+
return truncatedLines.join("\n");
|
|
296
|
+
}
|
|
297
|
+
__name(truncateExceptionStackTrace, "truncateExceptionStackTrace");
|
|
298
|
+
|
|
197
299
|
// src/common/tempGzipFile.ts
|
|
198
300
|
import { Buffer as Buffer2 } from "buffer";
|
|
199
301
|
import { randomUUID } from "crypto";
|
|
@@ -316,6 +418,7 @@ var DEFAULT_CONFIG = {
|
|
|
316
418
|
logRequestBody: false,
|
|
317
419
|
logResponseHeaders: true,
|
|
318
420
|
logResponseBody: false,
|
|
421
|
+
logException: true,
|
|
319
422
|
maskQueryParams: [],
|
|
320
423
|
maskHeaders: [],
|
|
321
424
|
excludePaths: []
|
|
@@ -388,7 +491,7 @@ var _RequestLogger = class _RequestLogger {
|
|
|
388
491
|
this.shouldMaskHeader(k) ? MASKED : v
|
|
389
492
|
]);
|
|
390
493
|
}
|
|
391
|
-
logRequest(request, response) {
|
|
494
|
+
logRequest(request, response, error) {
|
|
392
495
|
var _a3, _b, _c;
|
|
393
496
|
if (!this.enabled || this.suspendUntil !== null) return;
|
|
394
497
|
const url = new URL(request.url);
|
|
@@ -436,7 +539,13 @@ var _RequestLogger = class _RequestLogger {
|
|
|
436
539
|
const item = {
|
|
437
540
|
uuid: randomUUID2(),
|
|
438
541
|
request: skipEmptyValues(request),
|
|
439
|
-
response: skipEmptyValues(response)
|
|
542
|
+
response: skipEmptyValues(response),
|
|
543
|
+
exception: error && this.config.logException ? {
|
|
544
|
+
type: error.name,
|
|
545
|
+
message: truncateExceptionMessage(error.message),
|
|
546
|
+
stacktrace: truncateExceptionStackTrace(error.stack || ""),
|
|
547
|
+
sentryEventId: getSentryEventId()
|
|
548
|
+
} : null
|
|
440
549
|
};
|
|
441
550
|
[
|
|
442
551
|
item.request.body,
|
|
@@ -598,104 +707,6 @@ function checkWritableFs() {
|
|
|
598
707
|
}
|
|
599
708
|
__name(checkWritableFs, "checkWritableFs");
|
|
600
709
|
|
|
601
|
-
// src/common/serverErrorCounter.ts
|
|
602
|
-
import { createHash } from "crypto";
|
|
603
|
-
var MAX_MSG_LENGTH = 2048;
|
|
604
|
-
var MAX_STACKTRACE_LENGTH = 65536;
|
|
605
|
-
var _ServerErrorCounter = class _ServerErrorCounter {
|
|
606
|
-
errorCounts;
|
|
607
|
-
errorDetails;
|
|
608
|
-
sentryEventIds;
|
|
609
|
-
sentry;
|
|
610
|
-
constructor() {
|
|
611
|
-
this.errorCounts = /* @__PURE__ */ new Map();
|
|
612
|
-
this.errorDetails = /* @__PURE__ */ new Map();
|
|
613
|
-
this.sentryEventIds = /* @__PURE__ */ new Map();
|
|
614
|
-
this.tryImportSentry();
|
|
615
|
-
}
|
|
616
|
-
addServerError(serverError) {
|
|
617
|
-
const key = this.getKey(serverError);
|
|
618
|
-
if (!this.errorDetails.has(key)) {
|
|
619
|
-
this.errorDetails.set(key, serverError);
|
|
620
|
-
}
|
|
621
|
-
this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);
|
|
622
|
-
this.captureSentryEventId(key);
|
|
623
|
-
}
|
|
624
|
-
getAndResetServerErrors() {
|
|
625
|
-
const data = [];
|
|
626
|
-
this.errorCounts.forEach((count, key) => {
|
|
627
|
-
const serverError = this.errorDetails.get(key);
|
|
628
|
-
if (serverError) {
|
|
629
|
-
data.push({
|
|
630
|
-
consumer: serverError.consumer || null,
|
|
631
|
-
method: serverError.method,
|
|
632
|
-
path: serverError.path,
|
|
633
|
-
type: serverError.type,
|
|
634
|
-
msg: this.getTruncatedMessage(serverError.msg),
|
|
635
|
-
traceback: this.getTruncatedStack(serverError.traceback),
|
|
636
|
-
sentry_event_id: this.sentryEventIds.get(key) || null,
|
|
637
|
-
error_count: count
|
|
638
|
-
});
|
|
639
|
-
}
|
|
640
|
-
});
|
|
641
|
-
this.errorCounts.clear();
|
|
642
|
-
this.errorDetails.clear();
|
|
643
|
-
return data;
|
|
644
|
-
}
|
|
645
|
-
getKey(serverError) {
|
|
646
|
-
const hashInput = [
|
|
647
|
-
serverError.consumer || "",
|
|
648
|
-
serverError.method.toUpperCase(),
|
|
649
|
-
serverError.path,
|
|
650
|
-
serverError.type,
|
|
651
|
-
serverError.msg.trim(),
|
|
652
|
-
serverError.traceback.trim()
|
|
653
|
-
].join("|");
|
|
654
|
-
return createHash("md5").update(hashInput).digest("hex");
|
|
655
|
-
}
|
|
656
|
-
getTruncatedMessage(msg) {
|
|
657
|
-
msg = msg.trim();
|
|
658
|
-
if (msg.length <= MAX_MSG_LENGTH) {
|
|
659
|
-
return msg;
|
|
660
|
-
}
|
|
661
|
-
const suffix = "... (truncated)";
|
|
662
|
-
const cutoff = MAX_MSG_LENGTH - suffix.length;
|
|
663
|
-
return msg.substring(0, cutoff) + suffix;
|
|
664
|
-
}
|
|
665
|
-
getTruncatedStack(stack) {
|
|
666
|
-
const suffix = "... (truncated) ...";
|
|
667
|
-
const cutoff = MAX_STACKTRACE_LENGTH - suffix.length;
|
|
668
|
-
const lines = stack.trim().split("\n");
|
|
669
|
-
const truncatedLines = [];
|
|
670
|
-
let length = 0;
|
|
671
|
-
for (const line of lines) {
|
|
672
|
-
if (length + line.length + 1 > cutoff) {
|
|
673
|
-
truncatedLines.push(suffix);
|
|
674
|
-
break;
|
|
675
|
-
}
|
|
676
|
-
truncatedLines.push(line);
|
|
677
|
-
length += line.length + 1;
|
|
678
|
-
}
|
|
679
|
-
return truncatedLines.join("\n");
|
|
680
|
-
}
|
|
681
|
-
captureSentryEventId(serverErrorKey) {
|
|
682
|
-
if (this.sentry && this.sentry.lastEventId) {
|
|
683
|
-
const eventId = this.sentry.lastEventId();
|
|
684
|
-
if (eventId) {
|
|
685
|
-
this.sentryEventIds.set(serverErrorKey, eventId);
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
async tryImportSentry() {
|
|
690
|
-
try {
|
|
691
|
-
this.sentry = await import("@sentry/node");
|
|
692
|
-
} catch (e) {
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
};
|
|
696
|
-
__name(_ServerErrorCounter, "ServerErrorCounter");
|
|
697
|
-
var ServerErrorCounter = _ServerErrorCounter;
|
|
698
|
-
|
|
699
710
|
// src/common/validationErrorCounter.ts
|
|
700
711
|
import { createHash as createHash2 } from "crypto";
|
|
701
712
|
var _ValidationErrorCounter = class _ValidationErrorCounter {
|
|
@@ -1266,7 +1277,7 @@ var getMiddleware = /* @__PURE__ */ __name((app, client) => {
|
|
|
1266
1277
|
headers: convertHeaders(res.getHeaders()),
|
|
1267
1278
|
size: Number(res.get("content-length")),
|
|
1268
1279
|
body: convertBody(res.locals.body, res.get("content-type"))
|
|
1269
|
-
});
|
|
1280
|
+
}, res.locals.serverError);
|
|
1270
1281
|
}
|
|
1271
1282
|
} catch (error) {
|
|
1272
1283
|
client.logger.error("Error while logging request in Apitally middleware.", {
|