918ee480060c72360237b9e95cc4f08eb2f32ad4
[gnt-info] / gnt-i
1 #!/usr/bin/perl
2 use warnings;
3 use strict;
4 use autodie;
5
6 my $DEBUG = $ENV{DEBUG} || 0;
7
8 my $hostname = `hostname -s`;
9 chomp $hostname;
10
11 use Data::Dumper;
12 sub XXX { $DEBUG ? warn "XXX ",Dumper( @_ ) : {} };
13
14 my $stat;
15 my $mac_to_name;
16 my $lines;
17
18 my @nodes = @ARGV;
19
20 @nodes = map { chomp ; $_ } `gnt-node list -o name --no-header` unless @nodes;
21
22 next_node:
23 my $ssh = '';
24 if ( @nodes ) {
25         $hostname = shift @nodes;
26         $ssh = "ssh $hostname ";
27 }
28
29 # if prefixed with _ it will be hiddden from output, _args must be last!
30 my @ps_cols = qw( user pid
31         pcpu pmem
32         vsz
33         rss
34         nlwp
35         cputime etimes 
36         maj_flt min_flt
37         psr
38
39         _args);
40
41 sub ps_cols_all { map { my $t = $_; $t =~ s/^_//; $t } @ps_cols };
42 sub ps_cols_visible { grep { ! /^_/ } @ps_cols };
43
44 sub DD_hh_mm_ss {
45         my $t = shift;
46         # [[DD-]hh:]mm:ss.
47         my @f = reverse ( 24, 60, 60, 1 );
48         my @p = reverse split(/[-:]/, $t);
49         my $t_sec = 0;
50
51         for ( 0 .. $#p ) {
52                 my $i = $#p - $_;
53 #warn "### $i $p[$i] $f[$i]\n";
54                 $t_sec += $p[$i];
55                 $t_sec *= $f[$i];
56         }
57
58         warn "# DD-hh:mm:ss $t -> $t_sec\n" if $DEBUG;
59         return $t_sec;
60 }
61
62 my $cmd = $ssh . 'ps --no-headers axwwo ' . join(',', ps_cols_all);
63 warn "## $cmd\n";
64 open(my $ps, '-|', $cmd);
65 while(<$ps>) {
66         chomp;
67         s/^\s*//;
68
69         my %h;
70         @h{@ps_cols} = split(/\s+/, $_, $#ps_cols + 1);
71         $h{cputime} = DD_hh_mm_ss( $h{cputime} );
72
73 #XXX 'h = ', \%h;
74         if ( $h{user} =~ m/gnt/ && $h{_args} =~ m/qemu.*-name\s+(\S+)/ ) {
75
76                 my $name = $1;
77                 $stat->{$name}->{$_} = $h{$_} foreach ps_cols_all;
78
79                 while ( $h{_args} =~ m/mac=([0-9a-fA-F:]+)/g ) {
80                         $mac_to_name->{$1} = $name;
81                 }
82
83         } else {
84 #               warn "## SKIP [$_]\n";
85                 $stat->{ '__' . $hostname }->{$_} += $h{$_} foreach qw( pcpu pmem vsz rss cputime etimes maj_flt min_flt );
86                 
87         }
88
89 }
90
91 open(my $ip, '-|', $ssh . 'ip -s -o link');
92 while(<$ip>) {
93         chomp;
94         if ( m/master\s+(\S+).+ether\s+([0-9a-fA-F:]+).+RX:\s+.+\\\s+(\d+).+TX:\s+.+\\\s+(\d+)/ ) {
95                 my ( $br, $mac, $rx, $tx ) = ( $1, $2, $3, $4 );
96                 if ( my $name = $mac_to_name->{$mac} ) {
97                         $stat->{$name}->{link}->{ $br } = [ $rx, $tx ];
98                 } else {
99                         warn "## SKIP MAC $mac [$_]\n" if $DEBUG;
100                 }
101         } else {
102                 warn "## SKIP $_\n" if $DEBUG;
103         }
104 }
105
106 goto next_node if @nodes;
107
108 warn "# stat ", Dumper( $stat ) if $DEBUG;
109 XXX( @ps_cols );
110
111 sub push_line {
112         my @l = @_;
113         foreach my $i ( 0 .. $#l ) {
114                 my $len = length($l[$i]) || 0;
115                 $lines->{len}->[$i] ||= $len;
116                 $lines->{len}->[$i] = $len if $len > $lines->{len}->[$i];
117         }
118         push @{ $lines->{line} }, [ map { ! defined $_ ? '-' : $_ } @l ];
119 }
120
121 push_line '#name', ps_cols_visible;
122
123 foreach my $name ( sort keys %$stat ) {
124 #       printf "%6.2f %6.2f %8d %6d %6s %s\n", ( map { $stat->{$name}->{$_} || '' } qw( pcpu pmem vsz pid user ) ), $name;
125 #       print join("\t", $name, map { $stat->{$name}->{$_} } ps_cols_visible ), "\n";
126         push_line( $name, map { $stat->{$name}->{$_} } ps_cols_visible );
127 }
128
129 warn '# mac_to_name ', Dumper( $mac_to_name );
130
131 XXX $lines;
132
133 my $fmt = join(' ', map { '%' . $_ . 's' } @{ $lines->{len} } ) . "\n";
134 warn "# fmt = [$fmt]" if $DEBUG;
135 foreach my $line ( @{ $lines->{line} } ) {
136         printf $fmt, @$line;
137 }
138