balena-supervisor/sync/logs.ts
Cameron Diver 8ab63656bd Update synchronisation scripts for supervisor development
We move the old sync.js script to tools/, and delete the now-broken
sync-debug.js.

We add a command `npm run sync`, which starts a livepush process
with the supervisor on a device.

Change-type: minor
Signed-off-by: Cameron Diver <cameron@balena.io>
2020-04-06 13:05:38 +01:00

47 lines
1.2 KiB
TypeScript

import * as Docker from 'dockerode';
import * as _ from 'lodash';
export async function setupLogs(
docker: Docker,
containerId: string,
lastReadTimestamp = 0,
) {
const container = docker.getContainer(containerId);
const stream = await container.logs({
stdout: true,
stderr: true,
follow: true,
timestamps: true,
since: lastReadTimestamp,
});
stream.on('data', chunk => {
const { message, timestamp } = extractMessage(chunk);
// Add one here, other we can end up constantly reading
// the same log line
lastReadTimestamp = Math.floor(timestamp.getTime() / 1000) + 1;
process.stdout.write(message);
});
// This happens when a container is restarted
stream.on('end', () => {
setupLogs(docker, containerId, lastReadTimestamp);
});
}
function extractMessage(msgBuf: Buffer) {
// Non-tty message format from:
// https://docs.docker.com/engine/api/v1.30/#operation/ContainerAttach
if ([0, 1, 2].includes(msgBuf[0])) {
// Take the header from this message, and parse it as normal
msgBuf = msgBuf.slice(8);
}
const str = msgBuf.toString();
const space = str.indexOf(' ');
return {
timestamp: new Date(str.slice(0, space)),
message: str.slice(space + 1),
};
}