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
@@ -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.", {