X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=syslog-count-link.pl;h=c78ee402c2fe6a0dde14778b0714c8a74bff81cb;hb=9d7e77b558476e3485670f82a24df75d16a8476a;hp=b5648972e6a75ed0c70fda766c3f373be5581c45;hpb=839003821e6c6dca6428e0722a0d639cd3030bc5;p=dell-switch diff --git a/syslog-count-link.pl b/syslog-count-link.pl index b564897..c78ee40 100755 --- a/syslog-count-link.pl +++ b/syslog-count-link.pl @@ -11,6 +11,11 @@ use strict; # sudo tail -f /var/log/switch/sw-[a-z][0-9]*.log | ./syslog-count-link.pl & 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/; @@ -18,7 +23,7 @@ $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"); @@ -31,7 +36,12 @@ sub print_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; } @@ -40,8 +50,17 @@ sub print_stats { close($fh); } +sub reset_stats { + if ( -e "$dir/reset" && unlink "$dir/reset" ) { + $stat = {}; + warn "# reset stats\n"; + } +} + + $SIG{HUP} = sub { print_stats(); + reset_stats; }; warn "kill -HUP $$ # to dump stats\n"; @@ -51,6 +70,17 @@ warn "kill -HUP $$ # to dump stats\n"; 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-]+'; my $port_re = '[\w/]+'; @@ -58,34 +88,52 @@ my $port_re = '[\w/]+'; while(<>) { chomp; s/[\r\n]+//; + + reset_stats; + next if m/^$/; + next if m/%PIX-/; # ignore PIX logs - ## Dell + ## 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 ); - ## Mikrotik + ## 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( $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" || $ENV{DUMP} ) { + print "### ",strftime("%Y-%m-%d %H:%M:%S",localtime(time)), "\n"; + print_stats; } }