@loggerjs/node 0.4.0 → 0.5.1

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 (102) hide show
  1. package/README.md +5 -1
  2. package/dist/bullmq-integration.cjs +169 -0
  3. package/dist/bullmq-integration.cjs.map +1 -0
  4. package/dist/bullmq-integration.js +168 -0
  5. package/dist/bullmq-integration.js.map +1 -0
  6. package/dist/cli-integration.cjs +116 -0
  7. package/dist/cli-integration.cjs.map +1 -0
  8. package/dist/cli-integration.js +115 -0
  9. package/dist/cli-integration.js.map +1 -0
  10. package/dist/context.cjs +37 -0
  11. package/dist/context.cjs.map +1 -0
  12. package/dist/context.js +35 -0
  13. package/dist/context.js.map +1 -0
  14. package/dist/database-integration.cjs +128 -0
  15. package/dist/database-integration.cjs.map +1 -0
  16. package/dist/database-integration.js +127 -0
  17. package/dist/database-integration.js.map +1 -0
  18. package/dist/diagnostics-channel-integration.cjs +66 -0
  19. package/dist/diagnostics-channel-integration.cjs.map +1 -0
  20. package/dist/diagnostics-channel-integration.js +65 -0
  21. package/dist/diagnostics-channel-integration.js.map +1 -0
  22. package/dist/express-integration.cjs +130 -0
  23. package/dist/express-integration.cjs.map +1 -0
  24. package/dist/express-integration.js +129 -0
  25. package/dist/express-integration.js.map +1 -0
  26. package/dist/fastify-integration.cjs +120 -0
  27. package/dist/fastify-integration.cjs.map +1 -0
  28. package/dist/fastify-integration.js +119 -0
  29. package/dist/fastify-integration.js.map +1 -0
  30. package/dist/file-transport.cjs +260 -0
  31. package/dist/file-transport.cjs.map +1 -0
  32. package/dist/file-transport.js +259 -0
  33. package/dist/file-transport.js.map +1 -0
  34. package/dist/hapi-integration.cjs +61 -0
  35. package/dist/hapi-integration.cjs.map +1 -0
  36. package/dist/hapi-integration.js +60 -0
  37. package/dist/hapi-integration.js.map +1 -0
  38. package/dist/http-transport.cjs +55 -0
  39. package/dist/http-transport.cjs.map +1 -0
  40. package/dist/http-transport.js +54 -0
  41. package/dist/http-transport.js.map +1 -0
  42. package/dist/koa-integration.cjs +57 -0
  43. package/dist/koa-integration.cjs.map +1 -0
  44. package/dist/koa-integration.js +56 -0
  45. package/dist/koa-integration.js.map +1 -0
  46. package/dist/logger-diagnostics.cjs +46 -0
  47. package/dist/logger-diagnostics.cjs.map +1 -0
  48. package/dist/logger-diagnostics.js +45 -0
  49. package/dist/logger-diagnostics.js.map +1 -0
  50. package/dist/nest-integration.cjs +138 -0
  51. package/dist/nest-integration.cjs.map +1 -0
  52. package/dist/nest-integration.js +137 -0
  53. package/dist/nest-integration.js.map +1 -0
  54. package/dist/node-fetch-integration.cjs +113 -0
  55. package/dist/node-fetch-integration.cjs.map +1 -0
  56. package/dist/node-fetch-integration.js +112 -0
  57. package/dist/node-fetch-integration.js.map +1 -0
  58. package/dist/node-http-client-integration.cjs +192 -0
  59. package/dist/node-http-client-integration.cjs.map +1 -0
  60. package/dist/node-http-client-integration.js +192 -0
  61. package/dist/node-http-client-integration.js.map +1 -0
  62. package/dist/payload-transforms.cjs +29 -0
  63. package/dist/payload-transforms.cjs.map +1 -0
  64. package/dist/payload-transforms.js +28 -0
  65. package/dist/payload-transforms.js.map +1 -0
  66. package/dist/prisma-integration.cjs +150 -0
  67. package/dist/prisma-integration.cjs.map +1 -0
  68. package/dist/prisma-integration.js +149 -0
  69. package/dist/prisma-integration.js.map +1 -0
  70. package/dist/process-integration.cjs +134 -0
  71. package/dist/process-integration.cjs.map +1 -0
  72. package/dist/process-integration.js +133 -0
  73. package/dist/process-integration.js.map +1 -0
  74. package/dist/queue-integration.cjs +148 -0
  75. package/dist/queue-integration.cjs.map +1 -0
  76. package/dist/queue-integration.js +147 -0
  77. package/dist/queue-integration.js.map +1 -0
  78. package/dist/redis-integration.cjs +154 -0
  79. package/dist/redis-integration.cjs.map +1 -0
  80. package/dist/redis-integration.js +153 -0
  81. package/dist/redis-integration.js.map +1 -0
  82. package/dist/rotating-file-transport.cjs +318 -0
  83. package/dist/rotating-file-transport.cjs.map +1 -0
  84. package/dist/rotating-file-transport.js +317 -0
  85. package/dist/rotating-file-transport.js.map +1 -0
  86. package/dist/serverless-integration.cjs +104 -0
  87. package/dist/serverless-integration.cjs.map +1 -0
  88. package/dist/serverless-integration.js +103 -0
  89. package/dist/serverless-integration.js.map +1 -0
  90. package/dist/stdout-transport.cjs +197 -0
  91. package/dist/stdout-transport.cjs.map +1 -0
  92. package/dist/stdout-transport.js +195 -0
  93. package/dist/stdout-transport.js.map +1 -0
  94. package/dist/syslog-transport.cjs +135 -0
  95. package/dist/syslog-transport.cjs.map +1 -0
  96. package/dist/syslog-transport.js +133 -0
  97. package/dist/syslog-transport.js.map +1 -0
  98. package/dist/worker-transport.cjs +285 -0
  99. package/dist/worker-transport.cjs.map +1 -0
  100. package/dist/worker-transport.js +284 -0
  101. package/dist/worker-transport.js.map +1 -0
  102. package/package.json +104 -77
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-integration.js","names":[],"sources":["../src/cli-integration.ts"],"sourcesContent":["import {\n type CaptureInput,\n type Integration,\n type IntegrationSetupContext,\n type LoggerLevel,\n} from \"@loggerjs/core\";\n\nexport interface CliProcessLike {\n argv?: readonly string[];\n env?: Record<string, string | undefined>;\n exitCode?: number | string | null;\n cwd?: () => string;\n on?: (event: string, listener: (...args: unknown[]) => void) => unknown;\n off?: (event: string, listener: (...args: unknown[]) => void) => unknown;\n removeListener?: (event: string, listener: (...args: unknown[]) => void) => unknown;\n}\n\nexport interface CaptureCliOptions {\n name?: string;\n process?: CliProcessLike;\n captureStart?: boolean;\n captureExit?: boolean;\n captureSignals?: boolean;\n captureCwd?: boolean;\n captureEnv?: readonly string[];\n signals?: readonly string[];\n level?:\n | LoggerLevel\n | ((event: \"start\" | \"exit\" | \"signal\", code?: number | string) => LoggerLevel);\n getCommand?: (argv: readonly string[]) => string | undefined;\n sanitizeArg?: (arg: string, index: number, argv: readonly string[]) => string;\n}\n\nconst defaultSignals = [\"SIGINT\", \"SIGTERM\"] as const;\n\nfunction defaultProcess(): CliProcessLike | undefined {\n return (globalThis as unknown as { process?: CliProcessLike }).process;\n}\n\nfunction defaultSanitizeArg(arg: string) {\n if (/^(--?[^=\\s]*(token|password|passwd|secret|key)[^=\\s]*=)/i.test(arg)) {\n return arg.replace(/=.*/, \"=[redacted]\");\n }\n return arg;\n}\n\nfunction defaultCommand(argv: readonly string[]): string | undefined {\n return argv[1] ?? argv[0];\n}\n\nfunction levelFor(\n level: CaptureCliOptions[\"level\"],\n event: \"start\" | \"exit\" | \"signal\",\n code?: number | string,\n): LoggerLevel {\n if (typeof level === \"function\") return level(event, code);\n if (level) return level;\n if (event === \"signal\") return \"warn\";\n if (event === \"exit\" && Number(code ?? 0) !== 0) return \"error\";\n return \"info\";\n}\n\nfunction pickEnv(\n env: Record<string, string | undefined> | undefined,\n names: readonly string[] | undefined,\n) {\n if (!env || !names || names.length === 0) return undefined;\n const out: Record<string, string> = {};\n for (const name of names) {\n const value = env[name];\n if (value !== undefined) out[name] = value;\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction removeListener(\n processLike: CliProcessLike,\n event: string,\n listener: (...args: unknown[]) => void,\n) {\n if (processLike.off) {\n processLike.off(event, listener);\n return;\n }\n processLike.removeListener?.(event, listener);\n}\n\nexport function captureCliIntegration(options: CaptureCliOptions = {}): Integration {\n const name = options.name ?? \"cli\";\n const captureStart = options.captureStart ?? true;\n const captureExit = options.captureExit ?? true;\n const captureSignals = options.captureSignals ?? true;\n const captureCwd = options.captureCwd ?? true;\n const signals = options.signals ?? defaultSignals;\n const sanitizeArg = options.sanitizeArg ?? defaultSanitizeArg;\n const commandFor = options.getCommand ?? defaultCommand;\n\n return {\n name: \"capture-cli\",\n setup(api: IntegrationSetupContext) {\n const processLike = options.process ?? defaultProcess();\n if (!processLike) return;\n const argv = processLike.argv ?? [];\n const command = commandFor(argv);\n const sanitizedArgv = argv.map((arg, index) => sanitizeArg(arg, index, argv));\n const disposers: Array<() => void> = [];\n let disposed = false;\n\n const capture = api.guard((input: CaptureInput) => {\n if (!disposed) api.capture(input);\n });\n const cliBase = {\n kind: name,\n command,\n argv: sanitizedArgv,\n cwd: captureCwd ? processLike.cwd?.() : undefined,\n env: pickEnv(processLike.env, options.captureEnv),\n };\n\n if (captureStart) {\n capture({\n level: levelFor(options.level, \"start\"),\n message: `CLI start${command ? ` ${command}` : \"\"}`,\n props: {\n cli: {\n ...cliBase,\n lifecycle: \"start\",\n },\n },\n });\n }\n\n if (captureExit && processLike.on) {\n const onExit = (code: unknown) => {\n const exitCode = code ?? processLike.exitCode ?? 0;\n capture({\n level: levelFor(options.level, \"exit\", exitCode as number | string),\n message: `CLI exit ${String(exitCode)}`,\n props: {\n cli: {\n ...cliBase,\n lifecycle: \"exit\",\n exitCode,\n },\n },\n });\n };\n processLike.on(\"exit\", onExit);\n disposers.push(() => removeListener(processLike, \"exit\", onExit));\n }\n\n if (captureSignals && processLike.on) {\n for (const signal of signals) {\n const onSignal = () => {\n capture({\n level: levelFor(options.level, \"signal\", signal),\n message: `CLI signal ${signal}`,\n props: {\n cli: {\n ...cliBase,\n lifecycle: \"signal\",\n signal,\n },\n },\n });\n };\n processLike.on(signal, onSignal);\n disposers.push(() => removeListener(processLike, signal, onSignal));\n }\n }\n\n return () => {\n if (disposed) return;\n disposed = true;\n for (const dispose of disposers) dispose();\n };\n },\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let node_async_hooks = require("node:async_hooks");
3
+ let _loggerjs_core = require("@loggerjs/core");
4
+ //#region src/context.ts
5
+ function mergeContext(...items) {
6
+ const out = {};
7
+ for (const item of items) {
8
+ if (!item) continue;
9
+ Object.assign(out, item);
10
+ }
11
+ return (0, _loggerjs_core.createBoundContext)(out) ?? void 0;
12
+ }
13
+ function createAsyncLocalStorageContextManager(storage = new node_async_hooks.AsyncLocalStorage()) {
14
+ return {
15
+ get() {
16
+ return storage.getStore();
17
+ },
18
+ with(context, fn) {
19
+ return storage.run(mergeContext(storage.getStore(), context) ?? Object.freeze({}), fn);
20
+ },
21
+ disable() {
22
+ storage.disable();
23
+ }
24
+ };
25
+ }
26
+ function installAsyncLocalStorageContext(manager = createAsyncLocalStorageContextManager()) {
27
+ (0, _loggerjs_core.setContextManager)(manager);
28
+ return () => {
29
+ (0, _loggerjs_core.resetContextManager)();
30
+ manager.disable();
31
+ };
32
+ }
33
+ //#endregion
34
+ exports.createAsyncLocalStorageContextManager = createAsyncLocalStorageContextManager;
35
+ exports.installAsyncLocalStorageContext = installAsyncLocalStorageContext;
36
+
37
+ //# sourceMappingURL=context.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.cjs","names":["AsyncLocalStorage"],"sources":["../src/context.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport {\n createBoundContext,\n resetContextManager,\n setContextManager,\n type BoundContext,\n type ContextManager,\n} from \"@loggerjs/core\";\n\nfunction mergeContext(\n ...items: Array<Record<string, unknown> | undefined | null>\n): BoundContext | undefined {\n const out: Record<string, unknown> = {};\n for (const item of items) {\n if (!item) continue;\n Object.assign(out, item);\n }\n return createBoundContext(out) ?? undefined;\n}\n\nexport function createAsyncLocalStorageContextManager(\n storage = new AsyncLocalStorage<BoundContext>(),\n): ContextManager & { disable: () => void } {\n return {\n get() {\n return storage.getStore();\n },\n with(context, fn) {\n return storage.run(mergeContext(storage.getStore(), context) ?? Object.freeze({}), fn);\n },\n disable() {\n storage.disable();\n },\n };\n}\n\nexport function installAsyncLocalStorageContext(\n manager = createAsyncLocalStorageContextManager(),\n): () => void {\n setContextManager(manager);\n return () => {\n resetContextManager();\n manager.disable();\n };\n}\n"],"mappings":";;;;AASA,SAAS,aACP,GAAG,OACuB;CAC1B,MAAM,MAA+B,CAAC;CACtC,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,CAAC,MAAM;EACX,OAAO,OAAO,KAAK,IAAI;CACzB;CACA,QAAA,GAAA,eAAA,mBAAA,CAA0B,GAAG,KAAK,KAAA;AACpC;AAEA,SAAgB,sCACd,UAAU,IAAIA,iBAAAA,kBAAgC,GACJ;CAC1C,OAAO;EACL,MAAM;GACJ,OAAO,QAAQ,SAAS;EAC1B;EACA,KAAK,SAAS,IAAI;GAChB,OAAO,QAAQ,IAAI,aAAa,QAAQ,SAAS,GAAG,OAAO,KAAK,OAAO,OAAO,CAAC,CAAC,GAAG,EAAE;EACvF;EACA,UAAU;GACR,QAAQ,QAAQ;EAClB;CACF;AACF;AAEA,SAAgB,gCACd,UAAU,sCAAsC,GACpC;CACZ,CAAA,GAAA,eAAA,kBAAA,CAAkB,OAAO;CACzB,aAAa;EACX,CAAA,GAAA,eAAA,oBAAA,CAAoB;EACpB,QAAQ,QAAQ;CAClB;AACF"}
@@ -0,0 +1,35 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import { createBoundContext, resetContextManager, setContextManager } from "@loggerjs/core";
3
+ //#region src/context.ts
4
+ function mergeContext(...items) {
5
+ const out = {};
6
+ for (const item of items) {
7
+ if (!item) continue;
8
+ Object.assign(out, item);
9
+ }
10
+ return createBoundContext(out) ?? void 0;
11
+ }
12
+ function createAsyncLocalStorageContextManager(storage = new AsyncLocalStorage()) {
13
+ return {
14
+ get() {
15
+ return storage.getStore();
16
+ },
17
+ with(context, fn) {
18
+ return storage.run(mergeContext(storage.getStore(), context) ?? Object.freeze({}), fn);
19
+ },
20
+ disable() {
21
+ storage.disable();
22
+ }
23
+ };
24
+ }
25
+ function installAsyncLocalStorageContext(manager = createAsyncLocalStorageContextManager()) {
26
+ setContextManager(manager);
27
+ return () => {
28
+ resetContextManager();
29
+ manager.disable();
30
+ };
31
+ }
32
+ //#endregion
33
+ export { createAsyncLocalStorageContextManager, installAsyncLocalStorageContext };
34
+
35
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","names":[],"sources":["../src/context.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport {\n createBoundContext,\n resetContextManager,\n setContextManager,\n type BoundContext,\n type ContextManager,\n} from \"@loggerjs/core\";\n\nfunction mergeContext(\n ...items: Array<Record<string, unknown> | undefined | null>\n): BoundContext | undefined {\n const out: Record<string, unknown> = {};\n for (const item of items) {\n if (!item) continue;\n Object.assign(out, item);\n }\n return createBoundContext(out) ?? undefined;\n}\n\nexport function createAsyncLocalStorageContextManager(\n storage = new AsyncLocalStorage<BoundContext>(),\n): ContextManager & { disable: () => void } {\n return {\n get() {\n return storage.getStore();\n },\n with(context, fn) {\n return storage.run(mergeContext(storage.getStore(), context) ?? Object.freeze({}), fn);\n },\n disable() {\n storage.disable();\n },\n };\n}\n\nexport function installAsyncLocalStorageContext(\n manager = createAsyncLocalStorageContextManager(),\n): () => void {\n setContextManager(manager);\n return () => {\n resetContextManager();\n manager.disable();\n };\n}\n"],"mappings":";;;AASA,SAAS,aACP,GAAG,OACuB;CAC1B,MAAM,MAA+B,CAAC;CACtC,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,CAAC,MAAM;EACX,OAAO,OAAO,KAAK,IAAI;CACzB;CACA,OAAO,mBAAmB,GAAG,KAAK,KAAA;AACpC;AAEA,SAAgB,sCACd,UAAU,IAAI,kBAAgC,GACJ;CAC1C,OAAO;EACL,MAAM;GACJ,OAAO,QAAQ,SAAS;EAC1B;EACA,KAAK,SAAS,IAAI;GAChB,OAAO,QAAQ,IAAI,aAAa,QAAQ,SAAS,GAAG,OAAO,KAAK,OAAO,OAAO,CAAC,CAAC,GAAG,EAAE;EACvF;EACA,UAAU;GACR,QAAQ,QAAQ;EAClB;CACF;AACF;AAEA,SAAgB,gCACd,UAAU,sCAAsC,GACpC;CACZ,kBAAkB,OAAO;CACzB,aAAa;EACX,oBAAoB;EACpB,QAAQ,QAAQ;CAClB;AACF"}
@@ -0,0 +1,128 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let _loggerjs_core = require("@loggerjs/core");
3
+ //#region src/database-integration.ts
4
+ const defaultMethods = [
5
+ "query",
6
+ "execute",
7
+ "run",
8
+ "all",
9
+ "get"
10
+ ];
11
+ const defaultRandom = () => Math.random();
12
+ function defaultLevel(_durationMs, error) {
13
+ return error ? "error" : "debug";
14
+ }
15
+ function isPromiseLike(value) {
16
+ return typeof value === "object" && value !== null && typeof value.then === "function";
17
+ }
18
+ function defaultStatement(args) {
19
+ const first = args[0];
20
+ if (typeof first === "string") return first;
21
+ if (typeof first !== "object" || first === null) return void 0;
22
+ const input = first;
23
+ if (typeof input.sql === "string") return input.sql;
24
+ if (typeof input.text === "string") return input.text;
25
+ if (typeof input.query === "string") return input.query;
26
+ }
27
+ function statementFor(args, method, options) {
28
+ const statement = options.getStatement?.(args, method) ?? defaultStatement(args);
29
+ return statement && options.sanitizeStatement ? options.sanitizeStatement(statement) : statement;
30
+ }
31
+ function parametersFor(args, captureParameters) {
32
+ if (!captureParameters) return void 0;
33
+ const first = args[0];
34
+ const parameters = args[1] ?? (typeof first === "object" && first ? first.values ?? first.params ?? first.parameters : void 0);
35
+ return parameters === void 0 ? void 0 : (0, _loggerjs_core.normalizeValue)(parameters, {
36
+ maxDepth: 4,
37
+ maxObjectKeys: 80
38
+ });
39
+ }
40
+ function databaseIntegration(options = {}) {
41
+ const targets = options.targets ?? (options.client ? [{
42
+ client: options.client,
43
+ name: options.name,
44
+ system: options.system,
45
+ methods: options.methods
46
+ }] : []);
47
+ const captureAll = options.captureAll ?? options.captureSuccessful ?? false;
48
+ const sampleRate = options.sampleRate ?? 1;
49
+ const random = options.random ?? defaultRandom;
50
+ const levelFor = options.level ?? defaultLevel;
51
+ const shouldCapture = (durationMs, error) => {
52
+ if (error) return true;
53
+ if (options.minDurationMs !== void 0 && durationMs >= options.minDurationMs) return true;
54
+ if (!captureAll) return false;
55
+ return sampleRate >= 1 || random() < sampleRate;
56
+ };
57
+ return {
58
+ name: "database",
59
+ setup(api) {
60
+ const capture = api.guard((input) => api.capture(input));
61
+ const disposers = [];
62
+ let disposed = false;
63
+ const captureResult = (info, started, args, error) => {
64
+ const durationMs = Date.now() - started;
65
+ if (disposed || !shouldCapture(durationMs, error)) return;
66
+ capture({
67
+ level: levelFor(durationMs, error, info),
68
+ message: error ? `Database error ${info.method}${info.statement ? ` ${info.statement}` : ""}` : `Database ${info.method}${info.statement ? ` ${info.statement}` : ""}`,
69
+ error,
70
+ props: { db: {
71
+ kind: info.target,
72
+ system: info.system,
73
+ method: info.method,
74
+ statement: info.statement,
75
+ durationMs,
76
+ parameters: parametersFor(args, options.captureParameters ?? false)
77
+ } }
78
+ });
79
+ };
80
+ for (const target of targets) {
81
+ const methods = target.methods ?? options.methods ?? defaultMethods;
82
+ for (const method of methods) {
83
+ const original = target.client[method];
84
+ if (typeof original !== "function") continue;
85
+ const originalMethod = original;
86
+ const targetName = target.name ?? options.name ?? "database";
87
+ const system = target.system ?? options.system;
88
+ target.client[method] = function wrappedDatabaseMethod(...args) {
89
+ const started = Date.now();
90
+ const info = {
91
+ target: targetName,
92
+ system,
93
+ method,
94
+ statement: statementFor(args, method, options)
95
+ };
96
+ try {
97
+ const result = originalMethod.apply(this, args);
98
+ if (isPromiseLike(result)) return result.then((value) => {
99
+ captureResult(info, started, args, void 0);
100
+ return value;
101
+ }, (error) => {
102
+ captureResult(info, started, args, error);
103
+ throw error;
104
+ });
105
+ captureResult(info, started, args, void 0);
106
+ return result;
107
+ } catch (error) {
108
+ captureResult(info, started, args, error);
109
+ throw error;
110
+ }
111
+ };
112
+ disposers.push(() => {
113
+ target.client[method] = originalMethod;
114
+ });
115
+ }
116
+ }
117
+ return () => {
118
+ if (disposed) return;
119
+ disposed = true;
120
+ for (const dispose of disposers) dispose();
121
+ };
122
+ }
123
+ };
124
+ }
125
+ //#endregion
126
+ exports.databaseIntegration = databaseIntegration;
127
+
128
+ //# sourceMappingURL=database-integration.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-integration.cjs","names":[],"sources":["../src/database-integration.ts"],"sourcesContent":["import {\n normalizeValue,\n type CaptureInput,\n type Integration,\n type IntegrationSetupContext,\n type LoggerLevel,\n} from \"@loggerjs/core\";\n\nexport interface DatabaseClientLike {\n [method: string]: unknown;\n}\n\nexport interface DatabaseIntegrationTarget {\n client: DatabaseClientLike;\n name?: string;\n system?: string;\n methods?: readonly string[];\n}\n\nexport interface DatabaseOperationInfo {\n target: string;\n system?: string;\n method: string;\n statement?: string;\n}\n\nexport interface DatabaseIntegrationOptions {\n client?: DatabaseClientLike;\n targets?: readonly DatabaseIntegrationTarget[];\n name?: string;\n system?: string;\n methods?: readonly string[];\n captureAll?: boolean;\n captureSuccessful?: boolean;\n minDurationMs?: number;\n sampleRate?: number;\n random?: () => number;\n captureParameters?: boolean;\n sanitizeStatement?: (statement: string) => string;\n getStatement?: (args: readonly unknown[], method: string) => string | undefined;\n level?: (durationMs: number, error: unknown, info: DatabaseOperationInfo) => LoggerLevel;\n}\n\ntype DatabaseMethod = (this: unknown, ...args: unknown[]) => unknown;\n\nconst defaultMethods = [\"query\", \"execute\", \"run\", \"all\", \"get\"] as const;\nconst defaultRandom = () => Math.random();\n\nfunction defaultLevel(_durationMs: number, error: unknown): LoggerLevel {\n return error ? \"error\" : \"debug\";\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { then?: unknown }).then === \"function\"\n );\n}\n\nfunction defaultStatement(args: readonly unknown[]): string | undefined {\n const first = args[0];\n if (typeof first === \"string\") return first;\n if (typeof first !== \"object\" || first === null) return undefined;\n const input = first as { sql?: unknown; text?: unknown; query?: unknown };\n if (typeof input.sql === \"string\") return input.sql;\n if (typeof input.text === \"string\") return input.text;\n if (typeof input.query === \"string\") return input.query;\n return undefined;\n}\n\nfunction statementFor(\n args: readonly unknown[],\n method: string,\n options: DatabaseIntegrationOptions,\n) {\n const statement = options.getStatement?.(args, method) ?? defaultStatement(args);\n return statement && options.sanitizeStatement ? options.sanitizeStatement(statement) : statement;\n}\n\nfunction parametersFor(args: readonly unknown[], captureParameters: boolean) {\n if (!captureParameters) return undefined;\n const first = args[0];\n const second = args[1];\n const parameters =\n second ??\n (typeof first === \"object\" && first\n ? ((first as { values?: unknown; params?: unknown; parameters?: unknown }).values ??\n (first as { params?: unknown }).params ??\n (first as { parameters?: unknown }).parameters)\n : undefined);\n return parameters === undefined\n ? undefined\n : normalizeValue(parameters, { maxDepth: 4, maxObjectKeys: 80 });\n}\n\nexport function databaseIntegration(options: DatabaseIntegrationOptions = {}): Integration {\n const targets =\n options.targets ??\n (options.client\n ? [\n {\n client: options.client,\n name: options.name,\n system: options.system,\n methods: options.methods,\n },\n ]\n : []);\n const captureAll = options.captureAll ?? options.captureSuccessful ?? false;\n const sampleRate = options.sampleRate ?? 1;\n const random = options.random ?? defaultRandom;\n const levelFor = options.level ?? defaultLevel;\n\n const shouldCapture = (durationMs: number, error: unknown) => {\n if (error) return true;\n if (options.minDurationMs !== undefined && durationMs >= options.minDurationMs) return true;\n if (!captureAll) return false;\n return sampleRate >= 1 || random() < sampleRate;\n };\n\n return {\n name: \"database\",\n setup(api: IntegrationSetupContext) {\n const capture = api.guard((input: CaptureInput) => api.capture(input));\n const disposers: Array<() => void> = [];\n let disposed = false;\n\n const captureResult = (\n info: DatabaseOperationInfo,\n started: number,\n args: readonly unknown[],\n error: unknown,\n ) => {\n const durationMs = Date.now() - started;\n if (disposed || !shouldCapture(durationMs, error)) return;\n capture({\n level: levelFor(durationMs, error, info),\n message: error\n ? `Database error ${info.method}${info.statement ? ` ${info.statement}` : \"\"}`\n : `Database ${info.method}${info.statement ? ` ${info.statement}` : \"\"}`,\n error,\n props: {\n db: {\n kind: info.target,\n system: info.system,\n method: info.method,\n statement: info.statement,\n durationMs,\n parameters: parametersFor(args, options.captureParameters ?? false),\n },\n },\n });\n };\n\n for (const target of targets) {\n const methods = target.methods ?? options.methods ?? defaultMethods;\n for (const method of methods) {\n const original = target.client[method];\n if (typeof original !== \"function\") continue;\n const originalMethod = original as DatabaseMethod;\n const targetName = target.name ?? options.name ?? \"database\";\n const system = target.system ?? options.system;\n\n target.client[method] = function wrappedDatabaseMethod(\n this: unknown,\n ...args: unknown[]\n ) {\n const started = Date.now();\n const info: DatabaseOperationInfo = {\n target: targetName,\n system,\n method,\n statement: statementFor(args, method, options),\n };\n try {\n const result = originalMethod.apply(this, args);\n if (isPromiseLike(result)) {\n return result.then(\n (value) => {\n captureResult(info, started, args, undefined);\n return value;\n },\n (error) => {\n captureResult(info, started, args, error);\n throw error;\n },\n );\n }\n captureResult(info, started, args, undefined);\n return result;\n } catch (error) {\n captureResult(info, started, args, error);\n throw error;\n }\n };\n\n disposers.push(() => {\n target.client[method] = originalMethod;\n });\n }\n }\n\n return () => {\n if (disposed) return;\n disposed = true;\n for (const dispose of disposers) dispose();\n };\n },\n };\n}\n"],"mappings":";;;AA6CA,MAAM,iBAAiB;CAAC;CAAS;CAAW;CAAO;CAAO;AAAK;AAC/D,MAAM,sBAAsB,KAAK,OAAO;AAExC,SAAS,aAAa,aAAqB,OAA6B;CACtE,OAAO,QAAQ,UAAU;AAC3B;AAEA,SAAS,cAAc,OAA+C;CACpE,OACE,OAAO,UAAU,YACjB,UAAU,QACV,OAAQ,MAA6B,SAAS;AAElD;AAEA,SAAS,iBAAiB,MAA8C;CACtE,MAAM,QAAQ,KAAK;CACnB,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO,KAAA;CACxD,MAAM,QAAQ;CACd,IAAI,OAAO,MAAM,QAAQ,UAAU,OAAO,MAAM;CAChD,IAAI,OAAO,MAAM,SAAS,UAAU,OAAO,MAAM;CACjD,IAAI,OAAO,MAAM,UAAU,UAAU,OAAO,MAAM;AAEpD;AAEA,SAAS,aACP,MACA,QACA,SACA;CACA,MAAM,YAAY,QAAQ,eAAe,MAAM,MAAM,KAAK,iBAAiB,IAAI;CAC/E,OAAO,aAAa,QAAQ,oBAAoB,QAAQ,kBAAkB,SAAS,IAAI;AACzF;AAEA,SAAS,cAAc,MAA0B,mBAA4B;CAC3E,IAAI,CAAC,mBAAmB,OAAO,KAAA;CAC/B,MAAM,QAAQ,KAAK;CAEnB,MAAM,aADS,KAAK,OAGjB,OAAO,UAAU,YAAY,QACxB,MAAuE,UACxE,MAA+B,UAC/B,MAAmC,aACpC,KAAA;CACN,OAAO,eAAe,KAAA,IAClB,KAAA,KAAA,GAAA,eAAA,eAAA,CACe,YAAY;EAAE,UAAU;EAAG,eAAe;CAAG,CAAC;AACnE;AAEA,SAAgB,oBAAoB,UAAsC,CAAC,GAAgB;CACzF,MAAM,UACJ,QAAQ,YACP,QAAQ,SACL,CACE;EACE,QAAQ,QAAQ;EAChB,MAAM,QAAQ;EACd,QAAQ,QAAQ;EAChB,SAAS,QAAQ;CACnB,CACF,IACA,CAAC;CACP,MAAM,aAAa,QAAQ,cAAc,QAAQ,qBAAqB;CACtE,MAAM,aAAa,QAAQ,cAAc;CACzC,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,WAAW,QAAQ,SAAS;CAElC,MAAM,iBAAiB,YAAoB,UAAmB;EAC5D,IAAI,OAAO,OAAO;EAClB,IAAI,QAAQ,kBAAkB,KAAA,KAAa,cAAc,QAAQ,eAAe,OAAO;EACvF,IAAI,CAAC,YAAY,OAAO;EACxB,OAAO,cAAc,KAAK,OAAO,IAAI;CACvC;CAEA,OAAO;EACL,MAAM;EACN,MAAM,KAA8B;GAClC,MAAM,UAAU,IAAI,OAAO,UAAwB,IAAI,QAAQ,KAAK,CAAC;GACrE,MAAM,YAA+B,CAAC;GACtC,IAAI,WAAW;GAEf,MAAM,iBACJ,MACA,SACA,MACA,UACG;IACH,MAAM,aAAa,KAAK,IAAI,IAAI;IAChC,IAAI,YAAY,CAAC,cAAc,YAAY,KAAK,GAAG;IACnD,QAAQ;KACN,OAAO,SAAS,YAAY,OAAO,IAAI;KACvC,SAAS,QACL,kBAAkB,KAAK,SAAS,KAAK,YAAY,IAAI,KAAK,cAAc,OACxE,YAAY,KAAK,SAAS,KAAK,YAAY,IAAI,KAAK,cAAc;KACtE;KACA,OAAO,EACL,IAAI;MACF,MAAM,KAAK;MACX,QAAQ,KAAK;MACb,QAAQ,KAAK;MACb,WAAW,KAAK;MAChB;MACA,YAAY,cAAc,MAAM,QAAQ,qBAAqB,KAAK;KACpE,EACF;IACF,CAAC;GACH;GAEA,KAAK,MAAM,UAAU,SAAS;IAC5B,MAAM,UAAU,OAAO,WAAW,QAAQ,WAAW;IACrD,KAAK,MAAM,UAAU,SAAS;KAC5B,MAAM,WAAW,OAAO,OAAO;KAC/B,IAAI,OAAO,aAAa,YAAY;KACpC,MAAM,iBAAiB;KACvB,MAAM,aAAa,OAAO,QAAQ,QAAQ,QAAQ;KAClD,MAAM,SAAS,OAAO,UAAU,QAAQ;KAExC,OAAO,OAAO,UAAU,SAAS,sBAE/B,GAAG,MACH;MACA,MAAM,UAAU,KAAK,IAAI;MACzB,MAAM,OAA8B;OAClC,QAAQ;OACR;OACA;OACA,WAAW,aAAa,MAAM,QAAQ,OAAO;MAC/C;MACA,IAAI;OACF,MAAM,SAAS,eAAe,MAAM,MAAM,IAAI;OAC9C,IAAI,cAAc,MAAM,GACtB,OAAO,OAAO,MACX,UAAU;QACT,cAAc,MAAM,SAAS,MAAM,KAAA,CAAS;QAC5C,OAAO;OACT,IACC,UAAU;QACT,cAAc,MAAM,SAAS,MAAM,KAAK;QACxC,MAAM;OACR,CACF;OAEF,cAAc,MAAM,SAAS,MAAM,KAAA,CAAS;OAC5C,OAAO;MACT,SAAS,OAAO;OACd,cAAc,MAAM,SAAS,MAAM,KAAK;OACxC,MAAM;MACR;KACF;KAEA,UAAU,WAAW;MACnB,OAAO,OAAO,UAAU;KAC1B,CAAC;IACH;GACF;GAEA,aAAa;IACX,IAAI,UAAU;IACd,WAAW;IACX,KAAK,MAAM,WAAW,WAAW,QAAQ;GAC3C;EACF;CACF;AACF"}
@@ -0,0 +1,127 @@
1
+ import { normalizeValue } from "@loggerjs/core";
2
+ //#region src/database-integration.ts
3
+ const defaultMethods = [
4
+ "query",
5
+ "execute",
6
+ "run",
7
+ "all",
8
+ "get"
9
+ ];
10
+ const defaultRandom = () => Math.random();
11
+ function defaultLevel(_durationMs, error) {
12
+ return error ? "error" : "debug";
13
+ }
14
+ function isPromiseLike(value) {
15
+ return typeof value === "object" && value !== null && typeof value.then === "function";
16
+ }
17
+ function defaultStatement(args) {
18
+ const first = args[0];
19
+ if (typeof first === "string") return first;
20
+ if (typeof first !== "object" || first === null) return void 0;
21
+ const input = first;
22
+ if (typeof input.sql === "string") return input.sql;
23
+ if (typeof input.text === "string") return input.text;
24
+ if (typeof input.query === "string") return input.query;
25
+ }
26
+ function statementFor(args, method, options) {
27
+ const statement = options.getStatement?.(args, method) ?? defaultStatement(args);
28
+ return statement && options.sanitizeStatement ? options.sanitizeStatement(statement) : statement;
29
+ }
30
+ function parametersFor(args, captureParameters) {
31
+ if (!captureParameters) return void 0;
32
+ const first = args[0];
33
+ const parameters = args[1] ?? (typeof first === "object" && first ? first.values ?? first.params ?? first.parameters : void 0);
34
+ return parameters === void 0 ? void 0 : normalizeValue(parameters, {
35
+ maxDepth: 4,
36
+ maxObjectKeys: 80
37
+ });
38
+ }
39
+ function databaseIntegration(options = {}) {
40
+ const targets = options.targets ?? (options.client ? [{
41
+ client: options.client,
42
+ name: options.name,
43
+ system: options.system,
44
+ methods: options.methods
45
+ }] : []);
46
+ const captureAll = options.captureAll ?? options.captureSuccessful ?? false;
47
+ const sampleRate = options.sampleRate ?? 1;
48
+ const random = options.random ?? defaultRandom;
49
+ const levelFor = options.level ?? defaultLevel;
50
+ const shouldCapture = (durationMs, error) => {
51
+ if (error) return true;
52
+ if (options.minDurationMs !== void 0 && durationMs >= options.minDurationMs) return true;
53
+ if (!captureAll) return false;
54
+ return sampleRate >= 1 || random() < sampleRate;
55
+ };
56
+ return {
57
+ name: "database",
58
+ setup(api) {
59
+ const capture = api.guard((input) => api.capture(input));
60
+ const disposers = [];
61
+ let disposed = false;
62
+ const captureResult = (info, started, args, error) => {
63
+ const durationMs = Date.now() - started;
64
+ if (disposed || !shouldCapture(durationMs, error)) return;
65
+ capture({
66
+ level: levelFor(durationMs, error, info),
67
+ message: error ? `Database error ${info.method}${info.statement ? ` ${info.statement}` : ""}` : `Database ${info.method}${info.statement ? ` ${info.statement}` : ""}`,
68
+ error,
69
+ props: { db: {
70
+ kind: info.target,
71
+ system: info.system,
72
+ method: info.method,
73
+ statement: info.statement,
74
+ durationMs,
75
+ parameters: parametersFor(args, options.captureParameters ?? false)
76
+ } }
77
+ });
78
+ };
79
+ for (const target of targets) {
80
+ const methods = target.methods ?? options.methods ?? defaultMethods;
81
+ for (const method of methods) {
82
+ const original = target.client[method];
83
+ if (typeof original !== "function") continue;
84
+ const originalMethod = original;
85
+ const targetName = target.name ?? options.name ?? "database";
86
+ const system = target.system ?? options.system;
87
+ target.client[method] = function wrappedDatabaseMethod(...args) {
88
+ const started = Date.now();
89
+ const info = {
90
+ target: targetName,
91
+ system,
92
+ method,
93
+ statement: statementFor(args, method, options)
94
+ };
95
+ try {
96
+ const result = originalMethod.apply(this, args);
97
+ if (isPromiseLike(result)) return result.then((value) => {
98
+ captureResult(info, started, args, void 0);
99
+ return value;
100
+ }, (error) => {
101
+ captureResult(info, started, args, error);
102
+ throw error;
103
+ });
104
+ captureResult(info, started, args, void 0);
105
+ return result;
106
+ } catch (error) {
107
+ captureResult(info, started, args, error);
108
+ throw error;
109
+ }
110
+ };
111
+ disposers.push(() => {
112
+ target.client[method] = originalMethod;
113
+ });
114
+ }
115
+ }
116
+ return () => {
117
+ if (disposed) return;
118
+ disposed = true;
119
+ for (const dispose of disposers) dispose();
120
+ };
121
+ }
122
+ };
123
+ }
124
+ //#endregion
125
+ export { databaseIntegration };
126
+
127
+ //# sourceMappingURL=database-integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-integration.js","names":[],"sources":["../src/database-integration.ts"],"sourcesContent":["import {\n normalizeValue,\n type CaptureInput,\n type Integration,\n type IntegrationSetupContext,\n type LoggerLevel,\n} from \"@loggerjs/core\";\n\nexport interface DatabaseClientLike {\n [method: string]: unknown;\n}\n\nexport interface DatabaseIntegrationTarget {\n client: DatabaseClientLike;\n name?: string;\n system?: string;\n methods?: readonly string[];\n}\n\nexport interface DatabaseOperationInfo {\n target: string;\n system?: string;\n method: string;\n statement?: string;\n}\n\nexport interface DatabaseIntegrationOptions {\n client?: DatabaseClientLike;\n targets?: readonly DatabaseIntegrationTarget[];\n name?: string;\n system?: string;\n methods?: readonly string[];\n captureAll?: boolean;\n captureSuccessful?: boolean;\n minDurationMs?: number;\n sampleRate?: number;\n random?: () => number;\n captureParameters?: boolean;\n sanitizeStatement?: (statement: string) => string;\n getStatement?: (args: readonly unknown[], method: string) => string | undefined;\n level?: (durationMs: number, error: unknown, info: DatabaseOperationInfo) => LoggerLevel;\n}\n\ntype DatabaseMethod = (this: unknown, ...args: unknown[]) => unknown;\n\nconst defaultMethods = [\"query\", \"execute\", \"run\", \"all\", \"get\"] as const;\nconst defaultRandom = () => Math.random();\n\nfunction defaultLevel(_durationMs: number, error: unknown): LoggerLevel {\n return error ? \"error\" : \"debug\";\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { then?: unknown }).then === \"function\"\n );\n}\n\nfunction defaultStatement(args: readonly unknown[]): string | undefined {\n const first = args[0];\n if (typeof first === \"string\") return first;\n if (typeof first !== \"object\" || first === null) return undefined;\n const input = first as { sql?: unknown; text?: unknown; query?: unknown };\n if (typeof input.sql === \"string\") return input.sql;\n if (typeof input.text === \"string\") return input.text;\n if (typeof input.query === \"string\") return input.query;\n return undefined;\n}\n\nfunction statementFor(\n args: readonly unknown[],\n method: string,\n options: DatabaseIntegrationOptions,\n) {\n const statement = options.getStatement?.(args, method) ?? defaultStatement(args);\n return statement && options.sanitizeStatement ? options.sanitizeStatement(statement) : statement;\n}\n\nfunction parametersFor(args: readonly unknown[], captureParameters: boolean) {\n if (!captureParameters) return undefined;\n const first = args[0];\n const second = args[1];\n const parameters =\n second ??\n (typeof first === \"object\" && first\n ? ((first as { values?: unknown; params?: unknown; parameters?: unknown }).values ??\n (first as { params?: unknown }).params ??\n (first as { parameters?: unknown }).parameters)\n : undefined);\n return parameters === undefined\n ? undefined\n : normalizeValue(parameters, { maxDepth: 4, maxObjectKeys: 80 });\n}\n\nexport function databaseIntegration(options: DatabaseIntegrationOptions = {}): Integration {\n const targets =\n options.targets ??\n (options.client\n ? [\n {\n client: options.client,\n name: options.name,\n system: options.system,\n methods: options.methods,\n },\n ]\n : []);\n const captureAll = options.captureAll ?? options.captureSuccessful ?? false;\n const sampleRate = options.sampleRate ?? 1;\n const random = options.random ?? defaultRandom;\n const levelFor = options.level ?? defaultLevel;\n\n const shouldCapture = (durationMs: number, error: unknown) => {\n if (error) return true;\n if (options.minDurationMs !== undefined && durationMs >= options.minDurationMs) return true;\n if (!captureAll) return false;\n return sampleRate >= 1 || random() < sampleRate;\n };\n\n return {\n name: \"database\",\n setup(api: IntegrationSetupContext) {\n const capture = api.guard((input: CaptureInput) => api.capture(input));\n const disposers: Array<() => void> = [];\n let disposed = false;\n\n const captureResult = (\n info: DatabaseOperationInfo,\n started: number,\n args: readonly unknown[],\n error: unknown,\n ) => {\n const durationMs = Date.now() - started;\n if (disposed || !shouldCapture(durationMs, error)) return;\n capture({\n level: levelFor(durationMs, error, info),\n message: error\n ? `Database error ${info.method}${info.statement ? ` ${info.statement}` : \"\"}`\n : `Database ${info.method}${info.statement ? ` ${info.statement}` : \"\"}`,\n error,\n props: {\n db: {\n kind: info.target,\n system: info.system,\n method: info.method,\n statement: info.statement,\n durationMs,\n parameters: parametersFor(args, options.captureParameters ?? false),\n },\n },\n });\n };\n\n for (const target of targets) {\n const methods = target.methods ?? options.methods ?? defaultMethods;\n for (const method of methods) {\n const original = target.client[method];\n if (typeof original !== \"function\") continue;\n const originalMethod = original as DatabaseMethod;\n const targetName = target.name ?? options.name ?? \"database\";\n const system = target.system ?? options.system;\n\n target.client[method] = function wrappedDatabaseMethod(\n this: unknown,\n ...args: unknown[]\n ) {\n const started = Date.now();\n const info: DatabaseOperationInfo = {\n target: targetName,\n system,\n method,\n statement: statementFor(args, method, options),\n };\n try {\n const result = originalMethod.apply(this, args);\n if (isPromiseLike(result)) {\n return result.then(\n (value) => {\n captureResult(info, started, args, undefined);\n return value;\n },\n (error) => {\n captureResult(info, started, args, error);\n throw error;\n },\n );\n }\n captureResult(info, started, args, undefined);\n return result;\n } catch (error) {\n captureResult(info, started, args, error);\n throw error;\n }\n };\n\n disposers.push(() => {\n target.client[method] = originalMethod;\n });\n }\n }\n\n return () => {\n if (disposed) return;\n disposed = true;\n for (const dispose of disposers) dispose();\n };\n },\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let node_module = require("node:module");
3
+ let _loggerjs_core = require("@loggerjs/core");
4
+ //#region src/diagnostics-channel-integration.ts
5
+ const defaultChannels = [
6
+ "http.client.request.start",
7
+ "http.client.response.finish",
8
+ "http.server.request.start",
9
+ "http.server.response.finish",
10
+ "undici:request:create",
11
+ "undici:request:headers",
12
+ "undici:request:trailers",
13
+ "undici:request:error"
14
+ ];
15
+ const requireBuiltin = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
16
+ let cachedDiagnosticsChannel;
17
+ function diagnosticsChannelIntegration(options = {}) {
18
+ const channels = options.channels ?? defaultChannels;
19
+ const captureMessage = options.captureMessage ?? false;
20
+ return {
21
+ name: "diagnostics-channel",
22
+ setup(api) {
23
+ const diagnosticsChannel = options.diagnosticsChannel === void 0 ? loadDiagnosticsChannel() : options.diagnosticsChannel;
24
+ if (!diagnosticsChannel) return;
25
+ const disposers = [];
26
+ let disposed = false;
27
+ const capture = api.guard((input) => api.capture(input));
28
+ for (const channel of channels) {
29
+ const listener = (message, name) => {
30
+ capture({
31
+ level: name.endsWith(":error") ? "error" : "debug",
32
+ message: `diagnostics_channel ${name}`,
33
+ props: { diagnostics: {
34
+ channel: name,
35
+ message: captureMessage ? (0, _loggerjs_core.normalizeValue)(message, { maxDepth: 4 }) : void 0
36
+ } }
37
+ });
38
+ };
39
+ diagnosticsChannel.subscribe(channel, listener);
40
+ disposers.push(() => diagnosticsChannel.unsubscribe?.(channel, listener));
41
+ }
42
+ return () => {
43
+ if (disposed) return;
44
+ disposed = true;
45
+ for (const dispose of disposers) dispose();
46
+ };
47
+ }
48
+ };
49
+ }
50
+ function loadDiagnosticsChannel() {
51
+ if (cachedDiagnosticsChannel !== void 0) return cachedDiagnosticsChannel;
52
+ try {
53
+ cachedDiagnosticsChannel = requireBuiltin("node:diagnostics_channel");
54
+ } catch {
55
+ try {
56
+ cachedDiagnosticsChannel = requireBuiltin("diagnostics_channel");
57
+ } catch {
58
+ cachedDiagnosticsChannel = null;
59
+ }
60
+ }
61
+ return cachedDiagnosticsChannel;
62
+ }
63
+ //#endregion
64
+ exports.diagnosticsChannelIntegration = diagnosticsChannelIntegration;
65
+
66
+ //# sourceMappingURL=diagnostics-channel-integration.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics-channel-integration.cjs","names":[],"sources":["../src/diagnostics-channel-integration.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport {\n normalizeValue,\n type CaptureInput,\n type Integration,\n type IntegrationSetupContext,\n} from \"@loggerjs/core\";\n\nexport interface DiagnosticsChannelModule {\n subscribe: (name: string, listener: (message: unknown, name: string) => void) => void;\n unsubscribe?: (name: string, listener: (message: unknown, name: string) => void) => void;\n}\n\nexport interface DiagnosticsChannelIntegrationOptions {\n channels?: readonly string[];\n diagnosticsChannel?: DiagnosticsChannelModule | null;\n captureMessage?: boolean;\n}\n\nconst defaultChannels = [\n \"http.client.request.start\",\n \"http.client.response.finish\",\n \"http.server.request.start\",\n \"http.server.response.finish\",\n \"undici:request:create\",\n \"undici:request:headers\",\n \"undici:request:trailers\",\n \"undici:request:error\",\n] as const;\n\nconst requireBuiltin = createRequire(import.meta.url);\nlet cachedDiagnosticsChannel: DiagnosticsChannelModule | null | undefined;\n\nexport function diagnosticsChannelIntegration(\n options: DiagnosticsChannelIntegrationOptions = {},\n): Integration {\n const channels = options.channels ?? defaultChannels;\n const captureMessage = options.captureMessage ?? false;\n\n return {\n name: \"diagnostics-channel\",\n setup(api: IntegrationSetupContext) {\n const diagnosticsChannel =\n options.diagnosticsChannel === undefined\n ? loadDiagnosticsChannel()\n : options.diagnosticsChannel;\n if (!diagnosticsChannel) return;\n\n const disposers: Array<() => void> = [];\n let disposed = false;\n const capture = api.guard((input: CaptureInput) => api.capture(input));\n\n for (const channel of channels) {\n const listener = (message: unknown, name: string) => {\n capture({\n level: name.endsWith(\":error\") ? \"error\" : \"debug\",\n message: `diagnostics_channel ${name}`,\n props: {\n diagnostics: {\n channel: name,\n message: captureMessage ? normalizeValue(message, { maxDepth: 4 }) : undefined,\n },\n },\n });\n };\n diagnosticsChannel.subscribe(channel, listener);\n disposers.push(() => diagnosticsChannel.unsubscribe?.(channel, listener));\n }\n\n return () => {\n if (disposed) return;\n disposed = true;\n for (const dispose of disposers) dispose();\n };\n },\n };\n}\n\nfunction loadDiagnosticsChannel(): DiagnosticsChannelModule | null {\n if (cachedDiagnosticsChannel !== undefined) return cachedDiagnosticsChannel;\n try {\n cachedDiagnosticsChannel = requireBuiltin(\n \"node:diagnostics_channel\",\n ) as DiagnosticsChannelModule;\n } catch {\n try {\n cachedDiagnosticsChannel = requireBuiltin(\"diagnostics_channel\") as DiagnosticsChannelModule;\n } catch {\n cachedDiagnosticsChannel = null;\n }\n }\n return cachedDiagnosticsChannel;\n}\n"],"mappings":";;;;AAmBA,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,kBAAA,GAAA,YAAA,cAAA,CAAA,QAAA,KAAA,CAAA,CAAA,cAAA,UAAA,CAAA,CAAA,IAA8C;AACpD,IAAI;AAEJ,SAAgB,8BACd,UAAgD,CAAC,GACpC;CACb,MAAM,WAAW,QAAQ,YAAY;CACrC,MAAM,iBAAiB,QAAQ,kBAAkB;CAEjD,OAAO;EACL,MAAM;EACN,MAAM,KAA8B;GAClC,MAAM,qBACJ,QAAQ,uBAAuB,KAAA,IAC3B,uBAAuB,IACvB,QAAQ;GACd,IAAI,CAAC,oBAAoB;GAEzB,MAAM,YAA+B,CAAC;GACtC,IAAI,WAAW;GACf,MAAM,UAAU,IAAI,OAAO,UAAwB,IAAI,QAAQ,KAAK,CAAC;GAErE,KAAK,MAAM,WAAW,UAAU;IAC9B,MAAM,YAAY,SAAkB,SAAiB;KACnD,QAAQ;MACN,OAAO,KAAK,SAAS,QAAQ,IAAI,UAAU;MAC3C,SAAS,uBAAuB;MAChC,OAAO,EACL,aAAa;OACX,SAAS;OACT,SAAS,kBAAA,GAAA,eAAA,eAAA,CAAgC,SAAS,EAAE,UAAU,EAAE,CAAC,IAAI,KAAA;MACvE,EACF;KACF,CAAC;IACH;IACA,mBAAmB,UAAU,SAAS,QAAQ;IAC9C,UAAU,WAAW,mBAAmB,cAAc,SAAS,QAAQ,CAAC;GAC1E;GAEA,aAAa;IACX,IAAI,UAAU;IACd,WAAW;IACX,KAAK,MAAM,WAAW,WAAW,QAAQ;GAC3C;EACF;CACF;AACF;AAEA,SAAS,yBAA0D;CACjE,IAAI,6BAA6B,KAAA,GAAW,OAAO;CACnD,IAAI;EACF,2BAA2B,eACzB,0BACF;CACF,QAAQ;EACN,IAAI;GACF,2BAA2B,eAAe,qBAAqB;EACjE,QAAQ;GACN,2BAA2B;EAC7B;CACF;CACA,OAAO;AACT"}
@@ -0,0 +1,65 @@
1
+ import { createRequire } from "node:module";
2
+ import { normalizeValue } from "@loggerjs/core";
3
+ //#region src/diagnostics-channel-integration.ts
4
+ const defaultChannels = [
5
+ "http.client.request.start",
6
+ "http.client.response.finish",
7
+ "http.server.request.start",
8
+ "http.server.response.finish",
9
+ "undici:request:create",
10
+ "undici:request:headers",
11
+ "undici:request:trailers",
12
+ "undici:request:error"
13
+ ];
14
+ const requireBuiltin = createRequire(import.meta.url);
15
+ let cachedDiagnosticsChannel;
16
+ function diagnosticsChannelIntegration(options = {}) {
17
+ const channels = options.channels ?? defaultChannels;
18
+ const captureMessage = options.captureMessage ?? false;
19
+ return {
20
+ name: "diagnostics-channel",
21
+ setup(api) {
22
+ const diagnosticsChannel = options.diagnosticsChannel === void 0 ? loadDiagnosticsChannel() : options.diagnosticsChannel;
23
+ if (!diagnosticsChannel) return;
24
+ const disposers = [];
25
+ let disposed = false;
26
+ const capture = api.guard((input) => api.capture(input));
27
+ for (const channel of channels) {
28
+ const listener = (message, name) => {
29
+ capture({
30
+ level: name.endsWith(":error") ? "error" : "debug",
31
+ message: `diagnostics_channel ${name}`,
32
+ props: { diagnostics: {
33
+ channel: name,
34
+ message: captureMessage ? normalizeValue(message, { maxDepth: 4 }) : void 0
35
+ } }
36
+ });
37
+ };
38
+ diagnosticsChannel.subscribe(channel, listener);
39
+ disposers.push(() => diagnosticsChannel.unsubscribe?.(channel, listener));
40
+ }
41
+ return () => {
42
+ if (disposed) return;
43
+ disposed = true;
44
+ for (const dispose of disposers) dispose();
45
+ };
46
+ }
47
+ };
48
+ }
49
+ function loadDiagnosticsChannel() {
50
+ if (cachedDiagnosticsChannel !== void 0) return cachedDiagnosticsChannel;
51
+ try {
52
+ cachedDiagnosticsChannel = requireBuiltin("node:diagnostics_channel");
53
+ } catch {
54
+ try {
55
+ cachedDiagnosticsChannel = requireBuiltin("diagnostics_channel");
56
+ } catch {
57
+ cachedDiagnosticsChannel = null;
58
+ }
59
+ }
60
+ return cachedDiagnosticsChannel;
61
+ }
62
+ //#endregion
63
+ export { diagnosticsChannelIntegration };
64
+
65
+ //# sourceMappingURL=diagnostics-channel-integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics-channel-integration.js","names":[],"sources":["../src/diagnostics-channel-integration.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport {\n normalizeValue,\n type CaptureInput,\n type Integration,\n type IntegrationSetupContext,\n} from \"@loggerjs/core\";\n\nexport interface DiagnosticsChannelModule {\n subscribe: (name: string, listener: (message: unknown, name: string) => void) => void;\n unsubscribe?: (name: string, listener: (message: unknown, name: string) => void) => void;\n}\n\nexport interface DiagnosticsChannelIntegrationOptions {\n channels?: readonly string[];\n diagnosticsChannel?: DiagnosticsChannelModule | null;\n captureMessage?: boolean;\n}\n\nconst defaultChannels = [\n \"http.client.request.start\",\n \"http.client.response.finish\",\n \"http.server.request.start\",\n \"http.server.response.finish\",\n \"undici:request:create\",\n \"undici:request:headers\",\n \"undici:request:trailers\",\n \"undici:request:error\",\n] as const;\n\nconst requireBuiltin = createRequire(import.meta.url);\nlet cachedDiagnosticsChannel: DiagnosticsChannelModule | null | undefined;\n\nexport function diagnosticsChannelIntegration(\n options: DiagnosticsChannelIntegrationOptions = {},\n): Integration {\n const channels = options.channels ?? defaultChannels;\n const captureMessage = options.captureMessage ?? false;\n\n return {\n name: \"diagnostics-channel\",\n setup(api: IntegrationSetupContext) {\n const diagnosticsChannel =\n options.diagnosticsChannel === undefined\n ? loadDiagnosticsChannel()\n : options.diagnosticsChannel;\n if (!diagnosticsChannel) return;\n\n const disposers: Array<() => void> = [];\n let disposed = false;\n const capture = api.guard((input: CaptureInput) => api.capture(input));\n\n for (const channel of channels) {\n const listener = (message: unknown, name: string) => {\n capture({\n level: name.endsWith(\":error\") ? \"error\" : \"debug\",\n message: `diagnostics_channel ${name}`,\n props: {\n diagnostics: {\n channel: name,\n message: captureMessage ? normalizeValue(message, { maxDepth: 4 }) : undefined,\n },\n },\n });\n };\n diagnosticsChannel.subscribe(channel, listener);\n disposers.push(() => diagnosticsChannel.unsubscribe?.(channel, listener));\n }\n\n return () => {\n if (disposed) return;\n disposed = true;\n for (const dispose of disposers) dispose();\n };\n },\n };\n}\n\nfunction loadDiagnosticsChannel(): DiagnosticsChannelModule | null {\n if (cachedDiagnosticsChannel !== undefined) return cachedDiagnosticsChannel;\n try {\n cachedDiagnosticsChannel = requireBuiltin(\n \"node:diagnostics_channel\",\n ) as DiagnosticsChannelModule;\n } catch {\n try {\n cachedDiagnosticsChannel = requireBuiltin(\"diagnostics_channel\") as DiagnosticsChannelModule;\n } catch {\n cachedDiagnosticsChannel = null;\n }\n }\n return cachedDiagnosticsChannel;\n}\n"],"mappings":";;;AAmBA,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,iBAAiB,cAAc,OAAO,KAAK,GAAG;AACpD,IAAI;AAEJ,SAAgB,8BACd,UAAgD,CAAC,GACpC;CACb,MAAM,WAAW,QAAQ,YAAY;CACrC,MAAM,iBAAiB,QAAQ,kBAAkB;CAEjD,OAAO;EACL,MAAM;EACN,MAAM,KAA8B;GAClC,MAAM,qBACJ,QAAQ,uBAAuB,KAAA,IAC3B,uBAAuB,IACvB,QAAQ;GACd,IAAI,CAAC,oBAAoB;GAEzB,MAAM,YAA+B,CAAC;GACtC,IAAI,WAAW;GACf,MAAM,UAAU,IAAI,OAAO,UAAwB,IAAI,QAAQ,KAAK,CAAC;GAErE,KAAK,MAAM,WAAW,UAAU;IAC9B,MAAM,YAAY,SAAkB,SAAiB;KACnD,QAAQ;MACN,OAAO,KAAK,SAAS,QAAQ,IAAI,UAAU;MAC3C,SAAS,uBAAuB;MAChC,OAAO,EACL,aAAa;OACX,SAAS;OACT,SAAS,iBAAiB,eAAe,SAAS,EAAE,UAAU,EAAE,CAAC,IAAI,KAAA;MACvE,EACF;KACF,CAAC;IACH;IACA,mBAAmB,UAAU,SAAS,QAAQ;IAC9C,UAAU,WAAW,mBAAmB,cAAc,SAAS,QAAQ,CAAC;GAC1E;GAEA,aAAa;IACX,IAAI,UAAU;IACd,WAAW;IACX,KAAK,MAAM,WAAW,WAAW,QAAQ;GAC3C;EACF;CACF;AACF;AAEA,SAAS,yBAA0D;CACjE,IAAI,6BAA6B,KAAA,GAAW,OAAO;CACnD,IAAI;EACF,2BAA2B,eACzB,0BACF;CACF,QAAQ;EACN,IAAI;GACF,2BAA2B,eAAe,qBAAqB;EACjE,QAAQ;GACN,2BAA2B;EAC7B;CACF;CACA,OAAO;AACT"}