@loggerjs/node 0.0.2 → 0.1.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/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createRequire } from "node:module";
2
- import { batchTransport, createBoundContext, incrementLoggerMetaCounter, ndjsonCodec, normalizeValue, resetContextManager, safeJsonCodec, safeJsonStringify, setContextManager, toLevelValue, withContext } from "@loggerjs/core";
2
+ import { applyPayloadTransforms, batchTransport, createBoundContext, encodedPayloadToUint8Array, incrementLoggerMetaCounter, ndjsonCodec, normalizeValue, resetContextManager, safeJsonCodec, safeJsonStringify, setContextManager, toLevelValue, withContext } from "@loggerjs/core";
3
3
  import { closeSync, createWriteStream, existsSync, openSync, renameSync, statSync, unlinkSync, writeSync } from "fs";
4
+ import { brotliCompressSync, deflateSync, gzipSync } from "node:zlib";
4
5
  import { createSocket } from "dgram";
5
6
  import { createConnection } from "net";
6
7
  import { hostname } from "os";
@@ -252,13 +253,19 @@ function nodeHttpTransport(options) {
252
253
  minLevel: options.minLevel,
253
254
  async logBatch(events) {
254
255
  if (!fetchFn) throw new Error("fetch is not available. Use Node.js 18+ or pass fetchFn.");
256
+ const transformed = await applyPayloadTransforms(codec.encode(events), {
257
+ contentType: codec.contentType,
258
+ events,
259
+ transport: options.name ?? "node-http"
260
+ }, options.transformPayload);
255
261
  const response = await fetchFn(options.url, {
256
262
  method: options.method ?? "POST",
257
263
  headers: {
258
- "content-type": codec.contentType,
264
+ "content-type": transformed.contentType,
265
+ ...transformed.headers,
259
266
  ...options.headers
260
267
  },
261
- body: payloadToBody(codec.encode(events))
268
+ body: payloadToBody(transformed.payload)
262
269
  });
263
270
  if (!response.ok) throw new Error(`nodeHttpTransport failed with status ${response.status}`);
264
271
  }
@@ -283,6 +290,29 @@ function nodeHttpTransport(options) {
283
290
  });
284
291
  }
285
292
  //#endregion
293
+ //#region src/payload-transforms.ts
294
+ const contentEncodingByFormat = {
295
+ gzip: "gzip",
296
+ brotli: "br",
297
+ deflate: "deflate"
298
+ };
299
+ function compressPayload(payload, format, options) {
300
+ const input = encodedPayloadToUint8Array(payload);
301
+ if (format === "brotli") return Uint8Array.from(brotliCompressSync(input, options.brotliOptions));
302
+ if (format === "deflate") return Uint8Array.from(deflateSync(input, options.deflateOptions));
303
+ return Uint8Array.from(gzipSync(input, options.gzipOptions));
304
+ }
305
+ function nodeCompressionPayloadTransform(options = {}) {
306
+ const format = options.format ?? "gzip";
307
+ return (payload) => ({
308
+ payload: compressPayload(payload, format, options),
309
+ headers: {
310
+ "content-encoding": contentEncodingByFormat[format],
311
+ ...options.headers
312
+ }
313
+ });
314
+ }
315
+ //#endregion
286
316
  //#region src/syslog-transport.ts
287
317
  const severityByLevel = {
288
318
  trace: 7,
@@ -546,6 +576,170 @@ function installAsyncLocalStorageContext(manager = createAsyncLocalStorageContex
546
576
  };
547
577
  }
548
578
  //#endregion
