run method

  1. @override
Future<void> run()
override

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();
  }
}