@loggerjs/node 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/bullmq-integration.cjs +169 -0
- package/dist/bullmq-integration.cjs.map +1 -0
- package/dist/bullmq-integration.js +168 -0
- package/dist/bullmq-integration.js.map +1 -0
- package/dist/cli-integration.cjs +116 -0
- package/dist/cli-integration.cjs.map +1 -0
- package/dist/cli-integration.js +115 -0
- package/dist/cli-integration.js.map +1 -0
- package/dist/context.cjs +37 -0
- package/dist/context.cjs.map +1 -0
- package/dist/context.js +35 -0
- package/dist/context.js.map +1 -0
- package/dist/database-integration.cjs +128 -0
- package/dist/database-integration.cjs.map +1 -0
- package/dist/database-integration.js +127 -0
- package/dist/database-integration.js.map +1 -0
- package/dist/diagnostics-channel-integration.cjs +66 -0
- package/dist/diagnostics-channel-integration.cjs.map +1 -0
- package/dist/diagnostics-channel-integration.js +65 -0
- package/dist/diagnostics-channel-integration.js.map +1 -0
- package/dist/express-integration.cjs +130 -0
- package/dist/express-integration.cjs.map +1 -0
- package/dist/express-integration.js +129 -0
- package/dist/express-integration.js.map +1 -0
- package/dist/fastify-integration.cjs +120 -0
- package/dist/fastify-integration.cjs.map +1 -0
- package/dist/fastify-integration.js +119 -0
- package/dist/fastify-integration.js.map +1 -0
- package/dist/file-transport.cjs +260 -0
- package/dist/file-transport.cjs.map +1 -0
- package/dist/file-transport.js +259 -0
- package/dist/file-transport.js.map +1 -0
- package/dist/hapi-integration.cjs +61 -0
- package/dist/hapi-integration.cjs.map +1 -0
- package/dist/hapi-integration.js +60 -0
- package/dist/hapi-integration.js.map +1 -0
- package/dist/http-transport.cjs +55 -0
- package/dist/http-transport.cjs.map +1 -0
- package/dist/http-transport.js +54 -0
- package/dist/http-transport.js.map +1 -0
- package/dist/koa-integration.cjs +57 -0
- package/dist/koa-integration.cjs.map +1 -0
- package/dist/koa-integration.js +56 -0
- package/dist/koa-integration.js.map +1 -0
- package/dist/logger-diagnostics.cjs +46 -0
- package/dist/logger-diagnostics.cjs.map +1 -0
- package/dist/logger-diagnostics.js +45 -0
- package/dist/logger-diagnostics.js.map +1 -0
- package/dist/nest-integration.cjs +138 -0
- package/dist/nest-integration.cjs.map +1 -0
- package/dist/nest-integration.js +137 -0
- package/dist/nest-integration.js.map +1 -0
- package/dist/node-fetch-integration.cjs +113 -0
- package/dist/node-fetch-integration.cjs.map +1 -0
- package/dist/node-fetch-integration.js +112 -0
- package/dist/node-fetch-integration.js.map +1 -0
- package/dist/node-http-client-integration.cjs +192 -0
- package/dist/node-http-client-integration.cjs.map +1 -0
- package/dist/node-http-client-integration.js +192 -0
- package/dist/node-http-client-integration.js.map +1 -0
- package/dist/payload-transforms.cjs +29 -0
- package/dist/payload-transforms.cjs.map +1 -0
- package/dist/payload-transforms.js +28 -0
- package/dist/payload-transforms.js.map +1 -0
- package/dist/prisma-integration.cjs +150 -0
- package/dist/prisma-integration.cjs.map +1 -0
- package/dist/prisma-integration.js +149 -0
- package/dist/prisma-integration.js.map +1 -0
- package/dist/process-integration.cjs +134 -0
- package/dist/process-integration.cjs.map +1 -0
- package/dist/process-integration.js +133 -0
- package/dist/process-integration.js.map +1 -0
- package/dist/queue-integration.cjs +148 -0
- package/dist/queue-integration.cjs.map +1 -0
- package/dist/queue-integration.js +147 -0
- package/dist/queue-integration.js.map +1 -0
- package/dist/redis-integration.cjs +154 -0
- package/dist/redis-integration.cjs.map +1 -0
- package/dist/redis-integration.js +153 -0
- package/dist/redis-integration.js.map +1 -0
- package/dist/rotating-file-transport.cjs +318 -0
- package/dist/rotating-file-transport.cjs.map +1 -0
- package/dist/rotating-file-transport.js +317 -0
- package/dist/rotating-file-transport.js.map +1 -0
- package/dist/serverless-integration.cjs +104 -0
- package/dist/serverless-integration.cjs.map +1 -0
- package/dist/serverless-integration.js +103 -0
- package/dist/serverless-integration.js.map +1 -0
- package/dist/stdout-transport.cjs +197 -0
- package/dist/stdout-transport.cjs.map +1 -0
- package/dist/stdout-transport.js +195 -0
- package/dist/stdout-transport.js.map +1 -0
- package/dist/syslog-transport.cjs +135 -0
- package/dist/syslog-transport.cjs.map +1 -0
- package/dist/syslog-transport.js +133 -0
- package/dist/syslog-transport.js.map +1 -0
- package/dist/worker-transport.cjs +285 -0
- package/dist/worker-transport.cjs.map +1 -0
- package/dist/worker-transport.js +284 -0
- package/dist/worker-transport.js.map +1 -0
- package/package.json +104 -77
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { createSocket } from "dgram";
|
|
2
|
+
import { createConnection } from "net";
|
|
3
|
+
import { hostname } from "os";
|
|
4
|
+
import { safeJsonStringify } from "@loggerjs/core";
|
|
5
|
+
//#region src/syslog-transport.ts
|
|
6
|
+
const severityByLevel = {
|
|
7
|
+
trace: 7,
|
|
8
|
+
debug: 7,
|
|
9
|
+
info: 6,
|
|
10
|
+
warn: 4,
|
|
11
|
+
error: 3,
|
|
12
|
+
fatal: 2
|
|
13
|
+
};
|
|
14
|
+
function defaultUdpSocketFactory(protocol) {
|
|
15
|
+
return createSocket(protocol);
|
|
16
|
+
}
|
|
17
|
+
function defaultTcpSocketFactory(options) {
|
|
18
|
+
return createConnection(options);
|
|
19
|
+
}
|
|
20
|
+
function headerValue(value, fallback, maxLength) {
|
|
21
|
+
const text = String(value ?? fallback).trim().replace(/\s+/g, "_");
|
|
22
|
+
if (!text) return fallback;
|
|
23
|
+
return text.length > maxLength ? text.slice(0, maxLength) : text;
|
|
24
|
+
}
|
|
25
|
+
function timestamp(time) {
|
|
26
|
+
const value = new Date(time).toISOString();
|
|
27
|
+
return value === "Invalid Date" ? "-" : value;
|
|
28
|
+
}
|
|
29
|
+
function valueFor(value, event, fallback) {
|
|
30
|
+
return typeof value === "function" ? value(event) : value ?? fallback;
|
|
31
|
+
}
|
|
32
|
+
function defaultMessage(event) {
|
|
33
|
+
const extra = {};
|
|
34
|
+
if (event.data !== void 0) extra.data = event.data;
|
|
35
|
+
if (event.context !== void 0) extra.context = event.context;
|
|
36
|
+
if (event.error !== void 0) extra.error = event.error;
|
|
37
|
+
if (Object.keys(extra).length === 0) return event.message;
|
|
38
|
+
return `${event.message} ${safeJsonStringify(extra)}`;
|
|
39
|
+
}
|
|
40
|
+
function formatSyslogMessage(event, options = {}) {
|
|
41
|
+
const facility = Math.max(0, Math.min(23, Math.trunc(options.facility ?? 1)));
|
|
42
|
+
const severity = severityByLevel[event.levelName] ?? 6;
|
|
43
|
+
const priority = facility * 8 + severity;
|
|
44
|
+
const host = headerValue(options.hostname, hostname(), 255);
|
|
45
|
+
const appName = headerValue(valueFor(options.appName, event, event.logger), "-", 48);
|
|
46
|
+
const procId = headerValue(valueFor(options.procId, event, "-"), "-", 128);
|
|
47
|
+
const msgId = headerValue(valueFor(options.msgId, event, event.type ?? event.levelName), "-", 32);
|
|
48
|
+
const structuredData = valueFor(options.structuredData, event, "-") || "-";
|
|
49
|
+
const message = options.formatMessage ? options.formatMessage(event) : defaultMessage(event);
|
|
50
|
+
return `<${priority}>1 ${timestamp(event.time)} ${host} ${appName} ${procId} ${msgId} ${structuredData} ${message}`;
|
|
51
|
+
}
|
|
52
|
+
function nodeSyslogTransport(options = {}) {
|
|
53
|
+
const protocol = options.protocol ?? "udp4";
|
|
54
|
+
const host = options.host ?? "127.0.0.1";
|
|
55
|
+
const port = options.port ?? 514;
|
|
56
|
+
const transportName = options.name ?? "syslog";
|
|
57
|
+
const unref = options.unref ?? true;
|
|
58
|
+
const tcpFraming = options.tcpFraming ?? "newline";
|
|
59
|
+
const udpSocketFactory = options.udpSocketFactory ?? defaultUdpSocketFactory;
|
|
60
|
+
const tcpSocketFactory = options.tcpSocketFactory ?? defaultTcpSocketFactory;
|
|
61
|
+
let udpSocket;
|
|
62
|
+
let tcpSocket;
|
|
63
|
+
let lastContext;
|
|
64
|
+
const reportError = (error, context, operation) => {
|
|
65
|
+
try {
|
|
66
|
+
options.onError?.(error, { operation });
|
|
67
|
+
} catch (onErrorError) {
|
|
68
|
+
context?.reportInternalError(onErrorError, {
|
|
69
|
+
operation: "on-error",
|
|
70
|
+
phase: "transport",
|
|
71
|
+
transport: transportName
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
context?.reportInternalError(error, {
|
|
75
|
+
operation,
|
|
76
|
+
phase: "transport",
|
|
77
|
+
transport: transportName
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
const getUdpSocket = (context) => {
|
|
81
|
+
if (udpSocket) return udpSocket;
|
|
82
|
+
const socket = udpSocketFactory(protocol === "udp6" ? "udp6" : "udp4");
|
|
83
|
+
socket.on?.("error", (error) => reportError(error, lastContext ?? context, "socket-error"));
|
|
84
|
+
if (unref) socket.unref?.();
|
|
85
|
+
udpSocket = socket;
|
|
86
|
+
return socket;
|
|
87
|
+
};
|
|
88
|
+
const getTcpSocket = (context) => {
|
|
89
|
+
if (tcpSocket) return tcpSocket;
|
|
90
|
+
const socket = tcpSocketFactory({
|
|
91
|
+
host,
|
|
92
|
+
port
|
|
93
|
+
});
|
|
94
|
+
socket.on?.("error", (error) => reportError(error, lastContext ?? context, "socket-error"));
|
|
95
|
+
if (unref) socket.unref?.();
|
|
96
|
+
tcpSocket = socket;
|
|
97
|
+
return socket;
|
|
98
|
+
};
|
|
99
|
+
const send = (message, context) => {
|
|
100
|
+
lastContext = context;
|
|
101
|
+
if (protocol === "tcp") {
|
|
102
|
+
const bytes = new TextEncoder().encode(message).byteLength;
|
|
103
|
+
const payload = tcpFraming === "octet-counting" ? `${bytes} ${message}` : `${message}\n`;
|
|
104
|
+
getTcpSocket(context).write(payload, (error) => {
|
|
105
|
+
if (error) reportError(error, context, "send");
|
|
106
|
+
});
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
getUdpSocket(context).send(message, port, host, (error) => {
|
|
110
|
+
if (error) reportError(error, context, "send");
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
return {
|
|
114
|
+
name: transportName,
|
|
115
|
+
minLevel: options.minLevel,
|
|
116
|
+
log(event, context) {
|
|
117
|
+
send(formatSyslogMessage(event, options), context);
|
|
118
|
+
},
|
|
119
|
+
logBatch(events, context) {
|
|
120
|
+
for (const event of events) send(formatSyslogMessage(event, options), context);
|
|
121
|
+
},
|
|
122
|
+
async close() {
|
|
123
|
+
udpSocket?.close?.();
|
|
124
|
+
udpSocket = void 0;
|
|
125
|
+
tcpSocket?.end?.();
|
|
126
|
+
tcpSocket = void 0;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
//#endregion
|
|
131
|
+
export { formatSyslogMessage, nodeSyslogTransport };
|
|
132
|
+
|
|
133
|
+
//# sourceMappingURL=syslog-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syslog-transport.js","names":["getHostname"],"sources":["../src/syslog-transport.ts"],"sourcesContent":["import { createSocket } from \"dgram\";\nimport { createConnection } from \"net\";\nimport { hostname as getHostname } from \"os\";\nimport {\n safeJsonStringify,\n type LogEvent,\n type LoggerLevel,\n type Transport,\n type TransportContext,\n} from \"@loggerjs/core\";\n\nexport type NodeSyslogProtocol = \"tcp\" | \"udp4\" | \"udp6\";\nexport type NodeSyslogTcpFraming = \"newline\" | \"octet-counting\";\n\nexport interface NodeSyslogUdpSocket {\n send: (\n message: string | Uint8Array,\n port: number,\n host: string,\n callback?: (error: Error | null | undefined) => void,\n ) => void;\n close?: () => void;\n on?: (event: \"error\", listener: (error: Error) => void) => void;\n unref?: () => void;\n}\n\nexport interface NodeSyslogTcpSocket {\n write: (message: string | Uint8Array, callback?: (error?: Error | null) => void) => boolean;\n end?: () => void;\n destroy?: () => void;\n on?: (event: \"error\", listener: (error: Error) => void) => void;\n unref?: () => void;\n}\n\nexport type NodeSyslogUdpSocketFactory = (protocol: \"udp4\" | \"udp6\") => NodeSyslogUdpSocket;\nexport type NodeSyslogTcpSocketFactory = (options: {\n host: string;\n port: number;\n}) => NodeSyslogTcpSocket;\n\nexport interface NodeSyslogFormatOptions {\n facility?: number;\n hostname?: string;\n appName?: string | ((event: LogEvent) => string);\n procId?: string | number | ((event: LogEvent) => string | number);\n msgId?: string | ((event: LogEvent) => string);\n structuredData?: string | ((event: LogEvent) => string);\n formatMessage?: (event: LogEvent) => string;\n}\n\nexport interface NodeSyslogTransportOptions extends NodeSyslogFormatOptions {\n name?: string;\n minLevel?: LoggerLevel;\n protocol?: NodeSyslogProtocol;\n host?: string;\n port?: number;\n tcpFraming?: NodeSyslogTcpFraming;\n unref?: boolean;\n udpSocketFactory?: NodeSyslogUdpSocketFactory;\n tcpSocketFactory?: NodeSyslogTcpSocketFactory;\n onError?: (error: unknown, detail: { operation: string }) => void;\n}\n\nconst severityByLevel: Record<string, number> = {\n trace: 7,\n debug: 7,\n info: 6,\n warn: 4,\n error: 3,\n fatal: 2,\n};\n\nfunction defaultUdpSocketFactory(protocol: \"udp4\" | \"udp6\") {\n return createSocket(protocol);\n}\n\nfunction defaultTcpSocketFactory(options: { host: string; port: number }) {\n return createConnection(options);\n}\n\nfunction headerValue(value: unknown, fallback: string, maxLength: number) {\n const text = String(value ?? fallback)\n .trim()\n .replace(/\\s+/g, \"_\");\n if (!text) return fallback;\n return text.length > maxLength ? text.slice(0, maxLength) : text;\n}\n\nfunction timestamp(time: number) {\n const value = new Date(time).toISOString();\n return value === \"Invalid Date\" ? \"-\" : value;\n}\n\nfunction valueFor<T>(\n value: T | ((event: LogEvent) => T) | undefined,\n event: LogEvent,\n fallback: T,\n) {\n return typeof value === \"function\"\n ? (value as (event: LogEvent) => T)(event)\n : (value ?? fallback);\n}\n\nfunction defaultMessage(event: LogEvent) {\n const extra: Record<string, unknown> = {};\n if (event.data !== undefined) extra.data = event.data;\n if (event.context !== undefined) extra.context = event.context;\n if (event.error !== undefined) extra.error = event.error;\n if (Object.keys(extra).length === 0) return event.message;\n return `${event.message} ${safeJsonStringify(extra)}`;\n}\n\nexport function formatSyslogMessage(\n event: LogEvent,\n options: NodeSyslogFormatOptions = {},\n): string {\n const facility = Math.max(0, Math.min(23, Math.trunc(options.facility ?? 1)));\n const severity = severityByLevel[event.levelName] ?? 6;\n const priority = facility * 8 + severity;\n const host = headerValue(options.hostname, getHostname(), 255);\n const appName = headerValue(valueFor(options.appName, event, event.logger), \"-\", 48);\n const procId = headerValue(valueFor(options.procId, event, \"-\"), \"-\", 128);\n const msgId = headerValue(valueFor(options.msgId, event, event.type ?? event.levelName), \"-\", 32);\n const structuredData = valueFor(options.structuredData, event, \"-\") || \"-\";\n const message = options.formatMessage ? options.formatMessage(event) : defaultMessage(event);\n\n return `<${priority}>1 ${timestamp(event.time)} ${host} ${appName} ${procId} ${msgId} ${structuredData} ${message}`;\n}\n\nexport function nodeSyslogTransport(options: NodeSyslogTransportOptions = {}): Transport {\n const protocol = options.protocol ?? \"udp4\";\n const host = options.host ?? \"127.0.0.1\";\n const port = options.port ?? 514;\n const transportName = options.name ?? \"syslog\";\n const unref = options.unref ?? true;\n const tcpFraming = options.tcpFraming ?? \"newline\";\n const udpSocketFactory = options.udpSocketFactory ?? defaultUdpSocketFactory;\n const tcpSocketFactory = options.tcpSocketFactory ?? defaultTcpSocketFactory;\n let udpSocket: NodeSyslogUdpSocket | undefined;\n let tcpSocket: NodeSyslogTcpSocket | undefined;\n let lastContext: TransportContext | undefined;\n\n const reportError = (\n error: unknown,\n context: TransportContext | undefined,\n operation: string,\n ) => {\n try {\n options.onError?.(error, { operation });\n } catch (onErrorError) {\n context?.reportInternalError(onErrorError, {\n operation: \"on-error\",\n phase: \"transport\",\n transport: transportName,\n });\n }\n\n context?.reportInternalError(error, {\n operation,\n phase: \"transport\",\n transport: transportName,\n });\n };\n\n const getUdpSocket = (context: TransportContext) => {\n if (udpSocket) return udpSocket;\n const socket = udpSocketFactory(protocol === \"udp6\" ? \"udp6\" : \"udp4\");\n socket.on?.(\"error\", (error) => reportError(error, lastContext ?? context, \"socket-error\"));\n if (unref) socket.unref?.();\n udpSocket = socket;\n return socket;\n };\n\n const getTcpSocket = (context: TransportContext) => {\n if (tcpSocket) return tcpSocket;\n const socket = tcpSocketFactory({ host, port });\n socket.on?.(\"error\", (error) => reportError(error, lastContext ?? context, \"socket-error\"));\n if (unref) socket.unref?.();\n tcpSocket = socket;\n return socket;\n };\n\n const send = (message: string, context: TransportContext) => {\n lastContext = context;\n if (protocol === \"tcp\") {\n const bytes = new TextEncoder().encode(message).byteLength;\n const payload = tcpFraming === \"octet-counting\" ? `${bytes} ${message}` : `${message}\\n`;\n const socket = getTcpSocket(context);\n socket.write(payload, (error) => {\n if (error) reportError(error, context, \"send\");\n });\n return;\n }\n\n const socket = getUdpSocket(context);\n socket.send(message, port, host, (error) => {\n if (error) reportError(error, context, \"send\");\n });\n };\n\n return {\n name: transportName,\n minLevel: options.minLevel,\n log(event, context) {\n send(formatSyslogMessage(event, options), context);\n },\n logBatch(events, context) {\n for (const event of events) send(formatSyslogMessage(event, options), context);\n },\n async close() {\n udpSocket?.close?.();\n udpSocket = undefined;\n tcpSocket?.end?.();\n tcpSocket = undefined;\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let node_worker_threads = require("node:worker_threads");
|
|
3
|
+
let _loggerjs_core = require("@loggerjs/core");
|
|
4
|
+
//#region src/worker-transport.ts
|
|
5
|
+
function createDefaultWorker(options) {
|
|
6
|
+
if (!options.workerScript) throw new Error("workerTransport requires worker, workerFactory, or workerScript.");
|
|
7
|
+
return new node_worker_threads.Worker(options.workerScript, options.workerOptions);
|
|
8
|
+
}
|
|
9
|
+
function payloadToBytes(payload) {
|
|
10
|
+
if (typeof payload !== "string") return payload;
|
|
11
|
+
return new TextEncoder().encode(payload);
|
|
12
|
+
}
|
|
13
|
+
function transferablePayload(payload) {
|
|
14
|
+
const copy = Uint8Array.from(payload);
|
|
15
|
+
return {
|
|
16
|
+
payload: copy,
|
|
17
|
+
transferList: [copy.buffer]
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function normalizePositiveTimeout(value) {
|
|
21
|
+
if (value === void 0 || !Number.isFinite(value) || value <= 0) return 0;
|
|
22
|
+
return Math.floor(value);
|
|
23
|
+
}
|
|
24
|
+
function protocolMessage(value) {
|
|
25
|
+
if (!value || typeof value !== "object") return void 0;
|
|
26
|
+
const message = value;
|
|
27
|
+
if (message.type === "loggerjs:ready") return { type: "loggerjs:ready" };
|
|
28
|
+
if (message.type === "loggerjs:batch:ack") {
|
|
29
|
+
const id = value.id;
|
|
30
|
+
if (typeof id === "number") return {
|
|
31
|
+
type: "loggerjs:batch:ack",
|
|
32
|
+
id
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (message.type === "loggerjs:error") {
|
|
36
|
+
const item = value;
|
|
37
|
+
return {
|
|
38
|
+
type: "loggerjs:error",
|
|
39
|
+
error: item.error,
|
|
40
|
+
message: typeof item.message === "string" ? item.message : void 0
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function dropBatch(events, reason) {
|
|
45
|
+
(0, _loggerjs_core.incrementLoggerMetaCounter)("transport.dropped", events.length);
|
|
46
|
+
(0, _loggerjs_core.incrementLoggerMetaCounter)(`transport.dropped.${reason}`, events.length);
|
|
47
|
+
}
|
|
48
|
+
function workerTransport(options = {}) {
|
|
49
|
+
const codec = options.codec ?? (0, _loggerjs_core.safeJsonCodec)();
|
|
50
|
+
const transportName = options.name ?? "worker";
|
|
51
|
+
const fallback = options.fallback;
|
|
52
|
+
const readyTimeoutMs = normalizePositiveTimeout(options.readyTimeoutMs);
|
|
53
|
+
const ackTimeoutMs = normalizePositiveTimeout(options.ackTimeoutMs);
|
|
54
|
+
const autoEnd = options.autoEnd ?? true;
|
|
55
|
+
let worker;
|
|
56
|
+
let failed = false;
|
|
57
|
+
let failedError;
|
|
58
|
+
let lastContext;
|
|
59
|
+
let ready = readyTimeoutMs === 0;
|
|
60
|
+
let readyPromise;
|
|
61
|
+
let readyTimer;
|
|
62
|
+
let readyResolve;
|
|
63
|
+
let readyReject;
|
|
64
|
+
let nextBatchId = 1;
|
|
65
|
+
const pendingBatches = /* @__PURE__ */ new Map();
|
|
66
|
+
const setPendingGauge = () => {
|
|
67
|
+
(0, _loggerjs_core.setLoggerMetaGauge)(`transport.queue.depth.${transportName}`, pendingBatches.size);
|
|
68
|
+
};
|
|
69
|
+
const setReadyGauge = (value) => {
|
|
70
|
+
(0, _loggerjs_core.setLoggerMetaGauge)(`transport.ready.${transportName}`, value);
|
|
71
|
+
};
|
|
72
|
+
const reportInternalError = (error, operation) => {
|
|
73
|
+
lastContext?.reportInternalError(error, {
|
|
74
|
+
phase: "transport",
|
|
75
|
+
transport: transportName,
|
|
76
|
+
operation
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
const markFailed = (error, operation) => {
|
|
80
|
+
if (failed) return;
|
|
81
|
+
failed = true;
|
|
82
|
+
failedError = error instanceof Error ? error : new Error(String(error));
|
|
83
|
+
setReadyGauge(0);
|
|
84
|
+
(0, _loggerjs_core.incrementLoggerMetaCounter)("transport.worker.failed");
|
|
85
|
+
(0, _loggerjs_core.emitLoggerDiagnostic)({
|
|
86
|
+
stage: "worker",
|
|
87
|
+
phase: "error",
|
|
88
|
+
transport: transportName,
|
|
89
|
+
operation,
|
|
90
|
+
error
|
|
91
|
+
});
|
|
92
|
+
reportInternalError(error, operation);
|
|
93
|
+
readyReject?.(failedError);
|
|
94
|
+
failPendingBatches(operation);
|
|
95
|
+
};
|
|
96
|
+
const onWorkerError = (error) => markFailed(error, "worker-error");
|
|
97
|
+
const onWorkerExit = (code) => {
|
|
98
|
+
if (typeof code === "number" && code !== 0) markFailed(code, "worker-exit");
|
|
99
|
+
};
|
|
100
|
+
const onWorkerMessage = (value) => {
|
|
101
|
+
const message = protocolMessage(value);
|
|
102
|
+
if (!message) return;
|
|
103
|
+
if (message.type === "loggerjs:ready") {
|
|
104
|
+
ready = true;
|
|
105
|
+
setReadyGauge(1);
|
|
106
|
+
(0, _loggerjs_core.emitLoggerDiagnostic)({
|
|
107
|
+
stage: "worker",
|
|
108
|
+
phase: "end",
|
|
109
|
+
transport: transportName,
|
|
110
|
+
operation: "ready"
|
|
111
|
+
});
|
|
112
|
+
if (readyTimer) clearTimeout(readyTimer);
|
|
113
|
+
readyResolve?.();
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (message.type === "loggerjs:batch:ack") {
|
|
117
|
+
const pending = pendingBatches.get(message.id);
|
|
118
|
+
if (!pending) return;
|
|
119
|
+
pendingBatches.delete(message.id);
|
|
120
|
+
setPendingGauge();
|
|
121
|
+
if (pending.timer) clearTimeout(pending.timer);
|
|
122
|
+
pending.resolve();
|
|
123
|
+
(0, _loggerjs_core.incrementLoggerMetaCounter)("transport.worker.ack");
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
markFailed(message.error ?? new Error(message.message ?? "Worker reported an error"), "worker-message");
|
|
127
|
+
};
|
|
128
|
+
const fallbackOrDropBatch = async (events, context, reason) => {
|
|
129
|
+
if (fallback) {
|
|
130
|
+
await fallbackBatch(events, context);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
dropBatch(events, reason);
|
|
134
|
+
};
|
|
135
|
+
const failPendingBatch = (pending, reason) => {
|
|
136
|
+
pendingBatches.delete(pending.id);
|
|
137
|
+
setPendingGauge();
|
|
138
|
+
if (pending.timer) clearTimeout(pending.timer);
|
|
139
|
+
(0, _loggerjs_core.incrementLoggerMetaCounter)("transport.worker.pending-dropped", pending.events.length);
|
|
140
|
+
fallbackOrDropBatch(pending.events, pending.context, reason).finally(pending.resolve);
|
|
141
|
+
};
|
|
142
|
+
function failPendingBatches(reason) {
|
|
143
|
+
for (const pending of Array.from(pendingBatches.values())) failPendingBatch(pending, reason);
|
|
144
|
+
}
|
|
145
|
+
const waitForReady = async () => {
|
|
146
|
+
if (ready) return;
|
|
147
|
+
readyPromise ??= new Promise((resolve, reject) => {
|
|
148
|
+
readyResolve = resolve;
|
|
149
|
+
readyReject = reject;
|
|
150
|
+
readyTimer = setTimeout(() => {
|
|
151
|
+
reject(/* @__PURE__ */ new Error(`workerTransport ready timeout after ${readyTimeoutMs}ms`));
|
|
152
|
+
}, readyTimeoutMs);
|
|
153
|
+
});
|
|
154
|
+
await readyPromise;
|
|
155
|
+
};
|
|
156
|
+
const getWorker = () => {
|
|
157
|
+
if (failed) return void 0;
|
|
158
|
+
if (worker) return worker;
|
|
159
|
+
try {
|
|
160
|
+
worker = options.worker ?? options.workerFactory?.() ?? createDefaultWorker(options);
|
|
161
|
+
worker.on?.("error", onWorkerError);
|
|
162
|
+
worker.on?.("exit", onWorkerExit);
|
|
163
|
+
worker.on?.("message", onWorkerMessage);
|
|
164
|
+
if (ready) setReadyGauge(1);
|
|
165
|
+
return worker;
|
|
166
|
+
} catch (error) {
|
|
167
|
+
markFailed(error, "create-worker");
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
const fallbackBatch = async (events, context) => {
|
|
172
|
+
if (fallback?.logBatch) {
|
|
173
|
+
await fallback.logBatch(events, context);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (fallback?.log) for (const event of events) await fallback.log(event, context);
|
|
177
|
+
};
|
|
178
|
+
const postBatch = async (events, context) => {
|
|
179
|
+
lastContext = context;
|
|
180
|
+
const currentWorker = getWorker();
|
|
181
|
+
if (!currentWorker) {
|
|
182
|
+
await fallbackOrDropBatch(events, context, "worker-unavailable");
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
try {
|
|
186
|
+
await waitForReady();
|
|
187
|
+
} catch (error) {
|
|
188
|
+
markFailed(error, "worker-ready-timeout");
|
|
189
|
+
await fallbackOrDropBatch(events, context, "worker-ready-timeout");
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const encoded = payloadToBytes(codec.encode(events));
|
|
193
|
+
const transferable = options.transferBuffers === false ? {
|
|
194
|
+
payload: encoded,
|
|
195
|
+
transferList: void 0
|
|
196
|
+
} : transferablePayload(encoded);
|
|
197
|
+
const message = {
|
|
198
|
+
type: "loggerjs:batch",
|
|
199
|
+
codec: codec.name,
|
|
200
|
+
contentType: codec.contentType,
|
|
201
|
+
count: events.length,
|
|
202
|
+
payload: transferable.payload
|
|
203
|
+
};
|
|
204
|
+
let pending;
|
|
205
|
+
if (ackTimeoutMs > 0) {
|
|
206
|
+
const id = nextBatchId;
|
|
207
|
+
nextBatchId += 1;
|
|
208
|
+
message.id = id;
|
|
209
|
+
pending = {
|
|
210
|
+
id,
|
|
211
|
+
events,
|
|
212
|
+
context,
|
|
213
|
+
resolve: () => {}
|
|
214
|
+
};
|
|
215
|
+
pending.timer = setTimeout(() => {
|
|
216
|
+
if (!pending) return;
|
|
217
|
+
markFailed(/* @__PURE__ */ new Error(`workerTransport ack timeout after ${ackTimeoutMs}ms`), "worker-ack-timeout");
|
|
218
|
+
}, ackTimeoutMs);
|
|
219
|
+
pendingBatches.set(id, pending);
|
|
220
|
+
setPendingGauge();
|
|
221
|
+
}
|
|
222
|
+
try {
|
|
223
|
+
currentWorker.postMessage(message, transferable.transferList);
|
|
224
|
+
} catch (error) {
|
|
225
|
+
markFailed(error, "post-message");
|
|
226
|
+
if (!pending) await fallbackOrDropBatch(events, context, "worker-post-message");
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
const transport = {
|
|
230
|
+
name: transportName,
|
|
231
|
+
minLevel: options.minLevel,
|
|
232
|
+
async ready() {
|
|
233
|
+
if (!getWorker()) {
|
|
234
|
+
if (fallback) {
|
|
235
|
+
await fallback.ready?.();
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
throw failedError ?? /* @__PURE__ */ new Error("workerTransport is unavailable");
|
|
239
|
+
}
|
|
240
|
+
try {
|
|
241
|
+
await waitForReady();
|
|
242
|
+
} catch (error) {
|
|
243
|
+
markFailed(error, "worker-ready-timeout");
|
|
244
|
+
if (fallback) {
|
|
245
|
+
await fallback.ready?.();
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
throw error;
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
log(event, context) {
|
|
252
|
+
if (options.minLevel !== void 0 && event.level < (0, _loggerjs_core.toLevelValue)(options.minLevel)) return;
|
|
253
|
+
return postBatch([event], context);
|
|
254
|
+
},
|
|
255
|
+
logBatch(events, context) {
|
|
256
|
+
return postBatch(events, context);
|
|
257
|
+
},
|
|
258
|
+
async flush() {
|
|
259
|
+
await Promise.all(Array.from(pendingBatches.values(), (pending) => new Promise((resolve) => {
|
|
260
|
+
const originalResolve = pending.resolve;
|
|
261
|
+
pending.resolve = () => {
|
|
262
|
+
originalResolve();
|
|
263
|
+
resolve();
|
|
264
|
+
};
|
|
265
|
+
})));
|
|
266
|
+
await fallback?.flush?.();
|
|
267
|
+
},
|
|
268
|
+
async close() {
|
|
269
|
+
await transport.flush?.();
|
|
270
|
+
worker?.off?.("error", onWorkerError);
|
|
271
|
+
worker?.off?.("exit", onWorkerExit);
|
|
272
|
+
worker?.off?.("message", onWorkerMessage);
|
|
273
|
+
await fallback?.close?.();
|
|
274
|
+
if (autoEnd) await worker?.terminate?.();
|
|
275
|
+
if (readyTimer) clearTimeout(readyTimer);
|
|
276
|
+
readyReject = void 0;
|
|
277
|
+
readyResolve = void 0;
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
return transport;
|
|
281
|
+
}
|
|
282
|
+
//#endregion
|
|
283
|
+
exports.workerTransport = workerTransport;
|
|
284
|
+
|
|
285
|
+
//# sourceMappingURL=worker-transport.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-transport.cjs","names":["Worker"],"sources":["../src/worker-transport.ts"],"sourcesContent":["import { Worker } from \"node:worker_threads\";\nimport {\n emitLoggerDiagnostic,\n incrementLoggerMetaCounter,\n safeJsonCodec,\n setLoggerMetaGauge,\n toLevelValue,\n type Codec,\n type LogEvent,\n type LoggerLevel,\n type Transport,\n type TransportContext,\n} from \"@loggerjs/core\";\n\nexport interface WorkerLike {\n postMessage: (value: unknown, transferList?: ArrayBuffer[]) => void;\n terminate?: () => void | number | Promise<number>;\n on?: (event: \"error\" | \"exit\" | \"message\", listener: (...args: unknown[]) => void) => unknown;\n off?: (event: \"error\" | \"exit\" | \"message\", listener: (...args: unknown[]) => void) => unknown;\n}\n\nexport interface WorkerTransportMessage {\n type: \"loggerjs:batch\";\n id?: number;\n codec: string;\n contentType: string;\n count: number;\n payload: Uint8Array;\n}\n\nexport type WorkerTransportProtocolMessage =\n | { type: \"loggerjs:ready\" }\n | { type: \"loggerjs:batch:ack\"; id: number }\n | { type: \"loggerjs:error\"; error?: unknown; message?: string };\n\nexport interface WorkerTransportOptions {\n name?: string;\n worker?: WorkerLike;\n workerFactory?: () => WorkerLike;\n workerScript?: string | URL;\n workerOptions?: object;\n fallback?: Transport;\n codec?: Codec<string | Uint8Array>;\n minLevel?: LoggerLevel;\n transferBuffers?: boolean;\n readyTimeoutMs?: number;\n ackTimeoutMs?: number;\n autoEnd?: boolean;\n}\n\ninterface PendingBatch {\n id: number;\n events: LogEvent[];\n context: TransportContext;\n timer?: ReturnType<typeof setTimeout>;\n resolve: () => void;\n}\n\nfunction createDefaultWorker(options: WorkerTransportOptions): WorkerLike {\n if (!options.workerScript) {\n throw new Error(\"workerTransport requires worker, workerFactory, or workerScript.\");\n }\n return new Worker(options.workerScript, options.workerOptions);\n}\n\nfunction payloadToBytes(payload: string | Uint8Array): Uint8Array {\n if (typeof payload !== \"string\") return payload;\n return new TextEncoder().encode(payload);\n}\n\nfunction transferablePayload(payload: Uint8Array): {\n payload: Uint8Array;\n transferList?: ArrayBuffer[];\n} {\n const copy = Uint8Array.from(payload);\n return {\n payload: copy,\n transferList: [copy.buffer],\n };\n}\n\nfunction normalizePositiveTimeout(value: number | undefined): number {\n if (value === undefined || !Number.isFinite(value) || value <= 0) return 0;\n return Math.floor(value);\n}\n\nfunction protocolMessage(value: unknown): WorkerTransportProtocolMessage | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const message = value as { type?: unknown };\n if (message.type === \"loggerjs:ready\") return { type: \"loggerjs:ready\" };\n if (message.type === \"loggerjs:batch:ack\") {\n const id = (value as { id?: unknown }).id;\n if (typeof id === \"number\") return { type: \"loggerjs:batch:ack\", id };\n }\n if (message.type === \"loggerjs:error\") {\n const item = value as { error?: unknown; message?: unknown };\n return {\n type: \"loggerjs:error\",\n error: item.error,\n message: typeof item.message === \"string\" ? item.message : undefined,\n };\n }\n return undefined;\n}\n\nfunction dropBatch(events: LogEvent[], reason: string) {\n incrementLoggerMetaCounter(\"transport.dropped\", events.length);\n incrementLoggerMetaCounter(`transport.dropped.${reason}`, events.length);\n}\n\nexport function workerTransport(options: WorkerTransportOptions = {}): Transport {\n const codec = options.codec ?? safeJsonCodec();\n const transportName = options.name ?? \"worker\";\n const fallback = options.fallback;\n const readyTimeoutMs = normalizePositiveTimeout(options.readyTimeoutMs);\n const ackTimeoutMs = normalizePositiveTimeout(options.ackTimeoutMs);\n const autoEnd = options.autoEnd ?? true;\n let worker: WorkerLike | undefined;\n let failed = false;\n let failedError: Error | undefined;\n let lastContext: TransportContext | undefined;\n let ready = readyTimeoutMs === 0;\n let readyPromise: Promise<void> | undefined;\n let readyTimer: ReturnType<typeof setTimeout> | undefined;\n let readyResolve: (() => void) | undefined;\n let readyReject: ((error: Error) => void) | undefined;\n let nextBatchId = 1;\n const pendingBatches = new Map<number, PendingBatch>();\n\n const setPendingGauge = () => {\n setLoggerMetaGauge(`transport.queue.depth.${transportName}`, pendingBatches.size);\n };\n\n const setReadyGauge = (value: number) => {\n setLoggerMetaGauge(`transport.ready.${transportName}`, value);\n };\n\n const reportInternalError = (error: unknown, operation: string) => {\n lastContext?.reportInternalError(error, {\n phase: \"transport\",\n transport: transportName,\n operation,\n });\n };\n\n const markFailed = (error: unknown, operation: string) => {\n if (failed) return;\n failed = true;\n failedError = error instanceof Error ? error : new Error(String(error));\n setReadyGauge(0);\n incrementLoggerMetaCounter(\"transport.worker.failed\");\n emitLoggerDiagnostic({\n stage: \"worker\",\n phase: \"error\",\n transport: transportName,\n operation,\n error,\n });\n reportInternalError(error, operation);\n readyReject?.(failedError);\n failPendingBatches(operation);\n };\n\n const onWorkerError = (error: unknown) => markFailed(error, \"worker-error\");\n const onWorkerExit = (code: unknown) => {\n if (typeof code === \"number\" && code !== 0) markFailed(code, \"worker-exit\");\n };\n const onWorkerMessage = (value: unknown) => {\n const message = protocolMessage(value);\n if (!message) return;\n if (message.type === \"loggerjs:ready\") {\n ready = true;\n setReadyGauge(1);\n emitLoggerDiagnostic({\n stage: \"worker\",\n phase: \"end\",\n transport: transportName,\n operation: \"ready\",\n });\n if (readyTimer) clearTimeout(readyTimer);\n readyResolve?.();\n return;\n }\n if (message.type === \"loggerjs:batch:ack\") {\n const pending = pendingBatches.get(message.id);\n if (!pending) return;\n pendingBatches.delete(message.id);\n setPendingGauge();\n if (pending.timer) clearTimeout(pending.timer);\n pending.resolve();\n incrementLoggerMetaCounter(\"transport.worker.ack\");\n return;\n }\n markFailed(\n message.error ?? new Error(message.message ?? \"Worker reported an error\"),\n \"worker-message\",\n );\n };\n\n const fallbackOrDropBatch = async (\n events: LogEvent[],\n context: TransportContext,\n reason: string,\n ) => {\n if (fallback) {\n await fallbackBatch(events, context);\n return;\n }\n dropBatch(events, reason);\n };\n\n const failPendingBatch = (pending: PendingBatch, reason: string) => {\n pendingBatches.delete(pending.id);\n setPendingGauge();\n if (pending.timer) clearTimeout(pending.timer);\n incrementLoggerMetaCounter(\"transport.worker.pending-dropped\", pending.events.length);\n void fallbackOrDropBatch(pending.events, pending.context, reason).finally(pending.resolve);\n };\n\n function failPendingBatches(reason: string) {\n for (const pending of Array.from(pendingBatches.values())) failPendingBatch(pending, reason);\n }\n\n const waitForReady = async () => {\n if (ready) return;\n readyPromise ??= new Promise<void>((resolve, reject) => {\n readyResolve = resolve;\n readyReject = reject;\n readyTimer = setTimeout(() => {\n reject(new Error(`workerTransport ready timeout after ${readyTimeoutMs}ms`));\n }, readyTimeoutMs);\n });\n await readyPromise;\n };\n\n const getWorker = (): WorkerLike | undefined => {\n if (failed) return undefined;\n if (worker) return worker;\n try {\n worker = options.worker ?? options.workerFactory?.() ?? createDefaultWorker(options);\n worker.on?.(\"error\", onWorkerError);\n worker.on?.(\"exit\", onWorkerExit);\n worker.on?.(\"message\", onWorkerMessage);\n if (ready) setReadyGauge(1);\n return worker;\n } catch (error) {\n markFailed(error, \"create-worker\");\n return undefined;\n }\n };\n\n const fallbackBatch = async (events: LogEvent[], context: TransportContext) => {\n if (fallback?.logBatch) {\n await fallback.logBatch(events, context);\n return;\n }\n if (fallback?.log) {\n for (const event of events) {\n // oxlint-disable-next-line no-await-in-loop -- Fallback should preserve log order.\n await fallback.log(event, context);\n }\n }\n };\n\n const postBatch = async (events: LogEvent[], context: TransportContext) => {\n lastContext = context;\n const currentWorker = getWorker();\n if (!currentWorker) {\n await fallbackOrDropBatch(events, context, \"worker-unavailable\");\n return;\n }\n try {\n await waitForReady();\n } catch (error) {\n markFailed(error, \"worker-ready-timeout\");\n await fallbackOrDropBatch(events, context, \"worker-ready-timeout\");\n return;\n }\n\n const encoded = payloadToBytes(codec.encode(events));\n const transferable =\n options.transferBuffers === false\n ? { payload: encoded, transferList: undefined }\n : transferablePayload(encoded);\n const message: WorkerTransportMessage = {\n type: \"loggerjs:batch\",\n codec: codec.name,\n contentType: codec.contentType,\n count: events.length,\n payload: transferable.payload,\n };\n let pending: PendingBatch | undefined;\n if (ackTimeoutMs > 0) {\n const id = nextBatchId;\n nextBatchId += 1;\n message.id = id;\n pending = { id, events, context, resolve: () => {} };\n pending.timer = setTimeout(() => {\n if (!pending) return;\n markFailed(\n new Error(`workerTransport ack timeout after ${ackTimeoutMs}ms`),\n \"worker-ack-timeout\",\n );\n }, ackTimeoutMs);\n pendingBatches.set(id, pending);\n setPendingGauge();\n }\n\n try {\n currentWorker.postMessage(message, transferable.transferList);\n } catch (error) {\n markFailed(error, \"post-message\");\n if (!pending) await fallbackOrDropBatch(events, context, \"worker-post-message\");\n }\n };\n\n const transport: Transport = {\n name: transportName,\n minLevel: options.minLevel,\n async ready() {\n const currentWorker = getWorker();\n if (!currentWorker) {\n if (fallback) {\n await fallback.ready?.();\n return;\n }\n throw failedError ?? new Error(\"workerTransport is unavailable\");\n }\n try {\n await waitForReady();\n } catch (error) {\n markFailed(error, \"worker-ready-timeout\");\n if (fallback) {\n await fallback.ready?.();\n return;\n }\n throw error;\n }\n },\n log(event, context) {\n if (options.minLevel !== undefined && event.level < toLevelValue(options.minLevel)) return;\n return postBatch([event], context);\n },\n logBatch(events, context) {\n return postBatch(events, context);\n },\n async flush() {\n await Promise.all(\n Array.from(\n pendingBatches.values(),\n (pending) =>\n new Promise<void>((resolve) => {\n const originalResolve = pending.resolve;\n pending.resolve = () => {\n originalResolve();\n resolve();\n };\n }),\n ),\n );\n await fallback?.flush?.();\n },\n async close() {\n await transport.flush?.();\n worker?.off?.(\"error\", onWorkerError);\n worker?.off?.(\"exit\", onWorkerExit);\n worker?.off?.(\"message\", onWorkerMessage);\n await fallback?.close?.();\n if (autoEnd) await worker?.terminate?.();\n if (readyTimer) clearTimeout(readyTimer);\n readyReject = undefined;\n readyResolve = undefined;\n },\n };\n return transport;\n}\n"],"mappings":"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"}
|