diff --git a/docs/API.md b/docs/API.md index fd341015..50465f40 100644 --- a/docs/API.md +++ b/docs/API.md @@ -1291,5 +1291,15 @@ From an app container: $ curl -X POST -H "Content-Type: application/json" --data '{"follow":true,"all":true}' "$BALENA_SUPERVISOR_ADDRESS/v2/journal-logs?apikey=$BALENA_SUPERVISOR_API_KEY" > log.journal ``` +##### since: string +> **Introduced in supervisor v14.7.0** +Show journal logs since the given `since` timestamp, formats are described here: +[https://www.freedesktop.org/software/systemd/man/journalctl.html#-S](https://www.freedesktop.org/software/systemd/man/journalctl.html#-S) + +##### until: string +> **Introduced in supervisor v14.7.0** +Show journal logs until the given `until` timestamp, formats are described here: +[https://www.freedesktop.org/software/systemd/man/journalctl.html#-S](https://www.freedesktop.org/software/systemd/man/journalctl.html#-S) + An example project using this endpoint can be found [in this repository](https://github.com/balena-io-playground/device-cloud-logging). diff --git a/src/device-api/v2.ts b/src/device-api/v2.ts index 80e41634..1fdd8dd4 100644 --- a/src/device-api/v2.ts +++ b/src/device-api/v2.ts @@ -549,6 +549,8 @@ router.post('/v2/journal-logs', (req, res) => { const unit = req.body.unit; const format = req.body.format || 'short'; const containerId = req.body.containerId; + const since = req.body.since; + const until = req.body.until; const journald = spawnJournalctl({ all, @@ -557,6 +559,8 @@ router.post('/v2/journal-logs', (req, res) => { unit, format, containerId, + since, + until, }); res.status(200); // We know stdout will be present diff --git a/src/lib/journald.ts b/src/lib/journald.ts index 0512204d..f0d193bd 100644 --- a/src/lib/journald.ts +++ b/src/lib/journald.ts @@ -10,7 +10,8 @@ export function spawnJournalctl(opts: { containerId?: string; format: string; filterString?: string; - since?: number; + since?: number | string; + until?: number | string; }): ChildProcess { const args: string[] = []; if (opts.all) { @@ -33,12 +34,11 @@ export function spawnJournalctl(opts: { } if (opts.since != null) { args.push('-S'); - args.push( - new Date(opts.since) - .toISOString() - .replace(/T/, ' ') // replace T with a space - .replace(/\..+/, ''), // delete the dot and everything after - ); + args.push(opts.since.toString()); + } + if (opts.until != null) { + args.push('-U'); + args.push(opts.until.toString()); } args.push('-o'); args.push(opts.format); diff --git a/test/unit/lib/journald.spec.ts b/test/unit/lib/journald.spec.ts index f6b74993..809a3cb7 100644 --- a/test/unit/lib/journald.spec.ts +++ b/test/unit/lib/journald.spec.ts @@ -26,6 +26,8 @@ describe('lib/journald', () => { unit: 'nginx.service', containerId: 'abc123', format: 'json-pretty', + since: '2014-03-25 03:59:56.654563', + until: '2014-03-25 03:59:59.654563', }); const expectedCommand = `journalctl`; @@ -40,6 +42,10 @@ describe('lib/journald', () => { '10', '-o', 'json-pretty', + '-S', + '2014-03-25 03:59:56.654563', + '-U', + '2014-03-25 03:59:59.654563', ]; const actualCommand = spawn.firstCall.args[0];