mercoledì 21 gennaio 2009

Monitorare la velocità di trasferimento delle interfacce con iptables

Questo semplice script in Perl rileva ogni 2 secondi i byte trasferiti dalle interfacce di rete (ad esempio eth0 ed eth1) e il valore dei contatori delle regole di iptables, e ne calcola la velocità di trasferimento in byte al secondo.

Impostando opportunamente iptables si può monitorare in questo modo il traffico web, mail, ftp, ecc.

Ecco il codice:



use strict;
use warnings;

# quanti secondi attendo tra un campionamento e l'altro
my $sleep_interval = 2;

# quali interfacce di rete monitorare
my @net_interfaces = qw( eth0 eth1 );

my @bytes;
my @bytes_prev;

my %net_bytes;
my %net_bytes_prev;

while (1) {
my @lines;

# puliamo lo schermo
system('clear');

# otteniamo la data e l'ora dal sistema
my $cur_timestamp = `date`;
chomp $cur_timestamp;

# visualizziamo alcune informazioni di servizio
print "Sampling delay: $sleep_interval s Current time: $cur_timestamp\n";

# leggiamo i contatori delle regole di iptables
@lines = `iptables -v -n -x -L`;

# per ogni regola calcoliamo la differenza del valore del contatore in bytes tra l'invocazione attuale e quella precedente di iptables
# ogni regola viene stampata con il valore della differenza
my $i = 0;
foreach my $line(@lines) {
chomp $line;
if ($line =~ / \A Chain /xms) {
print "\n$line\n";
}
elsif ($line =~ / (\d+) \s+ (\d+) /xms) {
$bytes[$i] = $2;
if (!$bytes_prev[$i]) {
$bytes_prev[$i] = $bytes[$i];
}
my $delta = ($bytes[$i] - $bytes_prev[$i]) / $sleep_interval;
print "[$i] $line - [$delta bytes/s]\n";
$bytes_prev[$i] = $bytes[$i];
}
$i++;
}

print "\n";

foreach my $net_if(@net_interfaces) {
@lines = `ifconfig $net_if`;
foreach my $line(@lines) {
chomp $line;
if ($line =~ / RX \s+ bytes:(\d+) .* TX \s+ bytes:(\d+) /xms) {
my $rx = $1;
my $tx = $2;

$net_bytes{$net_if}{'rx'} = $rx;
$net_bytes{$net_if}{'tx'} = $tx;
if (!exists $net_bytes_prev{$net_if}) {
$net_bytes_prev{$net_if}{'rx'} = $rx;
$net_bytes_prev{$net_if}{'tx'} = $tx;
}

my $delta_rx = ($net_bytes{$net_if}{'rx'} - $net_bytes_prev{$net_if}{'rx'}) / $sleep_interval;
my $delta_tx = ($net_bytes{$net_if}{'tx'} - $net_bytes_prev{$net_if}{'tx'}) / $sleep_interval;

printf "$net_if: RX %10.1f bytes/s TX: %10.1f bytes/s\n", $delta_rx, $delta_tx;

$net_bytes_prev{$net_if}{'rx'} = $net_bytes{$net_if}{'rx'};
$net_bytes_prev{$net_if}{'tx'} = $net_bytes{$net_if}{'tx'};
}
}
}


sleep($sleep_interval);
}

Nessun commento: