@logtape/syslog 1.3.0-dev.388 → 1.3.0-dev.398

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/deno.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logtape/syslog",
3
- "version": "1.3.0-dev.388+fd5ba0d5",
3
+ "version": "1.3.0-dev.398+af761cb5",
4
4
  "license": "MIT",
5
5
  "exports": "./src/mod.ts",
6
6
  "exclude": [
package/dist/mod.d.cts CHANGED
@@ -1,2 +1,2 @@
1
- import { SyslogFacility, SyslogProtocol, SyslogSinkOptions, getSyslogSink } from "./syslog.cjs";
2
- export { SyslogFacility, SyslogProtocol, SyslogSinkOptions, getSyslogSink };
1
+ import { SyslogFacility, SyslogProtocol, SyslogSinkOptions, SyslogTlsOptions, getSyslogSink } from "./syslog.cjs";
2
+ export { SyslogFacility, SyslogProtocol, SyslogSinkOptions, SyslogTlsOptions, getSyslogSink };
package/dist/mod.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { SyslogFacility, SyslogProtocol, SyslogSinkOptions, getSyslogSink } from "./syslog.js";
2
- export { SyslogFacility, SyslogProtocol, SyslogSinkOptions, getSyslogSink };
1
+ import { SyslogFacility, SyslogProtocol, SyslogSinkOptions, SyslogTlsOptions, getSyslogSink } from "./syslog.js";
2
+ export { SyslogFacility, SyslogProtocol, SyslogSinkOptions, SyslogTlsOptions, getSyslogSink };
package/dist/syslog.cjs CHANGED
@@ -3,6 +3,7 @@ const node_dgram = require_rolldown_runtime.__toESM(require("node:dgram"));
3
3
  const node_net = require_rolldown_runtime.__toESM(require("node:net"));
4
4
  const node_os = require_rolldown_runtime.__toESM(require("node:os"));
5
5
  const node_process = require_rolldown_runtime.__toESM(require("node:process"));
6
+ const node_tls = require_rolldown_runtime.__toESM(require("node:tls"));
6
7
 
7
8
  //#region src/syslog.ts
8
9
  /**
@@ -208,23 +209,57 @@ var NodeUdpSyslogConnection = class {
208
209
  var DenoTcpSyslogConnection = class {
209
210
  connection;
210
211
  encoder = new TextEncoder();
211
- constructor(hostname$1, port, timeout) {
212
+ constructor(hostname$1, port, timeout, secure, tlsOptions) {
212
213
  this.hostname = hostname$1;
213
214
  this.port = port;
214
215
  this.timeout = timeout;
216
+ this.secure = secure;
217
+ this.tlsOptions = tlsOptions;
215
218
  }
216
219
  async connect() {
217
220
  try {
218
- if (this.timeout > 0) {
221
+ const connectOptions = {
222
+ hostname: this.hostname,
223
+ port: this.port,
224
+ transport: "tcp"
225
+ };
226
+ if (this.secure) {
227
+ const tlsConnectOptions = {
228
+ hostname: this.hostname,
229
+ port: this.port,
230
+ caCerts: this.tlsOptions?.ca ? Array.isArray(this.tlsOptions.ca) ? [...this.tlsOptions.ca] : [this.tlsOptions.ca] : void 0
231
+ };
232
+ const connectPromise = Deno.connectTls(tlsConnectOptions);
233
+ if (this.timeout > 0) {
234
+ let timeoutId;
235
+ let timedOut = false;
236
+ const timeoutPromise = new Promise((_, reject) => {
237
+ timeoutId = setTimeout(() => {
238
+ timedOut = true;
239
+ reject(new Error("TCP connection timeout"));
240
+ }, this.timeout);
241
+ });
242
+ try {
243
+ this.connection = await Promise.race([connectPromise, timeoutPromise]);
244
+ } catch (error) {
245
+ if (timedOut) connectPromise.then((conn) => {
246
+ try {
247
+ conn.close();
248
+ } catch {}
249
+ }).catch(() => {});
250
+ throw error;
251
+ } finally {
252
+ clearTimeout(timeoutId);
253
+ }
254
+ } else this.connection = await connectPromise;
255
+ } else if (this.timeout > 0) {
219
256
  const controller = new AbortController();
220
257
  const timeoutId = setTimeout(() => {
221
258
  controller.abort();
222
259
  }, this.timeout);
223
260
  try {
224
261
  this.connection = await Deno.connect({
225
- hostname: this.hostname,
226
- port: this.port,
227
- transport: "tcp",
262
+ ...connectOptions,
228
263
  signal: controller.signal
229
264
  });
230
265
  clearTimeout(timeoutId);
@@ -233,11 +268,7 @@ var DenoTcpSyslogConnection = class {
233
268
  if (controller.signal.aborted) throw new Error("TCP connection timeout");
234
269
  throw error;
235
270
  }
236
- } else this.connection = await Deno.connect({
237
- hostname: this.hostname,
238
- port: this.port,
239
- transport: "tcp"
240
- });
271
+ } else this.connection = await Deno.connect(connectOptions);
241
272
  } catch (error) {
242
273
  throw new Error(`Failed to connect to syslog server: ${error}`);
243
274
  }
@@ -275,15 +306,24 @@ var DenoTcpSyslogConnection = class {
275
306
  var NodeTcpSyslogConnection = class {
276
307
  connection;
277
308
  encoder = new TextEncoder();
278
- constructor(hostname$1, port, timeout) {
309
+ constructor(hostname$1, port, timeout, secure, tlsOptions) {
279
310
  this.hostname = hostname$1;
280
311
  this.port = port;
281
312
  this.timeout = timeout;
313
+ this.secure = secure;
314
+ this.tlsOptions = tlsOptions;
282
315
  }
283
316
  connect() {
284
317
  try {
285
318
  return new Promise((resolve, reject) => {
286
- const socket = new node_net.Socket();
319
+ const connectionOptions = {
320
+ port: this.port,
321
+ host: this.hostname,
322
+ timeout: this.timeout,
323
+ rejectUnauthorized: this.tlsOptions?.rejectUnauthorized ?? true,
324
+ ca: this.tlsOptions?.ca ? Array.isArray(this.tlsOptions.ca) ? [...this.tlsOptions.ca] : [this.tlsOptions.ca] : void 0
325
+ };
326
+ const socket = this.secure ? node_tls.connect(connectionOptions) : new node_net.Socket();
287
327
  const timeout = setTimeout(() => {
288
328
  socket.destroy();
289
329
  reject(new Error("TCP connection timeout"));
@@ -297,7 +337,7 @@ var NodeTcpSyslogConnection = class {
297
337
  clearTimeout(timeout);
298
338
  reject(error);
299
339
  });
300
- socket.connect(this.port, this.hostname);
340
+ if (!this.secure) socket.connect(this.port, this.hostname);
301
341
  });
302
342
  } catch (error) {
303
343
  throw new Error(`Failed to connect to syslog server: ${error}`);
@@ -422,6 +462,8 @@ function getSyslogSink(options = {}) {
422
462
  const hostname$1 = options.hostname ?? "localhost";
423
463
  const port = options.port ?? 514;
424
464
  const protocol = options.protocol ?? "udp";
465
+ const secure = options.secure ?? false;
466
+ const tlsOptions = options.tlsOptions;
425
467
  const facility = options.facility ?? "local0";
426
468
  const appName = options.appName ?? "logtape";
427
469
  const syslogHostname = options.syslogHostname ?? getSystemHostname();
@@ -438,8 +480,8 @@ function getSyslogSink(options = {}) {
438
480
  structuredDataId
439
481
  };
440
482
  const connection = (() => {
441
- if (typeof Deno !== "undefined") return protocol === "tcp" ? new DenoTcpSyslogConnection(hostname$1, port, timeout) : new DenoUdpSyslogConnection(hostname$1, port, timeout);
442
- else return protocol === "tcp" ? new NodeTcpSyslogConnection(hostname$1, port, timeout) : new NodeUdpSyslogConnection(hostname$1, port, timeout);
483
+ if (typeof Deno !== "undefined") return protocol === "tcp" ? new DenoTcpSyslogConnection(hostname$1, port, timeout, secure, tlsOptions) : new DenoUdpSyslogConnection(hostname$1, port, timeout);
484
+ else return protocol === "tcp" ? new NodeTcpSyslogConnection(hostname$1, port, timeout, secure, tlsOptions) : new NodeUdpSyslogConnection(hostname$1, port, timeout);
443
485
  })();
444
486
  let isConnected = false;
445
487
  let lastPromise = Promise.resolve();
@@ -461,6 +503,10 @@ function getSyslogSink(options = {}) {
461
503
  connection.close();
462
504
  isConnected = false;
463
505
  };
506
+ Object.defineProperty(sink, "_internal_lastPromise", {
507
+ get: () => lastPromise,
508
+ enumerable: false
509
+ });
464
510
  return sink;
465
511
  }
466
512
 
package/dist/syslog.d.cts CHANGED
@@ -12,6 +12,24 @@ type SyslogProtocol = "udp" | "tcp";
12
12
  * @since 0.12.0
13
13
  */
14
14
  type SyslogFacility = "kernel" | "user" | "mail" | "daemon" | "security" | "syslog" | "lpr" | "news" | "uucp" | "cron" | "authpriv" | "ftp" | "ntp" | "logaudit" | "logalert" | "clock" | "local0" | "local1" | "local2" | "local3" | "local4" | "local5" | "local6" | "local7";
15
+ /**
16
+ * TLS options for secure TCP connections.
17
+ * @since 1.3.0
18
+ */
19
+ interface SyslogTlsOptions {
20
+ /**
21
+ * Whether to reject connections with invalid certificates.
22
+ * Setting this to `false` disables certificate validation, which makes
23
+ * the connection vulnerable to man-in-the-middle attacks.
24
+ * @default `true`
25
+ */
26
+ readonly rejectUnauthorized?: boolean;
27
+ /**
28
+ * Custom CA certificates to trust. If not provided, the default system
29
+ * CA certificates are used.
30
+ */
31
+ readonly ca?: string | readonly string[];
32
+ }
15
33
  /**
16
34
  * Options for the syslog sink.
17
35
  * @since 0.12.0
@@ -32,6 +50,19 @@ interface SyslogSinkOptions {
32
50
  * @default "udp"
33
51
  */
34
52
  readonly protocol?: SyslogProtocol;
53
+ /**
54
+ * Whether to use TLS for TCP connections.
55
+ * This option is ignored for UDP connections.
56
+ * @default `false`
57
+ * @since 1.3.0
58
+ */
59
+ readonly secure?: boolean;
60
+ /**
61
+ * TLS options for secure TCP connections.
62
+ * This option is only used when `secure` is `true` and `protocol` is `"tcp"`.
63
+ * @since 1.3.0
64
+ */
65
+ readonly tlsOptions?: SyslogTlsOptions;
35
66
  /**
36
67
  * The syslog facility to use for all messages.
37
68
  * @default "local0"
@@ -169,5 +200,5 @@ interface SyslogSinkOptions {
169
200
  declare function getSyslogSink(options?: SyslogSinkOptions): Sink & AsyncDisposable;
170
201
  //# sourceMappingURL=syslog.d.ts.map
171
202
  //#endregion
172
- export { SyslogFacility, SyslogProtocol, SyslogSinkOptions, getSyslogSink };
203
+ export { SyslogFacility, SyslogProtocol, SyslogSinkOptions, SyslogTlsOptions, getSyslogSink };
173
204
  //# sourceMappingURL=syslog.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"syslog.d.cts","names":[],"sources":["../src/syslog.ts"],"sourcesContent":[],"mappings":";;;;;;AAUA;AAMA;AA0EiB,KAhFL,cAAA,GAgFsB,KAAA,GAAA,KAAA;;;;AAuBE;AA0iBpB,KA3oBJ,cAAA,GA2oBiB,QAAA,GAAA,MAAA,GAAA,MAAA,GAAA,QAAA,GAAA,UAAA,GAAA,QAAA,GAAA,KAAA,GAAA,MAAA,GAAA,MAAA,GAAA,MAAA,GAAA,UAAA,GAAA,KAAA,GAAA,KAAA,GAAA,UAAA,GAAA,UAAA,GAAA,OAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA;;;;;AAEJ,UAnkBR,iBAAA,CAmkBQ;;;;;;;;;;;;;;;sBAljBH;;;;;sBAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0iBN,aAAA,WACL,oBACR,OAAO"}
1
+ {"version":3,"file":"syslog.d.cts","names":[],"sources":["../src/syslog.ts"],"sourcesContent":[],"mappings":";;;;;;AAWA;AAMA;AA0EiB,KAhFL,cAAA,GAgFqB,KAAA,GAAA,KAAA;AAoBjC;;;;AAsCsB,KApIV,cAAA,GAoIU,QAAA,GAAA,MAAA,GAAA,MAAA,GAAA,QAAA,GAAA,UAAA,GAAA,QAAA,GAAA,KAAA,GAAA,MAAA,GAAA,MAAA,GAAA,MAAA,GAAA,UAAA,GAAA,KAAA,GAAA,KAAA,GAAA,UAAA,GAAA,UAAA,GAAA,OAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA;AAAc;AAgnBpC;;;AAEG,UA5qBc,gBAAA,CA4qBd;EAAI;AAAkB;;;;;;;;;;;;;;;;UAxpBR,iBAAA;;;;;;;;;;;;;;;sBAiBK;;;;;;;;;;;;;wBAeE;;;;;sBAMF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgnBN,aAAA,WACL,oBACR,OAAO"}
package/dist/syslog.d.ts CHANGED
@@ -12,6 +12,24 @@ type SyslogProtocol = "udp" | "tcp";
12
12
  * @since 0.12.0
13
13
  */
14
14
  type SyslogFacility = "kernel" | "user" | "mail" | "daemon" | "security" | "syslog" | "lpr" | "news" | "uucp" | "cron" | "authpriv" | "ftp" | "ntp" | "logaudit" | "logalert" | "clock" | "local0" | "local1" | "local2" | "local3" | "local4" | "local5" | "local6" | "local7";
15
+ /**
16
+ * TLS options for secure TCP connections.
17
+ * @since 1.3.0
18
+ */
19
+ interface SyslogTlsOptions {
20
+ /**
21
+ * Whether to reject connections with invalid certificates.
22
+ * Setting this to `false` disables certificate validation, which makes
23
+ * the connection vulnerable to man-in-the-middle attacks.
24
+ * @default `true`
25
+ */
26
+ readonly rejectUnauthorized?: boolean;
27
+ /**
28
+ * Custom CA certificates to trust. If not provided, the default system
29
+ * CA certificates are used.
30
+ */
31
+ readonly ca?: string | readonly string[];
32
+ }
15
33
  /**
16
34
  * Options for the syslog sink.
17
35
  * @since 0.12.0
@@ -32,6 +50,19 @@ interface SyslogSinkOptions {
32
50
  * @default "udp"
33
51
  */
34
52
  readonly protocol?: SyslogProtocol;
53
+ /**
54
+ * Whether to use TLS for TCP connections.
55
+ * This option is ignored for UDP connections.
56
+ * @default `false`
57
+ * @since 1.3.0
58
+ */
59
+ readonly secure?: boolean;
60
+ /**
61
+ * TLS options for secure TCP connections.
62
+ * This option is only used when `secure` is `true` and `protocol` is `"tcp"`.
63
+ * @since 1.3.0
64
+ */
65
+ readonly tlsOptions?: SyslogTlsOptions;
35
66
  /**
36
67
  * The syslog facility to use for all messages.
37
68
  * @default "local0"
@@ -169,5 +200,5 @@ interface SyslogSinkOptions {
169
200
  declare function getSyslogSink(options?: SyslogSinkOptions): Sink & AsyncDisposable;
170
201
  //# sourceMappingURL=syslog.d.ts.map
171
202
  //#endregion
172
- export { SyslogFacility, SyslogProtocol, SyslogSinkOptions, getSyslogSink };
203
+ export { SyslogFacility, SyslogProtocol, SyslogSinkOptions, SyslogTlsOptions, getSyslogSink };
173
204
  //# sourceMappingURL=syslog.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"syslog.d.ts","names":[],"sources":["../src/syslog.ts"],"sourcesContent":[],"mappings":";;;;;;AAUA;AAMA;AA0EiB,KAhFL,cAAA,GAgFsB,KAAA,GAAA,KAAA;;;;AAuBE;AA0iBpB,KA3oBJ,cAAA,GA2oBiB,QAAA,GAAA,MAAA,GAAA,MAAA,GAAA,QAAA,GAAA,UAAA,GAAA,QAAA,GAAA,KAAA,GAAA,MAAA,GAAA,MAAA,GAAA,MAAA,GAAA,UAAA,GAAA,KAAA,GAAA,KAAA,GAAA,UAAA,GAAA,UAAA,GAAA,OAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA;;;;;AAEJ,UAnkBR,iBAAA,CAmkBQ;;;;;;;;;;;;;;;sBAljBH;;;;;sBAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0iBN,aAAA,WACL,oBACR,OAAO"}
1
+ {"version":3,"file":"syslog.d.ts","names":[],"sources":["../src/syslog.ts"],"sourcesContent":[],"mappings":";;;;;;AAWA;AAMA;AA0EiB,KAhFL,cAAA,GAgFqB,KAAA,GAAA,KAAA;AAoBjC;;;;AAsCsB,KApIV,cAAA,GAoIU,QAAA,GAAA,MAAA,GAAA,MAAA,GAAA,QAAA,GAAA,UAAA,GAAA,QAAA,GAAA,KAAA,GAAA,MAAA,GAAA,MAAA,GAAA,MAAA,GAAA,UAAA,GAAA,KAAA,GAAA,KAAA,GAAA,UAAA,GAAA,UAAA,GAAA,OAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA,GAAA,QAAA;AAAc;AAgnBpC;;;AAEG,UA5qBc,gBAAA,CA4qBd;EAAI;AAAkB;;;;;;;;;;;;;;;;UAxpBR,iBAAA;;;;;;;;;;;;;;;sBAiBK;;;;;;;;;;;;;wBAeE;;;;;sBAMF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgnBN,aAAA,WACL,oBACR,OAAO"}
package/dist/syslog.js CHANGED
@@ -2,6 +2,7 @@ import { createSocket } from "node:dgram";
2
2
  import { Socket } from "node:net";
3
3
  import { hostname } from "node:os";
4
4
  import process from "node:process";
5
+ import * as tls from "node:tls";
5
6
 
6
7
  //#region src/syslog.ts
7
8
  /**
@@ -207,23 +208,57 @@ var NodeUdpSyslogConnection = class {
207
208
  var DenoTcpSyslogConnection = class {
208
209
  connection;
209
210
  encoder = new TextEncoder();
210
- constructor(hostname$1, port, timeout) {
211
+ constructor(hostname$1, port, timeout, secure, tlsOptions) {
211
212
  this.hostname = hostname$1;
212
213
  this.port = port;
213
214
  this.timeout = timeout;
215
+ this.secure = secure;
216
+ this.tlsOptions = tlsOptions;
214
217
  }
215
218
  async connect() {
216
219
  try {
217
- if (this.timeout > 0) {
220
+ const connectOptions = {
221
+ hostname: this.hostname,
222
+ port: this.port,
223
+ transport: "tcp"
224
+ };
225
+ if (this.secure) {
226
+ const tlsConnectOptions = {
227
+ hostname: this.hostname,
228
+ port: this.port,
229
+ caCerts: this.tlsOptions?.ca ? Array.isArray(this.tlsOptions.ca) ? [...this.tlsOptions.ca] : [this.tlsOptions.ca] : void 0
230
+ };
231
+ const connectPromise = Deno.connectTls(tlsConnectOptions);
232
+ if (this.timeout > 0) {
233
+ let timeoutId;
234
+ let timedOut = false;
235
+ const timeoutPromise = new Promise((_, reject) => {
236
+ timeoutId = setTimeout(() => {
237
+ timedOut = true;
238
+ reject(new Error("TCP connection timeout"));
239
+ }, this.timeout);
240
+ });
241
+ try {
242
+ this.connection = await Promise.race([connectPromise, timeoutPromise]);
243
+ } catch (error) {
244
+ if (timedOut) connectPromise.then((conn) => {
245
+ try {
246
+ conn.close();
247
+ } catch {}
248
+ }).catch(() => {});
249
+ throw error;
250
+ } finally {
251
+ clearTimeout(timeoutId);
252
+ }
253
+ } else this.connection = await connectPromise;
254
+ } else if (this.timeout > 0) {
218
255
  const controller = new AbortController();
219
256
  const timeoutId = setTimeout(() => {
220
257
  controller.abort();
221
258
  }, this.timeout);
222
259
  try {
223
260
  this.connection = await Deno.connect({
224
- hostname: this.hostname,
225
- port: this.port,
226
- transport: "tcp",
261
+ ...connectOptions,
227
262
  signal: controller.signal
228
263
  });
229
264
  clearTimeout(timeoutId);
@@ -232,11 +267,7 @@ var DenoTcpSyslogConnection = class {
232
267
  if (controller.signal.aborted) throw new Error("TCP connection timeout");
233
268
  throw error;
234
269
  }
235
- } else this.connection = await Deno.connect({
236
- hostname: this.hostname,
237
- port: this.port,
238
- transport: "tcp"
239
- });
270
+ } else this.connection = await Deno.connect(connectOptions);
240
271
  } catch (error) {
241
272
  throw new Error(`Failed to connect to syslog server: ${error}`);
242
273
  }
@@ -274,15 +305,24 @@ var DenoTcpSyslogConnection = class {
274
305
  var NodeTcpSyslogConnection = class {
275
306
  connection;
276
307
  encoder = new TextEncoder();
277
- constructor(hostname$1, port, timeout) {
308
+ constructor(hostname$1, port, timeout, secure, tlsOptions) {
278
309
  this.hostname = hostname$1;
279
310
  this.port = port;
280
311
  this.timeout = timeout;
312
+ this.secure = secure;
313
+ this.tlsOptions = tlsOptions;
281
314
  }
282
315
  connect() {
283
316
  try {
284
317
  return new Promise((resolve, reject) => {
285
- const socket = new Socket();
318
+ const connectionOptions = {
319
+ port: this.port,
320
+ host: this.hostname,
321
+ timeout: this.timeout,
322
+ rejectUnauthorized: this.tlsOptions?.rejectUnauthorized ?? true,
323
+ ca: this.tlsOptions?.ca ? Array.isArray(this.tlsOptions.ca) ? [...this.tlsOptions.ca] : [this.tlsOptions.ca] : void 0
324
+ };
325
+ const socket = this.secure ? tls.connect(connectionOptions) : new Socket();
286
326
  const timeout = setTimeout(() => {
287
327
  socket.destroy();
288
328
  reject(new Error("TCP connection timeout"));
@@ -296,7 +336,7 @@ var NodeTcpSyslogConnection = class {
296
336
  clearTimeout(timeout);
297
337
  reject(error);
298
338
  });
299
- socket.connect(this.port, this.hostname);
339
+ if (!this.secure) socket.connect(this.port, this.hostname);
300
340
  });
301
341
  } catch (error) {
302
342
  throw new Error(`Failed to connect to syslog server: ${error}`);
@@ -421,6 +461,8 @@ function getSyslogSink(options = {}) {
421
461
  const hostname$1 = options.hostname ?? "localhost";
422
462
  const port = options.port ?? 514;
423
463
  const protocol = options.protocol ?? "udp";
464
+ const secure = options.secure ?? false;
465
+ const tlsOptions = options.tlsOptions;
424
466
  const facility = options.facility ?? "local0";
425
467
  const appName = options.appName ?? "logtape";
426
468
  const syslogHostname = options.syslogHostname ?? getSystemHostname();
@@ -437,8 +479,8 @@ function getSyslogSink(options = {}) {
437
479
  structuredDataId
438
480
  };
439
481
  const connection = (() => {
440
- if (typeof Deno !== "undefined") return protocol === "tcp" ? new DenoTcpSyslogConnection(hostname$1, port, timeout) : new DenoUdpSyslogConnection(hostname$1, port, timeout);
441
- else return protocol === "tcp" ? new NodeTcpSyslogConnection(hostname$1, port, timeout) : new NodeUdpSyslogConnection(hostname$1, port, timeout);
482
+ if (typeof Deno !== "undefined") return protocol === "tcp" ? new DenoTcpSyslogConnection(hostname$1, port, timeout, secure, tlsOptions) : new DenoUdpSyslogConnection(hostname$1, port, timeout);
483
+ else return protocol === "tcp" ? new NodeTcpSyslogConnection(hostname$1, port, timeout, secure, tlsOptions) : new NodeUdpSyslogConnection(hostname$1, port, timeout);
442
484
  })();
443
485
  let isConnected = false;
444
486
  let lastPromise = Promise.resolve();
@@ -460,6 +502,10 @@ function getSyslogSink(options = {}) {
460
502
  connection.close();
461
503
  isConnected = false;
462
504
  };
505
+ Object.defineProperty(sink, "_internal_lastPromise", {
506
+ get: () => lastPromise,
507
+ enumerable: false
508
+ });
463
509
  return sink;
464
510
  }
465
511
 
@@ -1 +1 @@
1
- {"version":3,"file":"syslog.js","names":["FACILITY_CODES: Record<SyslogFacility, number>","SEVERITY_LEVELS: Record<LogLevel, number>","facility: SyslogFacility","severity: number","timestamp: number","value: string","record: LogRecord","structuredDataId: string","elements: string[]","options: Required<\n Pick<\n SyslogSinkOptions,\n | \"facility\"\n | \"appName\"\n | \"syslogHostname\"\n | \"processId\"\n | \"includeStructuredData\"\n | \"structuredDataId\"\n >\n >","hostname","hostname: string","port: number","timeout: number","message: string","error?: Error | null","options: SyslogSinkOptions","connection: SyslogConnection","sink: Sink & AsyncDisposable"],"sources":["../src/syslog.ts"],"sourcesContent":["import type { LogLevel, LogRecord, Sink } from \"@logtape/logtape\";\nimport { createSocket } from \"node:dgram\";\nimport { Socket } from \"node:net\";\nimport { hostname } from \"node:os\";\nimport process from \"node:process\";\n\n/**\n * Syslog protocol type.\n * @since 0.12.0\n */\nexport type SyslogProtocol = \"udp\" | \"tcp\";\n\n/**\n * Syslog facility codes as defined in RFC 5424.\n * @since 0.12.0\n */\nexport type SyslogFacility =\n | \"kernel\" // 0 - kernel messages\n | \"user\" // 1 - user-level messages\n | \"mail\" // 2 - mail system\n | \"daemon\" // 3 - system daemons\n | \"security\" // 4 - security/authorization messages\n | \"syslog\" // 5 - messages generated internally by syslogd\n | \"lpr\" // 6 - line printer subsystem\n | \"news\" // 7 - network news subsystem\n | \"uucp\" // 8 - UUCP subsystem\n | \"cron\" // 9 - clock daemon\n | \"authpriv\" // 10 - security/authorization messages\n | \"ftp\" // 11 - FTP daemon\n | \"ntp\" // 12 - NTP subsystem\n | \"logaudit\" // 13 - log audit\n | \"logalert\" // 14 - log alert\n | \"clock\" // 15 - clock daemon\n | \"local0\" // 16 - local use 0\n | \"local1\" // 17 - local use 1\n | \"local2\" // 18 - local use 2\n | \"local3\" // 19 - local use 3\n | \"local4\" // 20 - local use 4\n | \"local5\" // 21 - local use 5\n | \"local6\" // 22 - local use 6\n | \"local7\"; // 23 - local use 7\n\n/**\n * Syslog facility code mapping.\n * @since 0.12.0\n */\nconst FACILITY_CODES: Record<SyslogFacility, number> = {\n kernel: 0,\n user: 1,\n mail: 2,\n daemon: 3,\n security: 4,\n syslog: 5,\n lpr: 6,\n news: 7,\n uucp: 8,\n cron: 9,\n authpriv: 10,\n ftp: 11,\n ntp: 12,\n logaudit: 13,\n logalert: 14,\n clock: 15,\n local0: 16,\n local1: 17,\n local2: 18,\n local3: 19,\n local4: 20,\n local5: 21,\n local6: 22,\n local7: 23,\n};\n\n/**\n * Syslog severity levels as defined in RFC 5424.\n * @since 0.12.0\n */\nconst SEVERITY_LEVELS: Record<LogLevel, number> = {\n fatal: 0, // Emergency: system is unusable\n error: 3, // Error: error conditions\n warning: 4, // Warning: warning conditions\n info: 6, // Informational: informational messages\n debug: 7, // Debug: debug-level messages\n trace: 7, // Debug: debug-level messages (same as debug)\n};\n\n/**\n * Options for the syslog sink.\n * @since 0.12.0\n */\nexport interface SyslogSinkOptions {\n /**\n * The hostname or IP address of the syslog server.\n * @default \"localhost\"\n */\n readonly hostname?: string;\n\n /**\n * The port number of the syslog server.\n * @default 514\n */\n readonly port?: number;\n\n /**\n * The protocol to use for sending syslog messages.\n * @default \"udp\"\n */\n readonly protocol?: SyslogProtocol;\n\n /**\n * The syslog facility to use for all messages.\n * @default \"local0\"\n */\n readonly facility?: SyslogFacility;\n\n /**\n * The application name to include in syslog messages.\n * @default \"logtape\"\n */\n readonly appName?: string;\n\n /**\n * The hostname to include in syslog messages.\n * If not provided, the system hostname will be used.\n */\n readonly syslogHostname?: string;\n\n /**\n * The process ID to include in syslog messages.\n * If not provided, the current process ID will be used.\n */\n readonly processId?: string;\n\n /**\n * Connection timeout in milliseconds.\n * @default 5000\n */\n readonly timeout?: number;\n\n /**\n * Whether to include structured data in syslog messages.\n * @default `false`\n */\n readonly includeStructuredData?: boolean;\n\n /**\n * The structured data ID to use for log properties.\n * Should follow the format \"name@private-enterprise-number\".\n * @default \"logtape@32473\"\n */\n readonly structuredDataId?: string;\n}\n\n/**\n * Calculates the priority value for a syslog message.\n * Priority = Facility * 8 + Severity\n * @since 0.12.0\n */\nfunction calculatePriority(facility: SyslogFacility, severity: number): number {\n const facilityCode = FACILITY_CODES[facility];\n return facilityCode * 8 + severity;\n}\n\n/**\n * Formats a timestamp (number) as RFC 3339 timestamp for syslog.\n * @since 0.12.0\n */\nfunction formatTimestamp(timestamp: number): string {\n return new Date(timestamp).toISOString();\n}\n\n/**\n * Escapes special characters in structured data values.\n * @since 0.12.0\n */\nfunction escapeStructuredDataValue(value: string): string {\n return value\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\"/g, '\\\\\"')\n .replace(/]/g, \"\\\\]\");\n}\n\n/**\n * Formats structured data from log record properties.\n * @since 0.12.0\n */\nfunction formatStructuredData(\n record: LogRecord,\n structuredDataId: string,\n): string {\n if (!record.properties || Object.keys(record.properties).length === 0) {\n return \"-\";\n }\n\n const elements: string[] = [];\n for (const [key, value] of Object.entries(record.properties)) {\n const escapedValue = escapeStructuredDataValue(String(value));\n elements.push(`${key}=\"${escapedValue}\"`);\n }\n\n return `[${structuredDataId} ${elements.join(\" \")}]`;\n}\n\n/**\n * Formats a log record as RFC 5424 syslog message.\n * @since 0.12.0\n */\nfunction formatSyslogMessage(\n record: LogRecord,\n options: Required<\n Pick<\n SyslogSinkOptions,\n | \"facility\"\n | \"appName\"\n | \"syslogHostname\"\n | \"processId\"\n | \"includeStructuredData\"\n | \"structuredDataId\"\n >\n >,\n): string {\n const severity = SEVERITY_LEVELS[record.level];\n const priority = calculatePriority(options.facility, severity);\n const timestamp = formatTimestamp(record.timestamp);\n const hostname = options.syslogHostname || \"-\";\n const appName = options.appName || \"-\";\n const processId = options.processId || \"-\";\n const msgId = \"-\"; // Could be enhanced to include message ID\n\n let structuredData = \"-\";\n if (options.includeStructuredData) {\n structuredData = formatStructuredData(record, options.structuredDataId);\n }\n\n // Format the message text\n let message = \"\";\n for (let i = 0; i < record.message.length; i++) {\n if (i % 2 === 0) {\n message += record.message[i];\n } else {\n message += JSON.stringify(record.message[i]);\n }\n }\n\n // RFC 5424 format: <PRI>VERSION TIMESTAMP HOSTNAME APP-NAME PROCID MSGID STRUCTURED-DATA MSG\n return `<${priority}>1 ${timestamp} ${hostname} ${appName} ${processId} ${msgId} ${structuredData} ${message}`;\n}\n\n/**\n * Gets the system hostname.\n * @since 0.12.0\n */\nfunction getSystemHostname(): string {\n try {\n // Try Deno first\n if (typeof Deno !== \"undefined\" && Deno.hostname) {\n return Deno.hostname();\n }\n\n // Try Node.js os.hostname()\n return hostname();\n } catch {\n // Fallback to environment variable or localhost\n return process.env.HOSTNAME || \"localhost\";\n }\n}\n\n/**\n * Gets the current process ID.\n * @since 0.12.0\n */\nfunction getProcessId(): string {\n try {\n // Try Deno first\n if (typeof Deno !== \"undefined\" && Deno.pid) {\n return Deno.pid.toString();\n }\n\n // Try Node.js\n return process.pid.toString();\n } catch {\n return \"-\";\n }\n}\n\n/**\n * Base interface for syslog connections.\n * @since 0.12.0\n */\nexport interface SyslogConnection {\n connect(): void | Promise<void>;\n send(message: string): Promise<void>;\n close(): void;\n}\n\n/**\n * Deno UDP syslog connection implementation.\n * @since 0.12.0\n */\nexport class DenoUdpSyslogConnection implements SyslogConnection {\n private encoder = new TextEncoder();\n\n constructor(\n private hostname: string,\n private port: number,\n private timeout: number,\n ) {}\n\n connect(): void {\n // For UDP, we don't need to establish a persistent connection\n }\n\n send(message: string): Promise<void> {\n const data = this.encoder.encode(message);\n\n try {\n // Deno doesn't have native UDP support, use Node.js APIs\n const socket = createSocket(\"udp4\");\n\n if (this.timeout > 0) {\n return new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n socket.close();\n reject(new Error(\"UDP send timeout\"));\n }, this.timeout);\n\n socket.send(data, this.port, this.hostname, (error) => {\n clearTimeout(timeout);\n socket.close();\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n } else {\n // No timeout\n return new Promise<void>((resolve, reject) => {\n socket.send(data, this.port, this.hostname, (error) => {\n socket.close();\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n }\n } catch (error) {\n throw new Error(`Failed to send syslog message: ${error}`);\n }\n }\n\n close(): void {\n // UDP connections don't need explicit closing\n }\n}\n\n/**\n * Node.js UDP syslog connection implementation.\n * @since 0.12.0\n */\nexport class NodeUdpSyslogConnection implements SyslogConnection {\n private encoder = new TextEncoder();\n\n constructor(\n private hostname: string,\n private port: number,\n private timeout: number,\n ) {}\n\n connect(): void {\n // For UDP, we don't need to establish a persistent connection\n }\n\n send(message: string): Promise<void> {\n const data = this.encoder.encode(message);\n\n try {\n const socket = createSocket(\"udp4\");\n\n return new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n socket.close();\n reject(new Error(\"UDP send timeout\"));\n }, this.timeout);\n\n socket.send(data, this.port, this.hostname, (error) => {\n clearTimeout(timeout);\n socket.close();\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n } catch (error) {\n throw new Error(`Failed to send syslog message: ${error}`);\n }\n }\n\n close(): void {\n // UDP connections don't need explicit closing\n }\n}\n\n/**\n * Deno TCP syslog connection implementation.\n * @since 0.12.0\n */\nexport class DenoTcpSyslogConnection implements SyslogConnection {\n private connection?: Deno.TcpConn;\n private encoder = new TextEncoder();\n\n constructor(\n private hostname: string,\n private port: number,\n private timeout: number,\n ) {}\n\n async connect(): Promise<void> {\n try {\n if (this.timeout > 0) {\n // Use AbortController for proper timeout handling\n const controller = new AbortController();\n const timeoutId = setTimeout(() => {\n controller.abort();\n }, this.timeout);\n\n try {\n this.connection = await Deno.connect({\n hostname: this.hostname,\n port: this.port,\n transport: \"tcp\",\n signal: controller.signal,\n });\n clearTimeout(timeoutId);\n } catch (error) {\n clearTimeout(timeoutId);\n if (controller.signal.aborted) {\n throw new Error(\"TCP connection timeout\");\n }\n throw error;\n }\n } else {\n // No timeout\n this.connection = await Deno.connect({\n hostname: this.hostname,\n port: this.port,\n transport: \"tcp\",\n });\n }\n } catch (error) {\n throw new Error(`Failed to connect to syslog server: ${error}`);\n }\n }\n\n async send(message: string): Promise<void> {\n if (!this.connection) {\n throw new Error(\"Connection not established\");\n }\n\n const data = this.encoder.encode(message + \"\\n\");\n\n try {\n if (this.timeout > 0) {\n // Implement timeout for send using Promise.race\n const writePromise = this.connection.write(data);\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => {\n reject(new Error(\"TCP send timeout\"));\n }, this.timeout);\n });\n\n await Promise.race([writePromise, timeoutPromise]);\n } else {\n // No timeout\n await this.connection.write(data);\n }\n } catch (error) {\n throw new Error(`Failed to send syslog message: ${error}`);\n }\n }\n\n close(): void {\n if (this.connection) {\n try {\n this.connection.close();\n } catch {\n // Ignore errors during close\n }\n this.connection = undefined;\n }\n }\n}\n\n/**\n * Node.js TCP syslog connection implementation.\n * @since 0.12.0\n */\nexport class NodeTcpSyslogConnection implements SyslogConnection {\n private connection?: Socket;\n private encoder = new TextEncoder();\n\n constructor(\n private hostname: string,\n private port: number,\n private timeout: number,\n ) {}\n\n connect(): Promise<void> {\n try {\n return new Promise<void>((resolve, reject) => {\n const socket = new Socket();\n\n const timeout = setTimeout(() => {\n socket.destroy();\n reject(new Error(\"TCP connection timeout\"));\n }, this.timeout);\n\n socket.on(\"connect\", () => {\n clearTimeout(timeout);\n this.connection = socket;\n resolve();\n });\n\n socket.on(\"error\", (error) => {\n clearTimeout(timeout);\n reject(error);\n });\n\n socket.connect(this.port, this.hostname);\n });\n } catch (error) {\n throw new Error(`Failed to connect to syslog server: ${error}`);\n }\n }\n\n send(message: string): Promise<void> {\n if (!this.connection) {\n throw new Error(\"Connection not established\");\n }\n\n const data = this.encoder.encode(message + \"\\n\");\n\n try {\n return new Promise<void>((resolve, reject) => {\n this.connection!.write(data, (error?: Error | null) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n } catch (error) {\n throw new Error(`Failed to send syslog message: ${error}`);\n }\n }\n\n close(): void {\n if (this.connection) {\n try {\n this.connection.end();\n } catch {\n // Ignore errors during close\n }\n this.connection = undefined;\n }\n }\n}\n\n/**\n * Creates a syslog sink that sends log messages to a syslog server using the\n * RFC 5424 syslog protocol format.\n *\n * This sink supports both UDP and TCP protocols for reliable log transmission\n * to centralized logging systems. It automatically formats log records according\n * to RFC 5424 specification, including structured data support for log properties.\n *\n * ## Features\n *\n * - **RFC 5424 Compliance**: Full implementation of the RFC 5424 syslog protocol\n * - **Cross-Runtime Support**: Works with Deno, Node.js, Bun, and browsers\n * - **Multiple Protocols**: Supports both UDP (fire-and-forget) and TCP (reliable) delivery\n * - **Structured Data**: Automatically includes log record properties as RFC 5424 structured data\n * - **Facility Support**: All standard syslog facilities (kern, user, mail, daemon, local0-7, etc.)\n * - **Automatic Escaping**: Proper escaping of special characters in structured data values\n * - **Connection Management**: Automatic connection handling with configurable timeouts\n *\n * ## Protocol Differences\n *\n * - **UDP**: Fast, connectionless delivery suitable for high-throughput logging.\n * Messages may be lost during network issues but has minimal performance impact.\n * - **TCP**: Reliable, connection-based delivery that ensures message delivery.\n * Higher overhead but guarantees that log messages reach the server.\n *\n * @param options Configuration options for the syslog sink\n * @returns A sink function that sends log records to the syslog server, implementing AsyncDisposable for proper cleanup\n *\n * @example Basic usage with default options\n * ```typescript\n * import { configure } from \"@logtape/logtape\";\n * import { getSyslogSink } from \"@logtape/syslog\";\n *\n * await configure({\n * sinks: {\n * syslog: getSyslogSink(), // Sends to localhost:514 via UDP\n * },\n * loggers: [\n * { category: [], sinks: [\"syslog\"], lowestLevel: \"info\" },\n * ],\n * });\n * ```\n *\n * @example Custom syslog server configuration\n * ```typescript\n * import { configure } from \"@logtape/logtape\";\n * import { getSyslogSink } from \"@logtape/syslog\";\n *\n * await configure({\n * sinks: {\n * syslog: getSyslogSink({\n * hostname: \"log-server.example.com\",\n * port: 1514,\n * protocol: \"tcp\",\n * facility: \"mail\",\n * appName: \"my-application\",\n * timeout: 10000,\n * }),\n * },\n * loggers: [\n * { category: [], sinks: [\"syslog\"], lowestLevel: \"debug\" },\n * ],\n * });\n * ```\n *\n * @example Using structured data for log properties\n * ```typescript\n * import { configure, getLogger } from \"@logtape/logtape\";\n * import { getSyslogSink } from \"@logtape/syslog\";\n *\n * await configure({\n * sinks: {\n * syslog: getSyslogSink({\n * includeStructuredData: true,\n * structuredDataId: \"myapp@12345\",\n * }),\n * },\n * loggers: [\n * { category: [], sinks: [\"syslog\"], lowestLevel: \"info\" },\n * ],\n * });\n *\n * const logger = getLogger();\n * // This will include userId and action as structured data\n * logger.info(\"User action completed\", { userId: 123, action: \"login\" });\n * // Results in: <134>1 2024-01-01T12:00:00.000Z hostname myapp 1234 - [myapp@12345 userId=\"123\" action=\"login\"] User action completed\n * ```\n *\n * @since 0.12.0\n * @see {@link https://tools.ietf.org/html/rfc5424} RFC 5424 - The Syslog Protocol\n * @see {@link SyslogSinkOptions} for detailed configuration options\n */\nexport function getSyslogSink(\n options: SyslogSinkOptions = {},\n): Sink & AsyncDisposable {\n const hostname = options.hostname ?? \"localhost\";\n const port = options.port ?? 514;\n const protocol = options.protocol ?? \"udp\";\n const facility = options.facility ?? \"local0\";\n const appName = options.appName ?? \"logtape\";\n const syslogHostname = options.syslogHostname ?? getSystemHostname();\n const processId = options.processId ?? getProcessId();\n const timeout = options.timeout ?? 5000;\n const includeStructuredData = options.includeStructuredData ?? false;\n const structuredDataId = options.structuredDataId ?? \"logtape@32473\";\n\n const formatOptions = {\n facility,\n appName,\n syslogHostname,\n processId,\n includeStructuredData,\n structuredDataId,\n };\n\n // Create connection based on protocol and runtime\n const connection: SyslogConnection = (() => {\n if (typeof Deno !== \"undefined\") {\n // Deno runtime\n return protocol === \"tcp\"\n ? new DenoTcpSyslogConnection(hostname, port, timeout)\n : new DenoUdpSyslogConnection(hostname, port, timeout);\n } else {\n // Node.js runtime (and Bun, which uses Node.js APIs)\n return protocol === \"tcp\"\n ? new NodeTcpSyslogConnection(hostname, port, timeout)\n : new NodeUdpSyslogConnection(hostname, port, timeout);\n }\n })();\n\n let isConnected = false;\n let lastPromise = Promise.resolve();\n\n const sink: Sink & AsyncDisposable = (record: LogRecord) => {\n const syslogMessage = formatSyslogMessage(record, formatOptions);\n\n lastPromise = lastPromise\n .then(async () => {\n if (!isConnected) {\n await connection.connect();\n isConnected = true;\n }\n await connection.send(syslogMessage);\n })\n .catch((error) => {\n // If connection fails, try to reconnect on next message\n isConnected = false;\n throw error;\n });\n };\n\n sink[Symbol.asyncDispose] = async () => {\n await lastPromise.catch(() => {}); // Wait for any pending operations\n connection.close();\n isConnected = false;\n };\n\n return sink;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"syslog.js","names":["FACILITY_CODES: Record<SyslogFacility, number>","SEVERITY_LEVELS: Record<LogLevel, number>","facility: SyslogFacility","severity: number","timestamp: number","value: string","record: LogRecord","structuredDataId: string","elements: string[]","options: Required<\n Pick<\n SyslogSinkOptions,\n | \"facility\"\n | \"appName\"\n | \"syslogHostname\"\n | \"processId\"\n | \"includeStructuredData\"\n | \"structuredDataId\"\n >\n >","hostname","hostname: string","port: number","timeout: number","message: string","secure: boolean","tlsOptions?: SyslogTlsOptions","connectOptions: Deno.ConnectOptions","tlsConnectOptions: Deno.ConnectTlsOptions","timeoutId: number","connectionOptions: tls.ConnectionOptions","socket: Socket | tls.TLSSocket","error?: Error | null","options: SyslogSinkOptions","connection: SyslogConnection","sink: Sink & AsyncDisposable"],"sources":["../src/syslog.ts"],"sourcesContent":["import type { LogLevel, LogRecord, Sink } from \"@logtape/logtape\";\nimport { createSocket } from \"node:dgram\";\nimport { Socket } from \"node:net\";\nimport { hostname } from \"node:os\";\nimport process from \"node:process\";\nimport * as tls from \"node:tls\";\n\n/**\n * Syslog protocol type.\n * @since 0.12.0\n */\nexport type SyslogProtocol = \"udp\" | \"tcp\";\n\n/**\n * Syslog facility codes as defined in RFC 5424.\n * @since 0.12.0\n */\nexport type SyslogFacility =\n | \"kernel\" // 0 - kernel messages\n | \"user\" // 1 - user-level messages\n | \"mail\" // 2 - mail system\n | \"daemon\" // 3 - system daemons\n | \"security\" // 4 - security/authorization messages\n | \"syslog\" // 5 - messages generated internally by syslogd\n | \"lpr\" // 6 - line printer subsystem\n | \"news\" // 7 - network news subsystem\n | \"uucp\" // 8 - UUCP subsystem\n | \"cron\" // 9 - clock daemon\n | \"authpriv\" // 10 - security/authorization messages\n | \"ftp\" // 11 - FTP daemon\n | \"ntp\" // 12 - NTP subsystem\n | \"logaudit\" // 13 - log audit\n | \"logalert\" // 14 - log alert\n | \"clock\" // 15 - clock daemon\n | \"local0\" // 16 - local use 0\n | \"local1\" // 17 - local use 1\n | \"local2\" // 18 - local use 2\n | \"local3\" // 19 - local use 3\n | \"local4\" // 20 - local use 4\n | \"local5\" // 21 - local use 5\n | \"local6\" // 22 - local use 6\n | \"local7\"; // 23 - local use 7\n\n/**\n * Syslog facility code mapping.\n * @since 0.12.0\n */\nconst FACILITY_CODES: Record<SyslogFacility, number> = {\n kernel: 0,\n user: 1,\n mail: 2,\n daemon: 3,\n security: 4,\n syslog: 5,\n lpr: 6,\n news: 7,\n uucp: 8,\n cron: 9,\n authpriv: 10,\n ftp: 11,\n ntp: 12,\n logaudit: 13,\n logalert: 14,\n clock: 15,\n local0: 16,\n local1: 17,\n local2: 18,\n local3: 19,\n local4: 20,\n local5: 21,\n local6: 22,\n local7: 23,\n};\n\n/**\n * Syslog severity levels as defined in RFC 5424.\n * @since 0.12.0\n */\nconst SEVERITY_LEVELS: Record<LogLevel, number> = {\n fatal: 0, // Emergency: system is unusable\n error: 3, // Error: error conditions\n warning: 4, // Warning: warning conditions\n info: 6, // Informational: informational messages\n debug: 7, // Debug: debug-level messages\n trace: 7, // Debug: debug-level messages (same as debug)\n};\n\n/**\n * TLS options for secure TCP connections.\n * @since 1.3.0\n */\nexport interface SyslogTlsOptions {\n /**\n * Whether to reject connections with invalid certificates.\n * Setting this to `false` disables certificate validation, which makes\n * the connection vulnerable to man-in-the-middle attacks.\n * @default `true`\n */\n readonly rejectUnauthorized?: boolean;\n\n /**\n * Custom CA certificates to trust. If not provided, the default system\n * CA certificates are used.\n */\n readonly ca?: string | readonly string[];\n}\n\n/**\n * Options for the syslog sink.\n * @since 0.12.0\n */\nexport interface SyslogSinkOptions {\n /**\n * The hostname or IP address of the syslog server.\n * @default \"localhost\"\n */\n readonly hostname?: string;\n\n /**\n * The port number of the syslog server.\n * @default 514\n */\n readonly port?: number;\n\n /**\n * The protocol to use for sending syslog messages.\n * @default \"udp\"\n */\n readonly protocol?: SyslogProtocol;\n\n /**\n * Whether to use TLS for TCP connections.\n * This option is ignored for UDP connections.\n * @default `false`\n * @since 1.3.0\n */\n readonly secure?: boolean;\n\n /**\n * TLS options for secure TCP connections.\n * This option is only used when `secure` is `true` and `protocol` is `\"tcp\"`.\n * @since 1.3.0\n */\n readonly tlsOptions?: SyslogTlsOptions;\n\n /**\n * The syslog facility to use for all messages.\n * @default \"local0\"\n */\n readonly facility?: SyslogFacility;\n\n /**\n * The application name to include in syslog messages.\n * @default \"logtape\"\n */\n readonly appName?: string;\n\n /**\n * The hostname to include in syslog messages.\n * If not provided, the system hostname will be used.\n */\n readonly syslogHostname?: string;\n\n /**\n * The process ID to include in syslog messages.\n * If not provided, the current process ID will be used.\n */\n readonly processId?: string;\n\n /**\n * Connection timeout in milliseconds.\n * @default 5000\n */\n readonly timeout?: number;\n\n /**\n * Whether to include structured data in syslog messages.\n * @default `false`\n */\n readonly includeStructuredData?: boolean;\n\n /**\n * The structured data ID to use for log properties.\n * Should follow the format \"name@private-enterprise-number\".\n * @default \"logtape@32473\"\n */\n readonly structuredDataId?: string;\n}\n\n/**\n * Calculates the priority value for a syslog message.\n * Priority = Facility * 8 + Severity\n * @since 0.12.0\n */\nfunction calculatePriority(facility: SyslogFacility, severity: number): number {\n const facilityCode = FACILITY_CODES[facility];\n return facilityCode * 8 + severity;\n}\n\n/**\n * Formats a timestamp (number) as RFC 3339 timestamp for syslog.\n * @since 0.12.0\n */\nfunction formatTimestamp(timestamp: number): string {\n return new Date(timestamp).toISOString();\n}\n\n/**\n * Escapes special characters in structured data values.\n * @since 0.12.0\n */\nfunction escapeStructuredDataValue(value: string): string {\n return value\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\"/g, '\\\\\"')\n .replace(/]/g, \"\\\\]\");\n}\n\n/**\n * Formats structured data from log record properties.\n * @since 0.12.0\n */\nfunction formatStructuredData(\n record: LogRecord,\n structuredDataId: string,\n): string {\n if (!record.properties || Object.keys(record.properties).length === 0) {\n return \"-\";\n }\n\n const elements: string[] = [];\n for (const [key, value] of Object.entries(record.properties)) {\n const escapedValue = escapeStructuredDataValue(String(value));\n elements.push(`${key}=\"${escapedValue}\"`);\n }\n\n return `[${structuredDataId} ${elements.join(\" \")}]`;\n}\n\n/**\n * Formats a log record as RFC 5424 syslog message.\n * @since 0.12.0\n */\nfunction formatSyslogMessage(\n record: LogRecord,\n options: Required<\n Pick<\n SyslogSinkOptions,\n | \"facility\"\n | \"appName\"\n | \"syslogHostname\"\n | \"processId\"\n | \"includeStructuredData\"\n | \"structuredDataId\"\n >\n >,\n): string {\n const severity = SEVERITY_LEVELS[record.level];\n const priority = calculatePriority(options.facility, severity);\n const timestamp = formatTimestamp(record.timestamp);\n const hostname = options.syslogHostname || \"-\";\n const appName = options.appName || \"-\";\n const processId = options.processId || \"-\";\n const msgId = \"-\"; // Could be enhanced to include message ID\n\n let structuredData = \"-\";\n if (options.includeStructuredData) {\n structuredData = formatStructuredData(record, options.structuredDataId);\n }\n\n // Format the message text\n let message = \"\";\n for (let i = 0; i < record.message.length; i++) {\n if (i % 2 === 0) {\n message += record.message[i];\n } else {\n message += JSON.stringify(record.message[i]);\n }\n }\n\n // RFC 5424 format: <PRI>VERSION TIMESTAMP HOSTNAME APP-NAME PROCID MSGID STRUCTURED-DATA MSG\n return `<${priority}>1 ${timestamp} ${hostname} ${appName} ${processId} ${msgId} ${structuredData} ${message}`;\n}\n\n/**\n * Gets the system hostname.\n * @since 0.12.0\n */\nfunction getSystemHostname(): string {\n try {\n // Try Deno first\n if (typeof Deno !== \"undefined\" && Deno.hostname) {\n return Deno.hostname();\n }\n\n // Try Node.js os.hostname()\n return hostname();\n } catch {\n // Fallback to environment variable or localhost\n return process.env.HOSTNAME || \"localhost\";\n }\n}\n\n/**\n * Gets the current process ID.\n * @since 0.12.0\n */\nfunction getProcessId(): string {\n try {\n // Try Deno first\n if (typeof Deno !== \"undefined\" && Deno.pid) {\n return Deno.pid.toString();\n }\n\n // Try Node.js\n return process.pid.toString();\n } catch {\n return \"-\";\n }\n}\n\n/**\n * Base interface for syslog connections.\n * @since 0.12.0\n */\nexport interface SyslogConnection {\n connect(): void | Promise<void>;\n send(message: string): Promise<void>;\n close(): void;\n}\n\n/**\n * Deno UDP syslog connection implementation.\n * @since 0.12.0\n */\nexport class DenoUdpSyslogConnection implements SyslogConnection {\n private encoder = new TextEncoder();\n\n constructor(\n private hostname: string,\n private port: number,\n private timeout: number,\n ) {}\n\n connect(): void {\n // For UDP, we don't need to establish a persistent connection\n }\n\n send(message: string): Promise<void> {\n const data = this.encoder.encode(message);\n\n try {\n // Deno doesn't have native UDP support, use Node.js APIs\n const socket = createSocket(\"udp4\");\n\n if (this.timeout > 0) {\n return new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n socket.close();\n reject(new Error(\"UDP send timeout\"));\n }, this.timeout);\n\n socket.send(data, this.port, this.hostname, (error) => {\n clearTimeout(timeout);\n socket.close();\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n } else {\n // No timeout\n return new Promise<void>((resolve, reject) => {\n socket.send(data, this.port, this.hostname, (error) => {\n socket.close();\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n }\n } catch (error) {\n throw new Error(`Failed to send syslog message: ${error}`);\n }\n }\n\n close(): void {\n // UDP connections don't need explicit closing\n }\n}\n\n/**\n * Node.js UDP syslog connection implementation.\n * @since 0.12.0\n */\nexport class NodeUdpSyslogConnection implements SyslogConnection {\n private encoder = new TextEncoder();\n\n constructor(\n private hostname: string,\n private port: number,\n private timeout: number,\n ) {}\n\n connect(): void {\n // For UDP, we don't need to establish a persistent connection\n }\n\n send(message: string): Promise<void> {\n const data = this.encoder.encode(message);\n\n try {\n const socket = createSocket(\"udp4\");\n\n return new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n socket.close();\n reject(new Error(\"UDP send timeout\"));\n }, this.timeout);\n\n socket.send(data, this.port, this.hostname, (error) => {\n clearTimeout(timeout);\n socket.close();\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n } catch (error) {\n throw new Error(`Failed to send syslog message: ${error}`);\n }\n }\n\n close(): void {\n // UDP connections don't need explicit closing\n }\n}\n\n/**\n * Deno TCP syslog connection implementation.\n * @since 0.12.0\n */\nexport class DenoTcpSyslogConnection implements SyslogConnection {\n private connection?: Deno.TcpConn | Deno.TlsConn;\n private encoder = new TextEncoder();\n\n constructor(\n private hostname: string,\n private port: number,\n private timeout: number,\n private secure: boolean,\n private tlsOptions?: SyslogTlsOptions,\n ) {}\n\n async connect(): Promise<void> {\n try {\n const connectOptions: Deno.ConnectOptions = {\n hostname: this.hostname,\n port: this.port,\n transport: \"tcp\",\n };\n\n if (this.secure) {\n const tlsConnectOptions: Deno.ConnectTlsOptions = {\n hostname: this.hostname,\n port: this.port,\n caCerts: this.tlsOptions?.ca\n ? (Array.isArray(this.tlsOptions.ca)\n ? [...this.tlsOptions.ca]\n : [this.tlsOptions.ca])\n : undefined,\n };\n const connectPromise = Deno.connectTls(tlsConnectOptions);\n if (this.timeout > 0) {\n let timeoutId: number;\n let timedOut = false;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n timedOut = true;\n reject(new Error(\"TCP connection timeout\"));\n }, this.timeout);\n });\n\n try {\n this.connection = await Promise.race([\n connectPromise,\n timeoutPromise,\n ]);\n } catch (error) {\n // If timed out, clean up the connection when it eventually completes\n if (timedOut) {\n connectPromise\n .then((conn) => {\n try {\n conn.close();\n } catch {\n // Ignore close errors\n }\n })\n .catch(() => {\n // Ignore connection errors\n });\n }\n throw error;\n } finally {\n clearTimeout(timeoutId!);\n }\n } else {\n this.connection = await connectPromise;\n }\n } else { // Insecure TCP connection\n if (this.timeout > 0) {\n // Use AbortController for proper timeout handling\n const controller = new AbortController();\n const timeoutId = setTimeout(() => {\n controller.abort();\n }, this.timeout);\n\n try {\n this.connection = await Deno.connect({\n ...connectOptions,\n signal: controller.signal,\n });\n clearTimeout(timeoutId);\n } catch (error) {\n clearTimeout(timeoutId);\n if (controller.signal.aborted) {\n throw new Error(\"TCP connection timeout\");\n }\n throw error;\n }\n } else {\n this.connection = await Deno.connect(connectOptions);\n }\n }\n } catch (error) {\n throw new Error(`Failed to connect to syslog server: ${error}`);\n }\n }\n\n async send(message: string): Promise<void> {\n if (!this.connection) {\n throw new Error(\"Connection not established\");\n }\n\n const data = this.encoder.encode(message + \"\\n\");\n\n try {\n if (this.timeout > 0) {\n // Implement timeout for send using Promise.race\n const writePromise = this.connection.write(data);\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => {\n reject(new Error(\"TCP send timeout\"));\n }, this.timeout);\n });\n\n await Promise.race([writePromise, timeoutPromise]);\n } else {\n // No timeout\n await this.connection.write(data);\n }\n } catch (error) {\n throw new Error(`Failed to send syslog message: ${error}`);\n }\n }\n\n close(): void {\n if (this.connection) {\n try {\n this.connection.close();\n } catch {\n // Ignore errors during close\n }\n this.connection = undefined;\n }\n }\n}\n\n/**\n * Node.js TCP syslog connection implementation.\n * @since 0.12.0\n */\nexport class NodeTcpSyslogConnection implements SyslogConnection {\n private connection?: Socket | tls.TLSSocket;\n private encoder = new TextEncoder();\n\n constructor(\n private hostname: string,\n private port: number,\n private timeout: number,\n private secure: boolean,\n private tlsOptions?: SyslogTlsOptions,\n ) {}\n\n connect(): Promise<void> {\n try {\n return new Promise<void>((resolve, reject) => {\n const connectionOptions: tls.ConnectionOptions = {\n port: this.port,\n host: this.hostname,\n timeout: this.timeout,\n rejectUnauthorized: this.tlsOptions?.rejectUnauthorized ?? true,\n ca: this.tlsOptions?.ca\n ? (Array.isArray(this.tlsOptions.ca)\n ? [...this.tlsOptions.ca]\n : [this.tlsOptions.ca])\n : undefined,\n };\n\n const socket: Socket | tls.TLSSocket = this.secure\n ? tls.connect(connectionOptions)\n : new Socket();\n\n const timeout = setTimeout(() => {\n socket.destroy();\n reject(new Error(\"TCP connection timeout\"));\n }, this.timeout);\n\n socket.on(\"connect\", () => {\n clearTimeout(timeout);\n this.connection = socket;\n resolve();\n });\n\n socket.on(\"error\", (error) => {\n clearTimeout(timeout);\n reject(error);\n });\n\n // For non-TLS sockets, explicitly call connect\n if (!this.secure) {\n (socket as Socket).connect(this.port, this.hostname);\n }\n });\n } catch (error) {\n throw new Error(`Failed to connect to syslog server: ${error}`);\n }\n }\n\n send(message: string): Promise<void> {\n if (!this.connection) {\n throw new Error(\"Connection not established\");\n }\n\n const data = this.encoder.encode(message + \"\\n\");\n\n try {\n return new Promise<void>((resolve, reject) => {\n this.connection!.write(data, (error?: Error | null) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n } catch (error) {\n throw new Error(`Failed to send syslog message: ${error}`);\n }\n }\n\n close(): void {\n if (this.connection) {\n try {\n this.connection.end();\n } catch {\n // Ignore errors during close\n }\n this.connection = undefined;\n }\n }\n}\n\n/**\n * Creates a syslog sink that sends log messages to a syslog server using the\n * RFC 5424 syslog protocol format.\n *\n * This sink supports both UDP and TCP protocols for reliable log transmission\n * to centralized logging systems. It automatically formats log records according\n * to RFC 5424 specification, including structured data support for log properties.\n *\n * ## Features\n *\n * - **RFC 5424 Compliance**: Full implementation of the RFC 5424 syslog protocol\n * - **Cross-Runtime Support**: Works with Deno, Node.js, Bun, and browsers\n * - **Multiple Protocols**: Supports both UDP (fire-and-forget) and TCP (reliable) delivery\n * - **Structured Data**: Automatically includes log record properties as RFC 5424 structured data\n * - **Facility Support**: All standard syslog facilities (kern, user, mail, daemon, local0-7, etc.)\n * - **Automatic Escaping**: Proper escaping of special characters in structured data values\n * - **Connection Management**: Automatic connection handling with configurable timeouts\n *\n * ## Protocol Differences\n *\n * - **UDP**: Fast, connectionless delivery suitable for high-throughput logging.\n * Messages may be lost during network issues but has minimal performance impact.\n * - **TCP**: Reliable, connection-based delivery that ensures message delivery.\n * Higher overhead but guarantees that log messages reach the server.\n *\n * @param options Configuration options for the syslog sink\n * @returns A sink function that sends log records to the syslog server, implementing AsyncDisposable for proper cleanup\n *\n * @example Basic usage with default options\n * ```typescript\n * import { configure } from \"@logtape/logtape\";\n * import { getSyslogSink } from \"@logtape/syslog\";\n *\n * await configure({\n * sinks: {\n * syslog: getSyslogSink(), // Sends to localhost:514 via UDP\n * },\n * loggers: [\n * { category: [], sinks: [\"syslog\"], lowestLevel: \"info\" },\n * ],\n * });\n * ```\n *\n * @example Custom syslog server configuration\n * ```typescript\n * import { configure } from \"@logtape/logtape\";\n * import { getSyslogSink } from \"@logtape/syslog\";\n *\n * await configure({\n * sinks: {\n * syslog: getSyslogSink({\n * hostname: \"log-server.example.com\",\n * port: 1514,\n * protocol: \"tcp\",\n * facility: \"mail\",\n * appName: \"my-application\",\n * timeout: 10000,\n * }),\n * },\n * loggers: [\n * { category: [], sinks: [\"syslog\"], lowestLevel: \"debug\" },\n * ],\n * });\n * ```\n *\n * @example Using structured data for log properties\n * ```typescript\n * import { configure, getLogger } from \"@logtape/logtape\";\n * import { getSyslogSink } from \"@logtape/syslog\";\n *\n * await configure({\n * sinks: {\n * syslog: getSyslogSink({\n * includeStructuredData: true,\n * structuredDataId: \"myapp@12345\",\n * }),\n * },\n * loggers: [\n * { category: [], sinks: [\"syslog\"], lowestLevel: \"info\" },\n * ],\n * });\n *\n * const logger = getLogger();\n * // This will include userId and action as structured data\n * logger.info(\"User action completed\", { userId: 123, action: \"login\" });\n * // Results in: <134>1 2024-01-01T12:00:00.000Z hostname myapp 1234 - [myapp@12345 userId=\"123\" action=\"login\"] User action completed\n * ```\n *\n * @since 0.12.0\n * @see {@link https://tools.ietf.org/html/rfc5424} RFC 5424 - The Syslog Protocol\n * @see {@link SyslogSinkOptions} for detailed configuration options\n */\nexport function getSyslogSink(\n options: SyslogSinkOptions = {},\n): Sink & AsyncDisposable {\n const hostname = options.hostname ?? \"localhost\";\n const port = options.port ?? 514;\n const protocol = options.protocol ?? \"udp\";\n const secure = options.secure ?? false;\n const tlsOptions = options.tlsOptions;\n const facility = options.facility ?? \"local0\";\n const appName = options.appName ?? \"logtape\";\n const syslogHostname = options.syslogHostname ?? getSystemHostname();\n const processId = options.processId ?? getProcessId();\n const timeout = options.timeout ?? 5000;\n const includeStructuredData = options.includeStructuredData ?? false;\n const structuredDataId = options.structuredDataId ?? \"logtape@32473\";\n\n const formatOptions = {\n facility,\n appName,\n syslogHostname,\n processId,\n includeStructuredData,\n structuredDataId,\n };\n\n // Create connection based on protocol and runtime\n const connection: SyslogConnection = (() => {\n if (typeof Deno !== \"undefined\") {\n // Deno runtime\n return protocol === \"tcp\"\n ? new DenoTcpSyslogConnection(\n hostname,\n port,\n timeout,\n secure,\n tlsOptions,\n )\n : new DenoUdpSyslogConnection(hostname, port, timeout);\n } else {\n // Node.js runtime (and Bun, which uses Node.js APIs)\n return protocol === \"tcp\"\n ? new NodeTcpSyslogConnection(\n hostname,\n port,\n timeout,\n secure,\n tlsOptions,\n )\n : new NodeUdpSyslogConnection(hostname, port, timeout);\n }\n })();\n\n let isConnected = false;\n let lastPromise = Promise.resolve();\n\n const sink: Sink & AsyncDisposable = (record: LogRecord) => {\n const syslogMessage = formatSyslogMessage(record, formatOptions);\n\n lastPromise = lastPromise\n .then(async () => {\n if (!isConnected) {\n await connection.connect();\n isConnected = true;\n }\n await connection.send(syslogMessage);\n })\n .catch((error) => {\n // If connection fails, try to reconnect on next message\n isConnected = false;\n throw error;\n });\n };\n\n sink[Symbol.asyncDispose] = async () => {\n await lastPromise.catch(() => {}); // Wait for any pending operations\n connection.close();\n isConnected = false;\n };\n\n // Expose for testing purposes\n Object.defineProperty(sink, \"_internal_lastPromise\", {\n get: () => lastPromise,\n enumerable: false,\n });\n\n return sink;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logtape/syslog",
3
- "version": "1.3.0-dev.388+fd5ba0d5",
3
+ "version": "1.3.0-dev.398+af761cb5",
4
4
  "description": "Syslog sink for LogTape",
5
5
  "keywords": [
6
6
  "logging",
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "sideEffects": false,
47
47
  "peerDependencies": {
48
- "@logtape/logtape": "^1.3.0-dev.388+fd5ba0d5"
48
+ "@logtape/logtape": "^1.3.0-dev.398+af761cb5"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@alinea/suite": "^0.6.3",
package/src/mod.ts CHANGED
@@ -11,5 +11,6 @@ export type {
11
11
  SyslogFacility,
12
12
  SyslogProtocol,
13
13
  SyslogSinkOptions,
14
+ SyslogTlsOptions,
14
15
  } from "./syslog.ts";
15
16
  export { getSyslogSink } from "./syslog.ts";