Commit 453e0cf0 authored by Peter Pentchev's avatar Peter Pentchev

p6: use actual classes instead of data hashes.

parent 9fe44d83
......@@ -11,8 +11,6 @@ use Getopt::Tiny;
use Terminal::ANSIColor;
my $use_color;
my %prevstat;
my %total;
sub version()
{
......@@ -43,34 +41,85 @@ EOUSAGE
}
}
sub reset_totals()
{
%total = ( :kb({}), :packets({}) );
}
class Stats {
has Real $.in = 0;
has Real $.out = 0;
sub update_traffic(%dev, %odev, UInt:D $period)
{
for %dev.keys -> $what {
for %dev{$what}.keys -> $dir {
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;
}
method !set(Real:D $in, Real:D $out)
{
$!in = $in;
$!out = $out;
}
method reset()
{
self!set(0, 0);
}
method update_traffic(Stats:D $old, UInt:D $period)
{
my $diff-in = $!in - $old.in;
$diff-in += 4294967296 if $diff-in < 0;
my $diff-out = $!out - $old.out;
$diff-out += 4294967296 if $diff-out < 0;
$old!set($!in, $!out);
self!set($diff-in / $period, $diff-out / $period);
}
method add(Stats:D $more)
{
$!in += $more.in;
$!out += $more.out;
}
method kb_from(Stats:D $bytes)
{
$!in = $bytes.in / 1000000 * 8;
$!out = $bytes.out / 1000000 * 8;
}
}
sub add_up_totals(%total, %dev)
{
for %total.keys -> $what {
for <in out> -> $dir {
%total{$what}{$dir} += %dev{$what}{$dir};
}
class InterfaceStats {
has Str $.name is required;
has Stats $.bytes = Stats.new;
has Stats $.packets = Stats.new;
has Stats $.kb = Stats.new;
method reset()
{
$!bytes.reset();
$!packets.reset();
$!kb.reset();
}
method update_traffic(InterfaceStats:D $odev, UInt:D $period)
{
$!bytes.update_traffic($odev.bytes, $period);
$!packets.update_traffic($odev.packets, $period);
}
method add(InterfaceStats:D $more)
{
$!bytes.add($more.bytes);
$!packets.add($more.packets);
$!kb.add($more.kb);
}
method format()
{
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',
$!kb.in, $!kb.out,
$!packets.in, $!packets.out);
}
}
my InterfaceStats %prevstat;
my InterfaceStats $total;
grammar Interfaces {
token TOP {
<headerline>
......@@ -105,19 +154,17 @@ class InterfaceActions {
method TOP($/) { $/.make: $<ifaceline>.map(*.made) }
method ifaceline($/) {
$/.make: {
$/.make: InterfaceStats.new(
name => $<iface>.made,
data => {
bytes => {
in => $<in>.made<bytes>,
out => $<out>.made<bytes>,
},
packets => {
in => $<in>.made<packets>,
out => $<out>.made<packets>,
},
},
}
bytes => Stats.new(
in => $<in>.made<bytes>,
out => $<out>.made<bytes>,
),
packets => Stats.new(
in => $<in>.made<packets>,
out => $<out>.made<packets>,
),
)
}
method in($/) { $/.make: { :bytes($<bytes>.made), :packets($<packets>.made) } }
method out($/) { $/.make: { :bytes($<bytes>.made), :packets($<packets>.made) } }
......@@ -142,23 +189,21 @@ sub convert(Str $iface, UInt:D $period)
}
$f.close;
my %devs = Interfaces.parse($contents, :actions(InterfaceActions))
.made.map: { $_<name> => $_ };
my InterfaceStats %devs =
Interfaces.parse($contents, :actions(InterfaceActions))
.made.map: { $_.name => $_ };
if defined $iface {
%devs = %devs{$iface}:kv;
}
reset_totals;
$total.reset;
%devs<lo>:delete;
for %devs.values -> %dev {
my $name = %dev<name>;
%prevstat{$name} //= { :name($name) };
update_traffic %dev<data>, %prevstat{$name}, $period;
%dev<data><kb> = {
:in(%dev<data><bytes><in> / 1000000 * 8),
:out(%dev<data><bytes><out> / 1000000 * 8),
};
add_up_totals %total, %dev<data>;
for %devs.values -> $dev {
my $name = $dev.name;
%prevstat{$name} //= InterfaceStats.new(:name($name));
$dev.update_traffic(%prevstat{$name}, $period);
$dev.kb.kb_from($dev.bytes);
$total.add($dev);
}
return %devs;
}
......@@ -168,15 +213,6 @@ sub acolor(Str:D $name)
return $use_color?? color($name)!! '';
}
sub format_line(Str:D $name, %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',
%dev<kb><in>, %dev<kb><out>,
%dev<packets><in>, %dev<packets><out>);
}
{
my %flags;
my $opts = Getopt::Tiny.new;
......@@ -238,19 +274,18 @@ sub format_line(Str:D $name, %dev)
exit 0;
}
$total = InterfaceStats.new(:name('total'));
convert $iface, 1;
sleep 1;
loop {
my %devs = convert $iface, $period;
my InterfaceStats %devs = convert $iface, $period;
print time ~ ' ' if $addtime;
if %devs.elems > 1 {
say acolor('yellow') ~
format_line('total', %total) ~
$total.format ~
acolor('reset');
}
for %devs.values.sort(*<name> cmp *<name>) -> $dev {
say format_line($dev<name>, $dev<data>);
}
.format.say for %devs.values.sort: *.name;
if $count > 0 {
$count--;
exit 0 if $count < 1;
......
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