@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,197 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let _loggerjs_core = require("@loggerjs/core");
|
|
3
|
+
//#region src/node-destination.ts
|
|
4
|
+
const encoder = new TextEncoder();
|
|
5
|
+
const normalizeError = (error) => error instanceof Error ? error : new Error(String(error));
|
|
6
|
+
function byteLength(payload) {
|
|
7
|
+
return typeof payload === "string" ? encoder.encode(payload).byteLength : payload.byteLength;
|
|
8
|
+
}
|
|
9
|
+
function coalescePayloads(payloads) {
|
|
10
|
+
if (payloads.every((payload) => typeof payload === "string")) return payloads.join("");
|
|
11
|
+
const buffers = payloads.map((payload) => typeof payload === "string" ? Buffer.from(payload) : Buffer.from(payload));
|
|
12
|
+
return Buffer.concat(buffers);
|
|
13
|
+
}
|
|
14
|
+
function isEpipe(error) {
|
|
15
|
+
return Boolean(error) && typeof error === "object" && error.code === "EPIPE";
|
|
16
|
+
}
|
|
17
|
+
function normalizeMinLength(value) {
|
|
18
|
+
if (value === void 0 || !Number.isFinite(value) || value <= 0) return 0;
|
|
19
|
+
return Math.floor(value);
|
|
20
|
+
}
|
|
21
|
+
function createNodeStreamDestination(options) {
|
|
22
|
+
const minLength = normalizeMinLength(options.minLength);
|
|
23
|
+
const ignoreEpipe = options.ignoreEpipe ?? false;
|
|
24
|
+
const waiters = [];
|
|
25
|
+
const buffer = [];
|
|
26
|
+
const pendingPayloads = [];
|
|
27
|
+
let bufferedBytes = 0;
|
|
28
|
+
let pendingWrites = 0;
|
|
29
|
+
let pendingDrains = 0;
|
|
30
|
+
let lastError;
|
|
31
|
+
let lastContext;
|
|
32
|
+
let closed = false;
|
|
33
|
+
const reportInternalError = (error, operation) => {
|
|
34
|
+
if (ignoreEpipe && isEpipe(error)) return;
|
|
35
|
+
lastContext?.reportInternalError(error, {
|
|
36
|
+
phase: "transport",
|
|
37
|
+
transport: options.name,
|
|
38
|
+
operation
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
const settleWaitersIfIdle = () => {
|
|
42
|
+
if (pendingWrites + pendingDrains > 0) return;
|
|
43
|
+
if (waiters.length === 0) return;
|
|
44
|
+
const error = lastError;
|
|
45
|
+
lastError = void 0;
|
|
46
|
+
for (const waiter of waiters.splice(0)) if (error) waiter.reject(error);
|
|
47
|
+
else waiter.resolve();
|
|
48
|
+
};
|
|
49
|
+
const recordError = (error, operation) => {
|
|
50
|
+
if (ignoreEpipe && isEpipe(error)) {
|
|
51
|
+
closed = true;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
lastError = normalizeError(error);
|
|
55
|
+
reportInternalError(lastError, operation);
|
|
56
|
+
};
|
|
57
|
+
const onStreamError = (error) => {
|
|
58
|
+
recordError(error, "stream-error");
|
|
59
|
+
settleWaitersIfIdle();
|
|
60
|
+
};
|
|
61
|
+
const offError = () => options.stream.off?.("error", onStreamError);
|
|
62
|
+
options.stream.on?.("error", onStreamError);
|
|
63
|
+
const waitForDrain = () => {
|
|
64
|
+
if (!options.stream.once) return;
|
|
65
|
+
pendingDrains += 1;
|
|
66
|
+
options.stream.once("drain", () => {
|
|
67
|
+
pendingDrains -= 1;
|
|
68
|
+
settleWaitersIfIdle();
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
const removePending = (payload) => {
|
|
72
|
+
const index = pendingPayloads.indexOf(payload);
|
|
73
|
+
if (index >= 0) pendingPayloads.splice(index, 1);
|
|
74
|
+
};
|
|
75
|
+
const writeNow = (payload) => {
|
|
76
|
+
if (closed) return;
|
|
77
|
+
pendingPayloads.push(payload);
|
|
78
|
+
pendingWrites += 1;
|
|
79
|
+
try {
|
|
80
|
+
if (options.stream.write(payload, (error) => {
|
|
81
|
+
removePending(payload);
|
|
82
|
+
pendingWrites -= 1;
|
|
83
|
+
if (error) recordError(error, options.reportOperation ?? "write");
|
|
84
|
+
settleWaitersIfIdle();
|
|
85
|
+
}) === false) waitForDrain();
|
|
86
|
+
} catch (error) {
|
|
87
|
+
removePending(payload);
|
|
88
|
+
pendingWrites -= 1;
|
|
89
|
+
recordError(error, options.reportOperation ?? "write");
|
|
90
|
+
settleWaitersIfIdle();
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
const flushBuffered = () => {
|
|
94
|
+
if (buffer.length === 0) return;
|
|
95
|
+
const payload = coalescePayloads(buffer.splice(0));
|
|
96
|
+
bufferedBytes = 0;
|
|
97
|
+
writeNow(payload);
|
|
98
|
+
};
|
|
99
|
+
const destination = {
|
|
100
|
+
write(payload, context) {
|
|
101
|
+
if (closed) return;
|
|
102
|
+
lastContext = context;
|
|
103
|
+
if (minLength > 0) {
|
|
104
|
+
buffer.push(payload);
|
|
105
|
+
bufferedBytes += byteLength(payload);
|
|
106
|
+
if (bufferedBytes >= minLength) flushBuffered();
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
writeNow(payload);
|
|
110
|
+
},
|
|
111
|
+
flush() {
|
|
112
|
+
flushBuffered();
|
|
113
|
+
if (pendingWrites + pendingDrains === 0) {
|
|
114
|
+
const error = lastError;
|
|
115
|
+
lastError = void 0;
|
|
116
|
+
if (error) return Promise.reject(error);
|
|
117
|
+
return Promise.resolve();
|
|
118
|
+
}
|
|
119
|
+
return new Promise((resolve, reject) => {
|
|
120
|
+
waiters.push({
|
|
121
|
+
resolve,
|
|
122
|
+
reject
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
},
|
|
126
|
+
flushSync() {
|
|
127
|
+
if (!options.syncWrite) {
|
|
128
|
+
flushBuffered();
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
for (const payload of buffer.splice(0)) options.syncWrite(payload);
|
|
132
|
+
bufferedBytes = 0;
|
|
133
|
+
for (const payload of pendingPayloads.splice(0)) options.syncWrite(payload);
|
|
134
|
+
},
|
|
135
|
+
close() {
|
|
136
|
+
return destination.flush().then(() => new Promise((resolve, reject) => {
|
|
137
|
+
if (!options.stream.end) {
|
|
138
|
+
closed = true;
|
|
139
|
+
offError();
|
|
140
|
+
resolve();
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
options.stream.end((error) => {
|
|
144
|
+
closed = true;
|
|
145
|
+
offError();
|
|
146
|
+
if (error && !(ignoreEpipe && isEpipe(error))) reject(error);
|
|
147
|
+
else resolve();
|
|
148
|
+
});
|
|
149
|
+
}), (error) => {
|
|
150
|
+
offError();
|
|
151
|
+
return Promise.reject(error);
|
|
152
|
+
});
|
|
153
|
+
},
|
|
154
|
+
closeSync() {
|
|
155
|
+
destination.flushSync();
|
|
156
|
+
closed = true;
|
|
157
|
+
offError();
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
return destination;
|
|
161
|
+
}
|
|
162
|
+
//#endregion
|
|
163
|
+
//#region src/stdout-transport.ts
|
|
164
|
+
function stdoutTransport(options = {}) {
|
|
165
|
+
const codec = options.codec ?? (0, _loggerjs_core.ndjsonCodec)();
|
|
166
|
+
const stream = options.stream ?? process.stdout;
|
|
167
|
+
const transportName = options.name ?? "stdout";
|
|
168
|
+
const destination = createNodeStreamDestination({
|
|
169
|
+
name: transportName,
|
|
170
|
+
stream,
|
|
171
|
+
minLength: options.minLength,
|
|
172
|
+
ignoreEpipe: options.ignoreEpipe ?? true
|
|
173
|
+
});
|
|
174
|
+
return {
|
|
175
|
+
name: transportName,
|
|
176
|
+
minLevel: options.minLevel,
|
|
177
|
+
log(event, context) {
|
|
178
|
+
if (options.minLevel !== void 0 && event.level < (0, _loggerjs_core.toLevelValue)(options.minLevel)) return;
|
|
179
|
+
destination.write(codec.encode(event), context);
|
|
180
|
+
},
|
|
181
|
+
flush: destination.flush,
|
|
182
|
+
flushSync: destination.flushSync,
|
|
183
|
+
close: destination.close
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function stderrTransport(options = {}) {
|
|
187
|
+
return stdoutTransport({
|
|
188
|
+
...options,
|
|
189
|
+
name: options.name ?? "stderr",
|
|
190
|
+
stream: process.stderr
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
//#endregion
|
|
194
|
+
exports.stderrTransport = stderrTransport;
|
|
195
|
+
exports.stdoutTransport = stdoutTransport;
|
|
196
|
+
|
|
197
|
+
//# sourceMappingURL=stdout-transport.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdout-transport.cjs","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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"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { ndjsonCodec, toLevelValue } from "@loggerjs/core";
|
|
2
|
+
//#region src/node-destination.ts
|
|
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
|
|
162
|
+
//#region src/stdout-transport.ts
|
|
163
|
+
function stdoutTransport(options = {}) {
|
|
164
|
+
const codec = options.codec ?? ndjsonCodec();
|
|
165
|
+
const stream = options.stream ?? process.stdout;
|
|
166
|
+
const transportName = options.name ?? "stdout";
|
|
167
|
+
const destination = createNodeStreamDestination({
|
|
168
|
+
name: transportName,
|
|
169
|
+
stream,
|
|
170
|
+
minLength: options.minLength,
|
|
171
|
+
ignoreEpipe: options.ignoreEpipe ?? true
|
|
172
|
+
});
|
|
173
|
+
return {
|
|
174
|
+
name: transportName,
|
|
175
|
+
minLevel: options.minLevel,
|
|
176
|
+
log(event, context) {
|
|
177
|
+
if (options.minLevel !== void 0 && event.level < toLevelValue(options.minLevel)) return;
|
|
178
|
+
destination.write(codec.encode(event), context);
|
|
179
|
+
},
|
|
180
|
+
flush: destination.flush,
|
|
181
|
+
flushSync: destination.flushSync,
|
|
182
|
+
close: destination.close
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function stderrTransport(options = {}) {
|
|
186
|
+
return stdoutTransport({
|
|
187
|
+
...options,
|
|
188
|
+
name: options.name ?? "stderr",
|
|
189
|
+
stream: process.stderr
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
//#endregion
|
|
193
|
+
export { stderrTransport, stdoutTransport };
|
|
194
|
+
|
|
195
|
+
//# sourceMappingURL=stdout-transport.js.map
|
|
@@ -0,0 +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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"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let dgram = require("dgram");
|
|
3
|
+
let net = require("net");
|
|
4
|
+
let os = require("os");
|
|
5
|
+
let _loggerjs_core = require("@loggerjs/core");
|
|
6
|
+
//#region src/syslog-transport.ts
|
|
7
|
+
const severityByLevel = {
|
|
8
|
+
trace: 7,
|
|
9
|
+
debug: 7,
|
|
10
|
+
info: 6,
|
|
11
|
+
warn: 4,
|
|
12
|
+
error: 3,
|
|
13
|
+
fatal: 2
|
|
14
|
+
};
|
|
15
|
+
function defaultUdpSocketFactory(protocol) {
|
|
16
|
+
return (0, dgram.createSocket)(protocol);
|
|
17
|
+
}
|
|
18
|
+
function defaultTcpSocketFactory(options) {
|
|
19
|
+
return (0, net.createConnection)(options);
|
|
20
|
+
}
|
|
21
|
+
function headerValue(value, fallback, maxLength) {
|
|
22
|
+
const text = String(value ?? fallback).trim().replace(/\s+/g, "_");
|
|
23
|
+
if (!text) return fallback;
|
|
24
|
+
return text.length > maxLength ? text.slice(0, maxLength) : text;
|
|
25
|
+
}
|
|
26
|
+
function timestamp(time) {
|
|
27
|
+
const value = new Date(time).toISOString();
|
|
28
|
+
return value === "Invalid Date" ? "-" : value;
|
|
29
|
+
}
|
|
30
|
+
function valueFor(value, event, fallback) {
|
|
31
|
+
return typeof value === "function" ? value(event) : value ?? fallback;
|
|
32
|
+
}
|
|
33
|
+
function defaultMessage(event) {
|
|
34
|
+
const extra = {};
|
|
35
|
+
if (event.data !== void 0) extra.data = event.data;
|
|
36
|
+
if (event.context !== void 0) extra.context = event.context;
|
|
37
|
+
if (event.error !== void 0) extra.error = event.error;
|
|
38
|
+
if (Object.keys(extra).length === 0) return event.message;
|
|
39
|
+
return `${event.message} ${(0, _loggerjs_core.safeJsonStringify)(extra)}`;
|
|
40
|
+
}
|
|
41
|
+
function formatSyslogMessage(event, options = {}) {
|
|
42
|
+
const facility = Math.max(0, Math.min(23, Math.trunc(options.facility ?? 1)));
|
|
43
|
+
const severity = severityByLevel[event.levelName] ?? 6;
|
|
44
|
+
const priority = facility * 8 + severity;
|
|
45
|
+
const host = headerValue(options.hostname, (0, os.hostname)(), 255);
|
|
46
|
+
const appName = headerValue(valueFor(options.appName, event, event.logger), "-", 48);
|
|
47
|
+
const procId = headerValue(valueFor(options.procId, event, "-"), "-", 128);
|
|
48
|
+
const msgId = headerValue(valueFor(options.msgId, event, event.type ?? event.levelName), "-", 32);
|
|
49
|
+
const structuredData = valueFor(options.structuredData, event, "-") || "-";
|
|
50
|
+
const message = options.formatMessage ? options.formatMessage(event) : defaultMessage(event);
|
|
51
|
+
return `<${priority}>1 ${timestamp(event.time)} ${host} ${appName} ${procId} ${msgId} ${structuredData} ${message}`;
|
|
52
|
+
}
|
|
53
|
+
function nodeSyslogTransport(options = {}) {
|
|
54
|
+
const protocol = options.protocol ?? "udp4";
|
|
55
|
+
const host = options.host ?? "127.0.0.1";
|
|
56
|
+
const port = options.port ?? 514;
|
|
57
|
+
const transportName = options.name ?? "syslog";
|
|
58
|
+
const unref = options.unref ?? true;
|
|
59
|
+
const tcpFraming = options.tcpFraming ?? "newline";
|
|
60
|
+
const udpSocketFactory = options.udpSocketFactory ?? defaultUdpSocketFactory;
|
|
61
|
+
const tcpSocketFactory = options.tcpSocketFactory ?? defaultTcpSocketFactory;
|
|
62
|
+
let udpSocket;
|
|
63
|
+
let tcpSocket;
|
|
64
|
+
let lastContext;
|
|
65
|
+
const reportError = (error, context, operation) => {
|
|
66
|
+
try {
|
|
67
|
+
options.onError?.(error, { operation });
|
|
68
|
+
} catch (onErrorError) {
|
|
69
|
+
context?.reportInternalError(onErrorError, {
|
|
70
|
+
operation: "on-error",
|
|
71
|
+
phase: "transport",
|
|
72
|
+
transport: transportName
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
context?.reportInternalError(error, {
|
|
76
|
+
operation,
|
|
77
|
+
phase: "transport",
|
|
78
|
+
transport: transportName
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
const getUdpSocket = (context) => {
|
|
82
|
+
if (udpSocket) return udpSocket;
|
|
83
|
+
const socket = udpSocketFactory(protocol === "udp6" ? "udp6" : "udp4");
|
|
84
|
+
socket.on?.("error", (error) => reportError(error, lastContext ?? context, "socket-error"));
|
|
85
|
+
if (unref) socket.unref?.();
|
|
86
|
+
udpSocket = socket;
|
|
87
|
+
return socket;
|
|
88
|
+
};
|
|
89
|
+
const getTcpSocket = (context) => {
|
|
90
|
+
if (tcpSocket) return tcpSocket;
|
|
91
|
+
const socket = tcpSocketFactory({
|
|
92
|
+
host,
|
|
93
|
+
port
|
|
94
|
+
});
|
|
95
|
+
socket.on?.("error", (error) => reportError(error, lastContext ?? context, "socket-error"));
|
|
96
|
+
if (unref) socket.unref?.();
|
|
97
|
+
tcpSocket = socket;
|
|
98
|
+
return socket;
|
|
99
|
+
};
|
|
100
|
+
const send = (message, context) => {
|
|
101
|
+
lastContext = context;
|
|
102
|
+
if (protocol === "tcp") {
|
|
103
|
+
const bytes = new TextEncoder().encode(message).byteLength;
|
|
104
|
+
const payload = tcpFraming === "octet-counting" ? `${bytes} ${message}` : `${message}\n`;
|
|
105
|
+
getTcpSocket(context).write(payload, (error) => {
|
|
106
|
+
if (error) reportError(error, context, "send");
|
|
107
|
+
});
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
getUdpSocket(context).send(message, port, host, (error) => {
|
|
111
|
+
if (error) reportError(error, context, "send");
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
return {
|
|
115
|
+
name: transportName,
|
|
116
|
+
minLevel: options.minLevel,
|
|
117
|
+
log(event, context) {
|
|
118
|
+
send(formatSyslogMessage(event, options), context);
|
|
119
|
+
},
|
|
120
|
+
logBatch(events, context) {
|
|
121
|
+
for (const event of events) send(formatSyslogMessage(event, options), context);
|
|
122
|
+
},
|
|
123
|
+
async close() {
|
|
124
|
+
udpSocket?.close?.();
|
|
125
|
+
udpSocket = void 0;
|
|
126
|
+
tcpSocket?.end?.();
|
|
127
|
+
tcpSocket = void 0;
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
//#endregion
|
|
132
|
+
exports.formatSyslogMessage = formatSyslogMessage;
|
|
133
|
+
exports.nodeSyslogTransport = nodeSyslogTransport;
|
|
134
|
+
|
|
135
|
+
//# sourceMappingURL=syslog-transport.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syslog-transport.cjs","names":[],"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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"}
|