#!/usr/bin/perl -w # # spamdstats.pl - Gives back rudimentary stats based on spamd logs # # Copyright Clint Byrum, 2003. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # version 0.1 - Initial release # version 0.5 - Suggestion from viz, widening user column for virtual domains # version 0.6 - Adding total messages and spam percentage columns .. ty viz # my %cleandates; my %spamdates; my %userspam; my %userclean; my @top5scores; my @top5times; my ($month,$day,$loghost,$daemon); my ($word1,$word2,$scores,$junk,$user,$junk2,$proctime); my $date; my $logtime; my $cleanmsgs=0; my $spams=0; my $linecnt=0; my $timespent=0; my $totalscore=0; my $cleanscore=0; my $spamscore=0; my $maxuserlen=0; while($line=) { ($month,$day,$logtime,$loghost,$daemon,$word1,$word2, $scores,$junk,$user,$junk2,$proctime)=split(' ',$line); # print "DEBUG: m=$month d=$day l=$loghost daemon=$daemon\n"; if($daemon =~ /spamd/) { # yay $date="$month $day"; ($score,$junk)=split('\/',$scores); $score =~ s/^\(//; if($word1 =~ /clean|identified/) { if(length($user) > $maxuserlen) { $maxuserlen = length($user); } $totalscore += $score; $timespent += $proctime; if($word1 =~ /clean/) { $cleanmsgs=$cleanmsgs + 1; $userclean{$user} += 1; $cleandates{$date} += 1; $cleanscore += $score; } elsif($word1 =~ /identified/) { $spams=$spams + 1; $userspam{$user} += 1; $spamdates{$date} += 1; $spamscore += $score; } } } $linecnt=$linecnt + 1; } my $totalmsgs=$spams+$cleanmsgs; my $averageptime=$timespent/$totalmsgs; my $averagescore=$totalscore/$totalmsgs; my $avgcleanscore=$cleanscore/$cleanmsgs; my $avgspamscore; if($spams!=0) { $avgspamscore=$spamscore/$spams; } else { $avgspamscore="inf"; } print "Spams Found : $spams"; printf ("\t\tAverage Score: %5.3f\n",$avgspamscore); print "Clean Messages: $cleanmsgs"; printf ("\t\tAverage Score: %5.3f\n",$avgcleanscore); print "Total Messages: $totalmsgs"; printf ("\t\tAverage Score: %5.3f\n",$averagescore); #print "Lines Processed: $linecnt\n"; print "Time spent: $timespent\n"; printf("Average Time: %5.3f\n",$averageptime); print "\n"; #print "------------USERS-------------\n"; # we must adjust maxuserlen down by 2 to reduce the wasted space caused by uids $maxuserlen -= 2; $headstr = "%".$maxuserlen."s%10s%10s\n"; $pfstr = "%".$maxuserlen."s%10d%10d\n"; printf($headstr,"User","Spams","Clean"); printf($headstr,'-'x$maxuserlen,'-'x9,'-'x9); # XXX will only show users who got spam while(($user,$spams) = each %userspam) { $spams=0 unless defined $spams; $cleanmsgs=$userclean{$user}; $cleanmsgs=0 unless defined $cleanmsgs; ($user,$junk) = split(':',$user); printf($pfstr,$user,$spams,$cleanmsgs); } print "\n"; #print "------------DATES-------------\n"; printf($headstr,"Date","Spams","Clean"); printf($headstr,'-'x9,'-'x9,'-'x9); # XXX Will only show dates that spam was received on while(($date,$spams) = each %spamdates) { $cleanmsgs=$cleandates{$date}; #printf "$date\: $spams,$cleanmsgs\n"; printf($pfstr,$date,$spams,$cleanmsgs); } sub averagetimes { my @avgarray=@_; my ($total,$counter); foreach $datum (@avgarray) { $total += $datum; $counter++; } return $total / $counter; }