@loggerjs/node 0.5.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,60 @@
1
+ import { withContext } from "@loggerjs/core";
2
+ //#region src/hapi-integration.ts
3
+ function responseStatus(response) {
4
+ if (!response) return 200;
5
+ if ("statusCode" in response && typeof response.statusCode === "number") return response.statusCode;
6
+ if ("output" in response && typeof response.output?.statusCode === "number") return response.output.statusCode;
7
+ return 200;
8
+ }
9
+ function levelFor(status) {
10
+ if (status >= 500) return "error";
11
+ if (status >= 400) return "warn";
12
+ return "info";
13
+ }
14
+ function hapiIntegration(logger, options = {}) {
15
+ const minStatus = options.minStatus ?? 400;
16
+ const captureAll = options.captureAll ?? false;
17
+ const bindContext = options.bindContext ?? true;
18
+ const getLevel = options.level ?? levelFor;
19
+ return {
20
+ name: "loggerjs-hapi",
21
+ register(server) {
22
+ server.ext("onRequest", (request, h) => {
23
+ const context = {
24
+ httpMethod: (request.method ?? "GET").toUpperCase(),
25
+ httpUrl: request.url?.pathname ?? request.path ?? "/",
26
+ requestId: options.getRequestId?.(request) ?? request.info?.id,
27
+ ...options.context?.(request)
28
+ };
29
+ request.app = {
30
+ ...request.app,
31
+ loggerjsStartedAt: Date.now()
32
+ };
33
+ if (bindContext) return withContext(context, () => h.continue);
34
+ return h.continue;
35
+ });
36
+ server.events?.on?.("response", (request) => {
37
+ const status = responseStatus(request.response);
38
+ if (!captureAll && status < minStatus) return;
39
+ const method = (request.method ?? "GET").toUpperCase();
40
+ const url = request.url?.pathname ?? request.path ?? "/";
41
+ const requestId = options.getRequestId?.(request) ?? request.info?.id;
42
+ const started = request.app?.loggerjsStartedAt;
43
+ logger.log(getLevel(status, request), `Hapi ${status} ${method} ${url}`, { http: {
44
+ framework: "hapi",
45
+ kind: "hapi",
46
+ method,
47
+ url,
48
+ status,
49
+ durationMs: started ? Date.now() - started : void 0,
50
+ requestId,
51
+ remoteAddress: request.info?.remoteAddress
52
+ } });
53
+ });
54
+ }
55
+ };
56
+ }
57
+ //#endregion
58
+ export { hapiIntegration };
59
+
60
+ //# sourceMappingURL=hapi-integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hapi-integration.js","names":[],"sources":["../src/hapi-integration.ts"],"sourcesContent":["import { withContext, type LoggerLevel, type LoggerLike, type LogData } from \"@loggerjs/core\";\n\nexport interface HapiRequestLike {\n method?: string;\n path?: string;\n url?: { pathname?: string };\n info?: { id?: string; received?: number; remoteAddress?: string };\n response?: { statusCode?: number } | { isBoom?: boolean; output?: { statusCode?: number } };\n app?: Record<string, unknown>;\n}\n\nexport interface HapiToolkitLike {\n continue: unknown;\n}\n\nexport interface HapiServerLike {\n ext: (\n event: \"onRequest\",\n handler: (request: HapiRequestLike, h: HapiToolkitLike) => unknown,\n ) => unknown;\n events?: {\n on?: (event: \"response\", handler: (request: HapiRequestLike) => void) => unknown;\n };\n}\n\nexport interface HapiIntegrationOptions {\n minStatus?: number;\n captureAll?: boolean;\n bindContext?: boolean;\n getRequestId?: (request: HapiRequestLike) => string | undefined;\n context?: (request: HapiRequestLike) => Record<string, unknown> | undefined;\n level?: (status: number, request: HapiRequestLike) => LoggerLevel;\n}\n\nfunction responseStatus(response: HapiRequestLike[\"response\"]): number {\n if (!response) return 200;\n if (\"statusCode\" in response && typeof response.statusCode === \"number\")\n return response.statusCode;\n if (\"output\" in response && typeof response.output?.statusCode === \"number\") {\n return response.output.statusCode;\n }\n return 200;\n}\n\nfunction levelFor(status: number): LoggerLevel {\n if (status >= 500) return \"error\";\n if (status >= 400) return \"warn\";\n return \"info\";\n}\n\nexport function hapiIntegration(logger: LoggerLike, options: HapiIntegrationOptions = {}) {\n const minStatus = options.minStatus ?? 400;\n const captureAll = options.captureAll ?? false;\n const bindContext = options.bindContext ?? true;\n const getLevel = options.level ?? levelFor;\n\n return {\n name: \"loggerjs-hapi\",\n register(server: HapiServerLike) {\n server.ext(\"onRequest\", (request, h) => {\n const method = (request.method ?? \"GET\").toUpperCase();\n const url = request.url?.pathname ?? request.path ?? \"/\";\n const requestId = options.getRequestId?.(request) ?? request.info?.id;\n const context = {\n httpMethod: method,\n httpUrl: url,\n requestId,\n ...options.context?.(request),\n };\n request.app = { ...request.app, loggerjsStartedAt: Date.now() };\n if (bindContext) return withContext(context, () => h.continue);\n return h.continue;\n });\n\n server.events?.on?.(\"response\", (request) => {\n const status = responseStatus(request.response);\n if (!captureAll && status < minStatus) return;\n const method = (request.method ?? \"GET\").toUpperCase();\n const url = request.url?.pathname ?? request.path ?? \"/\";\n const requestId = options.getRequestId?.(request) ?? request.info?.id;\n const started = request.app?.loggerjsStartedAt as number | undefined;\n logger.log(getLevel(status, request), `Hapi ${status} ${method} ${url}`, {\n http: {\n framework: \"hapi\",\n kind: \"hapi\",\n method,\n url,\n status,\n durationMs: started ? Date.now() - started : undefined,\n requestId,\n remoteAddress: request.info?.remoteAddress,\n },\n } as LogData);\n });\n },\n };\n}\n"],"mappings":";;AAkCA,SAAS,eAAe,UAA+C;CACrE,IAAI,CAAC,UAAU,OAAO;CACtB,IAAI,gBAAgB,YAAY,OAAO,SAAS,eAAe,UAC7D,OAAO,SAAS;CAClB,IAAI,YAAY,YAAY,OAAO,SAAS,QAAQ,eAAe,UACjE,OAAO,SAAS,OAAO;CAEzB,OAAO;AACT;AAEA,SAAS,SAAS,QAA6B;CAC7C,IAAI,UAAU,KAAK,OAAO;CAC1B,IAAI,UAAU,KAAK,OAAO;CAC1B,OAAO;AACT;AAEA,SAAgB,gBAAgB,QAAoB,UAAkC,CAAC,GAAG;CACxF,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,aAAa,QAAQ,cAAc;CACzC,MAAM,cAAc,QAAQ,eAAe;CAC3C,MAAM,WAAW,QAAQ,SAAS;CAElC,OAAO;EACL,MAAM;EACN,SAAS,QAAwB;GAC/B,OAAO,IAAI,cAAc,SAAS,MAAM;IAItC,MAAM,UAAU;KACd,aAJc,QAAQ,UAAU,MAAA,CAAO,YAItB;KACjB,SAJU,QAAQ,KAAK,YAAY,QAAQ,QAAQ;KAKnD,WAJgB,QAAQ,eAAe,OAAO,KAAK,QAAQ,MAAM;KAKjE,GAAG,QAAQ,UAAU,OAAO;IAC9B;IACA,QAAQ,MAAM;KAAE,GAAG,QAAQ;KAAK,mBAAmB,KAAK,IAAI;IAAE;IAC9D,IAAI,aAAa,OAAO,YAAY,eAAe,EAAE,QAAQ;IAC7D,OAAO,EAAE;GACX,CAAC;GAED,OAAO,QAAQ,KAAK,aAAa,YAAY;IAC3C,MAAM,SAAS,eAAe,QAAQ,QAAQ;IAC9C,IAAI,CAAC,cAAc,SAAS,WAAW;IACvC,MAAM,UAAU,QAAQ,UAAU,MAAA,CAAO,YAAY;IACrD,MAAM,MAAM,QAAQ,KAAK,YAAY,QAAQ,QAAQ;IACrD,MAAM,YAAY,QAAQ,eAAe,OAAO,KAAK,QAAQ,MAAM;IACnE,MAAM,UAAU,QAAQ,KAAK;IAC7B,OAAO,IAAI,SAAS,QAAQ,OAAO,GAAG,QAAQ,OAAO,GAAG,OAAO,GAAG,OAAO,EACvE,MAAM;KACJ,WAAW;KACX,MAAM;KACN;KACA;KACA;KACA,YAAY,UAAU,KAAK,IAAI,IAAI,UAAU,KAAA;KAC7C;KACA,eAAe,QAAQ,MAAM;IAC/B,EACF,CAAY;GACd,CAAC;EACH;CACF;AACF"}
@@ -0,0 +1,55 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let _loggerjs_core = require("@loggerjs/core");
3
+ //#region src/http-transport.ts
4
+ function payloadToBody(payload) {
5
+ if (typeof payload === "string") return payload;
6
+ return Uint8Array.from(payload);
7
+ }
8
+ function nodeHttpTransport(options) {
9
+ const codec = options.codec ?? (0, _loggerjs_core.safeJsonCodec)();
10
+ const fetchFn = options.fetchFn ?? globalThis.fetch?.bind(globalThis);
11
+ return (0, _loggerjs_core.batchTransport)({
12
+ name: options.name ?? "node-http-inner",
13
+ minLevel: options.minLevel,
14
+ async logBatch(events) {
15
+ if (!fetchFn) throw new Error("fetch is not available. Use Node.js 18+ or pass fetchFn.");
16
+ const transformed = await (0, _loggerjs_core.applyPayloadTransforms)(codec.encode(events), {
17
+ contentType: codec.contentType,
18
+ events,
19
+ transport: options.name ?? "node-http"
20
+ }, options.transformPayload);
21
+ const response = await fetchFn(options.url, {
22
+ method: options.method ?? "POST",
23
+ headers: {
24
+ "content-type": transformed.contentType,
25
+ ...transformed.headers,
26
+ ...options.headers
27
+ },
28
+ body: payloadToBody(transformed.payload)
29
+ });
30
+ if (!response.ok) throw new Error(`nodeHttpTransport failed with status ${response.status}`);
31
+ }
32
+ }, {
33
+ name: options.name ?? "node-http",
34
+ maxRecords: options.maxRecords,
35
+ maxBatchSize: options.maxBatchSize,
36
+ maxBytes: options.maxBytes,
37
+ maxWaitMs: options.maxWaitMs,
38
+ flushIntervalMs: options.flushIntervalMs,
39
+ concurrency: options.concurrency,
40
+ maxQueueSize: options.maxQueueSize,
41
+ dropPolicy: options.dropPolicy,
42
+ estimateEventBytes: options.estimateEventBytes,
43
+ maxRetries: options.maxRetries,
44
+ retryBaseDelayMs: options.retryBaseDelayMs,
45
+ retryMaxDelayMs: options.retryMaxDelayMs,
46
+ random: options.random,
47
+ circuitBreakerFailureThreshold: options.circuitBreakerFailureThreshold,
48
+ circuitBreakerResetMs: options.circuitBreakerResetMs,
49
+ onDrop: options.onDrop
50
+ });
51
+ }
52
+ //#endregion
53
+ exports.nodeHttpTransport = nodeHttpTransport;
54
+
55
+ //# sourceMappingURL=http-transport.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-transport.cjs","names":[],"sources":["../src/http-transport.ts"],"sourcesContent":["import {\n applyPayloadTransforms,\n batchTransport,\n safeJsonCodec,\n type BatchTransportOptions,\n type Codec,\n type EncodedPayload,\n type LogEvent,\n type LoggerLevel,\n type PayloadTransform,\n type Transport,\n} from \"@loggerjs/core\";\n\nexport interface NodeHttpTransportOptions extends BatchTransportOptions {\n url: string;\n name?: string;\n method?: \"POST\" | \"PUT\";\n headers?: Record<string, string>;\n codec?: Codec<string | Uint8Array>;\n minLevel?: LoggerLevel;\n fetchFn?: typeof fetch;\n transformPayload?: PayloadTransform | readonly PayloadTransform[];\n}\n\nfunction payloadToBody(payload: EncodedPayload): BodyInit {\n if (typeof payload === \"string\") return payload;\n return Uint8Array.from(payload);\n}\n\nexport function nodeHttpTransport(options: NodeHttpTransportOptions): Transport {\n const codec = options.codec ?? safeJsonCodec();\n const fetchFn = options.fetchFn ?? globalThis.fetch?.bind(globalThis);\n const inner: Transport = {\n name: options.name ?? \"node-http-inner\",\n minLevel: options.minLevel,\n async logBatch(events: LogEvent[]) {\n if (!fetchFn) throw new Error(\"fetch is not available. Use Node.js 18+ or pass fetchFn.\");\n const encoded = codec.encode(events);\n const transformed = await applyPayloadTransforms(\n encoded,\n {\n contentType: codec.contentType,\n events,\n transport: options.name ?? \"node-http\",\n },\n options.transformPayload,\n );\n const response = await fetchFn(options.url, {\n method: options.method ?? \"POST\",\n headers: {\n \"content-type\": transformed.contentType,\n ...transformed.headers,\n ...options.headers,\n },\n body: payloadToBody(transformed.payload),\n });\n if (!response.ok) throw new Error(`nodeHttpTransport failed with status ${response.status}`);\n },\n };\n return batchTransport(inner, {\n name: options.name ?? \"node-http\",\n maxRecords: options.maxRecords,\n maxBatchSize: options.maxBatchSize,\n maxBytes: options.maxBytes,\n maxWaitMs: options.maxWaitMs,\n flushIntervalMs: options.flushIntervalMs,\n concurrency: options.concurrency,\n maxQueueSize: options.maxQueueSize,\n dropPolicy: options.dropPolicy,\n estimateEventBytes: options.estimateEventBytes,\n maxRetries: options.maxRetries,\n retryBaseDelayMs: options.retryBaseDelayMs,\n retryMaxDelayMs: options.retryMaxDelayMs,\n random: options.random,\n circuitBreakerFailureThreshold: options.circuitBreakerFailureThreshold,\n circuitBreakerResetMs: options.circuitBreakerResetMs,\n onDrop: options.onDrop,\n });\n}\n"],"mappings":";;;AAwBA,SAAS,cAAc,SAAmC;CACxD,IAAI,OAAO,YAAY,UAAU,OAAO;CACxC,OAAO,WAAW,KAAK,OAAO;AAChC;AAEA,SAAgB,kBAAkB,SAA8C;CAC9E,MAAM,QAAQ,QAAQ,UAAA,GAAA,eAAA,cAAA,CAAuB;CAC7C,MAAM,UAAU,QAAQ,WAAW,WAAW,OAAO,KAAK,UAAU;CA4BpE,QAAA,GAAA,eAAA,eAAA,CAAsB;EA1BpB,MAAM,QAAQ,QAAQ;EACtB,UAAU,QAAQ;EAClB,MAAM,SAAS,QAAoB;GACjC,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,0DAA0D;GAExF,MAAM,cAAc,OAAA,GAAA,eAAA,uBAAA,CADJ,MAAM,OAAO,MAErB,GACN;IACE,aAAa,MAAM;IACnB;IACA,WAAW,QAAQ,QAAQ;GAC7B,GACA,QAAQ,gBACV;GACA,MAAM,WAAW,MAAM,QAAQ,QAAQ,KAAK;IAC1C,QAAQ,QAAQ,UAAU;IAC1B,SAAS;KACP,gBAAgB,YAAY;KAC5B,GAAG,YAAY;KACf,GAAG,QAAQ;IACb;IACA,MAAM,cAAc,YAAY,OAAO;GACzC,CAAC;GACD,IAAI,CAAC,SAAS,IAAI,MAAM,IAAI,MAAM,wCAAwC,SAAS,QAAQ;EAC7F;CAEwB,GAAG;EAC3B,MAAM,QAAQ,QAAQ;EACtB,YAAY,QAAQ;EACpB,cAAc,QAAQ;EACtB,UAAU,QAAQ;EAClB,WAAW,QAAQ;EACnB,iBAAiB,QAAQ;EACzB,aAAa,QAAQ;EACrB,cAAc,QAAQ;EACtB,YAAY,QAAQ;EACpB,oBAAoB,QAAQ;EAC5B,YAAY,QAAQ;EACpB,kBAAkB,QAAQ;EAC1B,iBAAiB,QAAQ;EACzB,QAAQ,QAAQ;EAChB,gCAAgC,QAAQ;EACxC,uBAAuB,QAAQ;EAC/B,QAAQ,QAAQ;CAClB,CAAC;AACH"}
@@ -0,0 +1,54 @@
1
+ import { applyPayloadTransforms, batchTransport, safeJsonCodec } from "@loggerjs/core";
2
+ //#region src/http-transport.ts
3
+ function payloadToBody(payload) {
4
+ if (typeof payload === "string") return payload;
5
+ return Uint8Array.from(payload);
6
+ }
7
+ function nodeHttpTransport(options) {
8
+ const codec = options.codec ?? safeJsonCodec();
9
+ const fetchFn = options.fetchFn ?? globalThis.fetch?.bind(globalThis);
10
+ return batchTransport({
11
+ name: options.name ?? "node-http-inner",
12
+ minLevel: options.minLevel,
13
+ async logBatch(events) {
14
+ if (!fetchFn) throw new Error("fetch is not available. Use Node.js 18+ or pass fetchFn.");
15
+ const transformed = await applyPayloadTransforms(codec.encode(events), {
16
+ contentType: codec.contentType,
17
+ events,
18
+ transport: options.name ?? "node-http"
19
+ }, options.transformPayload);
20
+ const response = await fetchFn(options.url, {
21
+ method: options.method ?? "POST",
22
+ headers: {
23
+ "content-type": transformed.contentType,
24
+ ...transformed.headers,
25
+ ...options.headers
26
+ },
27
+ body: payloadToBody(transformed.payload)
28
+ });
29
+ if (!response.ok) throw new Error(`nodeHttpTransport failed with status ${response.status}`);
30
+ }
31
+ }, {
32
+ name: options.name ?? "node-http",
33
+ maxRecords: options.maxRecords,
34
+ maxBatchSize: options.maxBatchSize,
35
+ maxBytes: options.maxBytes,
36
+ maxWaitMs: options.maxWaitMs,
37
+ flushIntervalMs: options.flushIntervalMs,
38
+ concurrency: options.concurrency,
39
+ maxQueueSize: options.maxQueueSize,
40
+ dropPolicy: options.dropPolicy,
41
+ estimateEventBytes: options.estimateEventBytes,
42
+ maxRetries: options.maxRetries,
43
+ retryBaseDelayMs: options.retryBaseDelayMs,
44
+ retryMaxDelayMs: options.retryMaxDelayMs,
45
+ random: options.random,
46
+ circuitBreakerFailureThreshold: options.circuitBreakerFailureThreshold,
47
+ circuitBreakerResetMs: options.circuitBreakerResetMs,
48
+ onDrop: options.onDrop
49
+ });
50
+ }
51
+ //#endregion
52
+ export { nodeHttpTransport };
53
+
54
+ //# sourceMappingURL=http-transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-transport.js","names":[],"sources":["../src/http-transport.ts"],"sourcesContent":["import {\n applyPayloadTransforms,\n batchTransport,\n safeJsonCodec,\n type BatchTransportOptions,\n type Codec,\n type EncodedPayload,\n type LogEvent,\n type LoggerLevel,\n type PayloadTransform,\n type Transport,\n} from \"@loggerjs/core\";\n\nexport interface NodeHttpTransportOptions extends BatchTransportOptions {\n url: string;\n name?: string;\n method?: \"POST\" | \"PUT\";\n headers?: Record<string, string>;\n codec?: Codec<string | Uint8Array>;\n minLevel?: LoggerLevel;\n fetchFn?: typeof fetch;\n transformPayload?: PayloadTransform | readonly PayloadTransform[];\n}\n\nfunction payloadToBody(payload: EncodedPayload): BodyInit {\n if (typeof payload === \"string\") return payload;\n return Uint8Array.from(payload);\n}\n\nexport function nodeHttpTransport(options: NodeHttpTransportOptions): Transport {\n const codec = options.codec ?? safeJsonCodec();\n const fetchFn = options.fetchFn ?? globalThis.fetch?.bind(globalThis);\n const inner: Transport = {\n name: options.name ?? \"node-http-inner\",\n minLevel: options.minLevel,\n async logBatch(events: LogEvent[]) {\n if (!fetchFn) throw new Error(\"fetch is not available. Use Node.js 18+ or pass fetchFn.\");\n const encoded = codec.encode(events);\n const transformed = await applyPayloadTransforms(\n encoded,\n {\n contentType: codec.contentType,\n events,\n transport: options.name ?? \"node-http\",\n },\n options.transformPayload,\n );\n const response = await fetchFn(options.url, {\n method: options.method ?? \"POST\",\n headers: {\n \"content-type\": transformed.contentType,\n ...transformed.headers,\n ...options.headers,\n },\n body: payloadToBody(transformed.payload),\n });\n if (!response.ok) throw new Error(`nodeHttpTransport failed with status ${response.status}`);\n },\n };\n return batchTransport(inner, {\n name: options.name ?? \"node-http\",\n maxRecords: options.maxRecords,\n maxBatchSize: options.maxBatchSize,\n maxBytes: options.maxBytes,\n maxWaitMs: options.maxWaitMs,\n flushIntervalMs: options.flushIntervalMs,\n concurrency: options.concurrency,\n maxQueueSize: options.maxQueueSize,\n dropPolicy: options.dropPolicy,\n estimateEventBytes: options.estimateEventBytes,\n maxRetries: options.maxRetries,\n retryBaseDelayMs: options.retryBaseDelayMs,\n retryMaxDelayMs: options.retryMaxDelayMs,\n random: options.random,\n circuitBreakerFailureThreshold: options.circuitBreakerFailureThreshold,\n circuitBreakerResetMs: options.circuitBreakerResetMs,\n onDrop: options.onDrop,\n });\n}\n"],"mappings":";;AAwBA,SAAS,cAAc,SAAmC;CACxD,IAAI,OAAO,YAAY,UAAU,OAAO;CACxC,OAAO,WAAW,KAAK,OAAO;AAChC;AAEA,SAAgB,kBAAkB,SAA8C;CAC9E,MAAM,QAAQ,QAAQ,SAAS,cAAc;CAC7C,MAAM,UAAU,QAAQ,WAAW,WAAW,OAAO,KAAK,UAAU;CA4BpE,OAAO,eAAe;EA1BpB,MAAM,QAAQ,QAAQ;EACtB,UAAU,QAAQ;EAClB,MAAM,SAAS,QAAoB;GACjC,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,0DAA0D;GAExF,MAAM,cAAc,MAAM,uBADV,MAAM,OAAO,MAErB,GACN;IACE,aAAa,MAAM;IACnB;IACA,WAAW,QAAQ,QAAQ;GAC7B,GACA,QAAQ,gBACV;GACA,MAAM,WAAW,MAAM,QAAQ,QAAQ,KAAK;IAC1C,QAAQ,QAAQ,UAAU;IAC1B,SAAS;KACP,gBAAgB,YAAY;KAC5B,GAAG,YAAY;KACf,GAAG,QAAQ;IACb;IACA,MAAM,cAAc,YAAY,OAAO;GACzC,CAAC;GACD,IAAI,CAAC,SAAS,IAAI,MAAM,IAAI,MAAM,wCAAwC,SAAS,QAAQ;EAC7F;CAEwB,GAAG;EAC3B,MAAM,QAAQ,QAAQ;EACtB,YAAY,QAAQ;EACpB,cAAc,QAAQ;EACtB,UAAU,QAAQ;EAClB,WAAW,QAAQ;EACnB,iBAAiB,QAAQ;EACzB,aAAa,QAAQ;EACrB,cAAc,QAAQ;EACtB,YAAY,QAAQ;EACpB,oBAAoB,QAAQ;EAC5B,YAAY,QAAQ;EACpB,kBAAkB,QAAQ;EAC1B,iBAAiB,QAAQ;EACzB,QAAQ,QAAQ;EAChB,gCAAgC,QAAQ;EACxC,uBAAuB,QAAQ;EAC/B,QAAQ,QAAQ;CAClB,CAAC;AACH"}
@@ -0,0 +1,57 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let _loggerjs_core = require("@loggerjs/core");
3
+ //#region src/koa-integration.ts
4
+ function sanitizeUrl(url) {
5
+ return url.split(/[?#]/, 1)[0] || "/";
6
+ }
7
+ function levelFor(status, _ctx, error) {
8
+ if (error || status >= 500) return "error";
9
+ if (status >= 400) return "warn";
10
+ return "info";
11
+ }
12
+ function koaIntegration(logger, options = {}) {
13
+ const minStatus = options.minStatus ?? 400;
14
+ const captureAll = options.captureAll ?? false;
15
+ const bindContext = options.bindContext ?? true;
16
+ const sanitize = options.sanitizeUrl ?? sanitizeUrl;
17
+ const getLevel = options.level ?? levelFor;
18
+ return async (ctx, next) => {
19
+ const started = Date.now();
20
+ const method = (ctx.method ?? "GET").toUpperCase();
21
+ const url = sanitize(ctx.originalUrl ?? ctx.url ?? ctx.path ?? "/");
22
+ const requestId = options.getRequestId?.(ctx) ?? ctx.state?.requestId;
23
+ const context = {
24
+ httpMethod: method,
25
+ httpUrl: url,
26
+ requestId,
27
+ ...options.context?.(ctx)
28
+ };
29
+ let error;
30
+ try {
31
+ if (bindContext) await (0, _loggerjs_core.withContext)(context, next);
32
+ else await next();
33
+ } catch (caught) {
34
+ error = caught;
35
+ throw caught;
36
+ } finally {
37
+ const status = ctx.status ?? (error ? 500 : 200);
38
+ if (error || captureAll || status >= minStatus) logger.log(getLevel(status, ctx, error), `Koa ${status} ${method} ${url}`, {
39
+ http: {
40
+ framework: "koa",
41
+ kind: "koa",
42
+ method,
43
+ url,
44
+ status,
45
+ durationMs: Date.now() - started,
46
+ requestId,
47
+ remoteAddress: ctx.ip
48
+ },
49
+ error
50
+ });
51
+ }
52
+ };
53
+ }
54
+ //#endregion
55
+ exports.koaIntegration = koaIntegration;
56
+
57
+ //# sourceMappingURL=koa-integration.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"koa-integration.cjs","names":[],"sources":["../src/koa-integration.ts"],"sourcesContent":["import { withContext, type LoggerLevel, type LoggerLike, type LogData } from \"@loggerjs/core\";\n\nexport interface KoaContextLike {\n method?: string;\n originalUrl?: string;\n url?: string;\n path?: string;\n status?: number;\n ip?: string;\n state?: Record<string, unknown>;\n request?: { headers?: Record<string, string | string[] | undefined> };\n}\n\nexport type KoaNext = () => Promise<unknown>;\nexport type KoaMiddleware = (ctx: KoaContextLike, next: KoaNext) => Promise<void>;\n\nexport interface KoaIntegrationOptions {\n minStatus?: number;\n captureAll?: boolean;\n bindContext?: boolean;\n sanitizeUrl?: (url: string) => string;\n getRequestId?: (ctx: KoaContextLike) => string | undefined;\n context?: (ctx: KoaContextLike) => Record<string, unknown> | undefined;\n level?: (status: number, ctx: KoaContextLike, error: unknown) => LoggerLevel;\n}\n\nfunction sanitizeUrl(url: string): string {\n return url.split(/[?#]/, 1)[0] || \"/\";\n}\n\nfunction levelFor(status: number, _ctx: KoaContextLike, error: unknown): LoggerLevel {\n if (error || status >= 500) return \"error\";\n if (status >= 400) return \"warn\";\n return \"info\";\n}\n\nexport function koaIntegration(\n logger: LoggerLike,\n options: KoaIntegrationOptions = {},\n): KoaMiddleware {\n const minStatus = options.minStatus ?? 400;\n const captureAll = options.captureAll ?? false;\n const bindContext = options.bindContext ?? true;\n const sanitize = options.sanitizeUrl ?? sanitizeUrl;\n const getLevel = options.level ?? levelFor;\n\n return async (ctx, next) => {\n const started = Date.now();\n const method = (ctx.method ?? \"GET\").toUpperCase();\n const url = sanitize(ctx.originalUrl ?? ctx.url ?? ctx.path ?? \"/\");\n const requestId = options.getRequestId?.(ctx) ?? (ctx.state?.requestId as string | undefined);\n const context = { httpMethod: method, httpUrl: url, requestId, ...options.context?.(ctx) };\n let error: unknown;\n try {\n if (bindContext) await withContext(context, next);\n else await next();\n } catch (caught) {\n error = caught;\n throw caught;\n } finally {\n const status = ctx.status ?? (error ? 500 : 200);\n if (error || captureAll || status >= minStatus) {\n logger.log(getLevel(status, ctx, error), `Koa ${status} ${method} ${url}`, {\n http: {\n framework: \"koa\",\n kind: \"koa\",\n method,\n url,\n status,\n durationMs: Date.now() - started,\n requestId,\n remoteAddress: ctx.ip,\n },\n error,\n } as LogData);\n }\n }\n };\n}\n"],"mappings":";;;AA0BA,SAAS,YAAY,KAAqB;CACxC,OAAO,IAAI,MAAM,QAAQ,CAAC,CAAC,CAAC,MAAM;AACpC;AAEA,SAAS,SAAS,QAAgB,MAAsB,OAA6B;CACnF,IAAI,SAAS,UAAU,KAAK,OAAO;CACnC,IAAI,UAAU,KAAK,OAAO;CAC1B,OAAO;AACT;AAEA,SAAgB,eACd,QACA,UAAiC,CAAC,GACnB;CACf,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,aAAa,QAAQ,cAAc;CACzC,MAAM,cAAc,QAAQ,eAAe;CAC3C,MAAM,WAAW,QAAQ,eAAe;CACxC,MAAM,WAAW,QAAQ,SAAS;CAElC,OAAO,OAAO,KAAK,SAAS;EAC1B,MAAM,UAAU,KAAK,IAAI;EACzB,MAAM,UAAU,IAAI,UAAU,MAAA,CAAO,YAAY;EACjD,MAAM,MAAM,SAAS,IAAI,eAAe,IAAI,OAAO,IAAI,QAAQ,GAAG;EAClE,MAAM,YAAY,QAAQ,eAAe,GAAG,KAAM,IAAI,OAAO;EAC7D,MAAM,UAAU;GAAE,YAAY;GAAQ,SAAS;GAAK;GAAW,GAAG,QAAQ,UAAU,GAAG;EAAE;EACzF,IAAI;EACJ,IAAI;GACF,IAAI,aAAa,OAAA,GAAA,eAAA,YAAA,CAAkB,SAAS,IAAI;QAC3C,MAAM,KAAK;EAClB,SAAS,QAAQ;GACf,QAAQ;GACR,MAAM;EACR,UAAU;GACR,MAAM,SAAS,IAAI,WAAW,QAAQ,MAAM;GAC5C,IAAI,SAAS,cAAc,UAAU,WACnC,OAAO,IAAI,SAAS,QAAQ,KAAK,KAAK,GAAG,OAAO,OAAO,GAAG,OAAO,GAAG,OAAO;IACzE,MAAM;KACJ,WAAW;KACX,MAAM;KACN;KACA;KACA;KACA,YAAY,KAAK,IAAI,IAAI;KACzB;KACA,eAAe,IAAI;IACrB;IACA;GACF,CAAY;EAEhB;CACF;AACF"}
@@ -0,0 +1,56 @@
1
+ import { withContext } from "@loggerjs/core";
2
+ //#region src/koa-integration.ts
3
+ function sanitizeUrl(url) {
4
+ return url.split(/[?#]/, 1)[0] || "/";
5
+ }
6
+ function levelFor(status, _ctx, error) {
7
+ if (error || status >= 500) return "error";
8
+ if (status >= 400) return "warn";
9
+ return "info";
10
+ }
11
+ function koaIntegration(logger, options = {}) {
12
+ const minStatus = options.minStatus ?? 400;
13
+ const captureAll = options.captureAll ?? false;
14
+ const bindContext = options.bindContext ?? true;
15
+ const sanitize = options.sanitizeUrl ?? sanitizeUrl;
16
+ const getLevel = options.level ?? levelFor;
17
+ return async (ctx, next) => {
18
+ const started = Date.now();
19
+ const method = (ctx.method ?? "GET").toUpperCase();
20
+ const url = sanitize(ctx.originalUrl ?? ctx.url ?? ctx.path ?? "/");
21
+ const requestId = options.getRequestId?.(ctx) ?? ctx.state?.requestId;
22
+ const context = {
23
+ httpMethod: method,
24
+ httpUrl: url,
25
+ requestId,
26
+ ...options.context?.(ctx)
27
+ };
28
+ let error;
29
+ try {
30
+ if (bindContext) await withContext(context, next);
31
+ else await next();
32
+ } catch (caught) {
33
+ error = caught;
34
+ throw caught;
35
+ } finally {
36
+ const status = ctx.status ?? (error ? 500 : 200);
37
+ if (error || captureAll || status >= minStatus) logger.log(getLevel(status, ctx, error), `Koa ${status} ${method} ${url}`, {
38
+ http: {
39
+ framework: "koa",
40
+ kind: "koa",
41
+ method,
42
+ url,
43
+ status,
44
+ durationMs: Date.now() - started,
45
+ requestId,
46
+ remoteAddress: ctx.ip
47
+ },
48
+ error
49
+ });
50
+ }
51
+ };
52
+ }
53
+ //#endregion
54
+ export { koaIntegration };
55
+
56
+ //# sourceMappingURL=koa-integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"koa-integration.js","names":[],"sources":["../src/koa-integration.ts"],"sourcesContent":["import { withContext, type LoggerLevel, type LoggerLike, type LogData } from \"@loggerjs/core\";\n\nexport interface KoaContextLike {\n method?: string;\n originalUrl?: string;\n url?: string;\n path?: string;\n status?: number;\n ip?: string;\n state?: Record<string, unknown>;\n request?: { headers?: Record<string, string | string[] | undefined> };\n}\n\nexport type KoaNext = () => Promise<unknown>;\nexport type KoaMiddleware = (ctx: KoaContextLike, next: KoaNext) => Promise<void>;\n\nexport interface KoaIntegrationOptions {\n minStatus?: number;\n captureAll?: boolean;\n bindContext?: boolean;\n sanitizeUrl?: (url: string) => string;\n getRequestId?: (ctx: KoaContextLike) => string | undefined;\n context?: (ctx: KoaContextLike) => Record<string, unknown> | undefined;\n level?: (status: number, ctx: KoaContextLike, error: unknown) => LoggerLevel;\n}\n\nfunction sanitizeUrl(url: string): string {\n return url.split(/[?#]/, 1)[0] || \"/\";\n}\n\nfunction levelFor(status: number, _ctx: KoaContextLike, error: unknown): LoggerLevel {\n if (error || status >= 500) return \"error\";\n if (status >= 400) return \"warn\";\n return \"info\";\n}\n\nexport function koaIntegration(\n logger: LoggerLike,\n options: KoaIntegrationOptions = {},\n): KoaMiddleware {\n const minStatus = options.minStatus ?? 400;\n const captureAll = options.captureAll ?? false;\n const bindContext = options.bindContext ?? true;\n const sanitize = options.sanitizeUrl ?? sanitizeUrl;\n const getLevel = options.level ?? levelFor;\n\n return async (ctx, next) => {\n const started = Date.now();\n const method = (ctx.method ?? \"GET\").toUpperCase();\n const url = sanitize(ctx.originalUrl ?? ctx.url ?? ctx.path ?? \"/\");\n const requestId = options.getRequestId?.(ctx) ?? (ctx.state?.requestId as string | undefined);\n const context = { httpMethod: method, httpUrl: url, requestId, ...options.context?.(ctx) };\n let error: unknown;\n try {\n if (bindContext) await withContext(context, next);\n else await next();\n } catch (caught) {\n error = caught;\n throw caught;\n } finally {\n const status = ctx.status ?? (error ? 500 : 200);\n if (error || captureAll || status >= minStatus) {\n logger.log(getLevel(status, ctx, error), `Koa ${status} ${method} ${url}`, {\n http: {\n framework: \"koa\",\n kind: \"koa\",\n method,\n url,\n status,\n durationMs: Date.now() - started,\n requestId,\n remoteAddress: ctx.ip,\n },\n error,\n } as LogData);\n }\n }\n };\n}\n"],"mappings":";;AA0BA,SAAS,YAAY,KAAqB;CACxC,OAAO,IAAI,MAAM,QAAQ,CAAC,CAAC,CAAC,MAAM;AACpC;AAEA,SAAS,SAAS,QAAgB,MAAsB,OAA6B;CACnF,IAAI,SAAS,UAAU,KAAK,OAAO;CACnC,IAAI,UAAU,KAAK,OAAO;CAC1B,OAAO;AACT;AAEA,SAAgB,eACd,QACA,UAAiC,CAAC,GACnB;CACf,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,aAAa,QAAQ,cAAc;CACzC,MAAM,cAAc,QAAQ,eAAe;CAC3C,MAAM,WAAW,QAAQ,eAAe;CACxC,MAAM,WAAW,QAAQ,SAAS;CAElC,OAAO,OAAO,KAAK,SAAS;EAC1B,MAAM,UAAU,KAAK,IAAI;EACzB,MAAM,UAAU,IAAI,UAAU,MAAA,CAAO,YAAY;EACjD,MAAM,MAAM,SAAS,IAAI,eAAe,IAAI,OAAO,IAAI,QAAQ,GAAG;EAClE,MAAM,YAAY,QAAQ,eAAe,GAAG,KAAM,IAAI,OAAO;EAC7D,MAAM,UAAU;GAAE,YAAY;GAAQ,SAAS;GAAK;GAAW,GAAG,QAAQ,UAAU,GAAG;EAAE;EACzF,IAAI;EACJ,IAAI;GACF,IAAI,aAAa,MAAM,YAAY,SAAS,IAAI;QAC3C,MAAM,KAAK;EAClB,SAAS,QAAQ;GACf,QAAQ;GACR,MAAM;EACR,UAAU;GACR,MAAM,SAAS,IAAI,WAAW,QAAQ,MAAM;GAC5C,IAAI,SAAS,cAAc,UAAU,WACnC,OAAO,IAAI,SAAS,QAAQ,KAAK,KAAK,GAAG,OAAO,OAAO,GAAG,OAAO,GAAG,OAAO;IACzE,MAAM;KACJ,WAAW;KACX,MAAM;KACN;KACA;KACA;KACA,YAAY,KAAK,IAAI,IAAI;KACzB;KACA,eAAe,IAAI;IACrB;IACA;GACF,CAAY;EAEhB;CACF;AACF"}
@@ -0,0 +1,46 @@
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/logger-diagnostics.ts
5
+ const requireBuiltin = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
6
+ let cachedDiagnosticsChannel;
7
+ function loadDiagnosticsChannel() {
8
+ if (cachedDiagnosticsChannel !== void 0) return cachedDiagnosticsChannel;
9
+ try {
10
+ cachedDiagnosticsChannel = requireBuiltin("node:diagnostics_channel");
11
+ } catch {
12
+ try {
13
+ cachedDiagnosticsChannel = requireBuiltin("diagnostics_channel");
14
+ } catch {
15
+ cachedDiagnosticsChannel = null;
16
+ }
17
+ }
18
+ return cachedDiagnosticsChannel;
19
+ }
20
+ function installLoggerDiagnosticsChannel(options = {}) {
21
+ const diagnosticsChannel = options.diagnosticsChannel === void 0 ? loadDiagnosticsChannel() : options.diagnosticsChannel;
22
+ if (!diagnosticsChannel) return () => {};
23
+ const prefix = options.prefix ?? "loggerjs";
24
+ const channels = /* @__PURE__ */ new Map();
25
+ const channelFor = (stage) => {
26
+ const name = `${prefix}.${stage}`;
27
+ let channel = channels.get(name);
28
+ if (!channel) {
29
+ channel = diagnosticsChannel.channel(name);
30
+ channels.set(name, channel);
31
+ }
32
+ return channel;
33
+ };
34
+ const sink = (event) => {
35
+ channelFor(event.stage).publish(event);
36
+ };
37
+ sink.enabled = (stage) => channelFor(stage).hasSubscribers !== false;
38
+ const previous = (0, _loggerjs_core.setLoggerDiagnosticSink)(sink);
39
+ return () => {
40
+ (0, _loggerjs_core.setLoggerDiagnosticSink)(previous);
41
+ };
42
+ }
43
+ //#endregion
44
+ exports.installLoggerDiagnosticsChannel = installLoggerDiagnosticsChannel;
45
+
46
+ //# sourceMappingURL=logger-diagnostics.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger-diagnostics.cjs","names":[],"sources":["../src/logger-diagnostics.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport {\n setLoggerDiagnosticSink,\n type LoggerDiagnosticEvent,\n type LoggerDiagnosticSink,\n type LoggerDiagnosticStage,\n} from \"@loggerjs/core\";\n\nexport interface LoggerDiagnosticsChannelPublisher {\n hasSubscribers?: boolean;\n publish: (message: LoggerDiagnosticEvent) => void;\n}\n\nexport interface LoggerDiagnosticsChannelModule {\n channel: (name: string) => LoggerDiagnosticsChannelPublisher;\n}\n\nexport interface InstallLoggerDiagnosticsChannelOptions {\n diagnosticsChannel?: LoggerDiagnosticsChannelModule | null;\n prefix?: string;\n}\n\nconst requireBuiltin = createRequire(import.meta.url);\nlet cachedDiagnosticsChannel: LoggerDiagnosticsChannelModule | null | undefined;\n\nfunction loadDiagnosticsChannel(): LoggerDiagnosticsChannelModule | null {\n if (cachedDiagnosticsChannel !== undefined) return cachedDiagnosticsChannel;\n try {\n cachedDiagnosticsChannel = requireBuiltin(\n \"node:diagnostics_channel\",\n ) as LoggerDiagnosticsChannelModule;\n } catch {\n try {\n cachedDiagnosticsChannel = requireBuiltin(\n \"diagnostics_channel\",\n ) as LoggerDiagnosticsChannelModule;\n } catch {\n cachedDiagnosticsChannel = null;\n }\n }\n return cachedDiagnosticsChannel;\n}\n\nexport function installLoggerDiagnosticsChannel(\n options: InstallLoggerDiagnosticsChannelOptions = {},\n): () => void {\n const diagnosticsChannel =\n options.diagnosticsChannel === undefined\n ? loadDiagnosticsChannel()\n : options.diagnosticsChannel;\n if (!diagnosticsChannel) return () => {};\n\n const prefix = options.prefix ?? \"loggerjs\";\n const channels = new Map<string, LoggerDiagnosticsChannelPublisher>();\n const channelFor = (stage: LoggerDiagnosticStage) => {\n const name = `${prefix}.${stage}`;\n let channel = channels.get(name);\n if (!channel) {\n channel = diagnosticsChannel.channel(name);\n channels.set(name, channel);\n }\n return channel;\n };\n const sink: LoggerDiagnosticSink = (event) => {\n channelFor(event.stage).publish(event);\n };\n sink.enabled = (stage) => channelFor(stage).hasSubscribers !== false;\n const previous = setLoggerDiagnosticSink(sink);\n\n return () => {\n setLoggerDiagnosticSink(previous);\n };\n}\n"],"mappings":";;;;AAsBA,MAAM,kBAAA,GAAA,YAAA,cAAA,CAAA,QAAA,KAAA,CAAA,CAAA,cAAA,UAAA,CAAA,CAAA,IAA8C;AACpD,IAAI;AAEJ,SAAS,yBAAgE;CACvE,IAAI,6BAA6B,KAAA,GAAW,OAAO;CACnD,IAAI;EACF,2BAA2B,eACzB,0BACF;CACF,QAAQ;EACN,IAAI;GACF,2BAA2B,eACzB,qBACF;EACF,QAAQ;GACN,2BAA2B;EAC7B;CACF;CACA,OAAO;AACT;AAEA,SAAgB,gCACd,UAAkD,CAAC,GACvC;CACZ,MAAM,qBACJ,QAAQ,uBAAuB,KAAA,IAC3B,uBAAuB,IACvB,QAAQ;CACd,IAAI,CAAC,oBAAoB,aAAa,CAAC;CAEvC,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,2BAAW,IAAI,IAA+C;CACpE,MAAM,cAAc,UAAiC;EACnD,MAAM,OAAO,GAAG,OAAO,GAAG;EAC1B,IAAI,UAAU,SAAS,IAAI,IAAI;EAC/B,IAAI,CAAC,SAAS;GACZ,UAAU,mBAAmB,QAAQ,IAAI;GACzC,SAAS,IAAI,MAAM,OAAO;EAC5B;EACA,OAAO;CACT;CACA,MAAM,QAA8B,UAAU;EAC5C,WAAW,MAAM,KAAK,CAAC,CAAC,QAAQ,KAAK;CACvC;CACA,KAAK,WAAW,UAAU,WAAW,KAAK,CAAC,CAAC,mBAAmB;CAC/D,MAAM,YAAA,GAAA,eAAA,wBAAA,CAAmC,IAAI;CAE7C,aAAa;EACX,CAAA,GAAA,eAAA,wBAAA,CAAwB,QAAQ;CAClC;AACF"}
@@ -0,0 +1,45 @@
1
+ import { createRequire } from "node:module";
2
+ import { setLoggerDiagnosticSink } from "@loggerjs/core";
3
+ //#region src/logger-diagnostics.ts
4
+ const requireBuiltin = createRequire(import.meta.url);
5
+ let cachedDiagnosticsChannel;
6
+ function loadDiagnosticsChannel() {
7
+ if (cachedDiagnosticsChannel !== void 0) return cachedDiagnosticsChannel;
8
+ try {
9
+ cachedDiagnosticsChannel = requireBuiltin("node:diagnostics_channel");
10
+ } catch {
11
+ try {
12
+ cachedDiagnosticsChannel = requireBuiltin("diagnostics_channel");
13
+ } catch {
14
+ cachedDiagnosticsChannel = null;
15
+ }
16
+ }
17
+ return cachedDiagnosticsChannel;
18
+ }
19
+ function installLoggerDiagnosticsChannel(options = {}) {
20
+ const diagnosticsChannel = options.diagnosticsChannel === void 0 ? loadDiagnosticsChannel() : options.diagnosticsChannel;
21
+ if (!diagnosticsChannel) return () => {};
22
+ const prefix = options.prefix ?? "loggerjs";
23
+ const channels = /* @__PURE__ */ new Map();
24
+ const channelFor = (stage) => {
25
+ const name = `${prefix}.${stage}`;
26
+ let channel = channels.get(name);
27
+ if (!channel) {
28
+ channel = diagnosticsChannel.channel(name);
29
+ channels.set(name, channel);
30
+ }
31
+ return channel;
32
+ };
33
+ const sink = (event) => {
34
+ channelFor(event.stage).publish(event);
35
+ };
36
+ sink.enabled = (stage) => channelFor(stage).hasSubscribers !== false;
37
+ const previous = setLoggerDiagnosticSink(sink);
38
+ return () => {
39
+ setLoggerDiagnosticSink(previous);
40
+ };
41
+ }
42
+ //#endregion
43
+ export { installLoggerDiagnosticsChannel };
44
+
45
+ //# sourceMappingURL=logger-diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger-diagnostics.js","names":[],"sources":["../src/logger-diagnostics.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport {\n setLoggerDiagnosticSink,\n type LoggerDiagnosticEvent,\n type LoggerDiagnosticSink,\n type LoggerDiagnosticStage,\n} from \"@loggerjs/core\";\n\nexport interface LoggerDiagnosticsChannelPublisher {\n hasSubscribers?: boolean;\n publish: (message: LoggerDiagnosticEvent) => void;\n}\n\nexport interface LoggerDiagnosticsChannelModule {\n channel: (name: string) => LoggerDiagnosticsChannelPublisher;\n}\n\nexport interface InstallLoggerDiagnosticsChannelOptions {\n diagnosticsChannel?: LoggerDiagnosticsChannelModule | null;\n prefix?: string;\n}\n\nconst requireBuiltin = createRequire(import.meta.url);\nlet cachedDiagnosticsChannel: LoggerDiagnosticsChannelModule | null | undefined;\n\nfunction loadDiagnosticsChannel(): LoggerDiagnosticsChannelModule | null {\n if (cachedDiagnosticsChannel !== undefined) return cachedDiagnosticsChannel;\n try {\n cachedDiagnosticsChannel = requireBuiltin(\n \"node:diagnostics_channel\",\n ) as LoggerDiagnosticsChannelModule;\n } catch {\n try {\n cachedDiagnosticsChannel = requireBuiltin(\n \"diagnostics_channel\",\n ) as LoggerDiagnosticsChannelModule;\n } catch {\n cachedDiagnosticsChannel = null;\n }\n }\n return cachedDiagnosticsChannel;\n}\n\nexport function installLoggerDiagnosticsChannel(\n options: InstallLoggerDiagnosticsChannelOptions = {},\n): () => void {\n const diagnosticsChannel =\n options.diagnosticsChannel === undefined\n ? loadDiagnosticsChannel()\n : options.diagnosticsChannel;\n if (!diagnosticsChannel) return () => {};\n\n const prefix = options.prefix ?? \"loggerjs\";\n const channels = new Map<string, LoggerDiagnosticsChannelPublisher>();\n const channelFor = (stage: LoggerDiagnosticStage) => {\n const name = `${prefix}.${stage}`;\n let channel = channels.get(name);\n if (!channel) {\n channel = diagnosticsChannel.channel(name);\n channels.set(name, channel);\n }\n return channel;\n };\n const sink: LoggerDiagnosticSink = (event) => {\n channelFor(event.stage).publish(event);\n };\n sink.enabled = (stage) => channelFor(stage).hasSubscribers !== false;\n const previous = setLoggerDiagnosticSink(sink);\n\n return () => {\n setLoggerDiagnosticSink(previous);\n };\n}\n"],"mappings":";;;AAsBA,MAAM,iBAAiB,cAAc,OAAO,KAAK,GAAG;AACpD,IAAI;AAEJ,SAAS,yBAAgE;CACvE,IAAI,6BAA6B,KAAA,GAAW,OAAO;CACnD,IAAI;EACF,2BAA2B,eACzB,0BACF;CACF,QAAQ;EACN,IAAI;GACF,2BAA2B,eACzB,qBACF;EACF,QAAQ;GACN,2BAA2B;EAC7B;CACF;CACA,OAAO;AACT;AAEA,SAAgB,gCACd,UAAkD,CAAC,GACvC;CACZ,MAAM,qBACJ,QAAQ,uBAAuB,KAAA,IAC3B,uBAAuB,IACvB,QAAQ;CACd,IAAI,CAAC,oBAAoB,aAAa,CAAC;CAEvC,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,2BAAW,IAAI,IAA+C;CACpE,MAAM,cAAc,UAAiC;EACnD,MAAM,OAAO,GAAG,OAAO,GAAG;EAC1B,IAAI,UAAU,SAAS,IAAI,IAAI;EAC/B,IAAI,CAAC,SAAS;GACZ,UAAU,mBAAmB,QAAQ,IAAI;GACzC,SAAS,IAAI,MAAM,OAAO;EAC5B;EACA,OAAO;CACT;CACA,MAAM,QAA8B,UAAU;EAC5C,WAAW,MAAM,KAAK,CAAC,CAAC,QAAQ,KAAK;CACvC;CACA,KAAK,WAAW,UAAU,WAAW,KAAK,CAAC,CAAC,mBAAmB;CAC/D,MAAM,WAAW,wBAAwB,IAAI;CAE7C,aAAa;EACX,wBAAwB,QAAQ;CAClC;AACF"}
@@ -0,0 +1,138 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let _loggerjs_core = require("@loggerjs/core");
3
+ //#region src/express-integration.ts
4
+ const defaultRandom = () => Math.random();
5
+ function defaultSanitizeUrl(url) {
6
+ const queryIndex = url.indexOf("?");
7
+ const hashIndex = url.indexOf("#");
8
+ const end = Math.min(queryIndex >= 0 ? queryIndex : url.length, hashIndex >= 0 ? hashIndex : url.length);
9
+ return url.slice(0, end);
10
+ }
11
+ function defaultLevel(status, _req, _res, aborted) {
12
+ if (aborted) return "warn";
13
+ if (status >= 500) return "error";
14
+ if (status >= 400) return "warn";
15
+ return "info";
16
+ }
17
+ function requestUrl(req) {
18
+ return req.originalUrl ?? req.url ?? req.path ?? "/";
19
+ }
20
+ function headerValue(value) {
21
+ if (typeof value === "number") return String(value);
22
+ return value;
23
+ }
24
+ function pickRequestHeaders(req, names) {
25
+ if (!names || names.length === 0 || !req.headers) return void 0;
26
+ const out = {};
27
+ for (const name of names) {
28
+ const value = req.headers[name.toLowerCase()] ?? req.headers[name];
29
+ if (value !== void 0) out[name.toLowerCase()] = value;
30
+ }
31
+ return Object.keys(out).length > 0 ? out : void 0;
32
+ }
33
+ function pickResponseHeaders(res, names) {
34
+ if (!names || names.length === 0 || !res.getHeader) return void 0;
35
+ const out = {};
36
+ for (const name of names) {
37
+ const value = headerValue(res.getHeader(name));
38
+ if (value !== void 0) out[name.toLowerCase()] = value;
39
+ }
40
+ return Object.keys(out).length > 0 ? out : void 0;
41
+ }
42
+ function defaultRoute(req) {
43
+ const path = req.route?.path;
44
+ return typeof path === "string" ? path : void 0;
45
+ }
46
+ function removeListener(res, event, listener) {
47
+ if (res.off) {
48
+ res.off(event, listener);
49
+ return;
50
+ }
51
+ res.removeListener?.(event, listener);
52
+ }
53
+ function onResponseDone(res, event, listener) {
54
+ if (res.once) {
55
+ res.once(event, listener);
56
+ return;
57
+ }
58
+ res.on?.(event, listener);
59
+ }
60
+ function expressIntegration(logger, options = {}) {
61
+ const name = options.name ?? "express";
62
+ const minStatus = options.minStatus ?? 400;
63
+ const captureAll = options.captureAll ?? options.captureSuccessful ?? false;
64
+ const captureAborted = options.captureAborted ?? true;
65
+ const sampleRate = options.sampleRate ?? 1;
66
+ const random = options.random ?? defaultRandom;
67
+ const sanitizeUrl = options.sanitizeUrl ?? defaultSanitizeUrl;
68
+ const levelFor = options.level ?? defaultLevel;
69
+ const routeFor = options.getRoute ?? defaultRoute;
70
+ const bindContext = options.bindContext ?? true;
71
+ return (req, res, next) => {
72
+ const started = Date.now();
73
+ const method = (req.method ?? "GET").toUpperCase();
74
+ const url = sanitizeUrl(requestUrl(req));
75
+ const requestId = options.getRequestId?.(req, res);
76
+ let completed = false;
77
+ const context = {
78
+ httpMethod: method,
79
+ httpUrl: url,
80
+ requestId,
81
+ ...options.context?.(req, res)
82
+ };
83
+ const shouldCapture = (status, aborted) => {
84
+ if (aborted && captureAborted) return true;
85
+ if (status >= minStatus) return true;
86
+ if (!captureAll) return false;
87
+ return sampleRate >= 1 || random() < sampleRate;
88
+ };
89
+ const cleanup = () => {
90
+ removeListener(res, "finish", onFinish);
91
+ removeListener(res, "close", onClose);
92
+ };
93
+ const logRequest = (event) => {
94
+ if (completed) return;
95
+ completed = true;
96
+ cleanup();
97
+ const status = res.statusCode ?? 0;
98
+ const aborted = event === "close" && res.writableEnded !== true;
99
+ if (!shouldCapture(status, aborted)) return;
100
+ const http = {
101
+ kind: name,
102
+ framework: "express",
103
+ method,
104
+ url,
105
+ route: routeFor(req),
106
+ status,
107
+ durationMs: Date.now() - started,
108
+ aborted,
109
+ requestId,
110
+ remoteAddress: req.ip ?? req.socket?.remoteAddress,
111
+ requestHeaders: pickRequestHeaders(req, options.captureRequestHeaders),
112
+ responseHeaders: pickResponseHeaders(res, options.captureResponseHeaders)
113
+ };
114
+ logger.log(levelFor(status, req, res, aborted), `Express ${status} ${method} ${url}`, { http });
115
+ };
116
+ const onFinish = () => logRequest("finish");
117
+ const onClose = () => logRequest("close");
118
+ onResponseDone(res, "finish", onFinish);
119
+ onResponseDone(res, "close", onClose);
120
+ if (bindContext) {
121
+ (0, _loggerjs_core.withContext)(context, () => next());
122
+ return;
123
+ }
124
+ next();
125
+ };
126
+ }
127
+ //#endregion
128
+ //#region src/nest-integration.ts
129
+ function nestMiddlewareIntegration(logger, options = {}) {
130
+ return expressIntegration(logger, {
131
+ name: "nestjs",
132
+ ...options
133
+ });
134
+ }
135
+ //#endregion
136
+ exports.nestMiddlewareIntegration = nestMiddlewareIntegration;
137
+
138
+ //# sourceMappingURL=nest-integration.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nest-integration.cjs","names":[],"sources":["../src/express-integration.ts","../src/nest-integration.ts"],"sourcesContent":["import { withContext, type LoggerLevel, type LoggerLike, type LogData } from \"@loggerjs/core\";\n\nexport interface ExpressRequestLike {\n method?: string;\n originalUrl?: string;\n url?: string;\n path?: string;\n headers?: Record<string, string | string[] | undefined>;\n ip?: string;\n route?: { path?: string };\n socket?: { remoteAddress?: string };\n [key: string]: unknown;\n}\n\nexport interface ExpressResponseLike {\n statusCode?: number;\n writableEnded?: boolean;\n headersSent?: boolean;\n getHeader?: (name: string) => number | string | string[] | undefined;\n once?: (event: \"finish\" | \"close\", listener: () => void) => unknown;\n on?: (event: \"finish\" | \"close\", listener: () => void) => unknown;\n off?: (event: \"finish\" | \"close\", listener: () => void) => unknown;\n removeListener?: (event: \"finish\" | \"close\", listener: () => void) => unknown;\n}\n\nexport type ExpressNextFunction = (error?: unknown) => void;\nexport type ExpressRequestHandler = (\n req: ExpressRequestLike,\n res: ExpressResponseLike,\n next: ExpressNextFunction,\n) => void;\n\nexport interface ExpressIntegrationOptions {\n name?: string;\n minStatus?: number;\n captureAll?: boolean;\n captureSuccessful?: boolean;\n captureAborted?: boolean;\n sampleRate?: number;\n random?: () => number;\n bindContext?: boolean;\n captureRequestHeaders?: readonly string[];\n captureResponseHeaders?: readonly string[];\n sanitizeUrl?: (url: string) => string;\n getRequestId?: (req: ExpressRequestLike, res: ExpressResponseLike) => string | undefined;\n getRoute?: (req: ExpressRequestLike) => string | undefined;\n context?: (\n req: ExpressRequestLike,\n res: ExpressResponseLike,\n ) => Record<string, unknown> | undefined;\n level?: (\n status: number,\n req: ExpressRequestLike,\n res: ExpressResponseLike,\n aborted: boolean,\n ) => LoggerLevel;\n}\n\nconst defaultRandom = () => Math.random();\n\nfunction defaultSanitizeUrl(url: string): string {\n const queryIndex = url.indexOf(\"?\");\n const hashIndex = url.indexOf(\"#\");\n const end = Math.min(\n queryIndex >= 0 ? queryIndex : url.length,\n hashIndex >= 0 ? hashIndex : url.length,\n );\n return url.slice(0, end);\n}\n\nfunction defaultLevel(\n status: number,\n _req: ExpressRequestLike,\n _res: ExpressResponseLike,\n aborted: boolean,\n): LoggerLevel {\n if (aborted) return \"warn\";\n if (status >= 500) return \"error\";\n if (status >= 400) return \"warn\";\n return \"info\";\n}\n\nfunction requestUrl(req: ExpressRequestLike): string {\n return req.originalUrl ?? req.url ?? req.path ?? \"/\";\n}\n\nfunction headerValue(value: number | string | string[] | undefined): string | string[] | undefined {\n if (typeof value === \"number\") return String(value);\n return value;\n}\n\nfunction pickRequestHeaders(\n req: ExpressRequestLike,\n names: readonly string[] | undefined,\n): Record<string, string | string[]> | undefined {\n if (!names || names.length === 0 || !req.headers) return undefined;\n const out: Record<string, string | string[]> = {};\n for (const name of names) {\n const value = req.headers[name.toLowerCase()] ?? req.headers[name];\n if (value !== undefined) out[name.toLowerCase()] = value;\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction pickResponseHeaders(\n res: ExpressResponseLike,\n names: readonly string[] | undefined,\n): Record<string, string | string[]> | undefined {\n if (!names || names.length === 0 || !res.getHeader) return undefined;\n const out: Record<string, string | string[]> = {};\n for (const name of names) {\n const value = headerValue(res.getHeader(name));\n if (value !== undefined) out[name.toLowerCase()] = value;\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction defaultRoute(req: ExpressRequestLike): string | undefined {\n const path = req.route?.path;\n return typeof path === \"string\" ? path : undefined;\n}\n\nfunction removeListener(res: ExpressResponseLike, event: \"finish\" | \"close\", listener: () => void) {\n if (res.off) {\n res.off(event, listener);\n return;\n }\n res.removeListener?.(event, listener);\n}\n\nfunction onResponseDone(res: ExpressResponseLike, event: \"finish\" | \"close\", listener: () => void) {\n if (res.once) {\n res.once(event, listener);\n return;\n }\n res.on?.(event, listener);\n}\n\nexport function expressIntegration(\n logger: LoggerLike,\n options: ExpressIntegrationOptions = {},\n): ExpressRequestHandler {\n const name = options.name ?? \"express\";\n const minStatus = options.minStatus ?? 400;\n const captureAll = options.captureAll ?? options.captureSuccessful ?? false;\n const captureAborted = options.captureAborted ?? true;\n const sampleRate = options.sampleRate ?? 1;\n const random = options.random ?? defaultRandom;\n const sanitizeUrl = options.sanitizeUrl ?? defaultSanitizeUrl;\n const levelFor = options.level ?? defaultLevel;\n const routeFor = options.getRoute ?? defaultRoute;\n const bindContext = options.bindContext ?? true;\n\n return (req, res, next) => {\n const started = Date.now();\n const method = (req.method ?? \"GET\").toUpperCase();\n const url = sanitizeUrl(requestUrl(req));\n const requestId = options.getRequestId?.(req, res);\n let completed = false;\n\n const context = {\n httpMethod: method,\n httpUrl: url,\n requestId,\n ...options.context?.(req, res),\n };\n\n const shouldCapture = (status: number, aborted: boolean) => {\n if (aborted && captureAborted) return true;\n if (status >= minStatus) return true;\n if (!captureAll) return false;\n return sampleRate >= 1 || random() < sampleRate;\n };\n\n const cleanup = () => {\n removeListener(res, \"finish\", onFinish);\n removeListener(res, \"close\", onClose);\n };\n\n const logRequest = (event: \"finish\" | \"close\") => {\n if (completed) return;\n completed = true;\n cleanup();\n const status = res.statusCode ?? 0;\n const aborted = event === \"close\" && res.writableEnded !== true;\n if (!shouldCapture(status, aborted)) return;\n const http: Record<string, unknown> = {\n kind: name,\n framework: \"express\",\n method,\n url,\n route: routeFor(req),\n status,\n durationMs: Date.now() - started,\n aborted,\n requestId,\n remoteAddress: req.ip ?? req.socket?.remoteAddress,\n requestHeaders: pickRequestHeaders(req, options.captureRequestHeaders),\n responseHeaders: pickResponseHeaders(res, options.captureResponseHeaders),\n };\n logger.log(levelFor(status, req, res, aborted), `Express ${status} ${method} ${url}`, {\n http,\n } as LogData);\n };\n\n const onFinish = () => logRequest(\"finish\");\n const onClose = () => logRequest(\"close\");\n onResponseDone(res, \"finish\", onFinish);\n onResponseDone(res, \"close\", onClose);\n\n if (bindContext) {\n withContext(context, () => next());\n return;\n }\n next();\n };\n}\n","import type { LoggerLike } from \"@loggerjs/core\";\nimport {\n expressIntegration,\n type ExpressIntegrationOptions,\n type ExpressRequestHandler,\n} from \"./express-integration\";\n\nexport type NestMiddleware = ExpressRequestHandler;\n\nexport function nestMiddlewareIntegration(\n logger: LoggerLike,\n options: ExpressIntegrationOptions = {},\n): NestMiddleware {\n return expressIntegration(logger, {\n name: \"nestjs\",\n ...options,\n });\n}\n"],"mappings":"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"}