#!/usr/local/bin/perl
# blocked SPAM monthly stats
# author: Dominik M Miklaszewski (dmikey@distantmoon.net)
#
# usage: spam-monthly.pl [-m] [date1] [date2] (using -m generates monthly stats up to date)
# input: YYYYMMDD-mailstats - file generated by
# '/usr/local/bin/sma -a /var/log/maillog > /var/log/$CURR_DATE-mailstats' i.e. from cronjob:
#
# #!/bin/sh
# CURR_DATE=`/bin/date +'%Y%m%d'`
# /usr/local/bin/sma -a /var/log/maillog > /var/log/$CURR_DATE-mailstats
#
# output: png
# systems: Solaris 2.6, Solaris 2.8, Linux SuSE 7.3
# (shouldn't have problems on any others where PERL,gd and zlib-1.1.3/1.1.4 is installed)
#
# You need to have following PERL modules installed in your system:
# GD-1.27, DateManip-5.40, MailTools-1.1401, MIME-tools-5.408 (or any other more/less recent version of each)
#
# This tiny script can be easily expanded to graph out some other things sma provides and I will work on it..
# If you have any questions, ideas just email me.
# (Note: I know one can utilize RRD for that kind of stuff, but I didn't have enough time to learn RRD so just
# grabbed some old routines I wrote two years ago and modified them for this purpose.)
use GD;
use Date::Manip;
use MIME::Base64;
use MIME::Entity;
##########################################################
# path for files and other global settings #
##########################################################
$document_title = "Monthly SPAM Report";
$sender = "SysAdmin\@yourdomain\.com";
$reply_to = "yourself\@yourdomain\.com";
$recipient = "yourself\@yourdomain\.com";
$cc_recipient = "any_other_aliased_recipients";
$archpath = "/arch";
$destpath = ".";
$pre = "";
$post = "-mailstats";
$startdate = $ARGV[0];
$stopdate = $ARGV[1];
$storefile = $ARGV[2];
@table = ();
######################
# auxiliary settings #
######################
# ======== date butchery ==================
# first conditional is based on assumption that script is gonna be run on every 1st day of the month, how stupid..
if ($ARGV[0] eq "-m")
{
$startdate = &DateCalc("today"," - 1 month",\$err);
$stopdate = &DateCalc("today","- 1 day",\$err);
$chkstopdate = substr($stopdate,2,6);
$delta = &DateCalc($startdate,$stopdate,\$err);
@diff = split(/:/,$delta);
$delta = ($diff[2])*7+($diff[3]);
}
else
{
$startdate=&ParseDate($startdate);
$stopdate=&ParseDate($stopdate);
$chkstopdate = substr($stopdate,2,6);
$delta=&DateCalc($startdate,$stopdate,\$err);
@diff=split(/:/,$delta);
$delta=($diff[2])*7+($diff[3]);
}
$title1 = "Monthly blocked SPAM @mailrelay2: " . &UnixDate($startdate,"%a %b %e %Y") . " until " . &UnixDate($stopdate,"%a %b %e %Y");
$headtitle = "Monthly SPAM Report for: ". &UnixDate($startdate,"%a %b %e %Y") ." until " . &UnixDate($stopdate,"%a %b %e %Y");
&html_header("$headtitle");
$startdate = &UnixDate($startdate,"%Y%m%d");
$stopdate = &UnixDate($stopdate,"%Y%m%d");
$sdate=$startdate;
$testdate=$sdate;
for($i=0;$i<($delta+1);$i++)
{
for ($a=0;$a<4;$a++){$dtrend{$trentity[$a]}=0;}
$itestm = substr($testdate,2,2);
$testdate=&DateCalc($sdate,"+$i day",\$err);
$testdate=substr($testdate,0,8);
$testm = substr($testdate,2,2);
if (($testm ne $itestm) and ($itestm !="00"))
{
for ($a=0;$a<4;$a++){$mtrend{$trentity[$a]}=0;}
$itestm=$testm;
}
$logfile = $testdate . $post;
# the date when I started using sma for reporting - if you don't need that conditional simply replace first
# 'if' condition with ($testdate) and the 'else' will never happen :)
if ($testdate > 20020602)
{
$INPUT1 = `/bin/cat $archpath/$logfile |grep \"Ruleset based rejections\"\|awk \'{print $5}\'`;
$blocked_spam=(split(/\s+/,$INPUT1))[4];
}
# ..before we were using regular sendmail mailstats routine
else
{
$INPUT1 = `/bin/cat $archpath/$logfile |grep \"esmtp\"`;
$rej=(split(/\s+/,$INPUT1))[6];
$dis=(split(/\s+/,$INPUT1))[7];
$blocked_spam=$rej+$dis;
}
$table[$i]=$blocked_spam;
$totalspam+=$blocked_spam;
}
# creating .PNG files
######################################
# #
# Fancy drawing section #
# #
######################################
# create the chart layout
$output0 = "Blocked Spam at Inbound Mailrelay : $totalspam";
$scale=0.1;
$im1 = new GD::Image(640,512) || die;
$white = $im1 -> colorAllocate(255,255,255);
$black = $im1 -> colorAllocate(0,0,0);
$blue = $im1 -> colorAllocate(0,45,255);
$red = $im1 -> colorAllocate(255,0,45);
$im1 -> string(gdSmallFont,150,34,$title1,$black);
$im1 -> string(gdSmallFont,150,60,$output1,$blue);
$im1 -> string(gdSmallFont,150,75,$output0,$red);
$im1 -> line(46,136,46,484,$black);
$im1 -> line(46,484,606,484,$black);
######################## blocked spam monthly drawing ###############################
# X-Axis
for($i=1;$i<=$#table;$i++)
{
# autoscaling
if(($table[$i] > 4499) || ($table[$i] > 449)) { $scale=0.06;}
if(($table[$i] > 8999) || ($table[$i] > 899)) { $scale=0.04;}
$inc=$table[$i];
$t=$i*17;
$im1 -> line(36+$t,482,36+$t,484,$black);
$days="$i";
$im1->string(gdSmallFont,((36+$t)-length($days*(gdSmallFont->width))),(496-(gdSmallFont->height)),$days,$black);
$im1->filledRectangle((36+$t)-5,(484-(($table[$i])*$scale)),(36+$t),484,$blue);
}
# Y-axis description
for($i=0;$i<10;$i++)
{
$im1 -> line(46,484-$i*30,48,484-$i*30,$black);
$numb = (30*$i)/$scale;
$snumb = "$numb";
$im1->string(gdSmallFont,(30-(length($snumb)*(gdSmallFont->width))/2),(484-($i*30)-(gdSmallFont->height)),$snumb,$black);
}
$xline = "[days]";
$im1 ->string(gdMediumBoldFont,(240-length($xline*(gdMediumBoldFont->width))/2),(510-(gdMediumBoldFont->height)),$xline,$black);
$yline = "[blocked_SPAM/day]";
$im1 ->stringUp(gdSmallFont,(12-(gdSmallFont->height)),(256+(length($yline)*(gdSmallFont->width))/2),$yline,$black);
$png_data = $im1 -> png;
$chart1 = $destpath . &UnixDate($startdate,"%b%Y") . "spamtotal1.png";
open (PNG1, ">$chart1") || die "cannot create a file";
print PNG1 $png_data;
close PNG1;
&footer;
close MAINFILE;
$udate = &UnixDate($startdate,"%b%Y");
# send contents to the recipients
$top = MIME::Entity->build ( Type => "multipart/mixed",
From => "$sender",
Reply-To=> "$reply-to",
To => "$recipient",
Cc => "$cc_recipient",
Subject => "Mailrelay2 - Monthly Blocked SPAM Report - $udate",
Data => "Mailrelay2 - Monthly Blocked SPAM Report - $udate\n");
$top -> attach(Path => "$chart1",
Type => "image/png",
Encoding=> "Base64");
open MAIL, "| /usr/lib/sendmail -t -i" or die "open: $!";
$top -> print(\*MAIL);
close MAIL;
exit(0);
# these little subs can be useful if you need to create an html page within the script.
sub footer{
print MAINFILE "<CENTER>\n";
print MAINFILE "<img src=$pub_chart1><BR>\n";
print MAINFILE "<img src=$pub_chart2><BR>\n";
print MAINFILE "</center>\n";
print MAINFILE "<BR>","\n";
print MAINFILE "<BR><HR>";
print MAINFILE "\© Seabury & Smith 2001 <a href=\"mailto\:dominik\.miklaszewski\@seabury\.com\">Dominik</a><br>\n";
print MAINFILE "<a href=./index.html>[Return]</a>","\n";
print MAINFILE "</BODY>\n";
print MAINFILE "</HTML>\n";
}
sub html_header{
$document_title=$_[0];
#print "Content-type: text/html\n\n";
print MAINFILE "<HTML>\n";
print MAINFILE "<HEAD>\n";
print MAINFILE "<TITLE>$document_title</TITLE>\n";
print MAINFILE "</HEAD>\n";
print MAINFILE "<BODY bgcolor=FFFFFF>\n";
print MAINFILE "<CENTER><H2>$document_title</H2></CENTER>\n";
print MAINFILE "<P>\n";
}
syntax highlighted by Code2HTML, v. 0.9.1