syslog: restructure code
This commit is contained in:
6
package-lock.json
generated
6
package-lock.json
generated
@@ -39,6 +39,7 @@
|
||||
"multiparty": "^4.2.3",
|
||||
"mysql": "^2.18.1",
|
||||
"nodemailer": "^6.9.1",
|
||||
"nsyslog-parser": "^0.10.1",
|
||||
"oidc-provider": "^7.14.3",
|
||||
"qrcode": "^1.5.1",
|
||||
"readdirp": "^3.6.0",
|
||||
@@ -4132,6 +4133,11 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/nsyslog-parser": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/nsyslog-parser/-/nsyslog-parser-0.10.1.tgz",
|
||||
"integrity": "sha512-38XUyNf4j1nDXCpPIcGLxNxGceBUpSv06wQgcY3niZ7bydIDvyWr779Cx3RMjWpgib02hjueDUp84S15C9s5lQ=="
|
||||
},
|
||||
"node_modules/nwsapi": {
|
||||
"version": "2.2.2",
|
||||
"license": "MIT"
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
"description": "Main code for a cloudron",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"contributors": [ "Girish", "Johannes" ],
|
||||
"contributors": [
|
||||
"Girish",
|
||||
"Johannes"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.cloudron.io/cloudron/box.git"
|
||||
@@ -44,6 +47,7 @@
|
||||
"multiparty": "^4.2.3",
|
||||
"mysql": "^2.18.1",
|
||||
"nodemailer": "^6.9.1",
|
||||
"nsyslog-parser": "^0.10.1",
|
||||
"oidc-provider": "^7.14.3",
|
||||
"qrcode": "^1.5.1",
|
||||
"readdirp": "^3.6.0",
|
||||
|
||||
@@ -4,7 +4,7 @@ set -eu
|
||||
|
||||
readonly source_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
readonly DATA_DIR="${HOME}/.cloudron_test"
|
||||
readonly DEFAULT_TESTS="./src/test/*-test.js ./src/routes/test/*-test.js"
|
||||
readonly DEFAULT_TESTS="./syslog/*-test.js ./src/test/*-test.js ./src/routes/test/*-test.js"
|
||||
|
||||
! "${source_dir}/src/test/check-install" && exit 1
|
||||
|
||||
@@ -67,7 +67,7 @@ echo "=> Create iptables blocklist"
|
||||
sudo ipset create cloudron_blocklist hash:net || true
|
||||
|
||||
echo "=> Starting cloudron-syslog"
|
||||
cloudron-syslog --logdir "${DATA_DIR}/platformdata/logs/" &
|
||||
syslog/syslog-service.js "${DATA_DIR}/platformdata/logs/" &
|
||||
|
||||
echo "=> Ensure database"
|
||||
mysql -h"${MYSQL_IP}" -uroot -ppassword -e 'CREATE DATABASE IF NOT EXISTS box'
|
||||
|
||||
@@ -127,6 +127,9 @@ if ! which node 2>/dev/null || [[ "$(node --version)" != "v${node_version}" ]];
|
||||
rm -rf /usr/local/node-16.14.2
|
||||
fi
|
||||
|
||||
# obsolete module
|
||||
rm -rf /usr/local/cloudron-syslog
|
||||
|
||||
# note that rebuild requires the above node
|
||||
for try in `seq 1 10`; do
|
||||
# for reasons unknown, the dtrace package will fail. but rebuilding second time will work
|
||||
@@ -166,19 +169,6 @@ for image in ${images}; do
|
||||
done
|
||||
done
|
||||
|
||||
log "update cloudron-syslog"
|
||||
CLOUDRON_SYSLOG_DIR=/usr/local/cloudron-syslog
|
||||
CLOUDRON_SYSLOG="${CLOUDRON_SYSLOG_DIR}/bin/cloudron-syslog"
|
||||
CLOUDRON_SYSLOG_VERSION="1.1.0"
|
||||
while [[ ! -f "${CLOUDRON_SYSLOG}" || "$(${CLOUDRON_SYSLOG} --version)" != ${CLOUDRON_SYSLOG_VERSION} ]]; do
|
||||
rm -rf "${CLOUDRON_SYSLOG_DIR}"
|
||||
mkdir -p "${CLOUDRON_SYSLOG_DIR}"
|
||||
# verbatim is not needed in node 18 since that is the default there. in node 16, ipv4 is preferred and this breaks on ipv6 only servers
|
||||
if NODE_OPTIONS="--dns-result-order=verbatim" npm install --unsafe-perm -g --prefix "${CLOUDRON_SYSLOG_DIR}" cloudron-syslog@${CLOUDRON_SYSLOG_VERSION}; then break; fi
|
||||
log "Failed to install cloudron-syslog, trying again"
|
||||
sleep 5
|
||||
done
|
||||
|
||||
log "creating cloudron-support user"
|
||||
if ! id cloudron-support 2>/dev/null; then
|
||||
useradd --system --comment "Cloudron Support (support@cloudron.io)" --create-home --no-user-group --shell /bin/bash cloudron-support
|
||||
|
||||
@@ -3,9 +3,9 @@ Description=Cloudron Syslog
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/cloudron-syslog/bin/cloudron-syslog --port 2514 --logdir /home/yellowtent/platformdata/logs
|
||||
WorkingDirectory=/usr/local/cloudron-syslog
|
||||
Environment="NODE_ENV=production"
|
||||
ExecStart=/home/yellowtent/box/syslog/service.js
|
||||
WorkingDirectory=/home/yellowtent/box
|
||||
Environment="NODE_ENV=production" "DEBUG=syslog:*"
|
||||
Restart=always
|
||||
User=yellowtent
|
||||
Group=yellowtent
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
const server = require('./server.js');
|
||||
|
||||
const argv = require('yargs')
|
||||
.default('port', 2514, 'The port to listen on') // syslog is 514 so we prefix with 2
|
||||
.default('logdir', '/tmp/logs', 'The root log directory')
|
||||
.argv;
|
||||
|
||||
const options = {
|
||||
logFolder: argv.logdir,
|
||||
port: argv.port
|
||||
};
|
||||
|
||||
if (argv.version) {
|
||||
console.log('1.0.1');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
console.log();
|
||||
console.log('==========================================');
|
||||
console.log(' Cloudron Syslog Daemon ');
|
||||
console.log('==========================================');
|
||||
console.log();
|
||||
console.log(' Log Folder: ', options.logFolder);
|
||||
console.log(' UDP Port: ', options.port);
|
||||
console.log();
|
||||
console.log('==========================================');
|
||||
console.log();
|
||||
|
||||
server.start(options, function (error) {
|
||||
if (error) return console.error(error);
|
||||
console.log('Listening...');
|
||||
});
|
||||
1642
syslog/package-lock.json
generated
1642
syslog/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,27 +0,0 @@
|
||||
{
|
||||
"name": "cloudron-syslog",
|
||||
"version": "1.1.0",
|
||||
"description": "Cloudron Syslog Daemon listening on port 2514",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "./node_modules/.bin/mocha ./test.js"
|
||||
},
|
||||
"bin": {
|
||||
"cloudron-syslog": "./index.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.cloudron.io/cloudron/cloudron-syslog.git"
|
||||
},
|
||||
"author": "Cloudron Developers",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"nsyslog-parser": "^0.9.6",
|
||||
"yargs": "^17.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"expect.js": "^0.3.1",
|
||||
"grepit": "^1.0.0",
|
||||
"mocha": "^9.1.3"
|
||||
}
|
||||
}
|
||||
@@ -8,29 +8,34 @@ exports = module.exports = {
|
||||
const LOG_FILENAME = 'app.log';
|
||||
|
||||
const assert = require('assert'),
|
||||
debug = require('debug')('syslog:server'),
|
||||
dgram = require('dgram'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
parser = require('nsyslog-parser');
|
||||
parser = require('nsyslog-parser'),
|
||||
util = require('util');
|
||||
|
||||
let server = null;
|
||||
|
||||
function start(options, callback) {
|
||||
async function start(options) {
|
||||
assert.strictEqual(typeof options, 'object');
|
||||
assert.strictEqual(typeof options.port, 'number');
|
||||
assert.strictEqual(typeof options.logFolder, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
debug('==========================================');
|
||||
debug(' Cloudron Syslog Daemon ');
|
||||
debug('==========================================');
|
||||
|
||||
server = dgram.createSocket('udp4');
|
||||
|
||||
server.on('error', function (error) {
|
||||
callback(error);
|
||||
}).on('listening', function () {
|
||||
callback();
|
||||
}).on('message', function (msg /*, rinfo */) {
|
||||
console.error(`socket error: ${error}`);
|
||||
});
|
||||
|
||||
server.on('message', function (msg /*, rinfo */) {
|
||||
const info = parser(msg.toString());
|
||||
|
||||
if (!info || !info.appName) return console.log('Ignore unknown app log:', msg.toString());
|
||||
if (!info || !info.appName) return debug('Ignore unknown app log:', msg.toString());
|
||||
|
||||
// remove line breaks to avoid holes in the log file
|
||||
// we do not ignore empty log lines, to allow gaps for potential ease of readability
|
||||
@@ -45,17 +50,15 @@ function start(options, callback) {
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}).bind(options.port);
|
||||
});
|
||||
|
||||
await util.promisify(server.bind.bind(server))(options.port); // intentional double "bind"
|
||||
|
||||
debug(`Listening on port ${options.port}`);
|
||||
}
|
||||
|
||||
function stop(callback) {
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
if (!server) return callback();
|
||||
|
||||
server.close();
|
||||
|
||||
async function stop() {
|
||||
if (!server) return;
|
||||
await util.promisify(server.close.bind(server))();
|
||||
server = null;
|
||||
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
16
syslog/service.js
Executable file
16
syslog/service.js
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
const server = require('./server.js');
|
||||
|
||||
const options = {
|
||||
logFolder: process.argv[2] || '/home/yellowtent/platformdata/logs',
|
||||
port: 2514
|
||||
};
|
||||
|
||||
async function main() {
|
||||
await server.start(options);
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -9,7 +9,6 @@
|
||||
const dgram = require('dgram'),
|
||||
expect = require('expect.js'),
|
||||
fs = require('fs'),
|
||||
grepit = require('grepit'),
|
||||
path = require('path'),
|
||||
os = require('os'),
|
||||
server = require('./server.js');
|
||||
@@ -19,6 +18,7 @@ const LOG_FOLDER = path.join(os.tmpdir(), '/cloudron-syslog-test/');
|
||||
|
||||
function sendMessage(message, callback) {
|
||||
const client = dgram.createSocket('udp4');
|
||||
|
||||
client.send(message, PORT, 'localhost', function (error) {
|
||||
if (error) return callback(error);
|
||||
|
||||
@@ -31,25 +31,22 @@ function sendMessage(message, callback) {
|
||||
function verifyMessage(pattern, fileName, callback) {
|
||||
// give the server some time to write to disk
|
||||
setTimeout(function () {
|
||||
const found = grepit(pattern, path.join(LOG_FOLDER, fileName));
|
||||
if (found.length === 0) return callback('not found');
|
||||
callback();
|
||||
const data = fs.readFileSync(path.join(LOG_FOLDER, fileName), { encoding: 'utf8' });
|
||||
const found = data.match(new RegExp(pattern));
|
||||
return callback(found === null ? new Error('not found') : null);
|
||||
}, 250);
|
||||
}
|
||||
|
||||
describe('Daemon', function () {
|
||||
this.timeout(5000);
|
||||
|
||||
after(function (done) {
|
||||
after(async function () {
|
||||
fs.rmSync(LOG_FOLDER, { recursive: true, force: true });
|
||||
server.stop(done);
|
||||
await server.stop();
|
||||
});
|
||||
|
||||
it('can start', function (done) {
|
||||
server.start({ port: PORT, logFolder: LOG_FOLDER }, function (error) {
|
||||
expect(error).to.not.be.ok();
|
||||
done();
|
||||
});
|
||||
it('can start', async function () {
|
||||
await server.start({ port: PORT, logFolder: LOG_FOLDER });
|
||||
});
|
||||
|
||||
it('handle good message', function (done) {
|
||||
Reference in New Issue
Block a user