From d50d18d49216fe423cb7bae58217e80a8f368f2e Mon Sep 17 00:00:00 2001 From: Paulo Castro Date: Fri, 9 Apr 2021 22:41:30 +0100 Subject: [PATCH] push, logs: Fix parsing of local mode device logs (NDJSON stream) Resolves: #2185 Change-type: patch --- lib/utils/device/logs.ts | 27 +++++++++------------------ npm-shrinkwrap.json | 10 ++++++++++ package.json | 2 ++ 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/lib/utils/device/logs.ts b/lib/utils/device/logs.ts index 1181564f..125e75cf 100644 --- a/lib/utils/device/logs.ts +++ b/lib/utils/device/logs.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2018-2020 Balena Ltd. + * Copyright 2018-2021 Balena Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,6 +63,7 @@ async function displayDeviceLogs( filterServices?: string[], ): Promise { const { addSIGINTHandler } = await import('../helpers'); + const { parse: ndjsonParse } = await import('ndjson'); let gotSignal = false; const handleSignal = () => { gotSignal = true; @@ -72,8 +73,12 @@ async function displayDeviceLogs( process.once('SIGTERM', handleSignal); try { await new Promise((_resolve, reject) => { - logs.on('data', (log) => { - displayLogLine(log, logger, system, filterServices); + const jsonStream = ndjsonParse(); + jsonStream.on('data', (log) => { + displayLogObject(log, logger, system, filterServices); + }); + jsonStream.on('error', (e) => { + logger.logWarn(`Error parsing NDJSON log chunk: ${e}`); }); logs.once('error', reject); logs.once('end', () => { @@ -84,6 +89,7 @@ async function displayDeviceLogs( reject(new DeviceConnectionLostError()); } }); + logs.pipe(jsonStream); }); } finally { process.removeListener('SIGINT', handleSignal); @@ -140,21 +146,6 @@ export function displayBuildLog(log: BuildLog, logger: Logger): void { logger.logBuild(toPrint); } -// mutates serviceColours -function displayLogLine( - log: string | Buffer, - logger: Logger, - system: boolean, - filterServices?: string[], -): void { - try { - const obj: Log = JSON.parse(log.toString()); - displayLogObject(obj, logger, system, filterServices); - } catch (e) { - logger.logDebug(`Dropping device log due to failed parsing: ${e}`); - } -} - export function displayLogObject( obj: T, logger: Logger, diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index e92f001d..13dd3c49 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -2428,6 +2428,16 @@ "@types/node": "*" } }, + "@types/ndjson": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/ndjson/-/ndjson-2.0.0.tgz", + "integrity": "sha512-z1inV91BPfnnUwX0Q6TiIspIrhDsE7XJRGLutLGSRc++rQEqVzGxkG2xEKFgYjPVqaef4q3S4fXxcggJvfI70A==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/through": "*" + } + }, "@types/net-keepalive": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@types/net-keepalive/-/net-keepalive-0.4.1.tgz", diff --git a/package.json b/package.json index 13f23035..d28d367d 100644 --- a/package.json +++ b/package.json @@ -139,6 +139,7 @@ "@types/mocha": "^8.0.4", "@types/mock-require": "^2.0.0", "@types/moment-duration-format": "^2.2.2", + "@types/ndjson": "^2.0.0", "@types/net-keepalive": "^0.4.1", "@types/nock": "^11.0.7", "@types/node": "^10.17.28", @@ -245,6 +246,7 @@ "mixpanel": "^0.10.3", "moment": "^2.27.0", "moment-duration-format": "^2.3.2", + "ndjson": "^2.0.0", "node-cleanup": "^2.1.2", "node-unzip-2": "^0.2.8", "oclif": "^1.16.1",