Commit 4d0e37b5 authored by Peter Pentchev's avatar Peter Pentchev

Use data structures instead of global variables.

parent 6ca56e8f
......@@ -19,6 +19,8 @@ Change log for ethstats, the network traffic statistics utility
- use the version module
- use fewer parentheses and quotes
- use a local variable for the input file stream
- use data structures instead of passing data in a herd of
global variables
1.0 (unknown)
- released into the public domain by Drew Strieb
......
......@@ -56,9 +56,8 @@ sub version()
my $period = 10;
my ($COLOR, $addtime, $count, $iface);
my ($numdevs, $tkbin, $tkbout, $tpackin, $tpackout);
my (%kbin, %kbout, %packin, %packout);
my (%obytesin, %obytesout, %opackin, %opackout);
my %prevstat;
my %total = (kb => {}, packets => {});
sub acolor($)
{
......@@ -67,14 +66,20 @@ sub acolor($)
return $COLOR? Term::ANSIColor::color($color): '';
}
sub format_line($ $ $ $ $)
sub format_line($ $)
{
my ($dev, $kbin, $kbout, $packin, $packout) = @_;
my ($name, $dev) = @_;
return ($dev eq 'total'? 'total: ': sprintf(' %6s: ', $dev)).
return ($name eq 'total'? 'total: ': sprintf(' %6s: ', $name)).
sprintf('%7.2f Mb/s In %7.2f Mb/s Out - '.
'%8.1f p/s In %8.1f p/s Out',
$kbin, $kbout, $packin, $packout);
$dev->{kb}{in}, $dev->{kb}{out},
$dev->{packets}{in}, $dev->{packets}{out});
}
sub reset_totals()
{
%total = (kb => {}, packets => {});
}
$| = 1;
......@@ -128,16 +133,15 @@ convert;
sleep $period;
while(1) {
convert;
my $devs = convert;
print time.' ' if $addtime;
if ($numdevs > 1) {
if (scalar keys %{$devs} > 1) {
say acolor('yellow').
format_line('total', $tkbin, $tkbout, $tpackin, $tpackout).
format_line('total', \%total).
acolor('reset');
}
foreach my $dev (sort keys %kbin) {
say format_line($dev, $kbin{$dev}, $kbout{$dev},
$packin{$dev}, $packout{$dev});
foreach my $dev (sort { $a->{name} cmp $b->{name} } values %{$devs}) {
say format_line($dev->{name}, $dev->{data});
}
if (defined $count) {
$count--;
......@@ -147,11 +151,40 @@ while(1) {
sleep $period;
}
sub update_traffic($ $)
{
my ($dev, $odev) = @_;
for my $what (keys %{$dev}) {
for my $dir (keys %{$dev->{$what}}) {
my $diff = $dev->{$what}{$dir} -
($odev->{$what}{$dir} // 0);
$diff += 4294967296 if $diff < 0;
$odev->{$what}{$dir} = $dev->{$what}{$dir};
$dev->{$what}{$dir} = $diff / $period;
}
}
}
sub add_up_totals($ $)
{
my ($total, $dev) = @_;
for my $what (keys %{$total}) {
for my $dir (qw(in out)) {
$total->{$what}{$dir} =
($total->{$what}{$dir} // 0) +
$dev->{$what}{$dir};
}
}
}
sub convert()
{
open my $in, '/proc/net/dev' or die "Can't open /proc/net/dev: $!\n";
<$in>; <$in>;
my (%bytesin, %bytesout);
my %devs;
while (my $l = <$in>) {
chop $l;
my ($dev, $rest) = split /:/, $l;
......@@ -159,45 +192,33 @@ sub convert()
next if defined $iface && $dev ne $iface;
$rest =~ s/^\s+//;
my @devarr = split /\s+/, $rest;
$bytesin{$dev} = $devarr[0]; $bytesout{$dev} = $devarr[8];
$packin{$dev} = $devarr[1]; $packout{$dev} = $devarr[9];
$devs{$dev} = {
name => $dev,
data => {
bytes => {
in => $devarr[0],
out => $devarr[8],
},
packets => {
in => $devarr[1],
out => $devarr[8],
},
},
};
}
close($in);
$numdevs = 0;
$tpackin = 0;
$tpackout = 0;
$tkbin = 0;
$tkbout = 0;
foreach my $dev (sort keys %bytesin) {
next if $dev eq 'lo';
$numdevs++;
# packets in/out
my $packdiffin = $packin{$dev} - ($opackin{$dev} // 0);
my $packdiffout = $packout{$dev} - ($opackout{$dev} // 0);
$packdiffin += 4294967296 if $packdiffin < 0;
$packdiffout += 4294967296 if $packdiffout < 0;
$opackin{$dev} = $packin{$dev};
$opackout{$dev} = $packout{$dev};
$packin{$dev} = $packdiffin / $period;
$packout{$dev} = $packdiffout / $period;
# bytes in/out
my $diffin = $bytesin{$dev} - ($obytesin{$dev} // 0);
my $diffout = $bytesout{$dev} - ($obytesout{$dev} // 0);
$diffin += 4294967296 if $diffin < 0;
$diffout += 4294967296 if $diffout < 0;
$obytesin{$dev} = $bytesin{$dev};
$obytesout{$dev} = $bytesout{$dev};
$kbin{$dev} = $diffin / $period / 1000000 * 8;
$kbout{$dev} = $diffout / $period / 1000000 * 8;
# increment totals
$tpackin += $packin{$dev};
$tpackout += $packout{$dev};
$tkbin += $kbin{$dev};
$tkbout += $kbout{$dev};
reset_totals;
delete $devs{lo};
foreach my $dev (sort { $a->{name} cmp $b->{name} } values %devs) {
$prevstat{$dev->{name}} //= { name => $dev->{name} };
update_traffic $dev->{data}, $prevstat{$dev->{name}};
$dev->{data}->{kb} = {
in => $dev->{data}->{bytes}->{in} / 1000000 * 8,
out => $dev->{data}->{bytes}->{out} / 1000000 * 8,
};
add_up_totals \%total, $dev->{data};
}
return \%devs;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment