@rabbit-company/logger 5.2.0 → 5.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -2
- package/module/logger.d.ts +262 -0
- package/module/logger.js +241 -0
- package/package.json +4 -5
package/README.md
CHANGED
|
@@ -10,10 +10,10 @@ A high-performance, multi-transport logging library for Node.js and browser envi
|
|
|
10
10
|
|
|
11
11
|
- **Multi-level logging**: 8 severity levels from ERROR to SILLY
|
|
12
12
|
- **Structured logging**: Attach rich metadata to log entries
|
|
13
|
-
- **Multiple transports**: Console, NDJSON,
|
|
13
|
+
- **Multiple transports**: Console, NDJSON, Grafana Loki and Syslog
|
|
14
14
|
- **Advanced formatting**: Customizable console output with extensive datetime options
|
|
15
15
|
- **Production-ready**: Batching, retries, and queue management for Loki
|
|
16
|
-
- **Cross-platform**: Works in Node.js, Deno
|
|
16
|
+
- **Cross-platform**: Works in Node.js, Deno and Bun
|
|
17
17
|
- **Type-safe**: Full TypeScript definitions included
|
|
18
18
|
|
|
19
19
|
## Installation 📦
|
|
@@ -162,6 +162,37 @@ const logger = new Logger({
|
|
|
162
162
|
});
|
|
163
163
|
```
|
|
164
164
|
|
|
165
|
+
### Syslog Transport
|
|
166
|
+
|
|
167
|
+
```js
|
|
168
|
+
import { SyslogTransport } from "@rabbit-company/logger";
|
|
169
|
+
|
|
170
|
+
const syslogTransport = new SyslogTransport({
|
|
171
|
+
host: "syslog.example.com",
|
|
172
|
+
port: 514,
|
|
173
|
+
protocol: "udp", // 'udp', 'tcp', or 'tcp-tls'
|
|
174
|
+
facility: 16, // local0 facility
|
|
175
|
+
appName: "my-app",
|
|
176
|
+
protocolVersion: 5424, // 3164 (BSD) or 5424 (modern)
|
|
177
|
+
tlsOptions: {
|
|
178
|
+
ca: fs.readFileSync("ca.pem"),
|
|
179
|
+
rejectUnauthorized: true,
|
|
180
|
+
},
|
|
181
|
+
maxQueueSize: 2000, // Max queued messages during outages
|
|
182
|
+
debug: true, // Log connection status
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
const logger = new Logger({
|
|
186
|
+
transports: [syslogTransport],
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// Features:
|
|
190
|
+
// - Automatic reconnection with exponential backoff
|
|
191
|
+
// - Message queuing during network issues
|
|
192
|
+
// - Supports UDP, TCP, and TLS encryption
|
|
193
|
+
// - Compliant with RFC 3164 and RFC 5424
|
|
194
|
+
```
|
|
195
|
+
|
|
165
196
|
## API Reference 📚
|
|
166
197
|
|
|
167
198
|
Full API documentation is available in the [TypeScript definitions](https://github.com/Rabbit-Company/Logger-JS/blob/main/src/types.ts).
|
package/module/logger.d.ts
CHANGED
|
@@ -322,6 +322,155 @@ export interface LokiStream {
|
|
|
322
322
|
]
|
|
323
323
|
];
|
|
324
324
|
}
|
|
325
|
+
/**
|
|
326
|
+
* Configuration options for Syslog transport
|
|
327
|
+
* @interface SyslogConfig
|
|
328
|
+
* @description Defines the configuration parameters for establishing a connection
|
|
329
|
+
* to a syslog server and customizing log message formatting.
|
|
330
|
+
*
|
|
331
|
+
* @example
|
|
332
|
+
* // Basic UDP configuration
|
|
333
|
+
* const config: SyslogConfig = {
|
|
334
|
+
* host: 'logs.example.com',
|
|
335
|
+
* port: 514,
|
|
336
|
+
* protocol: 'udp'
|
|
337
|
+
* };
|
|
338
|
+
*
|
|
339
|
+
* @example
|
|
340
|
+
* // Secure TCP with TLS configuration
|
|
341
|
+
* const secureConfig: SyslogConfig = {
|
|
342
|
+
* host: 'secure-logs.example.com',
|
|
343
|
+
* port: 6514,
|
|
344
|
+
* protocol: 'tcp-tls',
|
|
345
|
+
* tlsOptions: {
|
|
346
|
+
* ca: fs.readFileSync('ca.pem'),
|
|
347
|
+
* cert: fs.readFileSync('client-cert.pem'),
|
|
348
|
+
* key: fs.readFileSync('client-key.pem'),
|
|
349
|
+
* rejectUnauthorized: true
|
|
350
|
+
* },
|
|
351
|
+
* appName: 'my-service',
|
|
352
|
+
* facility: 16 // local0
|
|
353
|
+
* };
|
|
354
|
+
*/
|
|
355
|
+
export interface SyslogConfig {
|
|
356
|
+
/**
|
|
357
|
+
* Syslog server hostname or IP address
|
|
358
|
+
* @type {string}
|
|
359
|
+
* @default 'localhost'
|
|
360
|
+
* @example 'logs.example.com'
|
|
361
|
+
* @example '192.168.1.100'
|
|
362
|
+
*/
|
|
363
|
+
host?: string;
|
|
364
|
+
/**
|
|
365
|
+
* Syslog server port number
|
|
366
|
+
* @type {number}
|
|
367
|
+
* @default 514
|
|
368
|
+
* @example 514 // Standard syslog port
|
|
369
|
+
* @example 6514 // Common port for syslog over TLS
|
|
370
|
+
*/
|
|
371
|
+
port?: number;
|
|
372
|
+
/**
|
|
373
|
+
* Network protocol to use for syslog transmission
|
|
374
|
+
* @type {'udp' | 'tcp' | 'tcp-tls'}
|
|
375
|
+
* @default 'udp'
|
|
376
|
+
* @description
|
|
377
|
+
* - 'udp': Unreliable but fast (RFC 3164 compatible)
|
|
378
|
+
* - 'tcp': Reliable connection (RFC 6587)
|
|
379
|
+
* - 'tcp-tls': Encrypted connection (RFC 5425)
|
|
380
|
+
*/
|
|
381
|
+
protocol?: "udp" | "tcp" | "tcp-tls";
|
|
382
|
+
/**
|
|
383
|
+
* Syslog facility code
|
|
384
|
+
* @type {number}
|
|
385
|
+
* @range 0-23
|
|
386
|
+
* @default 1 // USER
|
|
387
|
+
* @description
|
|
388
|
+
* Standard syslog facilities:
|
|
389
|
+
* - 0: kern - Kernel messages
|
|
390
|
+
* - 1: user - User-level messages
|
|
391
|
+
* - 2: mail - Mail system
|
|
392
|
+
* - 3: daemon - System daemons
|
|
393
|
+
* - 4: auth - Security/authentication
|
|
394
|
+
* - 5: syslog - Internal syslog messages
|
|
395
|
+
* - 6: lpr - Line printer subsystem
|
|
396
|
+
* - 7: news - Network news subsystem
|
|
397
|
+
* - 8: uucp - UUCP subsystem
|
|
398
|
+
* - 9: cron - Clock daemon
|
|
399
|
+
* - 10: authpriv - Security/authentication
|
|
400
|
+
* - 11: ftp - FTP daemon
|
|
401
|
+
* - 16-23: local0-local7 - Locally used facilities
|
|
402
|
+
*/
|
|
403
|
+
facility?: number;
|
|
404
|
+
/**
|
|
405
|
+
* Application name identifier included in syslog messages
|
|
406
|
+
* @type {string}
|
|
407
|
+
* @default 'node'
|
|
408
|
+
* @description
|
|
409
|
+
* Should be a short string (typically <= 32 chars) identifying the application.
|
|
410
|
+
* @example 'auth-service'
|
|
411
|
+
* @example 'payment-processor'
|
|
412
|
+
*/
|
|
413
|
+
appName?: string;
|
|
414
|
+
/**
|
|
415
|
+
* Process ID included in syslog messages
|
|
416
|
+
* @type {number}
|
|
417
|
+
* @default process.pid
|
|
418
|
+
* @description
|
|
419
|
+
* Used to identify the specific process generating the log message.
|
|
420
|
+
*/
|
|
421
|
+
pid?: number;
|
|
422
|
+
/**
|
|
423
|
+
* Syslog protocol version specification
|
|
424
|
+
* @type {3164 | 5424}
|
|
425
|
+
* @default 5424
|
|
426
|
+
* @description
|
|
427
|
+
* - 3164: Traditional BSD syslog format (RFC 3164)
|
|
428
|
+
* - 5424: Modern structured syslog format (RFC 5424)
|
|
429
|
+
*/
|
|
430
|
+
protocolVersion?: 3164 | 5424;
|
|
431
|
+
/**
|
|
432
|
+
* TLS configuration options for secure connections
|
|
433
|
+
* @type {Object}
|
|
434
|
+
* @description Required when protocol is 'tcp-tls'
|
|
435
|
+
* @property {string} [ca] - PEM encoded CA certificate
|
|
436
|
+
* @property {string} [cert] - PEM encoded client certificate
|
|
437
|
+
* @property {string} [key] - PEM encoded client private key
|
|
438
|
+
* @property {boolean} [rejectUnauthorized=true] - Verify server certificate
|
|
439
|
+
*/
|
|
440
|
+
tlsOptions?: {
|
|
441
|
+
/** CA certificate */
|
|
442
|
+
ca?: string;
|
|
443
|
+
/** Client certificate */
|
|
444
|
+
cert?: string;
|
|
445
|
+
/** Client private key */
|
|
446
|
+
key?: string;
|
|
447
|
+
/** Whether to reject unauthorized certificates (default: true) */
|
|
448
|
+
rejectUnauthorized?: boolean;
|
|
449
|
+
};
|
|
450
|
+
/**
|
|
451
|
+
* Maximum number of log messages to buffer in memory
|
|
452
|
+
* @type {number}
|
|
453
|
+
* @default 1000
|
|
454
|
+
* @description
|
|
455
|
+
* When the queue reaches this size, oldest messages will be dropped.
|
|
456
|
+
* Set to 0 for unlimited (not recommended in production).
|
|
457
|
+
*/
|
|
458
|
+
maxQueueSize?: number;
|
|
459
|
+
/**
|
|
460
|
+
* Initial retry delay in milliseconds (exponential backoff base)
|
|
461
|
+
* @description Delay doubles with each retry up to maximum 30s
|
|
462
|
+
* @default 1000
|
|
463
|
+
*/
|
|
464
|
+
retryBaseDelay?: number;
|
|
465
|
+
/**
|
|
466
|
+
* Enable debug output for transport operations
|
|
467
|
+
* @type {boolean}
|
|
468
|
+
* @default false
|
|
469
|
+
* @description
|
|
470
|
+
* When true, outputs connection status and error details to console.
|
|
471
|
+
*/
|
|
472
|
+
debug?: boolean;
|
|
473
|
+
}
|
|
325
474
|
/**
|
|
326
475
|
* Main Logger class that handles all logging functionality.
|
|
327
476
|
*
|
|
@@ -755,5 +904,118 @@ export declare class LokiTransport implements Transport {
|
|
|
755
904
|
*/
|
|
756
905
|
private sendBatch;
|
|
757
906
|
}
|
|
907
|
+
/**
|
|
908
|
+
* Syslog transport implementation for the logger library
|
|
909
|
+
* @class SyslogTransport
|
|
910
|
+
* @implements {Transport}
|
|
911
|
+
* @description A robust syslog client that supports UDP, TCP, and TLS-encrypted TCP connections
|
|
912
|
+
* with automatic reconnection and message queuing capabilities.
|
|
913
|
+
*
|
|
914
|
+
* @example
|
|
915
|
+
* // Basic UDP configuration
|
|
916
|
+
* const transport = new SyslogTransport({
|
|
917
|
+
* host: 'logs.example.com',
|
|
918
|
+
* port: 514,
|
|
919
|
+
* protocol: 'udp'
|
|
920
|
+
* });
|
|
921
|
+
*
|
|
922
|
+
* @example
|
|
923
|
+
* // Secure TLS configuration
|
|
924
|
+
* const secureTransport = new SyslogTransport({
|
|
925
|
+
* host: 'secure-logs.example.com',
|
|
926
|
+
* port: 6514,
|
|
927
|
+
* protocol: 'tcp-tls',
|
|
928
|
+
* tlsOptions: {
|
|
929
|
+
* ca: fs.readFileSync('ca.pem'),
|
|
930
|
+
* rejectUnauthorized: true
|
|
931
|
+
* },
|
|
932
|
+
* maxQueueSize: 5000
|
|
933
|
+
* });
|
|
934
|
+
*/
|
|
935
|
+
export declare class SyslogTransport implements Transport {
|
|
936
|
+
private socket;
|
|
937
|
+
private queue;
|
|
938
|
+
private isConnecting;
|
|
939
|
+
private retryCount;
|
|
940
|
+
private retryBaseDelay;
|
|
941
|
+
private maxQueueSize;
|
|
942
|
+
private debug;
|
|
943
|
+
private reconnectTimer;
|
|
944
|
+
private config;
|
|
945
|
+
/**
|
|
946
|
+
* Creates a new SyslogTransport instance
|
|
947
|
+
* @constructor
|
|
948
|
+
* @param {SyslogConfig} [config={}] - Configuration options for the transport
|
|
949
|
+
*/
|
|
950
|
+
constructor(config?: SyslogConfig);
|
|
951
|
+
/**
|
|
952
|
+
* Initializes the appropriate socket based on configured protocol
|
|
953
|
+
* @private
|
|
954
|
+
* @returns {void}
|
|
955
|
+
*/
|
|
956
|
+
private initializeSocket;
|
|
957
|
+
/**
|
|
958
|
+
* Initializes a UDP socket for syslog transmission
|
|
959
|
+
* @private
|
|
960
|
+
* @returns {void}
|
|
961
|
+
*/
|
|
962
|
+
private initializeUdpSocket;
|
|
963
|
+
/**
|
|
964
|
+
* Initializes a TCP socket for syslog transmission
|
|
965
|
+
* @private
|
|
966
|
+
* @returns {void}
|
|
967
|
+
*/
|
|
968
|
+
private initializeTcpSocket;
|
|
969
|
+
/**
|
|
970
|
+
* Initializes a TLS-secured TCP socket for syslog transmission
|
|
971
|
+
* @private
|
|
972
|
+
* @returns {void}
|
|
973
|
+
*/
|
|
974
|
+
private initializeTlsSocket;
|
|
975
|
+
/**
|
|
976
|
+
* Sets up common event handlers for TCP/TLS sockets
|
|
977
|
+
* @private
|
|
978
|
+
* @returns {void}
|
|
979
|
+
*/
|
|
980
|
+
private setupTcpSocketEvents;
|
|
981
|
+
/**
|
|
982
|
+
* Establishes a TCP connection to the syslog server
|
|
983
|
+
* @private
|
|
984
|
+
* @returns {void}
|
|
985
|
+
*/
|
|
986
|
+
private connectTcpSocket;
|
|
987
|
+
/**
|
|
988
|
+
* Handles socket errors and initiates reconnection if needed
|
|
989
|
+
* @private
|
|
990
|
+
* @returns {void}
|
|
991
|
+
*/
|
|
992
|
+
private handleSocketError;
|
|
993
|
+
/**
|
|
994
|
+
* Sends all queued messages to the syslog server
|
|
995
|
+
* @private
|
|
996
|
+
* @returns {void}
|
|
997
|
+
*/
|
|
998
|
+
private flushQueue;
|
|
999
|
+
/**
|
|
1000
|
+
* Sends a single message to the syslog server
|
|
1001
|
+
* @private
|
|
1002
|
+
* @param {string} message - The formatted syslog message to send
|
|
1003
|
+
* @returns {void}
|
|
1004
|
+
*/
|
|
1005
|
+
private sendMessage;
|
|
1006
|
+
/**
|
|
1007
|
+
* Processes a log entry by formatting and queueing it for transmission
|
|
1008
|
+
* @public
|
|
1009
|
+
* @param {LogEntry} entry - The log entry to process
|
|
1010
|
+
* @returns {void}
|
|
1011
|
+
*/
|
|
1012
|
+
log(entry: LogEntry): void;
|
|
1013
|
+
/**
|
|
1014
|
+
* Gracefully closes the transport connection
|
|
1015
|
+
* @public
|
|
1016
|
+
* @returns {Promise<void>} A promise that resolves when the connection is closed
|
|
1017
|
+
*/
|
|
1018
|
+
close(): Promise<void>;
|
|
1019
|
+
}
|
|
758
1020
|
|
|
759
1021
|
export {};
|
package/module/logger.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
3
|
+
|
|
1
4
|
// src/constants/colors.ts
|
|
2
5
|
var Colors;
|
|
3
6
|
((Colors2) => {
|
|
@@ -324,7 +327,245 @@ class LokiTransport {
|
|
|
324
327
|
}
|
|
325
328
|
}
|
|
326
329
|
}
|
|
330
|
+
// src/formatters/syslogFormatter.ts
|
|
331
|
+
var SYSLOG_SEVERITY = {
|
|
332
|
+
[0 /* ERROR */]: 3,
|
|
333
|
+
[1 /* WARN */]: 4,
|
|
334
|
+
[2 /* AUDIT */]: 5,
|
|
335
|
+
[3 /* INFO */]: 6,
|
|
336
|
+
[4 /* HTTP */]: 6,
|
|
337
|
+
[5 /* DEBUG */]: 7,
|
|
338
|
+
[6 /* VERBOSE */]: 7,
|
|
339
|
+
[7 /* SILLY */]: 7
|
|
340
|
+
};
|
|
341
|
+
function formatRFC3164(entry, facility, appName, pid) {
|
|
342
|
+
const severity = SYSLOG_SEVERITY[entry.level];
|
|
343
|
+
const priority = facility << 3 | severity;
|
|
344
|
+
const timestamp = new Date(entry.timestamp).toLocaleString("en-US", {
|
|
345
|
+
month: "short",
|
|
346
|
+
day: "2-digit",
|
|
347
|
+
hour: "2-digit",
|
|
348
|
+
minute: "2-digit",
|
|
349
|
+
second: "2-digit",
|
|
350
|
+
hour12: false
|
|
351
|
+
}).replace(/,/, "").replace(" at ", " ");
|
|
352
|
+
const hostname = __require("os").hostname();
|
|
353
|
+
const msg = entry.metadata ? `${entry.message} ${JSON.stringify(entry.metadata)}` : entry.message;
|
|
354
|
+
return `<${priority}>${timestamp} ${hostname} ${appName}[${pid}]: ${msg}`;
|
|
355
|
+
}
|
|
356
|
+
function formatRFC5424(entry, facility, appName, pid) {
|
|
357
|
+
const severity = SYSLOG_SEVERITY[entry.level];
|
|
358
|
+
const priority = facility << 3 | severity;
|
|
359
|
+
const timestamp = new Date(entry.timestamp).toISOString();
|
|
360
|
+
const hostname = __require("os").hostname();
|
|
361
|
+
const msgId = "-";
|
|
362
|
+
const structuredData = entry.metadata ? `[example@1 ${Object.entries(entry.metadata).map(([key, val]) => `${key}="${val}"`).join(" ")}]` : "-";
|
|
363
|
+
return `<${priority}>1 ${timestamp} ${hostname} ${appName} ${pid} ${msgId} ${structuredData} ${entry.message}`;
|
|
364
|
+
}
|
|
365
|
+
function formatSyslogMessage(entry, config) {
|
|
366
|
+
const facility = config.facility ?? 1;
|
|
367
|
+
const appName = config.appName ?? "node";
|
|
368
|
+
const pid = config.pid ?? process.pid;
|
|
369
|
+
const protocolVersion = config.protocolVersion ?? 5424;
|
|
370
|
+
return protocolVersion === 3164 ? formatRFC3164(entry, facility, appName, pid) : formatRFC5424(entry, facility, appName, pid);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// src/transports/syslogTransport.ts
|
|
374
|
+
import { createSocket, Socket } from "dgram";
|
|
375
|
+
import { Socket as NetSocket } from "net";
|
|
376
|
+
import { connect as tlsConnect } from "tls";
|
|
377
|
+
|
|
378
|
+
class SyslogTransport {
|
|
379
|
+
socket = null;
|
|
380
|
+
queue = [];
|
|
381
|
+
isConnecting = false;
|
|
382
|
+
retryCount = 0;
|
|
383
|
+
retryBaseDelay;
|
|
384
|
+
maxQueueSize;
|
|
385
|
+
debug;
|
|
386
|
+
reconnectTimer = null;
|
|
387
|
+
config;
|
|
388
|
+
constructor(config = {}) {
|
|
389
|
+
this.maxQueueSize = config.maxQueueSize ?? 1000;
|
|
390
|
+
this.retryBaseDelay = config.retryBaseDelay ?? 1000;
|
|
391
|
+
this.debug = config.debug ?? false;
|
|
392
|
+
this.config = {
|
|
393
|
+
host: config.host ?? "localhost",
|
|
394
|
+
port: config.port ?? 514,
|
|
395
|
+
protocol: config.protocol ?? "udp",
|
|
396
|
+
facility: config.facility ?? 1,
|
|
397
|
+
appName: config.appName ?? "node",
|
|
398
|
+
pid: config.pid ?? process.pid,
|
|
399
|
+
protocolVersion: config.protocolVersion ?? 5424,
|
|
400
|
+
tlsOptions: config.tlsOptions || {}
|
|
401
|
+
};
|
|
402
|
+
this.initializeSocket();
|
|
403
|
+
}
|
|
404
|
+
initializeSocket() {
|
|
405
|
+
if (this.reconnectTimer) {
|
|
406
|
+
clearTimeout(this.reconnectTimer);
|
|
407
|
+
this.reconnectTimer = null;
|
|
408
|
+
}
|
|
409
|
+
if (this.socket) {
|
|
410
|
+
this.socket.removeAllListeners();
|
|
411
|
+
if (!("destroy" in this.socket)) {
|
|
412
|
+
this.socket.close();
|
|
413
|
+
} else {
|
|
414
|
+
this.socket.destroy();
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
if (this.config.protocol === "udp") {
|
|
418
|
+
this.initializeUdpSocket();
|
|
419
|
+
} else if (this.config.protocol === "tcp") {
|
|
420
|
+
this.initializeTcpSocket();
|
|
421
|
+
} else if (this.config.protocol === "tcp-tls") {
|
|
422
|
+
this.initializeTlsSocket();
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
initializeUdpSocket() {
|
|
426
|
+
this.socket = createSocket("udp4");
|
|
427
|
+
this.socket.on("error", (err) => {
|
|
428
|
+
if (this.debug)
|
|
429
|
+
console.error("Syslog UDP error:", err);
|
|
430
|
+
this.handleSocketError();
|
|
431
|
+
});
|
|
432
|
+
this.socket.on("close", () => {
|
|
433
|
+
if (this.debug)
|
|
434
|
+
console.log("Syslog UDP socket closed");
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
initializeTcpSocket() {
|
|
438
|
+
this.socket = new NetSocket;
|
|
439
|
+
this.setupTcpSocketEvents();
|
|
440
|
+
this.connectTcpSocket();
|
|
441
|
+
}
|
|
442
|
+
initializeTlsSocket() {
|
|
443
|
+
const tlsOptions = {
|
|
444
|
+
host: this.config.host,
|
|
445
|
+
port: this.config.port,
|
|
446
|
+
...this.config.tlsOptions
|
|
447
|
+
};
|
|
448
|
+
this.socket = tlsConnect(tlsOptions, () => {
|
|
449
|
+
if (this.debug)
|
|
450
|
+
console.log("Syslog TLS connection established");
|
|
451
|
+
this.retryCount = 0;
|
|
452
|
+
this.flushQueue();
|
|
453
|
+
});
|
|
454
|
+
this.setupTcpSocketEvents();
|
|
455
|
+
}
|
|
456
|
+
setupTcpSocketEvents() {
|
|
457
|
+
if (!this.socket)
|
|
458
|
+
return;
|
|
459
|
+
this.socket.on("error", (err) => {
|
|
460
|
+
if (this.debug)
|
|
461
|
+
console.error("Syslog TCP/TLS error:", err);
|
|
462
|
+
this.handleSocketError();
|
|
463
|
+
});
|
|
464
|
+
this.socket.on("close", () => {
|
|
465
|
+
if (this.debug)
|
|
466
|
+
console.log("Syslog TCP/TLS connection closed");
|
|
467
|
+
this.handleSocketError();
|
|
468
|
+
});
|
|
469
|
+
this.socket.on("end", () => {
|
|
470
|
+
if (this.debug)
|
|
471
|
+
console.log("Syslog TCP/TLS connection ended");
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
connectTcpSocket() {
|
|
475
|
+
if (this.isConnecting || !(this.socket instanceof NetSocket))
|
|
476
|
+
return;
|
|
477
|
+
this.isConnecting = true;
|
|
478
|
+
this.socket.connect(this.config.port, this.config.host, () => {
|
|
479
|
+
if (this.debug)
|
|
480
|
+
console.log("Syslog TCP connection established");
|
|
481
|
+
this.isConnecting = false;
|
|
482
|
+
this.retryCount = 0;
|
|
483
|
+
this.flushQueue();
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
handleSocketError() {
|
|
487
|
+
if (this.reconnectTimer)
|
|
488
|
+
return;
|
|
489
|
+
this.socket = null;
|
|
490
|
+
this.isConnecting = false;
|
|
491
|
+
this.retryCount++;
|
|
492
|
+
const delay = Math.min(this.retryBaseDelay * Math.pow(2, this.retryCount - 1), 30000);
|
|
493
|
+
if (this.debug)
|
|
494
|
+
console.log(`Attempting to reconnect in ${delay}ms (attempt ${this.retryCount})`);
|
|
495
|
+
this.reconnectTimer = setTimeout(() => {
|
|
496
|
+
this.initializeSocket();
|
|
497
|
+
}, delay);
|
|
498
|
+
}
|
|
499
|
+
flushQueue() {
|
|
500
|
+
if (!this.socket || this.queue.length === 0)
|
|
501
|
+
return;
|
|
502
|
+
while (this.queue.length > 0) {
|
|
503
|
+
const message = this.queue.shift();
|
|
504
|
+
if (message) {
|
|
505
|
+
this.sendMessage(message);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
sendMessage(message) {
|
|
510
|
+
if (!this.socket) {
|
|
511
|
+
this.queue.unshift(message);
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
try {
|
|
515
|
+
if (this.socket instanceof Socket) {
|
|
516
|
+
this.socket.send(message, this.config.port, this.config.host, (err) => {
|
|
517
|
+
if (err && this.debug)
|
|
518
|
+
console.error("Syslog UDP send error:", err);
|
|
519
|
+
});
|
|
520
|
+
} else {
|
|
521
|
+
this.socket.write(message + `
|
|
522
|
+
`, (err) => {
|
|
523
|
+
if (err && this.debug)
|
|
524
|
+
console.error("Syslog TCP/TLS send error:", err);
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
} catch (err) {
|
|
528
|
+
if (this.debug)
|
|
529
|
+
console.error("Syslog send error:", err);
|
|
530
|
+
this.queue.unshift(message);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
log(entry) {
|
|
534
|
+
const message = formatSyslogMessage(entry, this.config);
|
|
535
|
+
if (this.queue.length >= this.maxQueueSize) {
|
|
536
|
+
if (this.debug)
|
|
537
|
+
console.warn("Syslog queue full - dropping oldest message");
|
|
538
|
+
this.queue.shift();
|
|
539
|
+
}
|
|
540
|
+
this.queue.push(message);
|
|
541
|
+
if (this.socket && !this.isConnecting) {
|
|
542
|
+
this.flushQueue();
|
|
543
|
+
} else if (!this.socket && !this.isConnecting) {}
|
|
544
|
+
}
|
|
545
|
+
close() {
|
|
546
|
+
return new Promise((resolve) => {
|
|
547
|
+
if (this.reconnectTimer) {
|
|
548
|
+
clearTimeout(this.reconnectTimer);
|
|
549
|
+
this.reconnectTimer = null;
|
|
550
|
+
}
|
|
551
|
+
if (!this.socket) {
|
|
552
|
+
resolve();
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
const handleClose = () => {
|
|
556
|
+
resolve();
|
|
557
|
+
};
|
|
558
|
+
if ("destroy" in this.socket) {
|
|
559
|
+
this.socket.destroy();
|
|
560
|
+
process.nextTick(handleClose);
|
|
561
|
+
} else {
|
|
562
|
+
this.socket.close(handleClose);
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
}
|
|
327
567
|
export {
|
|
568
|
+
SyslogTransport,
|
|
328
569
|
NDJsonTransport,
|
|
329
570
|
LokiTransport,
|
|
330
571
|
Logger,
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rabbit-company/logger",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"description": "A simple and lightweight logger",
|
|
5
|
-
"main": "./module/
|
|
5
|
+
"main": "./module/logger.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"homepage": "https://github.com/Rabbit-Company/Logger-JS",
|
|
8
8
|
"funding": "https://rabbit-company.com/donation",
|
|
@@ -35,9 +35,8 @@
|
|
|
35
35
|
"loki"
|
|
36
36
|
],
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@types/bun": "
|
|
39
|
-
"bun-plugin-dts": "^0.3.0"
|
|
40
|
-
"@rabbit-company/logger": "^4.0.0"
|
|
38
|
+
"@types/bun": "latest",
|
|
39
|
+
"bun-plugin-dts": "^0.3.0"
|
|
41
40
|
},
|
|
42
41
|
"peerDependencies": {
|
|
43
42
|
"typescript": "^5.5.4"
|