run method
Runs this command.
The return value is wrapped in a Future if necessary and returned by
CommandRunner.runCommand.
Implementation
@override
Future<void> run() async {
final args = argResults!;
final rest = args.rest;
if (rest.isEmpty) throw CliError('usage: node metrics <id> [--since 1h]');
final since = args['since'] as String?;
final query = [
'limit=${Uri.encodeQueryComponent(args['limit'] as String)}',
if (since != null) 'since=${Uri.encodeQueryComponent(since)}',
].join('&');
final client = _apiClientFrom(args);
try {
final series = await client.get('/nodes/${rest.first}/metrics?$query');
if (args['json'] as bool) {
stdout.writeln(const JsonEncoder.withIndent(' ').convert(series));
return;
}
final points = (series as List).cast<Map>();
if (points.isEmpty) {
stdout.writeln('no samples (the node may not have heartbeated yet)');
return;
}
stdout.writeln('AT CPU% MEM% DISK%');
// Newest first from the API; print oldest first so it reads as a timeline.
for (final p in points.reversed) {
final at = DateTime.parse(p['at'] as String).toLocal();
final cpu = (p['cpuPercent'] as num).toDouble();
final mem = _pct(p['memoryUsedBytes'], p['memoryTotalBytes']);
final disk = _pct(p['storageUsedBytes'], p['storageCapacityBytes']);
stdout.writeln(
'${at.toString().padRight(26)}'
'${cpu.toStringAsFixed(1).padLeft(5)} '
'${mem.padLeft(6)} ${disk.padLeft(6)}',
);
}
} finally {
client.close();
}
}