579
+ //#region src/queue-integration.ts
580
+ const defaultMethods$1 = [
581
+ "add",
582
+ "ack",
583
+ "consume",
584
+ "dequeue",
585
+ "nack",
586
+ "process",
587
+ "publish",
588
+ "receive",
589
+ "send",
590
+ "sendToQueue"
591
+ ];
592
+ const defaultRandom$6 = () => Math.random();
593
+ function defaultLevel$6(_durationMs, error) {
594
+ return error ? "error" : "debug";
595
+ }
596
+ function isPromiseLike$2(value) {
597
+ return typeof value === "object" && value !== null && typeof value.then === "function";
598
+ }
599
+ function defaultOperation$1(method) {
600
+ switch (method) {
601
+ case "add":
602
+ case "publish":
603
+ case "send":
604
+ case "sendToQueue": return "publish";
605
+ case "consume":
606
+ case "dequeue":
607
+ case "process":
608
+ case "receive": return "consume";
609
+ case "ack": return "ack";
610
+ case "nack": return "nack";
611
+ default: return "other";
612
+ }
613
+ }
614
+ function defaultPayload(args) {
615
+ return typeof args[0] === "string" && args.length > 1 ? args[1] : args[0];
616
+ }
617
+ function defaultMessageId(args) {
618
+ const payload = defaultPayload(args);
619
+ if (typeof payload !== "object" || payload === null) return void 0;
620
+ const value = payload.messageId ?? payload.id;
621
+ return value === void 0 ? void 0 : String(value);
622
+ }
623
+ function payloadFor(args, method, options) {
624
+ if (!options.capturePayload) return void 0;
625
+ const payload = options.getPayload?.(args, method) ?? defaultPayload(args);
626
+ return payload === void 0 ? void 0 : normalizeValue(payload, {
627
+ maxDepth: 4,
628
+ maxObjectKeys: 80
629
+ });
630
+ }
631
+ function queueIntegration(options = {}) {
632
+ const targets = options.targets ?? (options.client ? [{
633
+ client: options.client,
634
+ name: options.name,
635
+ system: options.system,
636
+ queueName: options.queueName,
637
+ methods: options.methods
638
+ }] : []);
639
+ const captureAll = options.captureAll ?? options.captureSuccessful ?? false;
640
+ const sampleRate = options.sampleRate ?? 1;
641
+ const random = options.random ?? defaultRandom$6;
642
+ const levelFor = options.level ?? defaultLevel$6;
643
+ const shouldCapture = (durationMs, error) => {
644
+ if (error) return true;
645
+ if (options.minDurationMs !== void 0 && durationMs >= options.minDurationMs) return true;
646
+ if (!captureAll) return false;
647
+ return sampleRate >= 1 || random() < sampleRate;
648
+ };
649
+ return {
650
+ name: "queue",
651
+ setup(api) {
652
+ const capture = api.guard((input) => api.capture(input));
653
+ const disposers = [];
654
+ let disposed = false;
655
+ const captureResult = (info, started, args, error) => {
656
+ const durationMs = Date.now() - started;
657
+ if (disposed || !shouldCapture(durationMs, error)) return;
658
+ capture({
659
+ level: levelFor(durationMs, error, info),
660
+ message: error ? `Queue error ${info.operation} ${info.queueName ?? info.method}` : `Queue ${info.operation} ${info.queueName ?? info.method}`,
661
+ error,
662
+ props: { queue: {
663
+ kind: info.target,
664
+ system: info.system,
665
+ queueName: info.queueName,
666
+ method: info.method,
667
+ operation: info.operation,
668
+ durationMs,
669
+ messageId: options.getMessageId?.(args, info.method) ?? defaultMessageId(args),
670
+ payload: payloadFor(args, info.method, options)
671
+ } }
672
+ });
673
+ };
674
+ for (const target of targets) {
675
+ const methods = target.methods ?? options.methods ?? defaultMethods$1;
676
+ for (const method of methods) {
677
+ const original = target.client[method];
678
+ if (typeof original !== "function") continue;
679
+ const originalMethod = original;
680
+ const targetName = target.name ?? options.name ?? "queue";
681
+ const system = target.system ?? options.system;
682
+ target.client[method] = function wrappedQueueMethod(...args) {
683
+ const started = Date.now();
684
+ const operation = options.getOperation?.(method, args) ?? defaultOperation$1(method);
685
+ const info = {
686
+ target: targetName,
687
+ system,
688
+ queueName: options.getQueueName?.(args, method) ?? target.queueName ?? options.queueName ?? (typeof args[0] === "string" ? args[0] : void 0),
689
+ method,
690
+ operation
691
+ };
692
+ try {
693
+ const result = originalMethod.apply(this, args);
694
+ if (isPromiseLike$2(result)) return result.then((value) => {
695
+ captureResult(info, started, args, void 0);
696
+ return value;
697
+ }, (error) => {
698
+ captureResult(info, started, args, error);
699
+ throw error;
700
+ });
701
+ captureResult(info, started, args, void 0);
702
+ return result;
703
+ } catch (error) {
704
+ captureResult(info, started, args, error);
705
+ throw error;
706
+ }
707
+ };
708
+ disposers.push(() => {
709
+ target.client[method] = originalMethod;
710
+ });
711
+ }
712
+ }
713
+ return () => {
714
+ if (disposed) return;
715
+ disposed = true;
716
+ for (const dispose of disposers) dispose();
717
+ };
718
+ }
719
+ };
720
+ }
721
+ //#endregion
722
+ //#region src/bullmq-integration.ts
723
+ const bullMqMethods = [
724
+ "add",
725
+ "addBulk",
726
+ "process"
727
+ ];
728
+ function queueName(args, fallback) {
729
+ const first = args[0];
730
+ return typeof first === "string" ? first : fallback;
731
+ }
732
+ function bullMqIntegration(options) {
733
+ return queueIntegration({
734
+ ...options,
735
+ name: options.name ?? "bullmq",
736
+ system: "bullmq",
737
+ methods: options.methods ?? bullMqMethods,
738
+ queueName: options.queueName ?? options.client.name,
739
+ getQueueName: (args) => queueName(args, options.queueName ?? options.client.name)
740
+ });
741
+ }
742
+ //#endregion
549
743
  //#region src/cli-integration.ts
