reset stats when file is present and kill -HUP is sent
[dell-switch] / syslog-count-link.pl
1 #!/usr/bin/perl
2 use warnings;
3 use strict;
4
5 # count Dell and Microtik syslog for port and stp events
6
7 ## report all logs:
8 # sudo cat /var/log/switch/sw-[a-z][0-9]*.log | ./syslog-count-link.pl | less -S
9 #
10 ## tail logs and report status on kill -HUP
11 # sudo tail -f /var/log/switch/sw-[a-z][0-9]*.log | ./syslog-count-link.pl &
12
13 use Data::Dump qw(dump);
14 use POSIX qw(strftime);
15
16 my $name = $0;
17 $name =~ s/.*\/([^\/]+)$/$1/;
18 $name =~ s/\.pl$//;
19 my $dir = "/dev/shm/$name";
20 mkdir $dir unless -e $dir;
21
22 my $stat;
23
24 sub print_stats {
25         open(my $fh, '>', "$dir/stats");
26
27         foreach my $host ( sort keys %$stat ) {
28                 foreach my $port ( sort {
29                         my $a1 = $a; $a1 =~ s/\D+//g;
30                         my $b1 = $b; $b1 =~ s/\D+//g;
31                         no warnings;
32                         $a1 <=> $b1;
33                 } keys %{ $stat->{$host} } ) {
34                         next if $port =~ m/^_/;
35                         my $out = sprintf "%s %s:%s %d\n", $host, $port, $stat->{$host}->{$port}, $stat->{$host}->{_count}->{$port};
36                         print $out;
37                         print $fh $out;
38                 }
39         }
40
41         close($fh);
42 }
43
44 sub reset_stats {
45         if ( -e "$dir/reset" && unlink "$dir/reset" ) {
46                 $stat = {};
47                 warn "# reset stats\n";
48         }
49 }
50
51
52 $SIG{HUP} = sub {
53         print_stats();
54         reset_stats;
55 };
56
57 warn "kill -HUP $$  # to dump stats\n";
58 {
59         open(my $fh, '>', "$dir/pid");
60         print $fh $$;
61         close($fh);
62 }
63
64
65
66 my $host_re = '[\w-]+';
67 my $port_re = '[\w/]+';
68
69 while(<>) {
70         chomp;
71         s/[\r\n]+//;
72
73         reset_stats;
74
75         next if m/^$/;
76         next if m/%PIX-/; # ignore PIX logs
77
78         ## Dell old
79         if ( m/(\S+)\s%LINK-[IW]-(\w+):\s*(\w+)/ ) {
80                 my ($host,$state,$port) = ($1,$2,$3);
81                 $stat->{$host}->{$port} .= substr($state,0,1);
82                 $stat->{$host}->{_count}->{$port} += $state =~ m/Up/ ? 1 : -1;
83         } elsif ( m/(\S+)\s%STP-W-PORTSTATUS:\s([\w\/]+): STP status (\w+)/ ) {
84                 my ($host,$port,$state) = ($1,$2,$3);
85                 $stat->{$host}->{$port} .= '-';
86                 $stat->{$host}->{_count}->{$port} += $state =~ m/F/ ? 1 : -1;
87
88
89         ## Dell new
90         } elsif ( m/LINK - (\w+) - Hostname: <($host_re)>, ($port_re)/ ) {
91                 my ($state, $host, $port ) = ($1,$2,$3);
92                 $stat->{$host}->{$port} .= substr($state,0,1);
93                 $stat->{$host}->{_count}->{$port} += $state =~ m/U/ ? 1 : -1;
94         } elsif ( m/STP - PORTSTATUS - Hostname: <($host_re)>,($port_re): STP status (\w+)/ ) {
95                 my ($host,$port,$state) = ($1,$2,$3);
96                 $stat->{$host}->{$port} .= '-';
97                 $stat->{$host}->{_count}->{$port} += $state =~ m/F/ ? 1 : -1;
98
99
100         } elsif ( m'==> /var/log/' ) {
101                 # ignore tail output
102         } else {
103                 warn "IGNORE: [$_]\n";
104         }
105
106         if ( -e "$dir/dump" ) {
107                 print "### ",strftime("%Y-%m-%d %H:%M:%S",localtime(time)), "\n";
108                 print_stats;
109         }
110 }
111
112
113
114 warn "# stat = ", dump($stat);
115 print_stats;
116
117