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.
Files changed (60) hide show
  1. package/README.md +2 -2
  2. package/dist/common/client.cjs +116 -105
  3. package/dist/common/client.cjs.map +1 -1
  4. package/dist/common/client.js +111 -100
  5. package/dist/common/client.js.map +1 -1
  6. package/dist/common/requestLogger.cjs +55 -2
  7. package/dist/common/requestLogger.cjs.map +1 -1
  8. package/dist/common/requestLogger.d.cts +2 -1
  9. package/dist/common/requestLogger.d.ts +2 -1
  10. package/dist/common/requestLogger.js +55 -2
  11. package/dist/common/requestLogger.js.map +1 -1
  12. package/dist/common/sentry.cjs +55 -0
  13. package/dist/common/sentry.cjs.map +1 -0
  14. package/dist/common/sentry.d.cts +6 -0
  15. package/dist/common/sentry.d.ts +6 -0
  16. package/dist/common/sentry.js +22 -0
  17. package/dist/common/sentry.js.map +1 -0
  18. package/dist/common/serverErrorCounter.cjs +58 -45
  19. package/dist/common/serverErrorCounter.cjs.map +1 -1
  20. package/dist/common/serverErrorCounter.d.cts +3 -6
  21. package/dist/common/serverErrorCounter.d.ts +3 -6
  22. package/dist/common/serverErrorCounter.js +53 -45
  23. package/dist/common/serverErrorCounter.js.map +1 -1
  24. package/dist/express/index.cjs +117 -106
  25. package/dist/express/index.cjs.map +1 -1
  26. package/dist/express/index.js +112 -101
  27. package/dist/express/index.js.map +1 -1
  28. package/dist/express/middleware.cjs +117 -106
  29. package/dist/express/middleware.cjs.map +1 -1
  30. package/dist/express/middleware.js +112 -101
  31. package/dist/express/middleware.js.map +1 -1
  32. package/dist/fastify/index.cjs +117 -106
  33. package/dist/fastify/index.cjs.map +1 -1
  34. package/dist/fastify/index.js +112 -101
  35. package/dist/fastify/index.js.map +1 -1
  36. package/dist/fastify/plugin.cjs +117 -106
  37. package/dist/fastify/plugin.cjs.map +1 -1
  38. package/dist/fastify/plugin.js +112 -101
  39. package/dist/fastify/plugin.js.map +1 -1
  40. package/dist/hono/index.cjs +117 -106
  41. package/dist/hono/index.cjs.map +1 -1
  42. package/dist/hono/index.js +112 -101
  43. package/dist/hono/index.js.map +1 -1
  44. package/dist/hono/middleware.cjs +117 -106
  45. package/dist/hono/middleware.cjs.map +1 -1
  46. package/dist/hono/middleware.js +112 -101
  47. package/dist/hono/middleware.js.map +1 -1
  48. package/dist/koa/index.cjs +119 -106
  49. package/dist/koa/index.cjs.map +1 -1
  50. package/dist/koa/index.js +114 -101
  51. package/dist/koa/index.js.map +1 -1
  52. package/dist/koa/middleware.cjs +119 -106
  53. package/dist/koa/middleware.cjs.map +1 -1
  54. package/dist/koa/middleware.js +114 -101
  55. package/dist/koa/middleware.js.map +1 -1
  56. package/dist/nestjs/index.cjs +117 -106
  57. package/dist/nestjs/index.cjs.map +1 -1
  58. package/dist/nestjs/index.js +112 -101
  59. package/dist/nestjs/index.js.map +1 -1
  60. package/package.json +1 -1
@@ -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.", {