use Data::Dump qw(dump);
use POSIX qw(strftime);
+my $timeout = $ENV{TIMEOUT} || 60; # forget switch after sec
+# timeout should be smaller than stp refresh inverval or
+# stp messages will accumulate forever
+
my $name = $0;
$name =~ s/.*\/([^\/]+)$/$1/;
$name =~ s/\.pl$//;
my $dir = "/dev/shm/$name";
mkdir $dir unless -e $dir;
-my $stat;
+our $stat;
sub print_stats {
open(my $fh, '>', "$dir/stats");
$a1 <=> $b1;
} keys %{ $stat->{$host} } ) {
next if $port =~ m/^_/;
- my $out = sprintf "%s %s:%s %d\n", $host, $port, $stat->{$host}->{$port}, $stat->{$host}->{_count}->{$port};
+ my $dt = time() - $stat->{$host}->{$port}->[0];
+ if ( $dt > $timeout ) {
+ delete $stat->{$host}->{$port};
+ next;
+ }
+ my $out = sprintf "%-12s %-8s %-2d %s\n", $host, $port, $dt, $stat->{$host}->{$port}->[1];
print $out;
print $fh $out;
}
close($fh);
}
+sub stat_host_port {
+ my ( $host, $port, $state ) = @_;
+ if ( ! exists $stat->{$host}->{$port} ) {
+ $stat->{$host}->{$port} = [-1, $state];
+ } else {
+ $stat->{$host}->{$port}->[1] .= $state;
+ }
+ $stat->{$host}->{$port}->[0] = time();
+ #warn "# stat_host_port ",dump($stat);
+}
my $host_re = '[\w-]+';
## Dell old
if ( m/(\S+)\s%LINK-[IW]-(\w+):\s*(\w+)/ ) {
my ($host,$state,$port) = ($1,$2,$3);
- $stat->{$host}->{$port} .= substr($state,0,1);
- $stat->{$host}->{_count}->{$port} += $state =~ m/Up/ ? 1 : -1;
- } elsif ( m/(\S+)\s%STP-W-PORTSTATUS:\s([\w\/]+): STP status (\w+)/ ) {
- my ($host,$port,$state) = ($1,$2,$3);
- $stat->{$host}->{$port} .= '-';
- $stat->{$host}->{_count}->{$port} += $state =~ m/F/ ? 1 : -1;
+ stat_host_port( $host, $port, substr($state,0,1) );
+ } elsif ( m/(\S+)\s%STP-W-PORTSTATUS:\s([\w\/]+)(?: of instance \d+)?: STP status (\w+)/ ) {
+ my ($host,$port,$state) = ($1,$2,substr($3,0,1) );
+ stat_host_port( $host, $port, $state =~ m/f/i ? '-' : $state );
## Dell new
} elsif ( m/LINK - (\w+) - Hostname: <($host_re)>, ($port_re)/ ) {
my ($state, $host, $port ) = ($1,$2,$3);
- $stat->{$host}->{$port} .= substr($state,0,1);
- $stat->{$host}->{_count}->{$port} += $state =~ m/U/ ? 1 : -1;
+ stat_host_port( $host, $port, substr($state,0,1) );
} elsif ( m/STP - PORTSTATUS - Hostname: <($host_re)>,($port_re): STP status (\w+)/ ) {
my ($host,$port,$state) = ($1,$2,$3);
- $stat->{$host}->{$port} .= '-';
- $stat->{$host}->{_count}->{$port} += $state =~ m/F/ ? 1 : -1;
+ stat_host_port( $host, $port, '-' );
## Mikrotik
} elsif ( m/($host_re) \w+: ([\w\-]+) link (\w+)/ ) {
my ($host, $port, $state ) = ($1,$2,$3);
- $stat->{$host}->{$port} .= substr($state,0,1);
- $stat->{$host}->{_count}->{$port} += $state =~ m/U/i ? 1 : -1;
+ stat_host_port( $host, $port, substr($state,0,1) );
+
+
+ } elsif ( m/($host_re) TRAPMGR.* %% Spanning Tree Topology Change: (\d+)/ ) {
+ my ( $host, $state ) = ( $1, $2 );
+ stat_host_port( $host, 'STP', $2 );
} elsif ( m'==> /var/log/' ) {
# ignore tail output
+ next;
} else {
warn "IGNORE: [$_]\n";
+ next;
}
- if ( -e "$dir/dump" ) {
+ if ( -e "$dir/dump" || $ENV{DUMP} ) {
print "### ",strftime("%Y-%m-%d %H:%M:%S",localtime(time)), "\n";
print_stats;
}