550
744
  const defaultSignals = ["SIGINT", "SIGTERM"];
551
745
  function defaultProcess() {
@@ -558,7 +752,7 @@ function defaultSanitizeArg(arg) {
558
752
  function defaultCommand(argv) {
559
753
  return argv[1] ?? argv[0];
560
754
  }
561
- function levelFor(level, event, code) {
755
+ function levelFor$2(level, event, code) {
562
756
  if (typeof level === "function") return level(event, code);
563
757
  if (level) return level;
564
758
  if (event === "signal") return "warn";
@@ -611,7 +805,7 @@ function captureCliIntegration(options = {}) {
611
805
  env: pickEnv(processLike.env, options.captureEnv)
612
806
  };
613
807
  if (captureStart) capture({
614
- level: levelFor(options.level, "start"),
808
+ level: levelFor$2(options.level, "start"),
615
809
  message: `CLI start${command ? ` ${command}` : ""}`,
616
810
  props: { cli: {
617
811
  ...cliBase,
@@ -622,7 +816,7 @@ function captureCliIntegration(options = {}) {
622
816
  const onExit = (code) => {
623
817
  const exitCode = code ?? processLike.exitCode ?? 0;
624
818
  capture({
625
- level: levelFor(options.level, "exit", exitCode),
819
+ level: levelFor$2(options.level, "exit", exitCode),
626
820
  message: `CLI exit ${String(exitCode)}`,
627
821
  props: { cli: {
628
822
  ...cliBase,
@@ -637,7 +831,7 @@ function captureCliIntegration(options = {}) {
637
831
  if (captureSignals && processLike.on) for (const signal of signals) {
638
832
  const onSignal = () => {
639
833
  capture({
640
- level: levelFor(options.level, "signal", signal),
834
+ level: levelFor$2(options.level, "signal", signal),
641
835
  message: `CLI signal ${signal}`,
642
836
  props: { cli: {
643
837
  ...cliBase,
@@ -659,18 +853,18 @@ function captureCliIntegration(options = {}) {
659
853
  }
660
854
  //#endregion
661
855
  //#region src/database-integration.ts
662
- const defaultMethods$1 = [
856
+ const defaultMethods = [
663
857
  "query",
664
858
  "execute",
665
859
  "run",
666
860
  "all",
667
861
  "get"
668
862
  ];
669
- const defaultRandom$6 = () => Math.random();
670
- function defaultLevel$6(_durationMs, error) {
863
+ const defaultRandom$5 = () => Math.random();
864
+ function defaultLevel$5(_durationMs, error) {
671
865
  return error ? "error" : "debug";
672
866
  }
673
- function isPromiseLike$2(value) {
867
+ function isPromiseLike$1(value) {
674
868
  return typeof value === "object" && value !== null && typeof value.then === "function";
675
869
  }
676
870
  function defaultStatement(args) {
@@ -704,8 +898,8 @@ function databaseIntegration(options = {}) {
704
898
  }] : []);
705
899
  const captureAll = options.captureAll ?? options.captureSuccessful ?? false;
706
900
  const sampleRate = options.sampleRate ?? 1;
707
- const random = options.random ?? defaultRandom$6;
708
- const levelFor = options.level ?? defaultLevel$6;
901
+ const random = options.random ?? defaultRandom$5;
902
+ const levelFor = options.level ?? defaultLevel$5;
709
903
  const shouldCapture = (durationMs, error) => {
710
904
  if (error) return true;
711
905
  if (options.minDurationMs !== void 0 && durationMs >= options.minDurationMs) return true;
@@ -736,7 +930,7 @@ function databaseIntegration(options = {}) {
736
930
  });
737
931
  };
738
932
  for (const target of targets) {
739
- const methods = target.methods ?? options.methods ?? defaultMethods$1;
933
+ const methods = target.methods ?? options.methods ?? defaultMethods;
740
934
  for (const method of methods) {
741
935
  const original = target.client[method];
742
936
  if (typeof original !== "function") continue;
@@ -753,7 +947,7 @@ function databaseIntegration(options = {}) {
753
947
  };
754
948
  try {
755
949
  const result = originalMethod.apply(this, args);
756
- if (isPromiseLike$2(result)) return result.then((value) => {
950
+ if (isPromiseLike$1(result)) return result.then((value) => {
757
951
  captureResult(info, started, args, void 0);
758
952
  return value;
759
953
  }, (error) => {
@@ -782,14 +976,14 @@ function databaseIntegration(options = {}) {
782
976
  }
783
977
  //#endregion
784
978
  //#region src/express-integration.ts
785
- const defaultRandom$5 = () => Math.random();
979
+ const defaultRandom$4 = () => Math.random();
786
980
  function defaultSanitizeUrl$3(url) {
787
981
  const queryIndex = url.indexOf("?");
788
982
  const hashIndex = url.indexOf("#");
789
983
  const end = Math.min(queryIndex >= 0 ? queryIndex : url.length, hashIndex >= 0 ? hashIndex : url.length);
790
984
  return url.slice(0, end);
791
985
  }
792
- function defaultLevel$5(status, _req, _res, aborted) {
986
+ function defaultLevel$4(status, _req, _res, aborted) {
793
987
  if (aborted) return "warn";
794
988
  if (status >= 500) return "error";
795
989
  if (status >= 400) return "warn";
@@ -844,9 +1038,9 @@ function expressIntegration(logger, options = {}) {
844
1038
  const captureAll = options.captureAll ?? options.captureSuccessful ?? false;
845
1039
  const captureAborted = options.captureAborted ?? true;
846
1040
  const sampleRate = options.sampleRate ?? 1;
847
- const random = options.random ?? defaultRandom$5;
1041
+ const random = options.random ?? defaultRandom$4;
848
1042
  const sanitizeUrl = options.sanitizeUrl ?? defaultSanitizeUrl$3;
849
- const levelFor = options.level ?? defaultLevel$5;
1043
+ const levelFor = options.level ?? defaultLevel$4;
850
1044
  const routeFor = options.getRoute ?? defaultRoute$1;
851
1045
  const bindContext = options.bindContext ?? true;
852
1046
  return (req, res, next) => {
@@ -907,14 +1101,14 @@ function expressIntegration(logger, options = {}) {
907
1101
  }
908
1102
  //#endregion
909
1103
  //#region src/fastify-integration.ts
910
- const defaultRandom$4 = () => Math.random();
1104
+ const defaultRandom$3 = () => Math.random();
911
1105
  function defaultSanitizeUrl$2(url) {
912
1106
  const queryIndex = url.indexOf("?");
913
1107
  const hashIndex = url.indexOf("#");
914
1108
  const end = Math.min(queryIndex >= 0 ? queryIndex : url.length, hashIndex >= 0 ? hashIndex : url.length);
915
1109
  return url.slice(0, end);
916
1110
  }
917
- function defaultLevel$4(status, _request, _reply, error) {
1111
+ function defaultLevel$3(status, _request, _reply, error) {
918
1112
  if (error || status >= 500) return "error";
919
1113
  if (status >= 400) return "warn";
920
1114
  return "info";
@@ -949,9 +1143,9 @@ function fastifyIntegration(logger, options = {}) {
949
1143
  const minStatus = options.minStatus ?? 400;
950
1144
  const captureAll = options.captureAll ?? options.captureSuccessful ?? false;
951
1145
  const sampleRate = options.sampleRate ?? 1;
952
- const random = options.random ?? defaultRandom$4;
1146
+ const random = options.random ?? defaultRandom$3;
953
1147
  const sanitizeUrl = options.sanitizeUrl ?? defaultSanitizeUrl$2;
954
- const levelFor = options.level ?? defaultLevel$4;
1148
+ const levelFor = options.level ?? defaultLevel$3;
955
1149
  const routeFor = options.getRoute ?? defaultRoute;
956
1150
  const bindContext = options.bindContext ?? true;
957
1151
  const states = /* @__PURE__ */ new WeakMap();
@@ -1021,15 +1215,131 @@ function fastifyIntegration(logger, options = {}) {
1021
1215
  };
1022
1216
  }
1023
1217
  //#endregion
1218
+ //#region src/hapi-integration.ts
1219
+ function responseStatus(response) {
1220
+ if (!response) return 200;
1221
+ if ("statusCode" in response && typeof response.statusCode === "number") return response.statusCode;
1222
+ if ("output" in response && typeof response.output?.statusCode === "number") return response.output.statusCode;
1223
+ return 200;
1224
+ }
1225
+ function levelFor$1(status) {
1226
+ if (status >= 500) return "error";
1227
+ if (status >= 400) return "warn";
1228
+ return "info";
1229
+ }
1230
+ function hapiIntegration(logger, options = {}) {
1231
+ const minStatus = options.minStatus ?? 400;
1232
+ const captureAll = options.captureAll ?? false;
1233
+ const bindContext = options.bindContext ?? true;
1234
+ const getLevel = options.level ?? levelFor$1;
1235
+ return {
1236
+ name: "loggerjs-hapi",
1237
+ register(server) {
1238
+ server.ext("onRequest", (request, h) => {
1239
+ const context = {
1240
+ httpMethod: (request.method ?? "GET").toUpperCase(),
1241
+ httpUrl: request.url?.pathname ?? request.path ?? "/",
1242
+ requestId: options.getRequestId?.(request) ?? request.info?.id,
1243
+ ...options.context?.(request)
1244
+ };
1245
+ request.app = {
1246
+ ...request.app,
1247
+ loggerjsStartedAt: Date.now()
1248
+ };
1249
+ if (bindContext) return withContext(context, () => h.continue);
1250
+ return h.continue;
1251
+ });
1252
+ server.events?.on?.("response", (request) => {
1253
+ const status = responseStatus(request.response);
1254
+ if (!captureAll && status < minStatus) return;
1255
+ const method = (request.method ?? "GET").toUpperCase();
1256
+ const url = request.url?.pathname ?? request.path ?? "/";
1257
+ const requestId = options.getRequestId?.(request) ?? request.info?.id;
1258
+ const started = request.app?.loggerjsStartedAt;
1259
+ logger.log(getLevel(status, request), `Hapi ${status} ${method} ${url}`, { http: {
1260
+ framework: "hapi",
1261
+ kind: "hapi",
1262
+ method,
1263
+ url,
1264
+ status,
1265
+ durationMs: started ? Date.now() - started : void 0,
1266
+ requestId,
1267
+ remoteAddress: request.info?.remoteAddress
1268
+ } });
1269
+ });
1270
+ }
1271
+ };
1272
+ }
1273
+ //#endregion
1274
+ //#region src/koa-integration.ts
1275
+ function sanitizeUrl(url) {
1276
+ return url.split(/[?#]/, 1)[0] || "/";
1277
+ }
1278
+ function levelFor(status, _ctx, error) {
1279
+ if (error || status >= 500) return "error";
1280
+ if (status >= 400) return "warn";
1281
+ return "info";
1282
+ }
1283
+ function koaIntegration(logger, options = {}) {
1284
+ const minStatus = options.minStatus ?? 400;
1285
+ const captureAll = options.captureAll ?? false;
1286
+ const bindContext = options.bindContext ?? true;
1287
+ const sanitize = options.sanitizeUrl ?? sanitizeUrl;
1288
+ const getLevel = options.level ?? levelFor;
1289
+ return async (ctx, next) => {
1290
+ const started = Date.now();
1291
+ const method = (ctx.method ?? "GET").toUpperCase();
1292
+ const url = sanitize(ctx.originalUrl ?? ctx.url ?? ctx.path ?? "/");
1293
+ const requestId = options.getRequestId?.(ctx) ?? ctx.state?.requestId;
1294
+ const context = {
1295
+ httpMethod: method,
1296
+ httpUrl: url,
1297
+ requestId,
1298
+ ...options.context?.(ctx)
1299
+ };
1300
+ let error;
1301
+ try {
1302
+ if (bindContext) await withContext(context, next);
1303
+ else await next();
1304
+ } catch (caught) {
1305
+ error = caught;
1306
+ throw caught;
1307
+ } finally {
1308
+ const status = ctx.status ?? (error ? 500 : 200);
1309
+ if (error || captureAll || status >= minStatus) logger.log(getLevel(status, ctx, error), `Koa ${status} ${method} ${url}`, {
1310
+ http: {
1311
+ framework: "koa",
1312
+ kind: "koa",
1313
+ method,
1314
+ url,
1315
+ status,
1316
+ durationMs: Date.now() - started,
1317
+ requestId,
1318
+ remoteAddress: ctx.ip
1319
+ },
1320
+ error
1321
+ });
1322
+ }
1323
+ };
1324
+ }
1325
+ //#endregion
1326
+ //#region src/nest-integration.ts
1327
+ function nestMiddlewareIntegration(logger, options = {}) {
1328
+ return expressIntegration(logger, {
1329
+ name: "nestjs",
1330
+ ...options
1331
+ });
1332
+ }
1333
+ //#endregion
1024
1334
  //#region src/node-fetch-integration.ts
1025
- const defaultRandom$3 = () => Math.random();
1335
+ const defaultRandom$2 = () => Math.random();
1026
1336
  function defaultSanitizeUrl$1(url) {
1027
1337
  const queryIndex = url.indexOf("?");
1028
1338
  const hashIndex = url.indexOf("#");
1029
1339
  const end = Math.min(queryIndex >= 0 ? queryIndex : url.length, hashIndex >= 0 ? hashIndex : url.length);
1030
1340
  return url.slice(0, end);
1031
1341
  }
1032
- function defaultLevel$3(status, error) {
1342
+ function defaultLevel$2(status, error) {
1033
1343
  if (error || status === void 0 || status >= 500) return "error";
1034
1344
  if (status >= 400) return "warn";
1035
1345
  return "info";
@@ -1072,9 +1382,9 @@ function nodeFetchIntegration(options = {}) {
1072
1382
  const minStatus = options.minStatus ?? 400;
1073
1383
  const captureAll = options.captureAll ?? options.captureSuccessful ?? false;
1074
1384
  const sampleRate = options.sampleRate ?? 1;
1075
- const random = options.random ?? defaultRandom$3;
1385
+ const random = options.random ?? defaultRandom$2;
1076
1386
  const sanitizeUrl = options.sanitizeUrl ?? defaultSanitizeUrl$1;
1077
- const levelFor = options.level ?? defaultLevel$3;
1387
+ const levelFor = options.level ?? defaultLevel$2;
1078
1388
  const shouldCapture = (status, error) => {
1079
1389
  if (error) return true;
1080
1390
  if (status !== void 0 && status >= minStatus) return true;
@@ -1132,7 +1442,7 @@ function nodeFetchIntegration(options = {}) {
1132
1442
  //#endregion
1133
1443
  //#region src/node-http-client-integration.ts
1134
1444
  const requireBuiltin$1 = createRequire(import.meta.url);
1135
- const defaultRandom$2 = () => Math.random();
1445
+ const defaultRandom$1 = () => Math.random();
1136
1446
  let cachedHttpModule;
1137
1447
  let cachedHttpsModule;
1138
1448
  function loadBuiltin(name, fallback) {
@@ -1162,7 +1472,7 @@ function defaultSanitizeUrl(url) {
1162
1472
  const end = Math.min(queryIndex >= 0 ? queryIndex : url.length, hashIndex >= 0 ? hashIndex : url.length);
1163
1473
  return url.slice(0, end);
1164
1474
  }
1165
- function defaultLevel$2(status, error) {
1475
+ function defaultLevel$1(status, error) {
1166
1476
  if (error || status === void 0 || status >= 500) return "error";
1167
1477
  if (status >= 400) return "warn";
1168
1478
  return "info";
@@ -1247,9 +1557,9 @@ function nodeHttpClientIntegration(options = {}) {
1247
1557
  const minStatus = options.minStatus ?? 400;
1248
1558
  const captureAll = options.captureAll ?? options.captureSuccessful ?? false;
1249
1559
  const sampleRate = options.sampleRate ?? 1;
1250
- const random = options.random ?? defaultRandom$2;
1560
+ const random = options.random ?? defaultRandom$1;
1251
1561
  const sanitizeUrl = options.sanitizeUrl ?? defaultSanitizeUrl;
1252
- const levelFor = options.level ?? defaultLevel$2;
1562
+ const levelFor = options.level ?? defaultLevel$1;
1253
1563
  const shouldCapture = (status, error) => {
1254
1564
  if (error) return true;
1255
1565
  if (status !== void 0 && status >= minStatus) return true;
@@ -1319,12 +1629,19 @@ function nodeHttpClientIntegration(options = {}) {
1319
1629
  }
1320
1630
  //#endregion
1321
1631
  //#region src/process-integration.ts
1632
+ const signalExitCodes = {
1633
+ SIGINT: 130,
1634
+ SIGTERM: 143
1635
+ };
1322
1636
  function captureProcessIntegration(options = {}) {
1323
1637
  const uncaughtException = options.uncaughtException ?? true;
1324
1638
  const unhandledRejection = options.unhandledRejection ?? true;
1325
1639
  const warning = options.warning ?? true;
1326
1640
  const beforeExitFlush = options.beforeExitFlush ?? true;
1327
1641
  const exitFlush = options.exitFlush ?? true;
1642
+ const signalFlush = options.signalFlush ?? true;
1643
+ const signals = options.signals ?? ["SIGTERM"];
1644
+ const exitOnSignal = options.exitOnSignal ?? true;
1328
1645
  const exitOnUncaught = options.exitOnUncaught ?? true;
1329
1646
  const flushTimeoutMs = options.flushTimeoutMs ?? 250;
1330
1647
  const exitFn = options.exitFn ?? ((code) => process.exit(code));
@@ -1414,6 +1731,23 @@ function captureProcessIntegration(options = {}) {
1414
1731
  process.on("exit", onExit);
1415
1732
  disposers.push(() => process.off("exit", onExit));
1416
1733
  }
1734
+ if (signalFlush) for (const signal of signals) {
1735
+ const onSignal = () => {
1736
+ capture({
1737
+ level: "fatal",
1738
+ message: `Process signal ${signal}`,
1739
+ props: { process: {
1740
+ kind: "signal",
1741
+ signal
1742
+ } }
1743
+ });
1744
+ flushSync();
1745
+ const flushed = flushBounded();
1746
+ if (exitOnSignal) flushed.finally(() => exitFn(signalExitCodes[signal] ?? 1));
1747
+ };
1748
+ process.on(signal, onSignal);
1749
+ disposers.push(() => process.off(signal, onSignal));
1750
+ }
1417
1751
  return () => {
1418
1752
  if (disposed) return;
1419
1753
  disposed = true;
@@ -1423,148 +1757,53 @@ function captureProcessIntegration(options = {}) {
1423
1757
  };
1424
1758
  }
1425
1759
  //#endregion
1426
- //#region src/queue-integration.ts
1427
- const defaultMethods = [
1428
- "add",
1429
- "ack",
1430
- "consume",
1431
- "dequeue",
1432
- "nack",
1433
- "process",
1434
- "publish",
1435
- "receive",
1436
- "send",
1437
- "sendToQueue"
1760
+ //#region src/prisma-integration.ts
1761
+ const prismaMethods = [
1762
+ "$executeRaw",
1763
+ "$executeRawUnsafe",
1764
+ "$queryRaw",
1765
+ "$queryRawUnsafe"
1438
1766
  ];
1439
- const defaultRandom$1 = () => Math.random();
1440
- function defaultLevel$1(_durationMs, error) {
1441
- return error ? "error" : "debug";
1442
- }
1443
- function isPromiseLike$1(value) {
1444
- return typeof value === "object" && value !== null && typeof value.then === "function";
1445
- }
1446
- function defaultOperation$1(method) {
1447
- switch (method) {
1448
- case "add":
1449
- case "publish":
1450
- case "send":
1451
- case "sendToQueue": return "publish";
1452
- case "consume":
1453
- case "dequeue":
1454
- case "process":
1455
- case "receive": return "consume";
1456
- case "ack": return "ack";
1457
- case "nack": return "nack";
1458
- default: return "other";
1459
- }
1767
+ function prismaStatement(args) {
1768
+ const first = args[0];
1769
+ if (typeof first === "string") return first;
1770
+ if (Array.isArray(first) && "raw" in first) return first.raw?.join("?");
1460
1771
  }
1461
- function defaultPayload(args) {
1462
- return typeof args[0] === "string" && args.length > 1 ? args[1] : args[0];
1772
+ function prismaIntegration(options) {
1773
+ return databaseIntegration({
1774
+ ...options,
1775
+ name: options.name ?? "prisma",
1776
+ system: "prisma",
1777
+ methods: prismaMethods,
1778
+ getStatement: prismaStatement
1779
+ });
1463
1780
  }
1464
- function defaultMessageId(args) {
1465
- const payload = defaultPayload(args);
1466
- if (typeof payload !== "object" || payload === null) return void 0;
1467
- const value = payload.messageId ?? payload.id;
1468
- return value === void 0 ? void 0 : String(value);
1781
+ //#endregion
1782
+ //#region src/redis-integration.ts
1783
+ const redisMethods = [
1784
+ "del",
1785
+ "get",
1786
+ "hget",
1787
+ "hset",
1788
+ "lpush",
1789
+ "publish",
1790
+ "rpush",
1791
+ "set",
1792
+ "xadd"
1793
+ ];
1794
+ function redisStatement(args, method) {
1795
+ const key = args[0] === void 0 ? "" : ` ${String(args[0])}`;
1796
+ return `${method.toUpperCase()}${key}`;
1469
1797
  }
1470
- function payloadFor(args, method, options) {
1471
- if (!options.capturePayload) return void 0;
1472
- const payload = options.getPayload?.(args, method) ?? defaultPayload(args);
1473
- return payload === void 0 ? void 0 : normalizeValue(payload, {
1474
- maxDepth: 4,
1475
- maxObjectKeys: 80
1798
+ function redisIntegration(options) {
1799
+ return databaseIntegration({
1800
+ ...options,
1801
+ name: options.name ?? "redis",
1802
+ system: "redis",
1803
+ methods: options.methods ?? redisMethods,
1804
+ getStatement: redisStatement
1476
1805
  });
1477
1806
  }
1478
- function queueIntegration(options = {}) {
1479
- const targets = options.targets ?? (options.client ? [{
1480
- client: options.client,
1481
- name: options.name,
1482
- system: options.system,
1483
- queueName: options.queueName,
1484
- methods: options.methods
1485
- }] : []);
1486
- const captureAll = options.captureAll ?? options.captureSuccessful ?? false;
1487
- const sampleRate = options.sampleRate ?? 1;
1488
- const random = options.random ?? defaultRandom$1;
1489
- const levelFor = options.level ?? defaultLevel$1;
1490
- const shouldCapture = (durationMs, error) => {
1491
- if (error) return true;
1492
- if (options.minDurationMs !== void 0 && durationMs >= options.minDurationMs) return true;
1493
- if (!captureAll) return false;
1494
- return sampleRate >= 1 || random() < sampleRate;
1495
- };
1496
- return {
1497
- name: "queue",
1498
- setup(api) {
1499
- const capture = api.guard((input) => api.capture(input));
1500
- const disposers = [];
1501
- let disposed = false;
1502
- const captureResult = (info, started, args, error) => {
1503
- const durationMs = Date.now() - started;
1504
- if (disposed || !shouldCapture(durationMs, error)) return;
1505
- capture({
1506
- level: levelFor(durationMs, error, info),
1507
- message: error ? `Queue error ${info.operation} ${info.queueName ?? info.method}` : `Queue ${info.operation} ${info.queueName ?? info.method}`,
1508
- error,
1509
- props: { queue: {
1510
- kind: info.target,
1511
- system: info.system,
1512
- queueName: info.queueName,
1513
- method: info.method,
1514
- operation: info.operation,
1515
- durationMs,
1516
- messageId: options.getMessageId?.(args, info.method) ?? defaultMessageId(args),
1517
- payload: payloadFor(args, info.method, options)
1518
- } }
1519
- });
1520
- };
1521
- for (const target of targets) {
1522
- const methods = target.methods ?? options.methods ?? defaultMethods;
1523
- for (const method of methods) {
1524
- const original = target.client[method];
1525
- if (typeof original !== "function") continue;
1526
- const originalMethod = original;
1527
- const targetName = target.name ?? options.name ?? "queue";
1528
- const system = target.system ?? options.system;
1529
- target.client[method] = function wrappedQueueMethod(...args) {
1530
- const started = Date.now();
1531
- const operation = options.getOperation?.(method, args) ?? defaultOperation$1(method);
1532
- const info = {
1533
- target: targetName,
1534
- system,
1535
- queueName: options.getQueueName?.(args, method) ?? target.queueName ?? options.queueName ?? (typeof args[0] === "string" ? args[0] : void 0),
1536
- method,
1537
- operation
1538
- };
1539
- try {
1540
- const result = originalMethod.apply(this, args);
1541
- if (isPromiseLike$1(result)) return result.then((value) => {
1542
- captureResult(info, started, args, void 0);
1543
- return value;
1544
- }, (error) => {
1545
- captureResult(info, started, args, error);
1546
- throw error;
1547
- });
1548
- captureResult(info, started, args, void 0);
1549
- return result;
1550
- } catch (error) {
1551
- captureResult(info, started, args, error);
1552
- throw error;
1553
- }
1554
- };
1555
- disposers.push(() => {
1556
- target.client[method] = originalMethod;
1557
- });
1558
- }
1559
- }
1560
- return () => {
1561
- if (disposed) return;
1562
- disposed = true;
1563
- for (const dispose of disposers) dispose();
1564
- };
1565
- }
1566
- };
1567
- }
1568
1807
  //#endregion
1569
1808
  //#region src/serverless-integration.ts
1570
1809
  const defaultRandom = () => Math.random();
@@ -1725,6 +1964,6 @@ function loadDiagnosticsChannel() {
1725
1964
  return cachedDiagnosticsChannel;
1726
1965
  }
1727
1966
  //#endregion
1728
- export { captureCliIntegration, captureProcessIntegration, createAsyncLocalStorageContextManager, databaseIntegration, diagnosticsChannelIntegration, expressIntegration, fastifyIntegration, fileTransport, formatSyslogMessage, installAsyncLocalStorageContext, nodeFetchIntegration, nodeHttpClientIntegration, nodeHttpTransport, nodeSyslogTransport, queueIntegration, rotatingFileTransport, serverlessIntegration, stderrTransport, stdoutTransport, workerTransport };
1967
+ export { bullMqIntegration, captureCliIntegration, captureProcessIntegration, createAsyncLocalStorageContextManager, databaseIntegration, diagnosticsChannelIntegration, expressIntegration, fastifyIntegration, fileTransport, formatSyslogMessage, hapiIntegration, installAsyncLocalStorageContext, koaIntegration, nestMiddlewareIntegration, nodeCompressionPayloadTransform, nodeFetchIntegration, nodeHttpClientIntegration, nodeHttpTransport, nodeSyslogTransport, prismaIntegration, queueIntegration, redisIntegration, rotatingFileTransport, serverlessIntegration, stderrTransport, stdoutTransport, workerTransport };
1729
1968
 
1730
1969
  //# sourceMappingURL=index.js.map