@loggerjs/node 0.6.0 → 0.7.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 (71) hide show
  1. package/README.md +5 -4
  2. package/dist/bullmq-integration.cjs +2 -145
  3. package/dist/bullmq-integration.cjs.map +1 -1
  4. package/dist/bullmq-integration.js +1 -144
  5. package/dist/bullmq-integration.js.map +1 -1
  6. package/dist/chunks/node-destination-DvP8jBvm.cjs +254 -0
  7. package/dist/chunks/node-destination-DvP8jBvm.cjs.map +1 -0
  8. package/dist/chunks/node-destination-YnpYbctz.js +243 -0
  9. package/dist/chunks/node-destination-YnpYbctz.js.map +1 -0
  10. package/dist/context.cjs +1 -1
  11. package/dist/context.js +1 -1
  12. package/dist/diagnostics-channel-integration.cjs +1 -1
  13. package/dist/file-transport.cjs +3 -232
  14. package/dist/file-transport.cjs.map +1 -1
  15. package/dist/file-transport.js +3 -232
  16. package/dist/file-transport.js.map +1 -1
  17. package/dist/http-transport.cjs +25 -4
  18. package/dist/http-transport.cjs.map +1 -1
  19. package/dist/http-transport.d.ts +15 -0
  20. package/dist/http-transport.d.ts.map +1 -1
  21. package/dist/http-transport.js +25 -4
  22. package/dist/http-transport.js.map +1 -1
  23. package/dist/index.cjs +54 -2375
  24. package/dist/index.d.ts +211 -19
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +25 -2347
  27. package/dist/internal-types.d.ts +1 -0
  28. package/dist/internal-types.d.ts.map +1 -1
  29. package/dist/logger-diagnostics.cjs +4 -5
  30. package/dist/logger-diagnostics.cjs.map +1 -1
  31. package/dist/logger-diagnostics.d.ts +1 -1
  32. package/dist/logger-diagnostics.d.ts.map +1 -1
  33. package/dist/logger-diagnostics.js +1 -1
  34. package/dist/logger-diagnostics.js.map +1 -1
  35. package/dist/nest-integration.cjs +2 -127
  36. package/dist/nest-integration.cjs.map +1 -1
  37. package/dist/nest-integration.js +1 -126
  38. package/dist/nest-integration.js.map +1 -1
  39. package/dist/node-destination.d.ts.map +1 -1
  40. package/dist/payload-transforms.cjs +2 -2
  41. package/dist/payload-transforms.cjs.map +1 -1
  42. package/dist/payload-transforms.d.ts.map +1 -1
  43. package/dist/payload-transforms.js +1 -1
  44. package/dist/payload-transforms.js.map +1 -1
  45. package/dist/prisma-integration.cjs +2 -125
  46. package/dist/prisma-integration.cjs.map +1 -1
  47. package/dist/prisma-integration.js +1 -124
  48. package/dist/prisma-integration.js.map +1 -1
  49. package/dist/redis-integration.cjs +2 -125
  50. package/dist/redis-integration.cjs.map +1 -1
  51. package/dist/redis-integration.js +1 -124
  52. package/dist/redis-integration.js.map +1 -1
  53. package/dist/rotating-file-transport.cjs +24 -239
  54. package/dist/rotating-file-transport.cjs.map +1 -1
  55. package/dist/rotating-file-transport.d.ts.map +1 -1
  56. package/dist/rotating-file-transport.js +24 -239
  57. package/dist/rotating-file-transport.js.map +1 -1
  58. package/dist/stdout-transport.cjs +3 -162
  59. package/dist/stdout-transport.cjs.map +1 -1
  60. package/dist/stdout-transport.js +3 -162
  61. package/dist/stdout-transport.js.map +1 -1
  62. package/dist/syslog-transport.cjs +1 -1
  63. package/dist/syslog-transport.js +1 -1
  64. package/dist/worker-transport.cjs +5 -4
  65. package/dist/worker-transport.cjs.map +1 -1
  66. package/dist/worker-transport.d.ts.map +1 -1
  67. package/dist/worker-transport.js +3 -2
  68. package/dist/worker-transport.js.map +1 -1
  69. package/package.json +5 -2
  70. package/dist/index.cjs.map +0 -1
  71. package/dist/index.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,2349 +1,27 @@
1
- import { createRequire } from "node:module";
2
- import { applyPayloadTransforms, batchTransport, createBoundContext, emitLoggerDiagnostic, encodedPayloadToUint8Array, incrementLoggerMetaCounter, ndjsonCodec, normalizeValue, resetContextManager, safeJsonCodec, safeJsonStringify, setContextManager, setLoggerDiagnosticSink, setLoggerMetaGauge, toLevelValue, withContext } from "@loggerjs/core";
3
- import { closeSync, createWriteStream, existsSync, mkdirSync, openSync, renameSync, statSync, unlinkSync, writeSync } from "fs";
4
- import { dirname } from "path";
5
- import { brotliCompressSync, deflateSync, gzipSync } from "node:zlib";
6
- import { createSocket } from "dgram";
7
- import { createConnection } from "net";
8
- import { hostname } from "os";
9
- import { Worker } from "node:worker_threads";
10
- import { AsyncLocalStorage } from "node:async_hooks";
1
+ import { stderrTransport, stdoutTransport } from "./stdout-transport.js";
2
+ import { fileTransport } from "./file-transport.js";
3
+ import { rotatingFileTransport } from "./rotating-file-transport.js";
4
+ import { nodeHttpTransport } from "./http-transport.js";
5
+ import { nodeCompressionPayloadTransform } from "./payload-transforms.js";
6
+ import { formatSyslogMessage, nodeSyslogTransport } from "./syslog-transport.js";
7
+ import { workerTransport } from "./worker-transport.js";
8
+ import { createAsyncLocalStorageContextManager, installAsyncLocalStorageContext } from "./context.js";
9
+ import { queueIntegration } from "./queue-integration.js";
10
+ import { bullMqIntegration } from "./bullmq-integration.js";
11
+ import { captureCliIntegration } from "./cli-integration.js";
12
+ import { databaseIntegration } from "./database-integration.js";
13
+ import { expressIntegration } from "./express-integration.js";
14
+ import { fastifyIntegration } from "./fastify-integration.js";
15
+ import { hapiIntegration } from "./hapi-integration.js";
16
+ import { koaIntegration } from "./koa-integration.js";
17
+ import { nestMiddlewareIntegration } from "./nest-integration.js";
18
+ import { nodeFetchIntegration } from "./node-fetch-integration.js";
19
+ import { nodeHttpClientIntegration } from "./node-http-client-integration.js";
20
+ import { captureProcessIntegration } from "./process-integration.js";
21
+ import { prismaIntegration } from "./prisma-integration.js";
22
+ import { redisIntegration } from "./redis-integration.js";
23
+ import { serverlessIntegration } from "./serverless-integration.js";
24
+ import { diagnosticsChannelIntegration } from "./diagnostics-channel-integration.js";
25
+ import { installLoggerDiagnosticsChannel } from "./logger-diagnostics.js";
11
26
  export * from "@loggerjs/core";
