diff --git a/src/apps.js b/src/apps.js index 310ee4f25..65dd4cc9f 100644 --- a/src/apps.js +++ b/src/apps.js @@ -674,10 +674,9 @@ function appLogFilter(app) { return names.map(function (name) { return 'CONTAINER_NAME=' + name; }); } -function getLogs(appId, lines, follow, callback) { +function getLogs(appId, options, callback) { assert.strictEqual(typeof appId, 'string'); - assert.strictEqual(typeof lines, 'number'); - assert.strictEqual(typeof follow, 'boolean'); + assert(options && typeof options === 'object'); assert.strictEqual(typeof callback, 'function'); debug('Getting logs for %s', appId); @@ -686,13 +685,21 @@ function getLogs(appId, lines, follow, callback) { if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new AppsError(AppsError.NOT_FOUND)); if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error)); - var args = [ '--output=json', '--no-pager', '--lines=' + lines ]; + + var lines = options.lines || 100, + follow = !!options.follow, + format = options.format || 'json'; + + var args = [ '--no-pager', '--lines=' + lines ]; if (follow) args.push('--follow'); + if (format == 'short') args.push('--output=short', '-a'); else args.push('--output=json'); args = args.concat(appLogFilter(app)); var cp = spawn('/bin/journalctl', args); var transformStream = split(function mapper(line) { + if (format !== 'json') return line + '\n'; + var obj = safe.JSON.parse(line); if (!obj) return undefined; diff --git a/src/cloudron.js b/src/cloudron.js index 6082c1f33..dffd0d5f1 100644 --- a/src/cloudron.js +++ b/src/cloudron.js @@ -949,24 +949,34 @@ function refreshDNS(callback) { }); } -function getLogs(units, lines, follow, callback) { +function getLogs(options, callback) { + assert(options && typeof options === 'object'); + assert.strictEqual(typeof callback, 'function'); + + var units = options.units || [], + lines = options.lines || 100, + format = options.format || 'json', + follow = !!options.follow; + assert(Array.isArray(units)); assert.strictEqual(typeof lines, 'number'); - assert.strictEqual(typeof follow, 'boolean'); - assert.strictEqual(typeof callback, 'function'); + assert.strictEqual(typeof format, 'string'); debug('Getting logs for %j', units); - var args = [ '--output=json', '--no-pager', '--lines=' + lines ]; + var args = [ '--no-pager', '--lines=' + lines ]; units.forEach(function (u) { if (u === 'box') args.push('--unit=box'); - else if (u === 'mail') args.push('CONTAINER_ID=mail'); + else if (u === 'mail') args.push('CONTAINER_NAME=mail'); }); + if (format == 'short') args.push('--output=short', '-a'); else args.push('--output=json'); if (follow) args.push('--follow'); var cp = spawn('/bin/journalctl', args); var transformStream = split(function mapper(line) { + if (format !== 'json') return line + '\n'; + var obj = safe.JSON.parse(line); if (!obj) return undefined; diff --git a/src/routes/apps.js b/src/routes/apps.js index 767ac2aa8..f86d8886c 100644 --- a/src/routes/apps.js +++ b/src/routes/apps.js @@ -360,7 +360,13 @@ function getLogs(req, res, next) { debug('Getting logs of app id:%s', req.params.id); - apps.getLogs(req.params.id, lines, false /* follow */, function (error, logStream) { + var options = { + lines: lines, + follow: false, + format: req.query.format + }; + + apps.getLogs(req.params.id, options, function (error, logStream) { if (error && error.reason === AppsError.NOT_FOUND) return next(new HttpError(404, 'No such app')); if (error && error.reason === AppsError.BAD_STATE) return next(new HttpError(412, error.message)); if (error) return next(new HttpError(500, error)); diff --git a/src/routes/cloudron.js b/src/routes/cloudron.js index 872ac3790..7e038d6cf 100644 --- a/src/routes/cloudron.js +++ b/src/routes/cloudron.js @@ -230,9 +230,15 @@ function getLogs(req, res, next) { if (isNaN(lines)) return next(new HttpError(400, 'lines must be a number')); var units = req.query.units || 'all'; - debug('Getting logs of unit:%s', units); - cloudron.getLogs(units.split(','), lines, false /* follow */, function (error, logStream) { + var options = { + lines: lines, + follow: false, + units: units.split(','), + format: req.query.format + }; + + cloudron.getLogs(options, function (error, logStream) { if (error && error.reason === CloudronError.BAD_FIELD) return next(new HttpError(404, 'Invalid type')); if (error) return next(new HttpError(500, error)); diff --git a/webadmin/src/views/support.html b/webadmin/src/views/support.html index 023b3c824..03e5d9566 100644 --- a/webadmin/src/views/support.html +++ b/webadmin/src/views/support.html @@ -29,13 +29,16 @@