mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-02-01 08:48:05 +00:00
Merge pull request #1186 from balena-io/per-service-log-filtering
Add per-service filtering to logs and push
This commit is contained in:
commit
0aa10ba2a1
@ -865,12 +865,16 @@ If an IP address is passed to this command, logs are displayed from
|
||||
a local mode device with that address. Note that --tail is implied
|
||||
when this command is provided an IP address.
|
||||
|
||||
Logs from a single service can be displayed with the --service flag.
|
||||
|
||||
Examples:
|
||||
|
||||
$ balena logs 23c73a1
|
||||
$ balena logs 23c73a1 --tail
|
||||
$ balena logs 23c73a1 --service my-service
|
||||
|
||||
$ balena logs 192.168.0.31
|
||||
$ balena logs 192.168.0.31 --service my-service
|
||||
|
||||
### Options
|
||||
|
||||
@ -878,6 +882,10 @@ Examples:
|
||||
|
||||
continuously stream output
|
||||
|
||||
#### --service, -s <service>
|
||||
|
||||
Only show logs for a single service
|
||||
|
||||
# Sync
|
||||
|
||||
## sync [uuid]
|
||||
@ -1409,6 +1417,7 @@ Logs will be streamed back from the device as part of the same invocation.
|
||||
The web dashboard can be used to switch a device to local mode:
|
||||
https://www.balena.io/docs/learn/develop/local-mode/
|
||||
Note that local mode requires a supervisor version of at least v7.21.0.
|
||||
The logs from only a single service can be shown with the --service flag.
|
||||
|
||||
It is also possible to run a push to a local mode device in live mode.
|
||||
This will watch for changes in the source directory and perform an
|
||||
@ -1437,6 +1446,7 @@ Examples:
|
||||
$ balena push 10.0.0.1
|
||||
$ balena push 10.0.0.1 --source <source directory>
|
||||
$ balena push 10.0.0.1 -s <source directory>
|
||||
$ balena push 10.0.0.1 --service my-service
|
||||
|
||||
### Options
|
||||
|
||||
@ -1475,6 +1485,11 @@ This feature requires a device running supervisor version v9.7.0 or greater.
|
||||
|
||||
Don't tail application logs when pushing to a local mode device
|
||||
|
||||
#### --service <service>
|
||||
|
||||
Only show logs from a single service.
|
||||
Only valid when pushing to a local mode device.
|
||||
|
||||
# Settings
|
||||
|
||||
## settings
|
||||
|
@ -36,7 +36,7 @@ export const logs: CommandDefinition<
|
||||
{
|
||||
uuidOrDevice: string;
|
||||
},
|
||||
{ tail: boolean }
|
||||
{ tail: boolean; service: string }
|
||||
> = {
|
||||
signature: 'logs <uuidOrDevice>',
|
||||
description: 'show device logs',
|
||||
@ -51,12 +51,16 @@ export const logs: CommandDefinition<
|
||||
a local mode device with that address. Note that --tail is implied
|
||||
when this command is provided an IP address.
|
||||
|
||||
Logs from a single service can be displayed with the --service flag.
|
||||
|
||||
Examples:
|
||||
|
||||
$ balena logs 23c73a1
|
||||
$ balena logs 23c73a1 --tail
|
||||
$ balena logs 23c73a1 --service my-service
|
||||
|
||||
$ balena logs 192.168.0.31`,
|
||||
$ balena logs 192.168.0.31
|
||||
$ balena logs 192.168.0.31 --service my-service`,
|
||||
options: [
|
||||
{
|
||||
signature: 'tail',
|
||||
@ -64,6 +68,12 @@ export const logs: CommandDefinition<
|
||||
boolean: true,
|
||||
alias: 't',
|
||||
},
|
||||
{
|
||||
signature: 'service',
|
||||
description: 'Only show logs for a single service',
|
||||
parameter: 'service',
|
||||
alias: 's',
|
||||
},
|
||||
],
|
||||
permission: 'user',
|
||||
primary: true,
|
||||
@ -86,9 +96,9 @@ export const logs: CommandDefinition<
|
||||
if (serviceName == null) {
|
||||
serviceName = 'Unknown service';
|
||||
}
|
||||
displayLogObject({ serviceName, ...line }, logger);
|
||||
displayLogObject({ serviceName, ...line }, logger, options.service);
|
||||
} else {
|
||||
displayLogObject(line, logger);
|
||||
displayLogObject(line, logger, options.service);
|
||||
}
|
||||
};
|
||||
|
||||
@ -107,7 +117,7 @@ export const logs: CommandDefinition<
|
||||
}
|
||||
|
||||
const logStream = await deviceApi.getLogStream();
|
||||
displayDeviceLogs(logStream, logger);
|
||||
displayDeviceLogs(logStream, logger, options.service);
|
||||
} else {
|
||||
if (options.tail) {
|
||||
return balena.logs
|
||||
|
@ -108,6 +108,7 @@ export const push: CommandDefinition<
|
||||
'registry-secrets': string;
|
||||
live: boolean;
|
||||
detached: boolean;
|
||||
service: string;
|
||||
}
|
||||
> = {
|
||||
signature: 'push <applicationOrDevice>',
|
||||
@ -128,6 +129,7 @@ export const push: CommandDefinition<
|
||||
The web dashboard can be used to switch a device to local mode:
|
||||
https://www.balena.io/docs/learn/develop/local-mode/
|
||||
Note that local mode requires a supervisor version of at least v7.21.0.
|
||||
The logs from only a single service can be shown with the --service flag.
|
||||
|
||||
It is also possible to run a push to a local mode device in live mode.
|
||||
This will watch for changes in the source directory and perform an
|
||||
@ -144,6 +146,7 @@ export const push: CommandDefinition<
|
||||
$ balena push 10.0.0.1
|
||||
$ balena push 10.0.0.1 --source <source directory>
|
||||
$ balena push 10.0.0.1 -s <source directory>
|
||||
$ balena push 10.0.0.1 --service my-service
|
||||
`,
|
||||
options: [
|
||||
{
|
||||
@ -198,6 +201,13 @@ export const push: CommandDefinition<
|
||||
description: `Don't tail application logs when pushing to a local mode device`,
|
||||
boolean: true,
|
||||
},
|
||||
{
|
||||
signature: 'service',
|
||||
description: stripIndent`
|
||||
Only show logs from a single service.
|
||||
Only valid when pushing to a local mode device.`,
|
||||
parameter: 'service',
|
||||
},
|
||||
],
|
||||
async action(params, options, done) {
|
||||
const sdk = (await import('balena-sdk')).fromSharedOptions();
|
||||
@ -245,6 +255,11 @@ export const push: CommandDefinition<
|
||||
`The --detached flag is only valid when pushing to a local mode device.`,
|
||||
);
|
||||
}
|
||||
if (options.service) {
|
||||
exitWithExpectedError(
|
||||
'The --service flag is only valid when pushing to a local mode device.',
|
||||
);
|
||||
}
|
||||
|
||||
const app = appOrDevice;
|
||||
await exitIfNotLoggedIn();
|
||||
@ -285,6 +300,7 @@ export const push: CommandDefinition<
|
||||
nocache: options.nocache || false,
|
||||
live: options.live || false,
|
||||
detached: options.detached || false,
|
||||
service: options.service,
|
||||
}),
|
||||
)
|
||||
.catch(BuildError, e => {
|
||||
|
@ -48,6 +48,7 @@ export interface DeviceDeployOptions {
|
||||
nocache: boolean;
|
||||
live: boolean;
|
||||
detached: boolean;
|
||||
service?: string;
|
||||
}
|
||||
|
||||
async function checkSource(source: string): Promise<boolean> {
|
||||
@ -175,10 +176,10 @@ export async function deployToDevice(opts: DeviceDeployOptions): Promise<void> {
|
||||
globalLogger.logLivepush('Watching for file changes...');
|
||||
await Promise.all([
|
||||
livepush.init(),
|
||||
displayDeviceLogs(logStream, globalLogger),
|
||||
displayDeviceLogs(logStream, globalLogger, opts.service),
|
||||
]);
|
||||
} else {
|
||||
await displayDeviceLogs(logStream, globalLogger);
|
||||
await displayDeviceLogs(logStream, globalLogger, opts.service);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,15 +24,21 @@ interface BuildLog {
|
||||
* Display logs from a device logging stream. This function will return
|
||||
* when the log stream ends.
|
||||
*
|
||||
* @param logs A stream which produces newline seperated log objects
|
||||
* @param logs A stream which produces newline seperated log
|
||||
* objects
|
||||
* @param logger A Logger instance which the logs will be
|
||||
* displayed through
|
||||
* @param filterService Filter the logs so that only logs
|
||||
* from a single service will be displayed
|
||||
*/
|
||||
export function displayDeviceLogs(
|
||||
logs: Readable,
|
||||
logger: Logger,
|
||||
filterService?: string,
|
||||
): Bluebird<void> {
|
||||
return new Bluebird((resolve, reject) => {
|
||||
logs.on('data', log => {
|
||||
displayLogLine(log, logger);
|
||||
displayLogLine(log, logger, filterService);
|
||||
});
|
||||
|
||||
logs.on('error', reject);
|
||||
@ -48,16 +54,24 @@ export function displayBuildLog(log: BuildLog, logger: Logger): void {
|
||||
}
|
||||
|
||||
// mutates serviceColours
|
||||
function displayLogLine(log: string | Buffer, logger: Logger): void {
|
||||
function displayLogLine(
|
||||
log: string | Buffer,
|
||||
logger: Logger,
|
||||
filterService?: string,
|
||||
): void {
|
||||
try {
|
||||
const obj: Log = JSON.parse(log.toString());
|
||||
displayLogObject(obj, logger);
|
||||
displayLogObject(obj, logger, filterService);
|
||||
} catch (e) {
|
||||
logger.logDebug(`Dropping device log due to failed parsing: ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
export function displayLogObject<T extends Log>(obj: T, logger: Logger): void {
|
||||
export function displayLogObject<T extends Log>(
|
||||
obj: T,
|
||||
logger: Logger,
|
||||
filterService?: string,
|
||||
): void {
|
||||
let toPrint: string;
|
||||
if (obj.timestamp != null) {
|
||||
toPrint = `[${new Date(obj.timestamp).toLocaleString()}]`;
|
||||
@ -66,9 +80,16 @@ export function displayLogObject<T extends Log>(obj: T, logger: Logger): void {
|
||||
}
|
||||
|
||||
if (obj.serviceName != null) {
|
||||
if (filterService && obj.serviceName !== filterService) {
|
||||
return;
|
||||
}
|
||||
const colourFn = getServiceColourFn(obj.serviceName);
|
||||
|
||||
toPrint += ` ${colourFn(`[${obj.serviceName}]`)}`;
|
||||
} else if (filterService != null) {
|
||||
// We have a system log here but we are filtering based
|
||||
// on a service, so drop this too
|
||||
return;
|
||||
}
|
||||
|
||||
toPrint += ` ${obj.message}`;
|
||||
|
Loading…
x
Reference in New Issue
Block a user