syslog-client-ts
Version:
Modern typescript implementation of Syslog Client
156 lines • 6.01 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SyslogClient = void 0;
const node_net_1 = __importDefault(require("node:net"));
const node_dgram_1 = __importDefault(require("node:dgram"));
const node_events_1 = require("node:events");
const defaults_js_1 = require("./defaults.js");
class SyslogClient extends node_events_1.EventEmitter {
options;
identity;
tcpOptions;
socket;
isReconnecting;
isConnected;
constructor(options, defaultIdentity = {}, tcpOptions = {}) {
super();
this.options = Object.assign((0, defaults_js_1.DEFAULT_SYSLOG_CLIENT_OPTIONS)(), options);
this.identity = Object.assign((0, defaults_js_1.DEFAULT_IDENTITY)(), defaultIdentity);
this.tcpOptions = Object.assign((0, defaults_js_1.DEFAULT_TCP_OPTIONS)(), tcpOptions);
this.socket = null;
this.isConnected = false;
this.isReconnecting = false;
}
async connect() {
if ((this.options.transport ?? defaults_js_1.DEFAULT_SYSLOG_TRANSPORT) === 'tcp') {
return this.connectTCP();
}
else {
return this.connectUDP();
}
}
async connectTCP() {
return new Promise((resolve, reject) => {
const socket = new node_net_1.default.Socket();
const connectHandler = () => {
this.socket = socket;
this.isConnected = true;
this.emit('connect');
resolve();
};
const errorHandler = (err) => {
this.emit('error', err);
if (this.tcpOptions?.reconnect && !this.isReconnecting) {
this.isReconnecting = true;
setTimeout(() => {
this.isReconnecting = false;
this.connectTCP().catch(() => { });
}, this.tcpOptions?.reconnectInterval ?? 1000);
}
else {
reject(err);
}
};
const closeHandler = () => {
this.isConnected = false;
this.emit('disconnect');
if (this.tcpOptions?.reconnect && !this.isReconnecting) {
this.isReconnecting = true;
setTimeout(() => {
this.isReconnecting = false;
this.connectTCP().catch(() => { });
}, this.tcpOptions?.reconnectInterval ?? 1000);
}
};
socket.connect(this.options.port ?? defaults_js_1.DEFAULT_SYSLOG_PORT, this.options.hostname, connectHandler);
socket.on('error', errorHandler);
socket.on('close', closeHandler);
if (this.tcpOptions?.timeout) {
socket.setTimeout(this.tcpOptions.timeout);
socket.on('timeout', () => {
this.emit('error', new Error('Socket timeout'));
socket.destroy();
});
}
});
}
async connectUDP() {
return new Promise(resolve => {
const socket = node_dgram_1.default.createSocket('udp4');
socket.on('error', err => {
this.emit('error', err);
});
this.socket = socket;
this.isConnected = true;
this.emit('connect');
resolve();
});
}
async log(message, overrideIdentity = {}) {
const msg = this._prepareMessage(message, overrideIdentity);
await this._send(msg);
}
_prepareMessage(message, overrideIdentity = {}) {
const computedIdentity = Object.assign({}, this.identity, overrideIdentity);
const { facility, severity, appName, syslogHostname, pid } = computedIdentity;
const pri = facility * 8 + severity;
const timestamp = new Date().toISOString();
const hostname = syslogHostname;
const procId = pid ?? process.pid;
const msgId = '-';
const structuredData = '-';
const syslogMessage = `<${pri}>1 ${timestamp} ${hostname} ${appName} ${procId} ${msgId} ${structuredData} ${message}`;
return syslogMessage;
}
async _send(message) {
if (!this.isConnected) {
await this.connect();
}
if ((this.options.transport ?? defaults_js_1.DEFAULT_SYSLOG_TRANSPORT) === 'tcp') {
const socket = this.socket;
return new Promise((resolve, reject) => {
socket.write(message + '\n', 'utf8', err => {
if (err) {
this.emit('error', err);
reject(err);
}
else {
resolve();
}
});
});
}
else {
const socket = this.socket;
return new Promise((resolve, reject) => {
const messageBuffer = Buffer.from(message);
socket.send(messageBuffer, 0, messageBuffer.length, this.options.port ?? defaults_js_1.DEFAULT_SYSLOG_PORT, this.options.hostname, err => {
if (err) {
this.emit('error', err);
reject(err);
}
else {
resolve();
}
});
});
}
}
disconnect() {
if (this.socket) {
if ((this.options.transport ?? defaults_js_1.DEFAULT_SYSLOG_TRANSPORT) === 'tcp') {
this.socket.end();
}
else {
this.socket.close();
}
this.socket = null;
this.isConnected = false;
}
}
}
exports.SyslogClient = SyslogClient;
//# sourceMappingURL=client.js.map