diff --git a/CHANGES b/CHANGES index 9e0dbf894..12db855fe 100644 --- a/CHANGES +++ b/CHANGES @@ -2843,4 +2843,5 @@ * checklist: new checklist items on update are acknowledged * backups: automatically trigger a remount if mount is not active * dns: make app containers use system DNS +* logs: rework the syslog parser diff --git a/package-lock.json b/package-lock.json index 26b9179aa..7348f03ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,6 @@ "multiparty": "^4.2.3", "mysql": "^2.18.1", "nodemailer": "^6.9.13", - "nsyslog-parser-2": "^0.9.11", "oidc-provider": "^8.4.6", "ovh": "^2.0.3", "qrcode": "^1.5.3", @@ -4215,11 +4214,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/nsyslog-parser-2": { - "version": "0.9.11", - "resolved": "https://registry.npmjs.org/nsyslog-parser-2/-/nsyslog-parser-2-0.9.11.tgz", - "integrity": "sha512-QF13YP12BAA38NOWescMjiEoyJtnRV5k++fYOP8kNqKFtCubv1w73W9UhjCeER4l87M+4CWlm3MJcD5ZbgDJAg==" - }, "node_modules/nwsapi": { "version": "2.2.10", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.10.tgz", diff --git a/package.json b/package.json index f59f3cb30..2c84c5de2 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,6 @@ "multiparty": "^4.2.3", "mysql": "^2.18.1", "nodemailer": "^6.9.13", - "nsyslog-parser-2": "^0.9.11", "oidc-provider": "^8.4.6", "ovh": "^2.0.3", "qrcode": "^1.5.3", diff --git a/syslog.js b/syslog.js index 68c1b961a..1e29304e4 100755 --- a/syslog.js +++ b/syslog.js @@ -12,11 +12,33 @@ const debug = require('debug')('syslog:server'), net = require('net'), path = require('path'), paths = require('./src/paths.js'), - parser = require('nsyslog-parser-2'), util = require('util'); let gServer = null; +// https://docs.docker.com/engine/logging/drivers/syslog/ +// example: <34>1 2023-09-07T14:33:22Z myhost myapp 1234 5678 [exampleSDID@32473 iut="3" eventSource="Application"] An example message +function parseRFC5424Message(message) { + const syslogRegex = /^<(\d+)>(\d+) (\S+) (\S+) (\S+) (\S+) (\S+) (?:\[(.*?)\])?(.*)$/; + + const match = message.match(syslogRegex); + if (!match) return null; + + const [, pri, version, timestamp, hostname, appName, procId, msgId, structuredData, msg] = match; + + return { + pri: parseInt(pri, 10), // priority + version: parseInt(version, 10), // version + timestamp, // timestamp + hostname, // hostname + appName, // app name + procId, // process ID + msgId, // message ID + structuredData: structuredData ? structuredData : null, // structured data (if present) + msg: msg ? msg.trim() : null // message + }; +} + async function start() { debug('=========================================='); debug(' Cloudron Syslog Daemon '); @@ -32,11 +54,8 @@ async function start() { socket.on('data', function (msg) { const lines = msg.toString().split('\n'); // may be multiline data - lines.forEach(function (msg) { - if (!msg) return; - - const info = parser(msg); - + for (const msg of lines) { + const info = parseRFC5424Message(msg); if (!info || !info.appName) return debug('Ignore unknown app log:', msg); // remove line breaks to avoid holes in the log file @@ -47,15 +66,15 @@ async function start() { try { fs.mkdirSync(appLogDir, { recursive: true }); - fs.appendFileSync(`${appLogDir}/app.log`, info.ts.toISOString() + ' ' + message + '\n'); + fs.appendFileSync(`${appLogDir}/app.log`, `${info.timestamp} ${message}\n}`); } catch (error) { - console.error(error); + debug(error); } - }); + } }); socket.on('error', function (error) { - console.error(`socket error: ${error}`); + debug(`socket error: ${error}`); }); });