12
- //#region src/node-destination.ts
13
- const encoder = new TextEncoder();
14
- const normalizeError = (error) => error instanceof Error ? error : new Error(String(error));
15
- function byteLength(payload) {
16
- return typeof payload === "string" ? encoder.encode(payload).byteLength : payload.byteLength;
17
- }
18
- function coalescePayloads(payloads) {
19
- if (payloads.every((payload) => typeof payload === "string")) return payloads.join("");
20
- const buffers = payloads.map((payload) => typeof payload === "string" ? Buffer.from(payload) : Buffer.from(payload));
21
- return Buffer.concat(buffers);
22
- }
23
- function isEpipe(error) {
24
- return Boolean(error) && typeof error === "object" && error.code === "EPIPE";
25
- }
26
- function normalizeMinLength(value) {
27
- if (value === void 0 || !Number.isFinite(value) || value <= 0) return 0;
28
- return Math.floor(value);
29
- }
30
- function createNodeStreamDestination(options) {
31
- const minLength = normalizeMinLength(options.minLength);
32
- const ignoreEpipe = options.ignoreEpipe ?? false;
33
- const waiters = [];
34
- const buffer = [];
35
- const pendingPayloads = [];
36
- let bufferedBytes = 0;
37
- let pendingWrites = 0;
38
- let pendingDrains = 0;
39
- let lastError;
40
- let lastContext;
41
- let closed = false;
42
- const reportInternalError = (error, operation) => {
43
- if (ignoreEpipe && isEpipe(error)) return;
44
- lastContext?.reportInternalError(error, {
45
- phase: "transport",
46
- transport: options.name,
47
- operation
48
- });
49
- };
50
- const settleWaitersIfIdle = () => {
51
- if (pendingWrites + pendingDrains > 0) return;
52
- if (waiters.length === 0) return;
53
- const error = lastError;
54
- lastError = void 0;
55
- for (const waiter of waiters.splice(0)) if (error) waiter.reject(error);
56
- else waiter.resolve();
57
- };
58
- const recordError = (error, operation) => {
59
- if (ignoreEpipe && isEpipe(error)) {
60
- closed = true;
61
- return;
62
- }
63
- lastError = normalizeError(error);
64
- reportInternalError(lastError, operation);
65
- };
66
- const onStreamError = (error) => {
67
- recordError(error, "stream-error");
68
- settleWaitersIfIdle();
69
- };
70
- const offError = () => options.stream.off?.("error", onStreamError);
71
- options.stream.on?.("error", onStreamError);
72
- const waitForDrain = () => {
73
- if (!options.stream.once) return;
74
- pendingDrains += 1;
75
- options.stream.once("drain", () => {
76
- pendingDrains -= 1;
77
- settleWaitersIfIdle();
78
- });
79
- };
80
- const removePending = (payload) => {
81
- const index = pendingPayloads.indexOf(payload);
82
- if (index >= 0) pendingPayloads.splice(index, 1);
83
- };
84
- const writeNow = (payload) => {
85
- if (closed) return;
86
- pendingPayloads.push(payload);
87
- pendingWrites += 1;
88
- try {
89
- if (options.stream.write(payload, (error) => {
90
- removePending(payload);
91
- pendingWrites -= 1;
92
- if (error) recordError(error, options.reportOperation ?? "write");
93
- settleWaitersIfIdle();
94
- }) === false) waitForDrain();
95
- } catch (error) {
96
- removePending(payload);
97
- pendingWrites -= 1;
98
- recordError(error, options.reportOperation ?? "write");
99
- settleWaitersIfIdle();
100
- }
101
- };
102
- const flushBuffered = () => {
103
- if (buffer.length === 0) return;
104
- const payload = coalescePayloads(buffer.splice(0));
105
- bufferedBytes = 0;
106
- writeNow(payload);
107
- };
108
- const destination = {
109
- write(payload, context) {
110
- if (closed) return;
111
- lastContext = context;
112
- if (minLength > 0) {
113
- buffer.push(payload);
114
- bufferedBytes += byteLength(payload);
115
- if (bufferedBytes >= minLength) flushBuffered();
116
- return;
117
- }
118
- writeNow(payload);
119
- },
120
- flush() {
121
- flushBuffered();
122
- if (pendingWrites + pendingDrains === 0) {
123
- const error = lastError;
124
- lastError = void 0;
125
- if (error) return Promise.reject(error);
126
- return Promise.resolve();
127
- }
128
- return new Promise((resolve, reject) => {
129
- waiters.push({
130
- resolve,
131
- reject
132
- });
133
- });
134
- },
135
- flushSync() {
136
- if (!options.syncWrite) {
137
- flushBuffered();
138
- return;
139
- }
140
- for (const payload of buffer.splice(0)) options.syncWrite(payload);
141
- bufferedBytes = 0;
142
- for (const payload of pendingPayloads.splice(0)) options.syncWrite(payload);
143
- },
144
- close() {
145
- return destination.flush().then(() => new Promise((resolve, reject) => {
146
- if (!options.stream.end) {
147
- closed = true;
148
- offError();
149
- resolve();
150
- return;
151
- }
152
- options.stream.end((error) => {
153
- closed = true;
154
- offError();
155
- if (error && !(ignoreEpipe && isEpipe(error))) reject(error);
156
- else resolve();
157
- });
158
- }), (error) => {
159
- offError();
160
- return Promise.reject(error);
161
- });
162
- },
163
- closeSync() {
164
- destination.flushSync();
165
- closed = true;
166
- offError();
167
- }
168
- };
169
- return destination;
170
- }
171
- function createNodeFileDestination(options) {
172
- const flags = options.flags ?? (options.append === false ? "w" : "a");
173
- if (options.mkdir) mkdirSync(dirname(options.path), { recursive: true });
174
- let fd;
175
- const syncFlags = options.sync ? flags : "a";
176
- const getFd = () => {
177
- fd ??= openSync(options.path, syncFlags);
178
- return fd;
179
- };
180
- const syncWrite = (payload) => {
181
- if (typeof payload === "string") writeSync(getFd(), payload);
182
- else writeSync(getFd(), payload);
183
- };
184
- if (options.sync) {
185
- let closed = false;
186
- const releaseSync = () => {
187
- if (fd !== void 0) {
188
- closeSync(fd);
189
- fd = void 0;
190
- }
191
- };
192
- return {
193
- write(payload) {
194
- if (closed) return;
195
- syncWrite(payload);
196
- },
197
- flush() {
198
- return Promise.resolve();
199
- },
200
- flushSync() {},
201
- close() {
202
- releaseSync();
203
- closed = true;
204
- return Promise.resolve();
205
- },
206
- closeSync() {
207
- releaseSync();
208
- closed = true;
209
- },
210
- releaseSync
211
- };
212
- }
213
- const stream = createWriteStream(options.path, { flags });
214
- const destination = createNodeStreamDestination({
215
- name: options.name,
216
- stream,
217
- minLength: options.minLength,
218
- syncWrite
219
- });
220
- const releaseSync = () => {
221
- if (fd !== void 0) {
222
- closeSync(fd);
223
- fd = void 0;
224
- }
225
- };
226
- return {
227
- ...destination,
228
- stream,
229
- close() {
230
- return destination.close().finally(releaseSync);
231
- },
232
- closeSync() {
233
- destination.closeSync();
234
- releaseSync();
235
- },
236
- releaseSync
237
- };
238
- }
239
- //#endregion
240
- //#region src/stdout-transport.ts
241
- function stdoutTransport(options = {}) {
242
- const codec = options.codec ?? ndjsonCodec();
243
- const stream = options.stream ?? process.stdout;
244
- const transportName = options.name ?? "stdout";
245
- const destination = createNodeStreamDestination({
246
- name: transportName,
247
- stream,
248
- minLength: options.minLength,
249
- ignoreEpipe: options.ignoreEpipe ?? true
250
- });
251
- return {
252
- name: transportName,
253
- minLevel: options.minLevel,
254
- log(event, context) {
255
- if (options.minLevel !== void 0 && event.level < toLevelValue(options.minLevel)) return;
256
- destination.write(codec.encode(event), context);
257
- },
258
- flush: destination.flush,
259
- flushSync: destination.flushSync,
260
- close: destination.close
261
- };
262
- }
263
- function stderrTransport(options = {}) {
264
- return stdoutTransport({
265
- ...options,
266
- name: options.name ?? "stderr",
267
- stream: process.stderr
268
- });
269
- }
270
- //#endregion
271
- //#region src/file-transport.ts
272
- function fileTransport(options) {
273
- const codec = options.codec ?? ndjsonCodec();
274
- const destination = createNodeFileDestination({
275
- name: options.name ?? "file",
276
- path: options.path,
277
- flags: options.flags,
278
- append: options.append,
279
- mkdir: options.mkdir,
280
- sync: options.sync,
281
- minLength: options.minLength
282
- });
283
- return {
284
- name: options.name ?? "file",
285
- minLevel: options.minLevel,
286
- stream: destination.stream,
287
- log(event, context) {
288
- if (options.minLevel !== void 0 && event.level < toLevelValue(options.minLevel)) return;
289
- destination.write(codec.encode(event), context);
290
- },
291
- flush: destination.flush,
292
- flushSync: destination.flushSync,
293
- close: destination.close
294
- };
295
- }
296
- //#endregion
297
- //#region src/rotating-file-transport.ts
298
- const textEncoder = new TextEncoder();
299
- function payloadBytes(payload) {
300
- return typeof payload === "string" ? textEncoder.encode(payload).byteLength : payload.byteLength;
301
- }
302
- function normalizePositiveInteger(value, fallback) {
303
- if (value === void 0 || !Number.isFinite(value) || value <= 0) return fallback;
304
- return Math.floor(value);
305
- }
306
- function normalizeNonNegativeInteger(value, fallback) {
307
- if (value === void 0 || !Number.isFinite(value) || value < 0) return fallback;
308
- return Math.floor(value);
309
- }
310
- function defaultArchivePath(path, index) {
311
- return `${path}.${index}`;
312
- }
313
- function fileSize(path) {
314
- try {
315
- return statSync(path).size;
316
- } catch {
317
- return 0;
318
- }
319
- }
320
- function rotatingFileTransport(options) {
321
- const codec = options.codec ?? ndjsonCodec();
322
- const maxBytes = normalizePositiveInteger(options.maxBytes, 10 * 1024 * 1024);
323
- const maxFiles = normalizeNonNegativeInteger(options.maxFiles, 5);
324
- const archivePath = options.archivePath ?? defaultArchivePath;
325
- const destination = createNodeFileDestination({
326
- name: options.name ?? "rotating-file",
327
- path: options.path,
328
- flags: options.flags,
329
- append: options.append,
330
- mkdir: options.mkdir,
331
- sync: true
332
- });
333
- let bytes = fileSize(options.path);
334
- const rotate = () => {
335
- destination.releaseSync?.();
336
- if (maxFiles === 0) {
337
- if (existsSync(options.path)) unlinkSync(options.path);
338
- bytes = 0;
339
- return;
340
- }
341
- const oldest = archivePath(options.path, maxFiles);
342
- if (existsSync(oldest)) unlinkSync(oldest);
343
- for (let index = maxFiles - 1; index >= 1; index -= 1) {
344
- const source = archivePath(options.path, index);
345
- if (existsSync(source)) renameSync(source, archivePath(options.path, index + 1));
346
- }
347
- if (existsSync(options.path)) renameSync(options.path, archivePath(options.path, 1));
348
- bytes = 0;
349
- };
350
- const writePayload = (payload) => {
351
- const size = payloadBytes(payload);
352
- if (bytes > 0 && bytes + size > maxBytes) rotate();
353
- destination.write(payload);
354
- bytes += size;
355
- };
356
- return {
357
- name: options.name ?? "rotating-file",
358
- minLevel: options.minLevel,
359
- log(event) {
360
- if (options.minLevel !== void 0 && event.level < toLevelValue(options.minLevel)) return;
361
- writePayload(codec.encode(event));
362
- },
363
- logBatch(events) {
364
- for (const event of events) {
365
- if (options.minLevel !== void 0 && event.level < toLevelValue(options.minLevel)) continue;
366
- writePayload(codec.encode(event));
367
- }
368
- },
369
- flush() {
370
- return destination.flush();
371
- },
372
- flushSync: destination.flushSync,
373
- close() {
374
- return destination.close();
375
- },
376
- rotate,
377
- currentBytes: () => bytes
378
- };
379
- }
380
- //#endregion
381
- //#region src/http-transport.ts
382
- function payloadToBody(payload) {
383
- if (typeof payload === "string") return payload;
384
- return Uint8Array.from(payload);
385
- }
386
- function nodeHttpTransport(options) {
387
- const codec = options.codec ?? safeJsonCodec();
388
- const fetchFn = options.fetchFn ?? globalThis.fetch?.bind(globalThis);
389
- return batchTransport({
390
- name: options.name ?? "node-http-inner",
391
- minLevel: options.minLevel,
392
- async logBatch(events) {
393
- if (!fetchFn) throw new Error("fetch is not available. Use Node.js 18+ or pass fetchFn.");
394
- const transformed = await applyPayloadTransforms(codec.encode(events), {
395
- contentType: codec.contentType,
396
- events,
397
- transport: options.name ?? "node-http"
398
- }, options.transformPayload);
399
- const response = await fetchFn(options.url, {
400
- method: options.method ?? "POST",
401
- headers: {
402
- "content-type": transformed.contentType,
403
- ...transformed.headers,
404
- ...options.headers
405
- },
406
- body: payloadToBody(transformed.payload)
407
- });
408
- if (!response.ok) throw new Error(`nodeHttpTransport failed with status ${response.status}`);
409
- }
410
- }, {
411
- name: options.name ?? "node-http",
412
- maxRecords: options.maxRecords,
413
- maxBatchSize: options.maxBatchSize,
414
- maxBytes: options.maxBytes,
415
- maxWaitMs: options.maxWaitMs,
416
- flushIntervalMs: options.flushIntervalMs,
417
- concurrency: options.concurrency,
418
- maxQueueSize: options.maxQueueSize,
419
- dropPolicy: options.dropPolicy,
420
- estimateEventBytes: options.estimateEventBytes,
421
- maxRetries: options.maxRetries,
422
- retryBaseDelayMs: options.retryBaseDelayMs,
423
- retryMaxDelayMs: options.retryMaxDelayMs,
424
- random: options.random,
425
- circuitBreakerFailureThreshold: options.circuitBreakerFailureThreshold,
426
- circuitBreakerResetMs: options.circuitBreakerResetMs,
427
- onDrop: options.onDrop
428
- });
429
- }
430
- //#endregion
431
- //#region src/payload-transforms.ts
432
- const contentEncodingByFormat = {
433
- gzip: "gzip",
434
- brotli: "br",
435
- deflate: "deflate"
436
- };
437
- function compressPayload(payload, format, options) {
438
- const input = encodedPayloadToUint8Array(payload);
439
- if (format === "brotli") return Uint8Array.from(brotliCompressSync(input, options.brotliOptions));
440
- if (format === "deflate") return Uint8Array.from(deflateSync(input, options.deflateOptions));
441
- return Uint8Array.from(gzipSync(input, options.gzipOptions));
442
- }
443
- function nodeCompressionPayloadTransform(options = {}) {
444
- const format = options.format ?? "gzip";
445
- return (payload) => ({
446
- payload: compressPayload(payload, format, options),
447
- headers: {
448
- "content-encoding": contentEncodingByFormat[format],
449
- ...options.headers
450
- }
451
- });
452
- }
453
- //#endregion
454
- //#region src/syslog-transport.ts
455
- const severityByLevel = {
456
- trace: 7,
457
- debug: 7,
458
- info: 6,
459
- warn: 4,
460
- error: 3,
461
- fatal: 2
462
- };
463
- function defaultUdpSocketFactory(protocol) {
464
- return createSocket(protocol);
465
- }
466
- function defaultTcpSocketFactory(options) {
467
- return createConnection(options);
468
- }
469
- function headerValue$4(value, fallback, maxLength) {
470
- const text = String(value ?? fallback).trim().replace(/\s+/g, "_");
471
- if (!text) return fallback;
472
- return text.length > maxLength ? text.slice(0, maxLength) : text;
473
- }
474
- function timestamp(time) {
475
- const value = new Date(time).toISOString();
476
- return value === "Invalid Date" ? "-" : value;
477
- }
478
- function valueFor(value, event, fallback) {
479
- return typeof value === "function" ? value(event) : value ?? fallback;
480
- }
481
- function defaultMessage(event) {
482
- const extra = {};
483
- if (event.data !== void 0) extra.data = event.data;
484
- if (event.context !== void 0) extra.context = event.context;
485
- if (event.error !== void 0) extra.error = event.error;
486
- if (Object.keys(extra).length === 0) return event.message;
487
- return `${event.message} ${safeJsonStringify(extra)}`;
488
- }
489
- function formatSyslogMessage(event, options = {}) {
490
- const facility = Math.max(0, Math.min(23, Math.trunc(options.facility ?? 1)));
491
- const severity = severityByLevel[event.levelName] ?? 6;
492
- const priority = facility * 8 + severity;
493
- const host = headerValue$4(options.hostname, hostname(), 255);
494
- const appName = headerValue$4(valueFor(options.appName, event, event.logger), "-", 48);
495
- const procId = headerValue$4(valueFor(options.procId, event, "-"), "-", 128);
496
- const msgId = headerValue$4(valueFor(options.msgId, event, event.type ?? event.levelName), "-", 32);
497
- const structuredData = valueFor(options.structuredData, event, "-") || "-";
498
- const message = options.formatMessage ? options.formatMessage(event) : defaultMessage(event);
499
- return `<${priority}>1 ${timestamp(event.time)} ${host} ${appName} ${procId} ${msgId} ${structuredData} ${message}`;
500
- }
501
- function nodeSyslogTransport(options = {}) {
502
- const protocol = options.protocol ?? "udp4";
503
- const host = options.host ?? "127.0.0.1";
504
- const port = options.port ?? 514;
505
- const transportName = options.name ?? "syslog";
506
- const unref = options.unref ?? true;
507
- const tcpFraming = options.tcpFraming ?? "newline";
508
- const udpSocketFactory = options.udpSocketFactory ?? defaultUdpSocketFactory;
509
- const tcpSocketFactory = options.tcpSocketFactory ?? defaultTcpSocketFactory;
510
- let udpSocket;
511
- let tcpSocket;
512
- let lastContext;
513
- const reportError = (error, context, operation) => {
514
- try {
515
- options.onError?.(error, { operation });
516
- } catch (onErrorError) {
517
- context?.reportInternalError(onErrorError, {
518
- operation: "on-error",
519
- phase: "transport",
520
- transport: transportName
521
- });
522
- }
523
- context?.reportInternalError(error, {
524
- operation,
525
- phase: "transport",
526
- transport: transportName
527
- });
528
- };
529
- const getUdpSocket = (context) => {
530
- if (udpSocket) return udpSocket;
531
- const socket = udpSocketFactory(protocol === "udp6" ? "udp6" : "udp4");
532
- socket.on?.("error", (error) => reportError(error, lastContext ?? context, "socket-error"));
533
- if (unref) socket.unref?.();
534
- udpSocket = socket;
535
- return socket;
536
- };
537
- const getTcpSocket = (context) => {
538
- if (tcpSocket) return tcpSocket;
539
- const socket = tcpSocketFactory({
540
- host,
541
- port
542
- });
543
- socket.on?.("error", (error) => reportError(error, lastContext ?? context, "socket-error"));
544
- if (unref) socket.unref?.();
545
- tcpSocket = socket;
546
- return socket;
547
- };
548
- const send = (message, context) => {
549
- lastContext = context;
550
- if (protocol === "tcp") {
551
- const bytes = new TextEncoder().encode(message).byteLength;
552
- const payload = tcpFraming === "octet-counting" ? `${bytes} ${message}` : `${message}\n`;
553
- getTcpSocket(context).write(payload, (error) => {
554
- if (error) reportError(error, context, "send");
555
- });
556
- return;
557
- }
558
- getUdpSocket(context).send(message, port, host, (error) => {
559
- if (error) reportError(error, context, "send");
560
- });
561
- };
562
- return {
563
- name: transportName,
564
- minLevel: options.minLevel,
565
- log(event, context) {
566
- send(formatSyslogMessage(event, options), context);
567
- },
568
- logBatch(events, context) {
569
- for (const event of events) send(formatSyslogMessage(event, options), context);
570
- },
571
- async close() {
572
- udpSocket?.close?.();
573
- udpSocket = void 0;
574
- tcpSocket?.end?.();
575
- tcpSocket = void 0;
576
- }
577
- };
578
- }
579
- //#endregion
580
- //#region src/worker-transport.ts
581
- function createDefaultWorker(options) {
582
- if (!options.workerScript) throw new Error("workerTransport requires worker, workerFactory, or workerScript.");
583
- return new Worker(options.workerScript, options.workerOptions);
584
- }
585
- function payloadToBytes(payload) {
586
- if (typeof payload !== "string") return payload;
587
- return new TextEncoder().encode(payload);
588
- }
589
- function transferablePayload(payload) {
590
- const copy = Uint8Array.from(payload);
591
- return {
592
- payload: copy,
593
- transferList: [copy.buffer]
594
- };
595
- }
596
- function normalizePositiveTimeout(value) {
597
- if (value === void 0 || !Number.isFinite(value) || value <= 0) return 0;
598
- return Math.floor(value);
599
- }
600
- function protocolMessage(value) {
601
- if (!value || typeof value !== "object") return void 0;
602
- const message = value;
603
- if (message.type === "loggerjs:ready") return { type: "loggerjs:ready" };
604
- if (message.type === "loggerjs:batch:ack") {
605
- const id = value.id;
606
- if (typeof id === "number") return {
607
- type: "loggerjs:batch:ack",
608
- id
609
- };
610
- }
611
- if (message.type === "loggerjs:error") {
612
- const item = value;
613
- return {
614
- type: "loggerjs:error",
615
- error: item.error,
616
- message: typeof item.message === "string" ? item.message : void 0
617
- };
618
- }
619
- }
620
- function dropBatch(events, reason) {
621
- incrementLoggerMetaCounter("transport.dropped", events.length);
622
- incrementLoggerMetaCounter(`transport.dropped.${reason}`, events.length);
623
- }
624
- function workerTransport(options = {}) {
625
- const codec = options.codec ?? safeJsonCodec();
626
- const transportName = options.name ?? "worker";
627
- const fallback = options.fallback;
628
- const readyTimeoutMs = normalizePositiveTimeout(options.readyTimeoutMs);
629
- const ackTimeoutMs = normalizePositiveTimeout(options.ackTimeoutMs);
630
- const autoEnd = options.autoEnd ?? true;
631
- let worker;
632
- let failed = false;
633
- let failedError;
634
- let lastContext;
635
- let ready = readyTimeoutMs === 0;
636
- let readyPromise;
637
- let readyTimer;
638
- let readyResolve;
639
- let readyReject;
640
- let nextBatchId = 1;
641
- const pendingBatches = /* @__PURE__ */ new Map();
642
- const setPendingGauge = () => {
643
- setLoggerMetaGauge(`transport.queue.depth.${transportName}`, pendingBatches.size);
644
- };
645
- const setReadyGauge = (value) => {
646
- setLoggerMetaGauge(`transport.ready.${transportName}`, value);
647
- };
648
- const reportInternalError = (error, operation) => {
649
- lastContext?.reportInternalError(error, {
650
- phase: "transport",
651
- transport: transportName,
652
- operation
653
- });
654
- };
655
- const markFailed = (error, operation) => {
656
- if (failed) return;
657
- failed = true;
658
- failedError = error instanceof Error ? error : new Error(String(error));
659
- setReadyGauge(0);
660
- incrementLoggerMetaCounter("transport.worker.failed");
661
- emitLoggerDiagnostic({
662
- stage: "worker",
663
- phase: "error",
664
- transport: transportName,
665
- operation,
666
- error
667
- });
668
- reportInternalError(error, operation);
669
- readyReject?.(failedError);
670
- failPendingBatches(operation);
671
- };
672
- const onWorkerError = (error) => markFailed(error, "worker-error");
673
- const onWorkerExit = (code) => {
674
- if (typeof code === "number" && code !== 0) markFailed(code, "worker-exit");
675
- };
676
- const onWorkerMessage = (value) => {
677
- const message = protocolMessage(value);
678
- if (!message) return;
679
- if (message.type === "loggerjs:ready") {
680
- ready = true;
681
- setReadyGauge(1);
682
- emitLoggerDiagnostic({
683
- stage: "worker",
684
- phase: "end",
685
- transport: transportName,
686
- operation: "ready"
687
- });
688
- if (readyTimer) clearTimeout(readyTimer);
689
- readyResolve?.();
690
- return;
691
- }
692
- if (message.type === "loggerjs:batch:ack") {
693
- const pending = pendingBatches.get(message.id);
694
- if (!pending) return;
695
- pendingBatches.delete(message.id);
696
- setPendingGauge();
697
- if (pending.timer) clearTimeout(pending.timer);
698
- pending.resolve();
699
- incrementLoggerMetaCounter("transport.worker.ack");
700
- return;
701
- }
702
- markFailed(message.error ?? new Error(message.message ?? "Worker reported an error"), "worker-message");
703
- };
704
- const fallbackOrDropBatch = async (events, context, reason) => {
705
- if (fallback) {
706
- await fallbackBatch(events, context);
707
- return;
708
- }
709
- dropBatch(events, reason);
710
- };
711
- const failPendingBatch = (pending, reason) => {
712
- pendingBatches.delete(pending.id);
713
- setPendingGauge();
714
- if (pending.timer) clearTimeout(pending.timer);
715
- incrementLoggerMetaCounter("transport.worker.pending-dropped", pending.events.length);
716
- fallbackOrDropBatch(pending.events, pending.context, reason).finally(pending.resolve);
717
- };
718
- function failPendingBatches(reason) {
719
- for (const pending of Array.from(pendingBatches.values())) failPendingBatch(pending, reason);
720
- }
721
- const waitForReady = async () => {
722
- if (ready) return;
723
- readyPromise ??= new Promise((resolve, reject) => {
724
- readyResolve = resolve;
725
- readyReject = reject;
726
- readyTimer = setTimeout(() => {
727
- reject(/* @__PURE__ */ new Error(`workerTransport ready timeout after ${readyTimeoutMs}ms`));
728
- }, readyTimeoutMs);
729
- });
730
- await readyPromise;
731
- };
732
- const getWorker = () => {
733
- if (failed) return void 0;
734
- if (worker) return worker;
735
- try {
736
- worker = options.worker ?? options.workerFactory?.() ?? createDefaultWorker(options);
737
- worker.on?.("error", onWorkerError);
738
- worker.on?.("exit", onWorkerExit);
739
- worker.on?.("message", onWorkerMessage);
740
- if (ready) setReadyGauge(1);
741
- return worker;
742
- } catch (error) {
743
- markFailed(error, "create-worker");
744
- return;
745
- }
746
- };
747
- const fallbackBatch = async (events, context) => {
748
- if (fallback?.logBatch) {
749
- await fallback.logBatch(events, context);
750
- return;
751
- }
752
- if (fallback?.log) for (const event of events) await fallback.log(event, context);
753
- };
754
- const postBatch = async (events, context) => {
755
- lastContext = context;
756
- const currentWorker = getWorker();
757
- if (!currentWorker) {
758
- await fallbackOrDropBatch(events, context, "worker-unavailable");
759
- return;
760
- }
761
- try {
762
- await waitForReady();
763
- } catch (error) {
764
- markFailed(error, "worker-ready-timeout");
765
- await fallbackOrDropBatch(events, context, "worker-ready-timeout");
766
- return;
767
- }
768
- const encoded = payloadToBytes(codec.encode(events));
769
- const transferable = options.transferBuffers === false ? {
770
- payload: encoded,
771
- transferList: void 0
772
- } : transferablePayload(encoded);
773
- const message = {
774
- type: "loggerjs:batch",
775
- codec: codec.name,
776
- contentType: codec.contentType,
777
- count: events.length,
778
- payload: transferable.payload
779
- };
780
- let pending;
781
- if (ackTimeoutMs > 0) {
782
- const id = nextBatchId;
783
- nextBatchId += 1;
784
- message.id = id;
785
- pending = {
786
- id,
787
- events,
788
- context,
789
- resolve: () => {}
790
- };
791
- pending.timer = setTimeout(() => {
792
- if (!pending) return;
793
- markFailed(/* @__PURE__ */ new Error(`workerTransport ack timeout after ${ackTimeoutMs}ms`), "worker-ack-timeout");
794
- }, ackTimeoutMs);
795
- pendingBatches.set(id, pending);
796
- setPendingGauge();
797
- }
798
- try {
799
- currentWorker.postMessage(message, transferable.transferList);
800
- } catch (error) {
801
- markFailed(error, "post-message");
802
- if (!pending) await fallbackOrDropBatch(events, context, "worker-post-message");
803
- }
804
- };
805
- const transport = {
806
- name: transportName,
807
- minLevel: options.minLevel,
808
- async ready() {
809
- if (!getWorker()) {
810
- if (fallback) {
811
- await fallback.ready?.();
812
- return;
813
- }
814
- throw failedError ?? /* @__PURE__ */ new Error("workerTransport is unavailable");
815
- }
816
- try {
817
- await waitForReady();
818
- } catch (error) {
819
- markFailed(error, "worker-ready-timeout");
820
- if (fallback) {
821
- await fallback.ready?.();
822
- return;
823
- }
824
- throw error;
825
- }
826
- },
827
- log(event, context) {
828
- if (options.minLevel !== void 0 && event.level < toLevelValue(options.minLevel)) return;
829
- return postBatch([event], context);
830
- },
831
- logBatch(events, context) {
832
- return postBatch(events, context);
833
- },
834
- async flush() {
835
- await Promise.all(Array.from(pendingBatches.values(), (pending) => new Promise((resolve) => {
836
- const originalResolve = pending.resolve;
837
- pending.resolve = () => {
838
- originalResolve();
839
- resolve();
840
- };
841
- })));
842
- await fallback?.flush?.();
843
- },
844
- async close() {
845
- await transport.flush?.();
846
- worker?.off?.("error", onWorkerError);
847
- worker?.off?.("exit", onWorkerExit);
848
- worker?.off?.("message", onWorkerMessage);
849
- await fallback?.close?.();
850
- if (autoEnd) await worker?.terminate?.();
851
- if (readyTimer) clearTimeout(readyTimer);
852
- readyReject = void 0;
853
- readyResolve = void 0;
854
- }
855
- };
856
- return transport;
857
- }
858
- //#endregion
859
- //#region src/context.ts
860
- function mergeContext(...items) {
861
- const out = {};
862
- for (const item of items) {
863
- if (!item) continue;
864
- Object.assign(out, item);
865
- }
866
- return createBoundContext(out) ?? void 0;
867
- }
868
- function createAsyncLocalStorageContextManager(storage = new AsyncLocalStorage()) {
869
- return {
870
- get() {
871
- return storage.getStore();
872
- },
873
- with(context, fn) {
874
- return storage.run(mergeContext(storage.getStore(), context) ?? Object.freeze({}), fn);
875
- },
876
- disable() {
877
- storage.disable();
878
- }
879
- };
880
- }
881
- function installAsyncLocalStorageContext(manager = createAsyncLocalStorageContextManager()) {
882
- setContextManager(manager);
883
- return () => {
884
- resetContextManager();
885
- manager.disable();
886
- };
887
- }
888
- //#endregion
889
- //#region src/queue-integration.ts
890
- const defaultMethods$1 = [
891
- "add",
892
- "ack",
893
- "consume",
894
- "dequeue",
895
- "nack",
896
- "process",
897
- "publish",
898
- "receive",
899
- "send",
900
- "sendToQueue"
901
- ];
902
- const defaultRandom$6 = () => Math.random();
903
- function defaultLevel$6(_durationMs, error) {
904
- return error ? "error" : "debug";
905
- }
906
- function isPromiseLike$2(value) {
907
- return typeof value === "object" && value !== null && typeof value.then === "function";
908
- }
909
- function defaultOperation$1(method) {
910
- switch (method) {
911
- case "add":
912
- case "publish":
913
- case "send":
914
- case "sendToQueue": return "publish";
915
- case "consume":
916
- case "dequeue":
917
- case "process":
918
- case "receive": return "consume";
919
- case "ack": return "ack";
920
- case "nack": return "nack";
921
- default: return "other";
922
- }
923
- }
924
- function defaultPayload(args) {
925
- return typeof args[0] === "string" && args.length > 1 ? args[1] : args[0];
926
- }
927
- function defaultMessageId(args) {
928
- const payload = defaultPayload(args);
929
- if (typeof payload !== "object" || payload === null) return void 0;
930
- const value = payload.messageId ?? payload.id;
931
- return value === void 0 ? void 0 : String(value);
932
- }
933
- function payloadFor(args, method, options) {
934
- if (!options.capturePayload) return void 0;
935
- const payload = options.getPayload?.(args, method) ?? defaultPayload(args);
936
- return payload === void 0 ? void 0 : normalizeValue(payload, {
937
- maxDepth: 4,
938
- maxObjectKeys: 80
939
- });
940
- }
941
- function queueIntegration(options = {}) {
942
- const targets = options.targets ?? (options.client ? [{
943
- client: options.client,
944
- name: options.name,
945
- system: options.system,
946
- queueName: options.queueName,
947
- methods: options.methods
948
- }] : []);
949
- const captureAll = options.captureAll ?? options.captureSuccessful ?? false;
950
- const sampleRate = options.sampleRate ?? 1;
951
- const random = options.random ?? defaultRandom$6;
952
- const levelFor = options.level ?? defaultLevel$6;
953
- const shouldCapture = (durationMs, error) => {
954
- if (error) return true;
955
- if (options.minDurationMs !== void 0 && durationMs >= options.minDurationMs) return true;
956
- if (!captureAll) return false;
957
- return sampleRate >= 1 || random() < sampleRate;
958
- };
959
- return {
960
- name: "queue",
961
- setup(api) {
962
- const capture = api.guard((input) => api.capture(input));
963
- const disposers = [];
964
- let disposed = false;
965
- const captureResult = (info, started, args, error) => {
966
- const durationMs = Date.now() - started;
967
- if (disposed || !shouldCapture(durationMs, error)) return;
968
- capture({
969
- level: levelFor(durationMs, error, info),
970
- message: error ? `Queue error ${info.operation} ${info.queueName ?? info.method}` : `Queue ${info.operation} ${info.queueName ?? info.method}`,
971
- error,
972
- props: { queue: {
973
- kind: info.target,
974
- system: info.system,
975
- queueName: info.queueName,
976
- method: info.method,
977
- operation: info.operation,
978
- durationMs,
979
- messageId: options.getMessageId?.(args, info.method) ?? defaultMessageId(args),
980
- payload: payloadFor(args, info.method, options)
981
- } }
982
- });
983
- };
984
- for (const target of targets) {
985
- const methods = target.methods ?? options.methods ?? defaultMethods$1;
986
- for (const method of methods) {
987
- const original = target.client[method];
988
- if (typeof original !== "function") continue;
989
- const originalMethod = original;
990
- const targetName = target.name ?? options.name ?? "queue";
991
- const system = target.system ?? options.system;
992
- target.client[method] = function wrappedQueueMethod(...args) {
993
- const started = Date.now();
994
- const operation = options.getOperation?.(method, args) ?? defaultOperation$1(method);
995
- const info = {
996
- target: targetName,
997
- system,
998
- queueName: options.getQueueName?.(args, method) ?? target.queueName ?? options.queueName ?? (typeof args[0] === "string" ? args[0] : void 0),
999
- method,
1000
- operation
1001
- };
1002
- try {
1003
- const result = originalMethod.apply(this, args);
1004
- if (isPromiseLike$2(result)) return result.then((value) => {
1005
- captureResult(info, started, args, void 0);
1006
- return value;
1007
- }, (error) => {
1008
- captureResult(info, started, args, error);
1009
- throw error;
1010
- });
1011
- captureResult(info, started, args, void 0);
1012
- return result;
1013
- } catch (error) {
1014
- captureResult(info, started, args, error);
1015
- throw error;
1016
- }
1017
- };
1018
- disposers.push(() => {
1019
- target.client[method] = originalMethod;
1020
- });
1021
- }
1022
- }
1023
- return () => {
1024
- if (disposed) return;
1025
- disposed = true;
1026
- for (const dispose of disposers) dispose();
1027
- };
1028
- }
1029
- };
1030
- }
1031
- //#endregion
1032
- //#region src/bullmq-integration.ts
1033
- const bullMqMethods = [
1034
- "add",
1035
- "addBulk",
1036
- "process"
1037
- ];
1038
- function queueName(args, fallback) {
1039
- const first = args[0];
1040
- return typeof first === "string" ? first : fallback;
1041
- }
1042
- function operationFor(method) {
1043
- if (method === "process") return "consume";
1044
- if (method === "add" || method === "addBulk") return "publish";
1045
- return "other";
1046
- }
1047
- function bullMqIntegration(options) {
1048
- return queueIntegration({
1049
- ...options,
1050
- name: options.name ?? "bullmq",
1051
- system: "bullmq",
1052
- methods: options.methods ?? bullMqMethods,
1053
- getOperation: options.getOperation ?? operationFor,
1054
- queueName: options.queueName ?? options.client.name,
1055
- getQueueName: (args) => queueName(args, options.queueName ?? options.client.name)
1056
- });
1057
- }
1058
- //#endregion
1059
- //#region src/cli-integration.ts
1060
- const defaultSignals = ["SIGINT", "SIGTERM"];
1061
- function defaultProcess() {
1062
- return globalThis.process;
1063
- }
1064
- function defaultSanitizeArg(arg) {
1065
- if (/^(--?[^=\s]*(token|password|passwd|secret|key)[^=\s]*=)/i.test(arg)) return arg.replace(/=.*/, "=[redacted]");
1066
- return arg;
1067
- }
1068
- function defaultCommand(argv) {
1069
- return argv[1] ?? argv[0];
1070
- }
1071
- function levelFor$2(level, event, code) {
1072
- if (typeof level === "function") return level(event, code);
1073
- if (level) return level;
1074
- if (event === "signal") return "warn";
1075
- if (event === "exit" && Number(code ?? 0) !== 0) return "error";
1076
- return "info";
1077
- }
1078
- function pickEnv(env, names) {
1079
- if (!env || !names || names.length === 0) return void 0;
1080
- const out = {};
1081
- for (const name of names) {
1082
- const value = env[name];
1083
- if (value !== void 0) out[name] = value;
1084
- }
1085
- return Object.keys(out).length > 0 ? out : void 0;
1086
- }
1087
- function removeListener$1(processLike, event, listener) {
1088
- if (processLike.off) {
1089
- processLike.off(event, listener);
1090
- return;
1091
- }
1092
- processLike.removeListener?.(event, listener);
1093
- }
1094
- function captureCliIntegration(options = {}) {
1095
- const name = options.name ?? "cli";
1096
- const captureStart = options.captureStart ?? true;
1097
- const captureExit = options.captureExit ?? true;
1098
- const captureSignals = options.captureSignals ?? true;
1099
- const captureCwd = options.captureCwd ?? true;
1100
- const signals = options.signals ?? defaultSignals;
1101
- const sanitizeArg = options.sanitizeArg ?? defaultSanitizeArg;
1102
- const commandFor = options.getCommand ?? defaultCommand;
1103
- return {
1104
- name: "capture-cli",
1105
- setup(api) {
1106
- const processLike = options.process ?? defaultProcess();
1107
- if (!processLike) return;
1108
- const argv = processLike.argv ?? [];
1109
- const command = commandFor(argv);
1110
- const sanitizedArgv = argv.map((arg, index) => sanitizeArg(arg, index, argv));
1111
- const disposers = [];
1112
- let disposed = false;
1113
- const capture = api.guard((input) => {
1114
- if (!disposed) api.capture(input);
1115
- });
1116
- const cliBase = {
1117
- kind: name,
1118
- command,
1119
- argv: sanitizedArgv,
1120
- cwd: captureCwd ? processLike.cwd?.() : void 0,
1121
- env: pickEnv(processLike.env, options.captureEnv)
1122
- };
1123
- if (captureStart) capture({
1124
- level: levelFor$2(options.level, "start"),
1125
- message: `CLI start${command ? ` ${command}` : ""}`,
1126
- props: { cli: {
1127
- ...cliBase,
1128
- lifecycle: "start"
1129
- } }
1130
- });
1131
- if (captureExit && processLike.on) {
1132
- const onExit = (code) => {
1133
- const exitCode = code ?? processLike.exitCode ?? 0;
1134
- capture({
1135
- level: levelFor$2(options.level, "exit", exitCode),
1136
- message: `CLI exit ${String(exitCode)}`,
1137
- props: { cli: {
1138
- ...cliBase,
1139
- lifecycle: "exit",
1140
- exitCode
1141
- } }
1142
- });
1143
- };
1144
- processLike.on("exit", onExit);
1145
- disposers.push(() => removeListener$1(processLike, "exit", onExit));
1146
- }
1147
- if (captureSignals && processLike.on) for (const signal of signals) {
1148
- const onSignal = () => {
1149
- capture({
1150
- level: levelFor$2(options.level, "signal", signal),
1151
- message: `CLI signal ${signal}`,
1152
- props: { cli: {
1153
- ...cliBase,
1154
- lifecycle: "signal",
1155
- signal
1156
- } }
1157
- });
1158
- };
1159
- processLike.on(signal, onSignal);
1160
- disposers.push(() => removeListener$1(processLike, signal, onSignal));
1161
- }
1162
- return () => {
1163
- if (disposed) return;
1164
- disposed = true;
1165
- for (const dispose of disposers) dispose();
1166
- };
1167
- }
1168
- };
1169
- }
1170
- //#endregion
1171
- //#region src/database-integration.ts
1172
- const defaultMethods = [
1173
- "query",
1174
- "execute",
1175
- "run",
1176
- "all",
1177
- "get"
1178
- ];
1179
- const defaultRandom$5 = () => Math.random();
1180
- function defaultLevel$5(_durationMs, error) {
1181
- return error ? "error" : "debug";
1182
- }
1183
- function isPromiseLike$1(value) {
1184
- return typeof value === "object" && value !== null && typeof value.then === "function";
1185
- }
1186
- function defaultStatement(args) {
1187
- const first = args[0];
1188
- if (typeof first === "string") return first;
1189
- if (typeof first !== "object" || first === null) return void 0;
1190
- const input = first;
1191
- if (typeof input.sql === "string") return input.sql;
1192
- if (typeof input.text === "string") return input.text;
1193
- if (typeof input.query === "string") return input.query;
1194
- }
1195
- function statementFor(args, method, options) {
1196
- const statement = options.getStatement?.(args, method) ?? defaultStatement(args);
1197
- return statement && options.sanitizeStatement ? options.sanitizeStatement(statement) : statement;
1198
- }
1199
- function parametersFor(args, captureParameters) {
1200
- if (!captureParameters) return void 0;
1201
- const first = args[0];
1202
- const parameters = args[1] ?? (typeof first === "object" && first ? first.values ?? first.params ?? first.parameters : void 0);
1203
- return parameters === void 0 ? void 0 : normalizeValue(parameters, {
1204
- maxDepth: 4,
1205
- maxObjectKeys: 80
1206
- });
1207
- }
1208
- function databaseIntegration(options = {}) {
1209
- const targets = options.targets ?? (options.client ? [{
1210
- client: options.client,
1211
- name: options.name,
1212
- system: options.system,
1213
- methods: options.methods
1214
- }] : []);
1215
- const captureAll = options.captureAll ?? options.captureSuccessful ?? false;
1216
- const sampleRate = options.sampleRate ?? 1;
1217
- const random = options.random ?? defaultRandom$5;
1218
- const levelFor = options.level ?? defaultLevel$5;
1219
- const shouldCapture = (durationMs, error) => {
1220
- if (error) return true;
1221
- if (options.minDurationMs !== void 0 && durationMs >= options.minDurationMs) return true;
1222
- if (!captureAll) return false;
1223
- return sampleRate >= 1 || random() < sampleRate;
1224
- };
1225
- return {
1226
- name: "database",
1227
- setup(api) {
1228
- const capture = api.guard((input) => api.capture(input));
1229
- const disposers = [];
1230
- let disposed = false;
1231
- const captureResult = (info, started, args, error) => {
1232
- const durationMs = Date.now() - started;
1233
- if (disposed || !shouldCapture(durationMs, error)) return;
1234
- capture({
1235
- level: levelFor(durationMs, error, info),
1236
- message: error ? `Database error ${info.method}${info.statement ? ` ${info.statement}` : ""}` : `Database ${info.method}${info.statement ? ` ${info.statement}` : ""}`,
1237
- error,
1238
- props: { db: {
1239
- kind: info.target,
1240
- system: info.system,
1241
- method: info.method,
1242
- statement: info.statement,
1243
- durationMs,
1244
- parameters: parametersFor(args, options.captureParameters ?? false)
1245
- } }
1246
- });
1247
- };
1248
- for (const target of targets) {
1249
- const methods = target.methods ?? options.methods ?? defaultMethods;
1250
- for (const method of methods) {
1251
- const original = target.client[method];
1252
- if (typeof original !== "function") continue;
1253
- const originalMethod = original;
1254
- const targetName = target.name ?? options.name ?? "database";
1255
- const system = target.system ?? options.system;
1256
- target.client[method] = function wrappedDatabaseMethod(...args) {
1257
- const started = Date.now();
1258
- const info = {
1259
- target: targetName,
1260
- system,
1261
- method,
1262
- statement: statementFor(args, method, options)
1263
- };
1264
- try {
1265
- const result = originalMethod.apply(this, args);
1266
- if (isPromiseLike$1(result)) return result.then((value) => {
1267
- captureResult(info, started, args, void 0);
1268
- return value;
1269
- }, (error) => {
1270
- captureResult(info, started, args, error);
1271
- throw error;
1272
- });
1273
- captureResult(info, started, args, void 0);
1274
- return result;
1275
- } catch (error) {
1276
- captureResult(info, started, args, error);
1277
- throw error;
1278
- }
1279
- };
1280
- disposers.push(() => {
1281
- target.client[method] = originalMethod;
1282
- });
1283
- }
1284
- }
1285
- return () => {
1286
- if (disposed) return;
1287
- disposed = true;
1288
- for (const dispose of disposers) dispose();
1289
- };
1290
- }
1291
- };
1292
- }
1293
- //#endregion
1294
- //#region src/express-integration.ts
1295
- const defaultRandom$4 = () => Math.random();
1296
- function defaultSanitizeUrl$3(url) {
1297
- const queryIndex = url.indexOf("?");
1298
- const hashIndex = url.indexOf("#");
1299
- const end = Math.min(queryIndex >= 0 ? queryIndex : url.length, hashIndex >= 0 ? hashIndex : url.length);
1300
- return url.slice(0, end);
1301
- }
1302
- function defaultLevel$4(status, _req, _res, aborted) {
1303
- if (aborted) return "warn";
1304
- if (status >= 500) return "error";
1305
- if (status >= 400) return "warn";
1306
- return "info";
1307
- }
1308
- function requestUrl(req) {
1309
- return req.originalUrl ?? req.url ?? req.path ?? "/";
1310
- }
1311
- function headerValue$3(value) {
1312
- if (typeof value === "number") return String(value);
1313
- return value;
1314
- }
1315
- function pickRequestHeaders$1(req, names) {
1316
- if (!names || names.length === 0 || !req.headers) return void 0;
1317
- const out = {};
1318
- for (const name of names) {
1319
- const value = req.headers[name.toLowerCase()] ?? req.headers[name];
1320
- if (value !== void 0) out[name.toLowerCase()] = value;
1321
- }
1322
- return Object.keys(out).length > 0 ? out : void 0;
1323
- }
1324
- function pickResponseHeaders$1(res, names) {
1325
- if (!names || names.length === 0 || !res.getHeader) return void 0;
1326
- const out = {};
1327
- for (const name of names) {
1328
- const value = headerValue$3(res.getHeader(name));
1329
- if (value !== void 0) out[name.toLowerCase()] = value;
1330
- }
1331
- return Object.keys(out).length > 0 ? out : void 0;
1332
- }
1333
- function defaultRoute$1(req) {
1334
- const path = req.route?.path;
1335
- return typeof path === "string" ? path : void 0;
1336
- }
1337
- function removeListener(res, event, listener) {
1338
- if (res.off) {
1339
- res.off(event, listener);
1340
- return;
1341
- }
1342
- res.removeListener?.(event, listener);
1343
- }
1344
- function onResponseDone(res, event, listener) {
1345
- if (res.once) {
1346
- res.once(event, listener);
1347
- return;
1348
- }
1349
- res.on?.(event, listener);
1350
- }
1351
- function expressIntegration(logger, options = {}) {
1352
- const name = options.name ?? "express";
1353
- const minStatus = options.minStatus ?? 400;
1354
- const captureAll = options.captureAll ?? options.captureSuccessful ?? false;
1355
- const captureAborted = options.captureAborted ?? true;
1356
- const sampleRate = options.sampleRate ?? 1;
1357
- const random = options.random ?? defaultRandom$4;
1358
- const sanitizeUrl = options.sanitizeUrl ?? defaultSanitizeUrl$3;
1359
- const levelFor = options.level ?? defaultLevel$4;
1360
- const routeFor = options.getRoute ?? defaultRoute$1;
1361
- const bindContext = options.bindContext ?? true;
1362
- return (req, res, next) => {
1363
- const started = Date.now();
1364
- const method = (req.method ?? "GET").toUpperCase();
1365
- const url = sanitizeUrl(requestUrl(req));
1366
- const requestId = options.getRequestId?.(req, res);
1367
- let completed = false;
1368
- const context = {
1369
- httpMethod: method,
1370
- httpUrl: url,
1371
- requestId,
1372
- ...options.context?.(req, res)
1373
- };
1374
- const shouldCapture = (status, aborted) => {
1375
- if (aborted && captureAborted) return true;
1376
- if (status >= minStatus) return true;
1377
- if (!captureAll) return false;
1378
- return sampleRate >= 1 || random() < sampleRate;
1379
- };
1380
- const cleanup = () => {
1381
- removeListener(res, "finish", onFinish);
1382
- removeListener(res, "close", onClose);
1383
- };
1384
- const logRequest = (event) => {
1385
- if (completed) return;
1386
- completed = true;
1387
- cleanup();
1388
- const status = res.statusCode ?? 0;
1389
- const aborted = event === "close" && res.writableEnded !== true;
1390
- if (!shouldCapture(status, aborted)) return;
1391
- const http = {
1392
- kind: name,
1393
- framework: "express",
1394
- method,
1395
- url,
1396
- route: routeFor(req),
1397
- status,
1398
- durationMs: Date.now() - started,
1399
- aborted,
1400
- requestId,
1401
- remoteAddress: req.ip ?? req.socket?.remoteAddress,
1402
- requestHeaders: pickRequestHeaders$1(req, options.captureRequestHeaders),
1403
- responseHeaders: pickResponseHeaders$1(res, options.captureResponseHeaders)
1404
- };
1405
- logger.log(levelFor(status, req, res, aborted), `Express ${status} ${method} ${url}`, { http });
1406
- };
1407
- const onFinish = () => logRequest("finish");
1408
- const onClose = () => logRequest("close");
1409
- onResponseDone(res, "finish", onFinish);
1410
- onResponseDone(res, "close", onClose);
1411
- if (bindContext) {
1412
- withContext(context, () => next());
1413
- return;
1414
- }
1415
- next();
1416
- };
1417
- }
1418
- //#endregion
1419
- //#region src/fastify-integration.ts
1420
- const defaultRandom$3 = () => Math.random();
1421
- function defaultSanitizeUrl$2(url) {
1422
- const queryIndex = url.indexOf("?");
1423
- const hashIndex = url.indexOf("#");
1424
- const end = Math.min(queryIndex >= 0 ? queryIndex : url.length, hashIndex >= 0 ? hashIndex : url.length);
1425
- return url.slice(0, end);
1426
- }
1427
- function defaultLevel$3(status, _request, _reply, error) {
1428
- if (error || status >= 500) return "error";
1429
- if (status >= 400) return "warn";
1430
- return "info";
1431
- }
1432
- function headerValue$2(value) {
1433
- if (typeof value === "number") return String(value);
1434
- return value;
1435
- }
1436
- function pickRequestHeaders(request, names) {
1437
- if (!names || names.length === 0 || !request.headers) return void 0;
1438
- const out = {};
1439
- for (const name of names) {
1440
- const value = request.headers[name.toLowerCase()] ?? request.headers[name];
1441
- if (value !== void 0) out[name.toLowerCase()] = value;
1442
- }
1443
- return Object.keys(out).length > 0 ? out : void 0;
1444
- }
1445
- function pickResponseHeaders(reply, names) {
1446
- if (!names || names.length === 0 || !reply.getHeader) return void 0;
1447
- const out = {};
1448
- for (const name of names) {
1449
- const value = headerValue$2(reply.getHeader(name));
1450
- if (value !== void 0) out[name.toLowerCase()] = value;
1451
- }
1452
- return Object.keys(out).length > 0 ? out : void 0;
1453
- }
1454
- function defaultRoute(request) {
1455
- return request.routeOptions?.url ?? request.routerPath;
1456
- }
1457
- function fastifyIntegration(logger, options = {}) {
1458
- const name = options.name ?? "fastify";
1459
- const minStatus = options.minStatus ?? 400;
1460
- const captureAll = options.captureAll ?? options.captureSuccessful ?? false;
1461
- const sampleRate = options.sampleRate ?? 1;
1462
- const random = options.random ?? defaultRandom$3;
1463
- const sanitizeUrl = options.sanitizeUrl ?? defaultSanitizeUrl$2;
1464
- const levelFor = options.level ?? defaultLevel$3;
1465
- const routeFor = options.getRoute ?? defaultRoute;
1466
- const bindContext = options.bindContext ?? true;
1467
- const states = /* @__PURE__ */ new WeakMap();
1468
- const shouldCapture = (status, error) => {
1469
- if (error) return true;
1470
- if (status >= minStatus) return true;
1471
- if (!captureAll) return false;
1472
- return sampleRate >= 1 || random() < sampleRate;
1473
- };
1474
- return (instance, _pluginOptions, done) => {
1475
- instance.addHook("onRequest", (request, reply, next) => {
1476
- const method = (request.method ?? "GET").toUpperCase();
1477
- const url = sanitizeUrl(request.url ?? "/");
1478
- const requestId = options.getRequestId?.(request, reply) ?? request.id;
1479
- states.set(request, { started: Date.now() });
1480
- const context = {
1481
- httpMethod: method,
1482
- httpUrl: url,
1483
- requestId,
1484
- ...options.context?.(request, reply)
1485
- };
1486
- if (bindContext) {
1487
- withContext(context, () => next());
1488
- return;
1489
- }
1490
- next();
1491
- });
1492
- instance.addHook("onError", (request, _reply, error, next) => {
1493
- const state = states.get(request);
1494
- if (state) state.error = error;
1495
- else states.set(request, {
1496
- started: Date.now(),
1497
- error
1498
- });
1499
- next();
1500
- });
1501
- instance.addHook("onResponse", (request, reply, next) => {
1502
- const state = states.get(request) ?? { started: Date.now() };
1503
- states.delete(request);
1504
- const status = reply.statusCode ?? 0;
1505
- const error = state.error;
1506
- if (!shouldCapture(status, error)) {
1507
- next();
1508
- return;
1509
- }
1510
- const method = (request.method ?? "GET").toUpperCase();
1511
- const url = sanitizeUrl(request.url ?? "/");
1512
- const requestId = options.getRequestId?.(request, reply) ?? request.id;
1513
- const data = { http: {
1514
- kind: name,
1515
- framework: "fastify",
1516
- method,
1517
- url,
1518
- route: routeFor(request),
1519
- status,
1520
- durationMs: Date.now() - state.started,
1521
- requestId,
1522
- remoteAddress: request.ip,
1523
- requestHeaders: pickRequestHeaders(request, options.captureRequestHeaders),
1524
- responseHeaders: pickResponseHeaders(reply, options.captureResponseHeaders)
1525
- } };
1526
- if (error) data.error = error;
1527
- logger.log(levelFor(status, request, reply, error), `Fastify ${status} ${method} ${url}`, { ...data });
1528
- next();
1529
- });
1530
- done?.();
1531
- };
1532
- }
1533
- //#endregion
1534
- //#region src/hapi-integration.ts
1535
- function responseStatus(response) {
1536
- if (!response) return 200;
1537
- if ("statusCode" in response && typeof response.statusCode === "number") return response.statusCode;
1538
- if ("output" in response && typeof response.output?.statusCode === "number") return response.output.statusCode;
1539
- return 200;
1540
- }
1541
- function levelFor$1(status) {
1542
- if (status >= 500) return "error";
1543
- if (status >= 400) return "warn";
1544
- return "info";
1545
- }
1546
- function hapiIntegration(logger, options = {}) {
1547
- const minStatus = options.minStatus ?? 400;
1548
- const captureAll = options.captureAll ?? false;
1549
- const bindContext = options.bindContext ?? true;
1550
- const getLevel = options.level ?? levelFor$1;
1551
- return {
1552
- name: "loggerjs-hapi",
1553
- register(server) {
1554
- server.ext("onRequest", (request, h) => {
1555
- const context = {
1556
- httpMethod: (request.method ?? "GET").toUpperCase(),
1557
- httpUrl: request.url?.pathname ?? request.path ?? "/",
1558
- requestId: options.getRequestId?.(request) ?? request.info?.id,
1559
- ...options.context?.(request)
1560
- };
1561
- request.app = {
1562
- ...request.app,
1563
- loggerjsStartedAt: Date.now()
1564
- };
1565
- if (bindContext) return withContext(context, () => h.continue);
1566
- return h.continue;
1567
- });
1568
- server.events?.on?.("response", (request) => {
1569
- const status = responseStatus(request.response);
1570
- if (!captureAll && status < minStatus) return;
1571
- const method = (request.method ?? "GET").toUpperCase();
1572
- const url = request.url?.pathname ?? request.path ?? "/";
1573
- const requestId = options.getRequestId?.(request) ?? request.info?.id;
1574
- const started = request.app?.loggerjsStartedAt;
1575
- logger.log(getLevel(status, request), `Hapi ${status} ${method} ${url}`, { http: {
1576
- framework: "hapi",
1577
- kind: "hapi",
1578
- method,
1579
- url,
1580
- status,
1581
- durationMs: started ? Date.now() - started : void 0,
1582
- requestId,
1583
- remoteAddress: request.info?.remoteAddress
1584
- } });
1585
- });
1586
- }
1587
- };
1588
- }
1589
- //#endregion
1590
- //#region src/koa-integration.ts
1591
- function sanitizeUrl(url) {
1592
- return url.split(/[?#]/, 1)[0] || "/";
1593
- }
1594
- function levelFor(status, _ctx, error) {
1595
- if (error || status >= 500) return "error";
1596
- if (status >= 400) return "warn";
1597
- return "info";
1598
- }
1599
- function koaIntegration(logger, options = {}) {
1600
- const minStatus = options.minStatus ?? 400;
1601
- const captureAll = options.captureAll ?? false;
1602
- const bindContext = options.bindContext ?? true;
1603
- const sanitize = options.sanitizeUrl ?? sanitizeUrl;
1604
- const getLevel = options.level ?? levelFor;
1605
- return async (ctx, next) => {
1606
- const started = Date.now();
1607
- const method = (ctx.method ?? "GET").toUpperCase();
1608
- const url = sanitize(ctx.originalUrl ?? ctx.url ?? ctx.path ?? "/");
1609
- const requestId = options.getRequestId?.(ctx) ?? ctx.state?.requestId;
1610
- const context = {
1611
- httpMethod: method,
1612
- httpUrl: url,
1613
- requestId,
1614
- ...options.context?.(ctx)
1615
- };
1616
- let error;
1617
- try {
1618
- if (bindContext) await withContext(context, next);
1619
- else await next();
1620
- } catch (caught) {
1621
- error = caught;
1622
- throw caught;
1623
- } finally {
1624
- const status = ctx.status ?? (error ? 500 : 200);
1625
- if (error || captureAll || status >= minStatus) logger.log(getLevel(status, ctx, error), `Koa ${status} ${method} ${url}`, {
1626
- http: {
1627
- framework: "koa",
1628
- kind: "koa",
1629
- method,
1630
- url,
1631
- status,
1632
- durationMs: Date.now() - started,
1633
- requestId,
1634
- remoteAddress: ctx.ip
1635
- },
1636
- error
1637
- });
1638
- }
1639
- };
1640
- }
1641
- //#endregion
1642
- //#region src/nest-integration.ts
1643
- /**
1644
- * Express-compatible Nest middleware adapter. It observes the same request and
1645
- * response completion surface as `expressIntegration`; it does not hook Nest
1646
- * exception filters, interceptors, guards, or the original thrown `Error`.
1647
- */
1648
- function nestMiddlewareIntegration(logger, options = {}) {
1649
- return expressIntegration(logger, {
1650
- name: "nestjs",
1651
- ...options
1652
- });
1653
- }
1654
- //#endregion
1655
- //#region src/node-fetch-integration.ts
1656
- const defaultRandom$2 = () => Math.random();
1657
- function defaultSanitizeUrl$1(url) {
1658
- const queryIndex = url.indexOf("?");
1659
- const hashIndex = url.indexOf("#");
1660
- const end = Math.min(queryIndex >= 0 ? queryIndex : url.length, hashIndex >= 0 ? hashIndex : url.length);
1661
- return url.slice(0, end);
1662
- }
1663
- function defaultLevel$2(status, error) {
1664
- if (error || status === void 0 || status >= 500) return "error";
1665
- if (status >= 400) return "warn";
1666
- return "info";
1667
- }
1668
- function isUrlLike$1(value) {
1669
- return typeof URL !== "undefined" && value instanceof URL;
1670
- }
1671
- function isObject(value) {
1672
- return typeof value === "object" && value !== null;
1673
- }
1674
- function headerValue$1(headers, name) {
1675
- if (!isObject(headers)) return void 0;
1676
- if (typeof headers.get === "function") return headers.get?.(name) ?? void 0;
1677
- const value = headers[name.toLowerCase()] ?? headers[name];
1678
- return value === void 0 ? void 0 : String(value);
1679
- }
1680
- function pickHeaders$1(headers, names) {
1681
- if (!names || names.length === 0) return void 0;
1682
- const out = {};
1683
- for (const name of names) {
1684
- const lowerName = name.toLowerCase();
1685
- const value = headerValue$1(headers, lowerName) ?? headerValue$1(headers, name);
1686
- if (value !== void 0) out[lowerName] = value;
1687
- }
1688
- return Object.keys(out).length > 0 ? out : void 0;
1689
- }
1690
- function requestInfo$1(input, init, sanitizeUrl, captureRequestHeaders) {
1691
- const request = isObject(input) && !isUrlLike$1(input) ? input : void 0;
1692
- return {
1693
- method: (init?.method ?? request?.method ?? "GET").toUpperCase(),
1694
- url: sanitizeUrl(isUrlLike$1(input) ? input.href : typeof input === "string" ? input : request?.url ?? "/"),
1695
- requestHeaders: pickHeaders$1(init?.headers ?? request?.headers, captureRequestHeaders)
1696
- };
1697
- }
1698
- function statusMessage$1(status) {
1699
- return status === void 0 ? "unknown" : String(status);
1700
- }
1701
- function nodeFetchIntegration(options = {}) {
1702
- const name = options.name ?? "node-fetch";
1703
- const minStatus = options.minStatus ?? 400;
1704
- const captureAll = options.captureAll ?? options.captureSuccessful ?? false;
1705
- const sampleRate = options.sampleRate ?? 1;
1706
- const random = options.random ?? defaultRandom$2;
1707
- const sanitizeUrl = options.sanitizeUrl ?? defaultSanitizeUrl$1;
1708
- const levelFor = options.level ?? defaultLevel$2;
1709
- const shouldCapture = (status, error) => {
1710
- if (error) return true;
1711
- if (status !== void 0 && status >= minStatus) return true;
1712
- if (!captureAll) return false;
1713
- return sampleRate >= 1 || random() < sampleRate;
1714
- };
1715
- return {
1716
- name: "node-fetch",
1717
- setup(api) {
1718
- const target = options.target ?? globalThis;
1719
- if (!target.fetch) return;
1720
- const originalFetch = target.fetch;
1721
- const capture = api.guard((input) => api.capture(input));
1722
- let disposed = false;
1723
- const captureResult = (info, durationMs, status, error, responseHeaders) => {
1724
- if (disposed || !shouldCapture(status, error)) return;
1725
- capture({
1726
- level: levelFor(status, error, info),
1727
- message: error ? `Fetch error ${info.method} ${info.url}` : `Fetch ${statusMessage$1(status)} ${info.method} ${info.url}`,
1728
- error,
1729
- props: { http: {
1730
- kind: name,
1731
- runtime: "node",
1732
- instrument: "fetch",
1733
- direction: "outgoing",
1734
- method: info.method,
1735
- url: info.url,
1736
- status,
1737
- durationMs,
1738
- requestHeaders: info.requestHeaders,
1739
- responseHeaders
1740
- } }
1741
- });
1742
- };
1743
- target.fetch = async function patchedFetch(input, init) {
1744
- const started = Date.now();
1745
- const info = requestInfo$1(input, init, sanitizeUrl, options.captureRequestHeaders);
1746
- try {
1747
- const response = await originalFetch.call(this, input, init);
1748
- captureResult(info, Date.now() - started, response.status, void 0, pickHeaders$1(response.headers, options.captureResponseHeaders));
1749
- return response;
1750
- } catch (error) {
1751
- captureResult(info, Date.now() - started, void 0, error);
1752
- throw error;
1753
- }
1754
- };
1755
- return () => {
1756
- if (disposed) return;
1757
- disposed = true;
1758
- target.fetch = originalFetch;
1759
- };
1760
- }
1761
- };
1762
- }
1763
- //#endregion
1764
- //#region src/node-http-client-integration.ts
1765
- const requireBuiltin$2 = createRequire(import.meta.url);
1766
- const defaultRandom$1 = () => Math.random();
1767
- let cachedHttpModule;
1768
- let cachedHttpsModule;
1769
- function loadBuiltin(name, fallback) {
1770
- try {
1771
- return requireBuiltin$2(name);
1772
- } catch {
1773
- try {
1774
- return requireBuiltin$2(fallback);
1775
- } catch {
1776
- return null;
1777
- }
1778
- }
1779
- }
1780
- function loadHttpModule() {
1781
- if (cachedHttpModule !== void 0) return cachedHttpModule;
1782
- cachedHttpModule = loadBuiltin("node:http", "http");
1783
- return cachedHttpModule;
1784
- }
1785
- function loadHttpsModule() {
1786
- if (cachedHttpsModule !== void 0) return cachedHttpsModule;
1787
- cachedHttpsModule = loadBuiltin("node:https", "https");
1788
- return cachedHttpsModule;
1789
- }
1790
- function defaultSanitizeUrl(url) {
1791
- const queryIndex = url.indexOf("?");
1792
- const hashIndex = url.indexOf("#");
1793
- const end = Math.min(queryIndex >= 0 ? queryIndex : url.length, hashIndex >= 0 ? hashIndex : url.length);
1794
- return url.slice(0, end);
1795
- }
1796
- function defaultLevel$1(status, error) {
1797
- if (error || status === void 0 || status >= 500) return "error";
1798
- if (status >= 400) return "warn";
1799
- return "info";
1800
- }
1801
- function isUrlLike(value) {
1802
- return typeof URL !== "undefined" && value instanceof URL;
1803
- }
1804
- function isOptionsObject(value) {
1805
- return typeof value === "object" && value !== null && !isUrlLike(value);
1806
- }
1807
- function headerValue(value) {
1808
- if (value === void 0) return void 0;
1809
- if (Array.isArray(value)) return value.map(String);
1810
- return String(value);
1811
- }
1812
- function pickHeaders(headers, names) {
1813
- if (!names || names.length === 0 || !isOptionsObject(headers)) return void 0;
1814
- const out = {};
1815
- for (const name of names) {
1816
- const lowerName = name.toLowerCase();
1817
- const value = headerValue(headers[lowerName] ?? headers[name]);
1818
- if (value !== void 0) out[lowerName] = value;
1819
- }
1820
- return Object.keys(out).length > 0 ? out : void 0;
1821
- }
1822
- function maybeUrl(value) {
1823
- if (isUrlLike(value)) return value;
1824
- if (typeof value !== "string") return void 0;
1825
- try {
1826
- return new URL(value);
1827
- } catch {
1828
- return;
1829
- }
1830
- }
1831
- function pathFromUrl(url) {
1832
- if (!url) return "/";
1833
- return `${url.pathname || "/"}${url.search}`;
1834
- }
1835
- function optionString(options, key) {
1836
- const value = options[key];
1837
- if (value === void 0) return void 0;
1838
- return String(value);
1839
- }
1840
- function requestInfo(args, defaultProtocol, sanitizeUrl, captureRequestHeaders) {
1841
- const first = args[0];
1842
- const second = args[1];
1843
- const parsed = maybeUrl(first);
1844
- const options = isOptionsObject(first) ? first : isOptionsObject(second) ? second : void 0;
1845
- const protocol = optionString(options ?? {}, "protocol") ?? parsed?.protocol ?? defaultProtocol;
1846
- const method = (optionString(options ?? {}, "method") ?? "GET").toUpperCase();
1847
- const host = optionString(options ?? {}, "host") ?? optionString(options ?? {}, "hostname") ?? parsed?.host;
1848
- const port = optionString(options ?? {}, "port");
1849
- const path = optionString(options ?? {}, "path") ?? pathFromUrl(parsed);
1850
- const requestHeaders = pickHeaders(options?.headers, captureRequestHeaders);
1851
- return {
1852
- protocol,
1853
- method,
1854
- url: sanitizeUrl(parsed?.href ?? (host ? `${protocol}//${host}${port ? `:${port}` : ""}${path}` : path)),
1855
- requestHeaders
1856
- };
1857
- }
1858
- function listenOnce(request, event, listener) {
1859
- let active = true;
1860
- const wrapped = (...args) => {
1861
- if (!active) return;
1862
- active = false;
1863
- cleanup();
1864
- listener(...args);
1865
- };
1866
- const cleanup = () => {
1867
- request.off?.(event, wrapped);
1868
- request.removeListener?.(event, wrapped);
1869
- };
1870
- if (request.once) request.once(event, wrapped);
1871
- else request.on?.(event, wrapped);
1872
- }
1873
- function statusMessage(status) {
1874
- return status === void 0 ? "unknown" : String(status);
1875
- }
1876
- function nodeHttpClientIntegration(options = {}) {
1877
- const name = options.name ?? "node-http-client";
1878
- const minStatus = options.minStatus ?? 400;
1879
- const captureAll = options.captureAll ?? options.captureSuccessful ?? false;
1880
- const sampleRate = options.sampleRate ?? 1;
1881
- const random = options.random ?? defaultRandom$1;
1882
- const sanitizeUrl = options.sanitizeUrl ?? defaultSanitizeUrl;
1883
- const levelFor = options.level ?? defaultLevel$1;
1884
- const shouldCapture = (status, error) => {
1885
- if (error) return true;
1886
- if (status !== void 0 && status >= minStatus) return true;
1887
- if (!captureAll) return false;
1888
- return sampleRate >= 1 || random() < sampleRate;
1889
- };
1890
- return {
1891
- name: "node-http-client",
1892
- setup(api) {
1893
- const httpModule = options.httpModule === void 0 ? loadHttpModule() : options.httpModule;
1894
- const httpsModule = options.httpsModule === void 0 ? loadHttpsModule() : options.httpsModule;
1895
- const capture = api.guard((input) => api.capture(input));
1896
- const disposers = [];
1897
- let disposed = false;
1898
- const captureResult = (info, status, error, responseHeaders) => {
1899
- if (disposed || !shouldCapture(status, error)) return;
1900
- capture({
1901
- level: levelFor(status, error, info),
1902
- message: error ? `HTTP error ${info.method} ${info.url}` : `HTTP ${statusMessage(status)} ${info.method} ${info.url}`,
1903
- error,
1904
- props: { http: {
1905
- kind: name,
1906
- runtime: "node",
1907
- direction: "outgoing",
1908
- protocol: info.protocol,
1909
- method: info.method,
1910
- url: info.url,
1911
- status,
1912
- requestHeaders: info.requestHeaders,
1913
- responseHeaders
1914
- } }
1915
- });
1916
- };
1917
- const patchModule = (module, defaultProtocol) => {
1918
- if (!module?.request) return;
1919
- const originalRequest = module.request;
1920
- const originalGet = module.get;
1921
- module.request = function patchedRequest(...args) {
1922
- const info = requestInfo(args, defaultProtocol, sanitizeUrl, options.captureRequestHeaders);
1923
- const request = originalRequest.apply(this, args);
1924
- listenOnce(request, "response", (message) => {
1925
- const response = message;
1926
- captureResult(info, response.statusCode, void 0, pickHeaders(response.headers, options.captureResponseHeaders));
1927
- });
1928
- listenOnce(request, "error", (error) => captureResult(info, void 0, error));
1929
- return request;
1930
- };
1931
- if (originalGet) module.get = function patchedGet(...args) {
1932
- const request = module.request?.apply(this, args) ?? originalGet.apply(this, args);
1933
- request.end?.();
1934
- return request;
1935
- };
1936
- disposers.push(() => {
1937
- module.request = originalRequest;
1938
- if (originalGet) module.get = originalGet;
1939
- });
1940
- };
1941
- patchModule(httpModule, "http:");
1942
- patchModule(httpsModule, "https:");
1943
- return () => {
1944
- if (disposed) return;
1945
- disposed = true;
1946
- for (const dispose of disposers) dispose();
1947
- };
1948
- }
1949
- };
1950
- }
1951
- //#endregion
1952
- //#region src/process-integration.ts
1953
- const signalExitCodes = {
1954
- SIGINT: 130,
1955
- SIGTERM: 143
1956
- };
1957
- function unhandledRejectionsMode() {
1958
- const flags = [...process.execArgv, ...(process.env.NODE_OPTIONS ?? "").split(/\s+/)];
1959
- let mode = "throw";
1960
- for (const flag of flags) {
1961
- const match = /^--unhandled-rejections=(.+)$/.exec(flag);
1962
- if (match?.[1]) mode = match[1];
1963
- }
1964
- return mode;
1965
- }
1966
- function captureProcessIntegration(options = {}) {
1967
- const uncaughtException = options.uncaughtException ?? true;
1968
- const unhandledRejection = options.unhandledRejection ?? true;
1969
- const warning = options.warning ?? true;
1970
- const beforeExitFlush = options.beforeExitFlush ?? true;
1971
- const exitFlush = options.exitFlush ?? true;
1972
- const signalFlush = options.signalFlush ?? true;
1973
- const signals = options.signals ?? ["SIGTERM"];
1974
- const exitOnSignal = options.exitOnSignal ?? true;
1975
- const exitOnUncaught = options.exitOnUncaught ?? true;
1976
- const rejectionsMode = unhandledRejectionsMode();
1977
- const exitOnUnhandledRejection = options.exitOnUnhandledRejection ?? (rejectionsMode === "throw" || rejectionsMode === "strict");
1978
- const flushTimeoutMs = options.flushTimeoutMs ?? 250;
1979
- const exitFn = options.exitFn ?? ((code) => process.exit(code));
1980
- return {
1981
- name: "capture-process",
1982
- setup(api) {
1983
- const disposers = [];
1984
- let disposed = false;
1985
- const capture = api.guard((input) => api.capture(input));
1986
- const flushSync = () => {
1987
- try {
1988
- api.flushSync?.();
1989
- } catch {}
1990
- };
1991
- const flushBounded = async () => {
1992
- let timer;
1993
- try {
1994
- await Promise.race([api.flush(), new Promise((resolve) => {
1995
- timer = setTimeout(resolve, flushTimeoutMs);
1996
- })]);
1997
- } catch {} finally {
1998
- if (timer) clearTimeout(timer);
1999
- }
2000
- };
2001
- const flushBestEffort = () => {
2002
- flushSync();
2003
- flushBounded();
2004
- };
2005
- if (uncaughtException) {
2006
- const onUncaughtException = (error) => {
2007
- capture({
2008
- level: "fatal",
2009
- message: error.message,
2010
- error,
2011
- props: { process: { kind: "uncaughtException" } }
2012
- });
2013
- flushSync();
2014
- const flushed = flushBounded();
2015
- if (exitOnUncaught) flushed.finally(() => exitFn(1));
2016
- };
2017
- process.on("uncaughtException", onUncaughtException);
2018
- disposers.push(() => process.off("uncaughtException", onUncaughtException));
2019
- }
2020
- if (unhandledRejection) {
2021
- const onUnhandledRejection = (reason) => {
2022
- capture({
2023
- level: exitOnUnhandledRejection ? "fatal" : "error",
2024
- message: reason instanceof Error ? reason.message : "Unhandled promise rejection",
2025
- error: reason,
2026
- props: {
2027
- process: { kind: "unhandledRejection" },
2028
- reason: normalizeValue(reason, { maxDepth: 5 })
2029
- }
2030
- });
2031
- if (exitOnUnhandledRejection) {
2032
- flushSync();
2033
- flushBounded().finally(() => exitFn(1));
2034
- return;
2035
- }
2036
- if (options.exitOnUnhandledRejection === void 0) {
2037
- if (rejectionsMode === "warn-with-error-code") process.exitCode = 1;
2038
- }
2039
- flushBestEffort();
2040
- };
2041
- process.on("unhandledRejection", onUnhandledRejection);
2042
- disposers.push(() => process.off("unhandledRejection", onUnhandledRejection));
2043
- }
2044
- if (warning) {
2045
- const onWarning = (warn) => {
2046
- capture({
2047
- level: "warn",
2048
- message: warn.message,
2049
- error: warn,
2050
- props: { process: {
2051
- kind: "warning",
2052
- name: warn.name,
2053
- code: warn.code
2054
- } }
2055
- });
2056
- };
2057
- process.on("warning", onWarning);
2058
- disposers.push(() => process.off("warning", onWarning));
2059
- }
2060
- if (beforeExitFlush) {
2061
- const onBeforeExit = () => {
2062
- flushBounded();
2063
- };
2064
- process.on("beforeExit", onBeforeExit);
2065
- disposers.push(() => process.off("beforeExit", onBeforeExit));
2066
- }
2067
- if (exitFlush) {
2068
- const onExit = () => {
2069
- flushSync();
2070
- };
2071
- process.on("exit", onExit);
2072
- disposers.push(() => process.off("exit", onExit));
2073
- }
2074
- if (signalFlush) for (const signal of signals) {
2075
- const onSignal = () => {
2076
- capture({
2077
- level: "fatal",
2078
- message: `Process signal ${signal}`,
2079
- props: { process: {
2080
- kind: "signal",
2081
- signal
2082
- } }
2083
- });
2084
- flushSync();
2085
- const flushed = flushBounded();
2086
- if (exitOnSignal) flushed.finally(() => exitFn(signalExitCodes[signal] ?? 1));
2087
- };
2088
- process.on(signal, onSignal);
2089
- disposers.push(() => process.off(signal, onSignal));
2090
- }
2091
- return () => {
2092
- if (disposed) return;
2093
- disposed = true;
2094
- for (const dispose of disposers) dispose();
2095
- };
2096
- }
2097
- };
2098
- }
2099
- //#endregion
2100
- //#region src/prisma-integration.ts
2101
- const prismaMethods = [
2102
- "$executeRaw",
2103
- "$executeRawUnsafe",
2104
- "$queryRaw",
2105
- "$queryRawUnsafe"
2106
- ];
2107
- function prismaStatement(args) {
2108
- const first = args[0];
2109
- if (typeof first === "string") return first;
2110
- if (Array.isArray(first) && "raw" in first) return first.raw?.join("?");
2111
- }
2112
- function prismaIntegration(options) {
2113
- return databaseIntegration({
2114
- ...options,
2115
- name: options.name ?? "prisma",
2116
- system: "prisma",
2117
- methods: prismaMethods,
2118
- getStatement: prismaStatement
2119
- });
2120
- }
2121
- //#endregion
2122
- //#region src/redis-integration.ts
2123
- const redisMethods = [
2124
- "del",
2125
- "get",
2126
- "hget",
2127
- "hset",
2128
- "lpush",
2129
- "publish",
2130
- "rpush",
2131
- "set",
2132
- "xadd"
2133
- ];
2134
- function redisStatement(args, method) {
2135
- const key = args[0] === void 0 ? "" : ` ${String(args[0])}`;
2136
- return `${method.toUpperCase()}${key}`;
2137
- }
2138
- function redisIntegration(options) {
2139
- return databaseIntegration({
2140
- ...options,
2141
- name: options.name ?? "redis",
2142
- system: "redis",
2143
- methods: options.methods ?? redisMethods,
2144
- getStatement: redisStatement
2145
- });
2146
- }
2147
- //#endregion
2148
- //#region src/serverless-integration.ts
2149
- const defaultRandom = () => Math.random();
2150
- let coldStart = true;
2151
- function isPromiseLike(value) {
2152
- return typeof value === "object" && value !== null && typeof value.then === "function";
2153
- }
2154
- function defaultLevel(error) {
2155
- return error ? "error" : "info";
2156
- }
2157
- function defaultRequestId(event, context) {
2158
- const ctx = context;
2159
- const evt = event;
2160
- return ctx?.awsRequestId ?? evt?.requestContext?.requestId ?? evt?.headers?.["x-request-id"] ?? evt?.headers?.["X-Request-Id"];
2161
- }
2162
- function defaultOperation(event, context) {
2163
- const ctx = context;
2164
- const evt = event;
2165
- return evt?.routeKey ?? evt?.requestContext?.routeKey ?? (evt?.requestContext?.http?.method && evt.requestContext.http.path ? `${evt.requestContext.http.method} ${evt.requestContext.http.path}` : void 0) ?? (evt?.httpMethod && (evt.rawPath ?? evt.path) ? `${evt.httpMethod} ${evt.rawPath ?? evt.path}` : void 0) ?? ctx?.functionName;
2166
- }
2167
- function normalizeUnknown(value) {
2168
- return normalizeValue(value, {
2169
- maxDepth: 5,
2170
- maxObjectKeys: 120
2171
- });
2172
- }
2173
- function serverlessIntegration(logger, handler, options = {}) {
2174
- const name = options.name ?? "serverless";
2175
- const platform = options.platform ?? "serverless";
2176
- const captureSuccessful = options.captureSuccessful ?? options.captureAll ?? true;
2177
- const sampleRate = options.sampleRate ?? 1;
2178
- const random = options.random ?? defaultRandom;
2179
- const bindContext = options.bindContext ?? true;
2180
- const levelFor = options.level ?? defaultLevel;
2181
- return (event, context, callback) => {
2182
- const started = Date.now();
2183
- const currentColdStart = coldStart;
2184
- coldStart = false;
2185
- const requestId = options.getRequestId?.(event, context) ?? defaultRequestId(event, context);
2186
- const operation = options.getOperation?.(event, context) ?? defaultOperation(event, context);
2187
- let captured = false;
2188
- const shouldCapture = (error) => {
2189
- if (error) return true;
2190
- if (!captureSuccessful) return false;
2191
- return sampleRate >= 1 || random() < sampleRate;
2192
- };
2193
- const capture = (error, result) => {
2194
- if (captured || !shouldCapture(error)) return;
2195
- captured = true;
2196
- const durationMs = Date.now() - started;
2197
- const info = {
2198
- context,
2199
- event,
2200
- operation,
2201
- requestId
2202
- };
2203
- logger.log(levelFor(error, durationMs, info), `Serverless ${operation ?? name}`, {
2204
- error,
2205
- serverless: {
2206
- kind: name,
2207
- platform,
2208
- operation,
2209
- requestId,
2210
- coldStart: currentColdStart,
2211
- durationMs,
2212
- event: options.captureEvent ? options.normalizeEvent?.(event) ?? normalizeUnknown(event) : void 0,
2213
- result: options.captureResult && result !== void 0 ? options.normalizeResult?.(result) ?? normalizeUnknown(result) : void 0
2214
- }
2215
- });
2216
- };
2217
- const wrappedCallback = callback ? (error, result) => {
2218
- capture(error, result);
2219
- callback(error, result);
2220
- } : void 0;
2221
- const invoke = () => {
2222
- try {
2223
- const result = handler(event, context, wrappedCallback);
2224
- if (isPromiseLike(result)) return result.then((value) => {
2225
- capture(void 0, value);
2226
- return value;
2227
- }, (error) => {
2228
- capture(error);
2229
- throw error;
2230
- });
2231
- if (result !== void 0 || !wrappedCallback) capture(void 0, result);
2232
- return result;
2233
- } catch (error) {
2234
- capture(error);
2235
- throw error;
2236
- }
2237
- };
2238
- if (!bindContext) return invoke();
2239
- return withContext({
2240
- functionName: context?.functionName,
2241
- requestId,
2242
- serverlessPlatform: platform
2243
- }, invoke);
2244
- };
2245
- }
2246
- //#endregion
2247
- //#region src/diagnostics-channel-integration.ts
2248
- const defaultChannels = [
2249
- "http.client.request.start",
2250
- "http.client.response.finish",
2251
- "http.server.request.start",
2252
- "http.server.response.finish",
2253
- "undici:request:create",
2254
- "undici:request:headers",
2255
- "undici:request:trailers",
2256
- "undici:request:error"
2257
- ];
2258
- const requireBuiltin$1 = createRequire(import.meta.url);
2259
- let cachedDiagnosticsChannel$1;
2260
- function diagnosticsChannelIntegration(options = {}) {
2261
- const channels = options.channels ?? defaultChannels;
2262
- const captureMessage = options.captureMessage ?? false;
2263
- return {
2264
- name: "diagnostics-channel",
2265
- setup(api) {
2266
- const diagnosticsChannel = options.diagnosticsChannel === void 0 ? loadDiagnosticsChannel$1() : options.diagnosticsChannel;
2267
- if (!diagnosticsChannel) return;
2268
- const disposers = [];
2269
- let disposed = false;
2270
- const capture = api.guard((input) => api.capture(input));
2271
- for (const channel of channels) {
2272
- const listener = (message, name) => {
2273
- capture({
2274
- level: name.endsWith(":error") ? "error" : "debug",
2275
- message: `diagnostics_channel ${name}`,
2276
- props: { diagnostics: {
2277
- channel: name,
2278
- message: captureMessage ? normalizeValue(message, { maxDepth: 4 }) : void 0
2279
- } }
2280
- });
2281
- };
2282
- diagnosticsChannel.subscribe(channel, listener);
2283
- disposers.push(() => diagnosticsChannel.unsubscribe?.(channel, listener));
2284
- }
2285
- return () => {
2286
- if (disposed) return;
2287
- disposed = true;
2288
- for (const dispose of disposers) dispose();
2289
- };
2290
- }
2291
- };
2292
- }
2293
- function loadDiagnosticsChannel$1() {
2294
- if (cachedDiagnosticsChannel$1 !== void 0) return cachedDiagnosticsChannel$1;
2295
- try {
2296
- cachedDiagnosticsChannel$1 = requireBuiltin$1("node:diagnostics_channel");
2297
- } catch {
2298
- try {
2299
- cachedDiagnosticsChannel$1 = requireBuiltin$1("diagnostics_channel");
2300
- } catch {
2301
- cachedDiagnosticsChannel$1 = null;
2302
- }
2303
- }
2304
- return cachedDiagnosticsChannel$1;
2305
- }
2306
- //#endregion
2307
- //#region src/logger-diagnostics.ts
2308
- const requireBuiltin = createRequire(import.meta.url);
2309
- let cachedDiagnosticsChannel;
2310
- function loadDiagnosticsChannel() {
2311
- if (cachedDiagnosticsChannel !== void 0) return cachedDiagnosticsChannel;
2312
- try {
2313
- cachedDiagnosticsChannel = requireBuiltin("node:diagnostics_channel");
2314
- } catch {
2315
- try {
2316
- cachedDiagnosticsChannel = requireBuiltin("diagnostics_channel");
2317
- } catch {
2318
- cachedDiagnosticsChannel = null;
2319
- }
2320
- }
2321
- return cachedDiagnosticsChannel;
2322
- }
2323
- function installLoggerDiagnosticsChannel(options = {}) {
2324
- const diagnosticsChannel = options.diagnosticsChannel === void 0 ? loadDiagnosticsChannel() : options.diagnosticsChannel;
2325
- if (!diagnosticsChannel) return () => {};
2326
- const prefix = options.prefix ?? "loggerjs";
2327
- const channels = /* @__PURE__ */ new Map();
2328
- const channelFor = (stage) => {
2329
- const name = `${prefix}.${stage}`;
2330
- let channel = channels.get(name);
2331
- if (!channel) {
2332
- channel = diagnosticsChannel.channel(name);
2333
- channels.set(name, channel);
2334
- }
2335
- return channel;
2336
- };
2337
- const sink = (event) => {
2338
- channelFor(event.stage).publish(event);
2339
- };
2340
- sink.enabled = (stage) => channelFor(stage).hasSubscribers !== false;
2341
- const previous = setLoggerDiagnosticSink(sink);
2342
- return () => {
2343
- setLoggerDiagnosticSink(previous);
2344
- };
2345
- }
2346
- //#endregion
2347
27
  export { bullMqIntegration, captureCliIntegration, captureProcessIntegration, createAsyncLocalStorageContextManager, databaseIntegration, diagnosticsChannelIntegration, expressIntegration, fastifyIntegration, fileTransport, formatSyslogMessage, hapiIntegration, installAsyncLocalStorageContext, installLoggerDiagnosticsChannel, koaIntegration, nestMiddlewareIntegration, nodeCompressionPayloadTransform, nodeFetchIntegration, nodeHttpClientIntegration, nodeHttpTransport, nodeSyslogTransport, prismaIntegration, queueIntegration, redisIntegration, rotatingFileTransport, serverlessIntegration, stderrTransport, stdoutTransport, workerTransport };
2348
-
2349
- //# sourceMappingURL=index.js.map