@loggerjs/node 0.5.6 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -26
- package/dist/bullmq-integration.cjs +2 -145
- package/dist/bullmq-integration.cjs.map +1 -1
- package/dist/bullmq-integration.js +1 -144
- package/dist/bullmq-integration.js.map +1 -1
- package/dist/chunks/node-destination-DvP8jBvm.cjs +254 -0
- package/dist/chunks/node-destination-DvP8jBvm.cjs.map +1 -0
- package/dist/chunks/node-destination-YnpYbctz.js +243 -0
- package/dist/chunks/node-destination-YnpYbctz.js.map +1 -0
- package/dist/context.cjs +1 -1
- package/dist/context.js +1 -1
- package/dist/diagnostics-channel-integration.cjs +1 -1
- package/dist/file-transport.cjs +3 -231
- package/dist/file-transport.cjs.map +1 -1
- package/dist/file-transport.js +3 -231
- package/dist/file-transport.js.map +1 -1
- package/dist/http-transport.cjs +25 -4
- package/dist/http-transport.cjs.map +1 -1
- package/dist/http-transport.d.ts +15 -0
- package/dist/http-transport.d.ts.map +1 -1
- package/dist/http-transport.js +25 -4
- package/dist/http-transport.js.map +1 -1
- package/dist/index.cjs +54 -2355
- package/dist/index.d.ts +211 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -2327
- package/dist/internal-types.d.ts +1 -0
- package/dist/internal-types.d.ts.map +1 -1
- package/dist/logger-diagnostics.cjs +4 -5
- package/dist/logger-diagnostics.cjs.map +1 -1
- package/dist/logger-diagnostics.d.ts +1 -1
- package/dist/logger-diagnostics.d.ts.map +1 -1
- package/dist/logger-diagnostics.js +1 -1
- package/dist/logger-diagnostics.js.map +1 -1
- package/dist/nest-integration.cjs +2 -127
- package/dist/nest-integration.cjs.map +1 -1
- package/dist/nest-integration.js +1 -126
- package/dist/nest-integration.js.map +1 -1
- package/dist/node-destination.d.ts.map +1 -1
- package/dist/payload-transforms.cjs +2 -2
- package/dist/payload-transforms.cjs.map +1 -1
- package/dist/payload-transforms.d.ts.map +1 -1
- package/dist/payload-transforms.js +1 -1
- package/dist/payload-transforms.js.map +1 -1
- package/dist/prisma-integration.cjs +2 -125
- package/dist/prisma-integration.cjs.map +1 -1
- package/dist/prisma-integration.js +1 -124
- package/dist/prisma-integration.js.map +1 -1
- package/dist/process-integration.cjs +20 -1
- package/dist/process-integration.cjs.map +1 -1
- package/dist/process-integration.d.ts +7 -0
- package/dist/process-integration.d.ts.map +1 -1
- package/dist/process-integration.js +20 -1
- package/dist/process-integration.js.map +1 -1
- package/dist/redis-integration.cjs +2 -125
- package/dist/redis-integration.cjs.map +1 -1
- package/dist/redis-integration.js +1 -124
- package/dist/redis-integration.js.map +1 -1
- package/dist/rotating-file-transport.cjs +24 -238
- package/dist/rotating-file-transport.cjs.map +1 -1
- package/dist/rotating-file-transport.d.ts.map +1 -1
- package/dist/rotating-file-transport.js +24 -238
- package/dist/rotating-file-transport.js.map +1 -1
- package/dist/stdout-transport.cjs +3 -162
- package/dist/stdout-transport.cjs.map +1 -1
- package/dist/stdout-transport.js +3 -162
- package/dist/stdout-transport.js.map +1 -1
- package/dist/syslog-transport.cjs +1 -1
- package/dist/syslog-transport.js +1 -1
- package/dist/worker-transport.cjs +5 -4
- package/dist/worker-transport.cjs.map +1 -1
- package/dist/worker-transport.d.ts.map +1 -1
- package/dist/worker-transport.js +3 -2
- package/dist/worker-transport.js.map +1 -1
- package/package.json +5 -2
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
package/dist/stdout-transport.js
CHANGED
|
@@ -1,167 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
const encoder = new TextEncoder();
|
|
4
|
-
const normalizeError = (error) => error instanceof Error ? error : new Error(String(error));
|
|
5
|
-
function byteLength(payload) {
|
|
6
|
-
return typeof payload === "string" ? encoder.encode(payload).byteLength : payload.byteLength;
|
|
7
|
-
}
|
|
8
|
-
function coalescePayloads(payloads) {
|
|
9
|
-
if (payloads.every((payload) => typeof payload === "string")) return payloads.join("");
|
|
10
|
-
const buffers = payloads.map((payload) => typeof payload === "string" ? Buffer.from(payload) : Buffer.from(payload));
|
|
11
|
-
return Buffer.concat(buffers);
|
|
12
|
-
}
|
|
13
|
-
function isEpipe(error) {
|
|
14
|
-
return Boolean(error) && typeof error === "object" && error.code === "EPIPE";
|
|
15
|
-
}
|
|
16
|
-
function normalizeMinLength(value) {
|
|
17
|
-
if (value === void 0 || !Number.isFinite(value) || value <= 0) return 0;
|
|
18
|
-
return Math.floor(value);
|
|
19
|
-
}
|
|
20
|
-
function createNodeStreamDestination(options) {
|
|
21
|
-
const minLength = normalizeMinLength(options.minLength);
|
|
22
|
-
const ignoreEpipe = options.ignoreEpipe ?? false;
|
|
23
|
-
const waiters = [];
|
|
24
|
-
const buffer = [];
|
|
25
|
-
const pendingPayloads = [];
|
|
26
|
-
let bufferedBytes = 0;
|
|
27
|
-
let pendingWrites = 0;
|
|
28
|
-
let pendingDrains = 0;
|
|
29
|
-
let lastError;
|
|
30
|
-
let lastContext;
|
|
31
|
-
let closed = false;
|
|
32
|
-
const reportInternalError = (error, operation) => {
|
|
33
|
-
if (ignoreEpipe && isEpipe(error)) return;
|
|
34
|
-
lastContext?.reportInternalError(error, {
|
|
35
|
-
phase: "transport",
|
|
36
|
-
transport: options.name,
|
|
37
|
-
operation
|
|
38
|
-
});
|
|
39
|
-
};
|
|
40
|
-
const settleWaitersIfIdle = () => {
|
|
41
|
-
if (pendingWrites + pendingDrains > 0) return;
|
|
42
|
-
if (waiters.length === 0) return;
|
|
43
|
-
const error = lastError;
|
|
44
|
-
lastError = void 0;
|
|
45
|
-
for (const waiter of waiters.splice(0)) if (error) waiter.reject(error);
|
|
46
|
-
else waiter.resolve();
|
|
47
|
-
};
|
|
48
|
-
const recordError = (error, operation) => {
|
|
49
|
-
if (ignoreEpipe && isEpipe(error)) {
|
|
50
|
-
closed = true;
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
lastError = normalizeError(error);
|
|
54
|
-
reportInternalError(lastError, operation);
|
|
55
|
-
};
|
|
56
|
-
const onStreamError = (error) => {
|
|
57
|
-
recordError(error, "stream-error");
|
|
58
|
-
settleWaitersIfIdle();
|
|
59
|
-
};
|
|
60
|
-
const offError = () => options.stream.off?.("error", onStreamError);
|
|
61
|
-
options.stream.on?.("error", onStreamError);
|
|
62
|
-
const waitForDrain = () => {
|
|
63
|
-
if (!options.stream.once) return;
|
|
64
|
-
pendingDrains += 1;
|
|
65
|
-
options.stream.once("drain", () => {
|
|
66
|
-
pendingDrains -= 1;
|
|
67
|
-
settleWaitersIfIdle();
|
|
68
|
-
});
|
|
69
|
-
};
|
|
70
|
-
const removePending = (payload) => {
|
|
71
|
-
const index = pendingPayloads.indexOf(payload);
|
|
72
|
-
if (index >= 0) pendingPayloads.splice(index, 1);
|
|
73
|
-
};
|
|
74
|
-
const writeNow = (payload) => {
|
|
75
|
-
if (closed) return;
|
|
76
|
-
pendingPayloads.push(payload);
|
|
77
|
-
pendingWrites += 1;
|
|
78
|
-
try {
|
|
79
|
-
if (options.stream.write(payload, (error) => {
|
|
80
|
-
removePending(payload);
|
|
81
|
-
pendingWrites -= 1;
|
|
82
|
-
if (error) recordError(error, options.reportOperation ?? "write");
|
|
83
|
-
settleWaitersIfIdle();
|
|
84
|
-
}) === false) waitForDrain();
|
|
85
|
-
} catch (error) {
|
|
86
|
-
removePending(payload);
|
|
87
|
-
pendingWrites -= 1;
|
|
88
|
-
recordError(error, options.reportOperation ?? "write");
|
|
89
|
-
settleWaitersIfIdle();
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
const flushBuffered = () => {
|
|
93
|
-
if (buffer.length === 0) return;
|
|
94
|
-
const payload = coalescePayloads(buffer.splice(0));
|
|
95
|
-
bufferedBytes = 0;
|
|
96
|
-
writeNow(payload);
|
|
97
|
-
};
|
|
98
|
-
const destination = {
|
|
99
|
-
write(payload, context) {
|
|
100
|
-
if (closed) return;
|
|
101
|
-
lastContext = context;
|
|
102
|
-
if (minLength > 0) {
|
|
103
|
-
buffer.push(payload);
|
|
104
|
-
bufferedBytes += byteLength(payload);
|
|
105
|
-
if (bufferedBytes >= minLength) flushBuffered();
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
writeNow(payload);
|
|
109
|
-
},
|
|
110
|
-
flush() {
|
|
111
|
-
flushBuffered();
|
|
112
|
-
if (pendingWrites + pendingDrains === 0) {
|
|
113
|
-
const error = lastError;
|
|
114
|
-
lastError = void 0;
|
|
115
|
-
if (error) return Promise.reject(error);
|
|
116
|
-
return Promise.resolve();
|
|
117
|
-
}
|
|
118
|
-
return new Promise((resolve, reject) => {
|
|
119
|
-
waiters.push({
|
|
120
|
-
resolve,
|
|
121
|
-
reject
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
},
|
|
125
|
-
flushSync() {
|
|
126
|
-
if (!options.syncWrite) {
|
|
127
|
-
flushBuffered();
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
for (const payload of buffer.splice(0)) options.syncWrite(payload);
|
|
131
|
-
bufferedBytes = 0;
|
|
132
|
-
for (const payload of pendingPayloads.splice(0)) options.syncWrite(payload);
|
|
133
|
-
},
|
|
134
|
-
close() {
|
|
135
|
-
return destination.flush().then(() => new Promise((resolve, reject) => {
|
|
136
|
-
if (!options.stream.end) {
|
|
137
|
-
closed = true;
|
|
138
|
-
offError();
|
|
139
|
-
resolve();
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
options.stream.end((error) => {
|
|
143
|
-
closed = true;
|
|
144
|
-
offError();
|
|
145
|
-
if (error && !(ignoreEpipe && isEpipe(error))) reject(error);
|
|
146
|
-
else resolve();
|
|
147
|
-
});
|
|
148
|
-
}), (error) => {
|
|
149
|
-
offError();
|
|
150
|
-
return Promise.reject(error);
|
|
151
|
-
});
|
|
152
|
-
},
|
|
153
|
-
closeSync() {
|
|
154
|
-
destination.flushSync();
|
|
155
|
-
closed = true;
|
|
156
|
-
offError();
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
return destination;
|
|
160
|
-
}
|
|
161
|
-
//#endregion
|
|
1
|
+
import { n as createNodeStreamDestination } from "./chunks/node-destination-YnpYbctz.js";
|
|
2
|
+
import { ndjsonEncoder, toLevelValue } from "@loggerjs/core";
|
|
162
3
|
//#region src/stdout-transport.ts
|
|
163
4
|
function stdoutTransport(options = {}) {
|
|
164
|
-
const codec = options.codec ??
|
|
5
|
+
const codec = options.codec ?? ndjsonEncoder();
|
|
165
6
|
const stream = options.stream ?? process.stdout;
|
|
166
7
|
const transportName = options.name ?? "stdout";
|
|
167
8
|
const destination = createNodeStreamDestination({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdout-transport.js","names":[],"sources":["../src/node-destination.ts","../src/stdout-transport.ts"],"sourcesContent":["import { closeSync, createWriteStream, mkdirSync, openSync, writeSync, type WriteStream } from \"fs\";\nimport { dirname } from \"path\";\nimport type { TransportContext } from \"@loggerjs/core\";\nimport type { WritableLike } from \"./internal-types\";\n\nexport interface NodeDestination {\n stream?: WriteStream;\n write: (payload: string | Uint8Array, context?: TransportContext) => void;\n flush: () => Promise<void>;\n flushSync: () => void;\n close: () => Promise<void>;\n closeSync: () => void;\n releaseSync?: () => void;\n}\n\nexport interface NodeStreamDestinationOptions {\n name: string;\n stream: WritableLike;\n minLength?: number;\n ignoreEpipe?: boolean;\n reportOperation?: string;\n syncWrite?: (payload: string | Uint8Array) => void;\n}\n\nexport interface NodeFileDestinationOptions {\n name: string;\n path: string;\n flags?: string;\n append?: boolean;\n mkdir?: boolean;\n sync?: boolean;\n minLength?: number;\n}\n\ninterface FlushWaiter {\n resolve: () => void;\n reject: (error: Error) => void;\n}\n\nconst encoder = new TextEncoder();\n\nconst normalizeError = (error: unknown): Error =>\n error instanceof Error ? error : new Error(String(error));\n\nfunction byteLength(payload: string | Uint8Array): number {\n return typeof payload === \"string\" ? encoder.encode(payload).byteLength : payload.byteLength;\n}\n\nfunction coalescePayloads(payloads: Array<string | Uint8Array>): string | Uint8Array {\n if (payloads.every((payload) => typeof payload === \"string\")) {\n return payloads.join(\"\");\n }\n const buffers = payloads.map((payload) =>\n typeof payload === \"string\" ? Buffer.from(payload) : Buffer.from(payload),\n );\n return Buffer.concat(buffers);\n}\n\nfunction isEpipe(error: unknown): boolean {\n return (\n Boolean(error) && typeof error === \"object\" && (error as { code?: unknown }).code === \"EPIPE\"\n );\n}\n\nfunction normalizeMinLength(value: number | undefined): number {\n if (value === undefined || !Number.isFinite(value) || value <= 0) return 0;\n return Math.floor(value);\n}\n\nexport function createNodeStreamDestination(\n options: NodeStreamDestinationOptions,\n): NodeDestination {\n const minLength = normalizeMinLength(options.minLength);\n const ignoreEpipe = options.ignoreEpipe ?? false;\n const waiters: FlushWaiter[] = [];\n const buffer: Array<string | Uint8Array> = [];\n const pendingPayloads: Array<string | Uint8Array> = [];\n let bufferedBytes = 0;\n let pendingWrites = 0;\n let pendingDrains = 0;\n let lastError: Error | undefined;\n let lastContext: TransportContext | undefined;\n let closed = false;\n\n const reportInternalError = (error: unknown, operation: string) => {\n if (ignoreEpipe && isEpipe(error)) return;\n lastContext?.reportInternalError(error, {\n phase: \"transport\",\n transport: options.name,\n operation,\n });\n };\n\n const settleWaitersIfIdle = () => {\n if (pendingWrites + pendingDrains > 0) return;\n if (waiters.length === 0) return;\n const error = lastError;\n lastError = undefined;\n for (const waiter of waiters.splice(0)) {\n if (error) waiter.reject(error);\n else waiter.resolve();\n }\n };\n\n const recordError = (error: unknown, operation: string) => {\n if (ignoreEpipe && isEpipe(error)) {\n closed = true;\n return;\n }\n lastError = normalizeError(error);\n reportInternalError(lastError, operation);\n };\n\n const onStreamError = (error: Error) => {\n recordError(error, \"stream-error\");\n settleWaitersIfIdle();\n };\n const offError = () => options.stream.off?.(\"error\", onStreamError);\n options.stream.on?.(\"error\", onStreamError);\n\n const waitForDrain = () => {\n if (!options.stream.once) return;\n pendingDrains += 1;\n options.stream.once(\"drain\", () => {\n pendingDrains -= 1;\n settleWaitersIfIdle();\n });\n };\n\n const removePending = (payload: string | Uint8Array) => {\n const index = pendingPayloads.indexOf(payload);\n if (index >= 0) pendingPayloads.splice(index, 1);\n };\n\n const writeNow = (payload: string | Uint8Array) => {\n if (closed) return;\n pendingPayloads.push(payload);\n pendingWrites += 1;\n try {\n const result = options.stream.write(payload, (error?: Error | null) => {\n removePending(payload);\n pendingWrites -= 1;\n if (error) recordError(error, options.reportOperation ?? \"write\");\n settleWaitersIfIdle();\n });\n if (result === false) waitForDrain();\n } catch (error) {\n removePending(payload);\n pendingWrites -= 1;\n recordError(error, options.reportOperation ?? \"write\");\n settleWaitersIfIdle();\n }\n };\n\n const flushBuffered = () => {\n if (buffer.length === 0) return;\n const payload = coalescePayloads(buffer.splice(0));\n bufferedBytes = 0;\n writeNow(payload);\n };\n\n const destination: NodeDestination = {\n write(payload, context) {\n if (closed) return;\n lastContext = context;\n if (minLength > 0) {\n buffer.push(payload);\n bufferedBytes += byteLength(payload);\n if (bufferedBytes >= minLength) flushBuffered();\n return;\n }\n writeNow(payload);\n },\n flush() {\n flushBuffered();\n if (pendingWrites + pendingDrains === 0) {\n const error = lastError;\n lastError = undefined;\n if (error) return Promise.reject(error);\n return Promise.resolve();\n }\n return new Promise<void>((resolve, reject) => {\n waiters.push({ resolve, reject });\n });\n },\n flushSync() {\n if (!options.syncWrite) {\n flushBuffered();\n return;\n }\n for (const payload of buffer.splice(0)) options.syncWrite(payload);\n bufferedBytes = 0;\n for (const payload of pendingPayloads.splice(0)) options.syncWrite(payload);\n },\n close() {\n return destination.flush().then(\n () =>\n new Promise<void>((resolve, reject) => {\n if (!options.stream.end) {\n closed = true;\n offError();\n resolve();\n return;\n }\n options.stream.end((error?: Error | null) => {\n closed = true;\n offError();\n if (error && !(ignoreEpipe && isEpipe(error))) reject(error);\n else resolve();\n });\n }),\n (error: unknown) => {\n offError();\n return Promise.reject(error);\n },\n );\n },\n closeSync() {\n destination.flushSync();\n closed = true;\n offError();\n },\n };\n return destination;\n}\n\nexport function createNodeFileDestination(options: NodeFileDestinationOptions): NodeDestination {\n const flags = options.flags ?? (options.append === false ? \"w\" : \"a\");\n if (options.mkdir) mkdirSync(dirname(options.path), { recursive: true });\n\n let fd: number | undefined;\n const getFd = () => {\n fd ??= openSync(options.path, flags);\n return fd;\n };\n const syncWrite = (payload: string | Uint8Array) => {\n if (typeof payload === \"string\") writeSync(getFd(), payload);\n else writeSync(getFd(), payload);\n };\n\n if (options.sync) {\n let closed = false;\n const releaseSync = () => {\n if (fd !== undefined) {\n closeSync(fd);\n fd = undefined;\n }\n };\n return {\n write(payload) {\n if (closed) return;\n syncWrite(payload);\n },\n flush() {\n return Promise.resolve();\n },\n flushSync() {},\n close() {\n releaseSync();\n closed = true;\n return Promise.resolve();\n },\n closeSync() {\n releaseSync();\n closed = true;\n },\n releaseSync,\n };\n }\n\n const stream = createWriteStream(options.path, { flags });\n const destination = createNodeStreamDestination({\n name: options.name,\n stream,\n minLength: options.minLength,\n syncWrite,\n });\n const releaseSync = () => {\n if (fd !== undefined) {\n closeSync(fd);\n fd = undefined;\n }\n };\n return {\n ...destination,\n stream,\n close() {\n return destination.close().finally(releaseSync);\n },\n closeSync() {\n destination.closeSync();\n releaseSync();\n },\n releaseSync,\n };\n}\n","import {\n ndjsonCodec,\n toLevelValue,\n type Codec,\n type LogEvent,\n type LoggerLevel,\n type Transport,\n} from \"@loggerjs/core\";\nimport type { WritableLike } from \"./internal-types\";\nimport { createNodeStreamDestination } from \"./node-destination\";\n\nexport interface StdoutTransportOptions {\n name?: string;\n stream?: WritableLike;\n codec?: Codec<string | Uint8Array>;\n minLevel?: LoggerLevel;\n minLength?: number;\n ignoreEpipe?: boolean;\n}\n\nexport function stdoutTransport(options: StdoutTransportOptions = {}): Transport {\n const codec = options.codec ?? ndjsonCodec();\n const stream = options.stream ?? process.stdout;\n const transportName = options.name ?? \"stdout\";\n const destination = createNodeStreamDestination({\n name: transportName,\n stream,\n minLength: options.minLength,\n ignoreEpipe: options.ignoreEpipe ?? true,\n });\n\n return {\n name: transportName,\n minLevel: options.minLevel,\n log(event: LogEvent, context) {\n if (options.minLevel !== undefined && event.level < toLevelValue(options.minLevel)) return;\n destination.write(codec.encode(event), context);\n },\n flush: destination.flush,\n flushSync: destination.flushSync,\n close: destination.close,\n };\n}\n\nexport function stderrTransport(options: Omit<StdoutTransportOptions, \"stream\"> = {}): Transport {\n return stdoutTransport({ ...options, name: options.name ?? \"stderr\", stream: process.stderr });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stdout-transport.js","names":[],"sources":["../src/stdout-transport.ts"],"sourcesContent":["import {\n ndjsonEncoder,\n toLevelValue,\n type Codec,\n type LogEvent,\n type LoggerLevel,\n type Transport,\n} from \"@loggerjs/core\";\nimport type { WritableLike } from \"./internal-types\";\nimport { createNodeStreamDestination } from \"./node-destination\";\n\nexport interface StdoutTransportOptions {\n name?: string;\n stream?: WritableLike;\n codec?: Codec<string | Uint8Array>;\n minLevel?: LoggerLevel;\n minLength?: number;\n ignoreEpipe?: boolean;\n}\n\nexport function stdoutTransport(options: StdoutTransportOptions = {}): Transport {\n const codec = options.codec ?? ndjsonEncoder();\n const stream = options.stream ?? process.stdout;\n const transportName = options.name ?? \"stdout\";\n const destination = createNodeStreamDestination({\n name: transportName,\n stream,\n minLength: options.minLength,\n ignoreEpipe: options.ignoreEpipe ?? true,\n });\n\n return {\n name: transportName,\n minLevel: options.minLevel,\n log(event: LogEvent, context) {\n if (options.minLevel !== undefined && event.level < toLevelValue(options.minLevel)) return;\n destination.write(codec.encode(event), context);\n },\n flush: destination.flush,\n flushSync: destination.flushSync,\n close: destination.close,\n };\n}\n\nexport function stderrTransport(options: Omit<StdoutTransportOptions, \"stream\"> = {}): Transport {\n return stdoutTransport({ ...options, name: options.name ?? \"stderr\", stream: process.stderr });\n}\n"],"mappings":";;;AAoBA,SAAgB,gBAAgB,UAAkC,CAAC,GAAc;CAC/E,MAAM,QAAQ,QAAQ,SAAS,cAAc;CAC7C,MAAM,SAAS,QAAQ,UAAU,QAAQ;CACzC,MAAM,gBAAgB,QAAQ,QAAQ;CACtC,MAAM,cAAc,4BAA4B;EAC9C,MAAM;EACN;EACA,WAAW,QAAQ;EACnB,aAAa,QAAQ,eAAe;CACtC,CAAC;CAED,OAAO;EACL,MAAM;EACN,UAAU,QAAQ;EAClB,IAAI,OAAiB,SAAS;GAC5B,IAAI,QAAQ,aAAa,KAAA,KAAa,MAAM,QAAQ,aAAa,QAAQ,QAAQ,GAAG;GACpF,YAAY,MAAM,MAAM,OAAO,KAAK,GAAG,OAAO;EAChD;EACA,OAAO,YAAY;EACnB,WAAW,YAAY;EACvB,OAAO,YAAY;CACrB;AACF;AAEA,SAAgB,gBAAgB,UAAkD,CAAC,GAAc;CAC/F,OAAO,gBAAgB;EAAE,GAAG;EAAS,MAAM,QAAQ,QAAQ;EAAU,QAAQ,QAAQ;CAAO,CAAC;AAC/F"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let _loggerjs_core = require("@loggerjs/core");
|
|
2
3
|
let dgram = require("dgram");
|
|
3
4
|
let net = require("net");
|
|
4
5
|
let os = require("os");
|
|
5
|
-
let _loggerjs_core = require("@loggerjs/core");
|
|
6
6
|
//#region src/syslog-transport.ts
|
|
7
7
|
const severityByLevel = {
|
|
8
8
|
trace: 7,
|
package/dist/syslog-transport.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { safeJsonStringify } from "@loggerjs/core";
|
|
1
2
|
import { createSocket } from "dgram";
|
|
2
3
|
import { createConnection } from "net";
|
|
3
4
|
import { hostname } from "os";
|
|
4
|
-
import { safeJsonStringify } from "@loggerjs/core";
|
|
5
5
|
//#region src/syslog-transport.ts
|
|
6
6
|
const severityByLevel = {
|
|
7
7
|
trace: 7,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
let node_worker_threads = require("node:worker_threads");
|
|
3
2
|
let _loggerjs_core = require("@loggerjs/core");
|
|
3
|
+
let node_worker_threads = require("node:worker_threads");
|
|
4
|
+
let _loggerjs_core_diagnostics = require("@loggerjs/core/diagnostics");
|
|
4
5
|
//#region src/worker-transport.ts
|
|
5
6
|
function createDefaultWorker(options) {
|
|
6
7
|
if (!options.workerScript) throw new Error("workerTransport requires worker, workerFactory, or workerScript.");
|
|
@@ -46,7 +47,7 @@ function dropBatch(events, reason) {
|
|
|
46
47
|
(0, _loggerjs_core.incrementLoggerMetaCounter)(`transport.dropped.${reason}`, events.length);
|
|
47
48
|
}
|
|
48
49
|
function workerTransport(options = {}) {
|
|
49
|
-
const codec = options.codec ?? (0, _loggerjs_core.
|
|
50
|
+
const codec = options.codec ?? (0, _loggerjs_core.safeJsonEncoder)();
|
|
50
51
|
const transportName = options.name ?? "worker";
|
|
51
52
|
const fallback = options.fallback;
|
|
52
53
|
const readyTimeoutMs = normalizePositiveTimeout(options.readyTimeoutMs);
|
|
@@ -82,7 +83,7 @@ function workerTransport(options = {}) {
|
|
|
82
83
|
failedError = error instanceof Error ? error : new Error(String(error));
|
|
83
84
|
setReadyGauge(0);
|
|
84
85
|
(0, _loggerjs_core.incrementLoggerMetaCounter)("transport.worker.failed");
|
|
85
|
-
(0,
|
|
86
|
+
(0, _loggerjs_core_diagnostics.emitLoggerDiagnostic)({
|
|
86
87
|
stage: "worker",
|
|
87
88
|
phase: "error",
|
|
88
89
|
transport: transportName,
|
|
@@ -103,7 +104,7 @@ function workerTransport(options = {}) {
|
|
|
103
104
|
if (message.type === "loggerjs:ready") {
|
|
104
105
|
ready = true;
|
|
105
106
|
setReadyGauge(1);
|
|
106
|
-
(0,
|
|
107
|
+
(0, _loggerjs_core_diagnostics.emitLoggerDiagnostic)({
|
|
107
108
|
stage: "worker",
|
|
108
109
|
phase: "end",
|
|
109
110
|
transport: transportName,
|
|
@@ -1 +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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"}
|
|
1
|
+
{"version":3,"file":"worker-transport.cjs","names":["Worker"],"sources":["../src/worker-transport.ts"],"sourcesContent":["import { Worker } from \"node:worker_threads\";\nimport {\n incrementLoggerMetaCounter,\n safeJsonEncoder,\n setLoggerMetaGauge,\n toLevelValue,\n type Codec,\n type LogEvent,\n type LoggerLevel,\n type Transport,\n type TransportContext,\n} from \"@loggerjs/core\";\nimport { emitLoggerDiagnostic } from \"@loggerjs/core/diagnostics\";\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 ?? safeJsonEncoder();\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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-transport.d.ts","sourceRoot":"","sources":["../src/worker-transport.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"worker-transport.d.ts","sourceRoot":"","sources":["../src/worker-transport.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,KAAK,EAEV,KAAK,WAAW,EAChB,KAAK,SAAS,EAEf,MAAM,gBAAgB,CAAC;AAGxB,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,CAAC,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC;IACpE,SAAS,CAAC,EAAE,MAAM,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,KAAK,OAAO,CAAC;IAC9F,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,KAAK,OAAO,CAAC;CAChG;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,gBAAgB,CAAC;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,MAAM,8BAA8B,GACtC;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B;IAAE,IAAI,EAAE,oBAAoB,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAElE,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,UAAU,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;IACnC,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA8DD,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,SAAS,CAyQ/E"}
|
package/dist/worker-transport.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { incrementLoggerMetaCounter, safeJsonEncoder, setLoggerMetaGauge, toLevelValue } from "@loggerjs/core";
|
|
1
2
|
import { Worker } from "node:worker_threads";
|
|
2
|
-
import { emitLoggerDiagnostic
|
|
3
|
+
import { emitLoggerDiagnostic } from "@loggerjs/core/diagnostics";
|
|
3
4
|
//#region src/worker-transport.ts
|
|
4
5
|
function createDefaultWorker(options) {
|
|
5
6
|
if (!options.workerScript) throw new Error("workerTransport requires worker, workerFactory, or workerScript.");
|
|
@@ -45,7 +46,7 @@ function dropBatch(events, reason) {
|
|
|
45
46
|
incrementLoggerMetaCounter(`transport.dropped.${reason}`, events.length);
|
|
46
47
|
}
|
|
47
48
|
function workerTransport(options = {}) {
|
|
48
|
-
const codec = options.codec ??
|
|
49
|
+
const codec = options.codec ?? safeJsonEncoder();
|
|
49
50
|
const transportName = options.name ?? "worker";
|
|
50
51
|
const fallback = options.fallback;
|
|
51
52
|
const readyTimeoutMs = normalizePositiveTimeout(options.readyTimeoutMs);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-transport.js","names":[],"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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"}
|
|
1
|
+
{"version":3,"file":"worker-transport.js","names":[],"sources":["../src/worker-transport.ts"],"sourcesContent":["import { Worker } from \"node:worker_threads\";\nimport {\n incrementLoggerMetaCounter,\n safeJsonEncoder,\n setLoggerMetaGauge,\n toLevelValue,\n type Codec,\n type LogEvent,\n type LoggerLevel,\n type Transport,\n type TransportContext,\n} from \"@loggerjs/core\";\nimport { emitLoggerDiagnostic } from \"@loggerjs/core/diagnostics\";\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 ?? safeJsonEncoder();\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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loggerjs/node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Node.js transports and integrations for loggerjs.",
|
|
5
5
|
"homepage": "https://github.com/jskits/loggerjs/tree/main/packages/node#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -159,7 +159,10 @@
|
|
|
159
159
|
"provenance": true
|
|
160
160
|
},
|
|
161
161
|
"dependencies": {
|
|
162
|
-
"@loggerjs/core": "0.
|
|
162
|
+
"@loggerjs/core": "^0.7.0"
|
|
163
|
+
},
|
|
164
|
+
"engines": {
|
|
165
|
+
"node": ">=20.19.0"
|
|
163
166
|
},
|
|
164
167
|
"loggerjsSubpathEntries": {
|
|
165
168
|
"http-transport": "src/http-transport.ts",
|