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

ethstats.p6: use a Perl 6 grammar.

Also declare that /proc/net/dev is in the Latin-1 encoding.
parent 2ef66045
......@@ -67,37 +67,83 @@ sub add_up_totals(%total, %dev)
}
}
grammar Interfaces {
token TOP {
<headerline>
<headerline>
<ifaceline>*
}
rule headerline { <nonnl>\n }
token nonnl { <- [\n] >* }
rule ifaceline { <iface>':' <in> <out>\n }
rule in {<bytes> <packets> <errs> <drop> <fifo> <frame> <compressed> <multicast>}
rule out {<bytes> <packets> <errs> <drop> <fifo> <colls> <carrier> <compressed>}
token iface { \w+ }
token bytes { <uint> }
token packets { <uint> }
token errs { <uint> }
token drop { <uint> }
token fifo { <uint> }
token frame { <uint> }
token compressed { <uint> }
token multicast { <uint> }
token colls { <uint> }
token carrier { <uint> }
token uint { \d+ }
}
class InterfaceActions {
method TOP($/) { $/.make: $<ifaceline>>>.made }
method ifaceline($/) {
$/.make: {
name => $<iface>.made,
data => {
bytes => {
in => $<in>.made<bytes>,
out => $<out>.made<bytes>,
},
packets => {
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) } }
method iface($/) { $/.make: ~$/; }
method bytes($/) { $/.make: $<uint>.made }
method packets($/) { $/.make: $<uint>.made }
method uint($/) { $/.make: $/.UInt }
}
sub convert(Str $iface, UInt $period)
{
try my $f = open :r, '/proc/net/dev';
try my $f = open :r, '/proc/net/dev', :chomp(False), :enc('latin1');
die "Could not open the interface info pseudo-file: $!" if $!;
my %devs;
my $count = 0;
my $contents = '';
for $f.lines -> $line {
# Ah, the joys of reading from pseudo-files...
last if $line eq '';
$count++;
next if $count < 3;
my ($dev, $rest) = $line.split(':', 2).map(*.trim);
next if defined($iface) && $dev ne $iface;
my @data = $rest.split(/\s+/).map(*.Int);
%devs{$dev} = {
:name($dev),
:data({
:bytes({
:in(@data[0]),
:out(@data[8]),
}),
:packets({
:in(@data[1]),
:out(@data[9]),
}),
}),
};
$contents ~= $line;
}
$f.close;
my %devs = Interfaces.parse($contents, :actions(InterfaceActions))
.made.map: { $_<name> => $_ };
if defined $iface {
%devs = %devs{$iface}:kv;
}
reset_totals;
%devs<lo>:delete;
for %devs.values -> %dev {
......
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