#!/usr/bin/env node /* global it:false */ /* global describe:false */ /* global after:false */ 'use strict'; const expect = require('expect.js'), fs = require('node:fs'), net = require('node:net'), path = require('node:path'), paths = require('../paths.js'), safe = require('safetydance'), syslogServer = require('../../syslog.js'), timers = require('timers/promises'); async function sendMessage(message) { const client = net.createConnection(paths.SYSLOG_SOCKET_FILE); return new Promise((resolve, reject) => { client.on('connect', function () { client.end(message, function (error) { if (error) return reject(error); resolve(); }); }); }); } async function verifyMessage(pattern, fileName) { // give the server some time to write to disk await timers.setTimeout(250); const data = fs.readFileSync(path.join(paths.LOG_DIR, fileName), { encoding: 'utf8' }); const found = data.match(new RegExp(pattern)); if (found === null) throw new Error(`${pattern} not found in ${fileName}`); } describe('Syslog', function () { this.timeout(5000); after(async function () { await syslogServer.stop(); }); it('can start', async function () { await syslogServer.start(); }); it('handle good message', async function () { // IETF (RFC 5424) message, with structured data and chained hostnames const ietfLine = '<110>1 2009-05-03T14:00:39.529966+02:00 host.example.org/relay.example.org testapp 2138 - [exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"][exampleSDID@32474 iut="4" eventSource="Application" eventID="1012"][ssign VER="0111" RSID="1" SG="0" SPRI="0" GBC="2" FMN="1" CNT="7" HB="K6wzcombEvKJ+UTMcn9bPryAeaU= zrkDcIeaDluypaPCY8WWzwHpPok= zgrWOdpx16ADc7UmckyIFY53icE= XfopJ+S8/hODapiBBCgVQaLqBKg= J67gKMFl/OauTC20ibbydwIlJC8= M5GziVgB6KPY3ERU1HXdSi2vtdw= Wxd/lU7uG/ipEYT9xeqnsfohyH0=" SIGN="AKBbX4J7QkrwuwdbV7Taujk2lvOf8gCgC62We1QYfnrNHz7FzAvdySuMyfM="] BOMAn application event log entry'; await sendMessage(ietfLine); await verifyMessage(/An application event log entry/, 'testapp/app.log'); }); it('ignores invalid message', async function () { const invalidLine = 'foobar'; await sendMessage(invalidLine); const [error] = await safe(verifyMessage(/foobar/, 'testapp/app.log')); expect(error).to.be.ok(); }); it('can handle message with colons', async function () { // this is what we see from docker syslog const message = '<30>1 2018-06-24T22:22:53Z my.test.com testapp 26599 testapp - This: contains two : colons'; await sendMessage(message); await verifyMessage(/This: contains two : colons/, 'testapp/app.log'); }); });