Skip to content

Instantly share code, notes, and snippets.

@yaasita
Last active January 3, 2016 20:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yaasita/8517691 to your computer and use it in GitHub Desktop.
Save yaasita/8517691 to your computer and use it in GitHub Desktop.
Daily mail report
#!/usr/bin/perl
use strict;
use warnings;
use File::Temp;
### Initial Settings #####################################################
my $mail_log='/var/log/mail.log*';
my $my_ip='192.168.0.1';
my $notify_address='admin@example.com';
my @rbl_sites=("all.rbl.jp","bl.spamcop.net","sbl.spamhaus.org");
##########################################################################
my $tempfile = File::Temp->new();
select $tempfile;
# yesterday log
my $yesterday=`LANG=C date +'%b %_d' -d '1 days ago'`;
chomp $yesterday;
my @yesterday_log=`zgrep '^$yesterday' $mail_log`;
# read log
my %logs;
$logs{sent}{count} = $logs{deferred}{count} = $logs{bounced}{count} = $logs{reject}{count} = 0;
for (@yesterday_log) {
if (/status=(\w+)/){
my $target = $1;
$logs{$target}{count}++;
push (@{$logs{$target}{to}},$1) if /to=<(.+?)>/;
push (@{$logs{$target}{message}},$1) if /status=\w+\s+\((.*)\)/;
$logs{$target}{0+$1}++ if /$yesterday\s+(\d\d):\d\d:\d\d/
}
elsif (/NOQUEUE: reject:/){
my $target = "reject";
$logs{$target}{count}++;
push (@{$logs{$target}{to}},$1) if /to=<(.+?)>/;
push (@{$logs{$target}{message}},$1) if /NOQUEUE:\s+reject:\s+(.+)/;
$logs{$target}{0+$1}++ if /$yesterday\s+(\d\d):\d\d:\d\d/
}
}
# print Subject
{
my $yesterday_yyyy_mm_dd = `LANG=C date +'%Y-%m-%d' -d'1 days ago'`;
print "Subject: Daily mail report for $yesterday_yyyy_mm_dd\n\n";
}
# format
my ($COUNT,$ITEM);
format REPORT=
@>>>>>> @*
$COUNT,$ITEM
.
$~="REPORT";
## messages
print "messages\n";
for ('sent','deferred','bounced','reject'){
$COUNT = $logs{$_}{count} || 0;
$ITEM = $_;
write;
}
print "\n";
# Per-Hour Traffic Summary
my @LINE;
print <<EOL;
Per-Hour Traffic Summary
time sent deferred bounced rejected
---------------------------------------------------------
EOL
format TABLE=
@0##-@0## @>>>>>> @>>>>>> @>>>>>> @>>>>>>
@LINE
.
$~="TABLE";
for (0..23){
@LINE = (
$_
, $_+100
, $logs{sent}{$_} || 0
, $logs{deferred}{$_} || 0
, $logs{bounced}{$_} || 0
, $logs{reject}{$_} || 0
);
write;
}
print "\n";
$~="REPORT";
# address top 10
for ('sent','deferred','bounced','reject'){
my $target = $_;
print "top 10 $target by message count\n";
my %count;
$count{$_}++ for @{$logs{$target}{to}};
my $i;
for (sort {$count{$b} <=> $count{$a}} keys %count){
$COUNT = $count{$_};
$ITEM = $_;
$i++;
write;
last if $i >= 10;
}
print "\n";
}
# detail
for ('deferred','bounced','reject'){
my $target = $_;
print "message $target detail\n";
my %count;
$count{$_}++ for @{$logs{$target}{message}};
my $i;
for (sort {$count{$b} <=> $count{$a}} keys %count){
$COUNT = $count{$_};
$ITEM = $_;
$i++;
write;
last if $i >= 10;
}
print "\n";
}
# rbl
print "RBL Check\n";
{
my $rip = join(".",reverse split(/\./,$my_ip));
my @list;
for (@rbl_sites) {
system "host $rip.".$_."> /dev/null 2>&1" or push(@list,$_);
}
if (@list>0){
print "$my_ip listed in $_\n" for @list;
}
else {
print "none\n";
}
}
# sendmail
system "cat ".$tempfile->filename."| /usr/sbin/sendmail $notify_address";
#!/bin/bash
set -e
### Initial Settings #####################################################
yesterday=`LANG=C date +'%b %_d' -d '1 days ago'`
yesterday_log=`eval "zgrep '^$yesterday' mail.log* || :"`
my_ip="192.168.0.1"
to_address="admin@example.com"
##########################################################################
# temp file
tmpfile=`mktemp`
trap "rm -f $tmpfile" EXIT
# change stdout
exec 3>&1
exec > $tmpfile
# subject
echo -e "Subject: Daily mail report for $(LANG=C date +%Y)\n"
# message count
sent_count=$(echo "$yesterday_log" | grep -c 'status=sent') || :
deferred_count=$(echo "$yesterday_log" | grep -c 'status=deferred') || :
bounced_count=$(echo "$yesterday_log" | grep -c 'status=bounced') || :
reject_count=$(echo "$yesterday_log" | grep -c 'NOQUEUE: reject:') || :
echo "messages"
printf "%7s sent\n" $sent_count
printf "%7s deferred\n" $deferred_count
printf "%7s bounced\n" $bounced_count
printf "%7s reject\n" $reject_count
# address top 10
for s in sent deferred bounced
do
echo -e "\ntop 10 $s by message count"
echo "$yesterday_log" | grep "status=$s" | perl -nle 'print $1 if /to=<(.+?)>/' | sort | uniq -c | sort -r | head -10 | perl -nlae 'printf ("%7s %s\n",@F)'
done
echo -e "\ntop 10 reject by message count"
echo "$yesterday_log" | grep 'NOQUEUE: reject:' | perl -nle 'print $1 if /to=<(.+?)>/' | sort | uniq -c | sort -r | head -10 | perl -nlae 'printf ("%7s %s\n",@F)'
# detail
for s in deferred bounced
do
echo -e "\nmessage $s detail"
echo "$yesterday_log" | grep "status=$s" | perl -nle 'print $1 if /status=\w+\s+\((.*)\)/' | sort | uniq -c | sort -r | head -10 | perl -nlae 'printf ("%7s %s\n",$F[0],join(" ",@F[1..$#F]))'
done
echo -e "\nmessage reject detail"
echo "$yesterday_log" | grep "NOQUEUE: reject:" | perl -nle 'print $1 if /NOQUEUE:\s+reject:\s+(.+)/' | sort | uniq -c | sort -r | head -10 | perl -nlae 'printf ("%7s %s\n",$F[0],join(" ",@F[1..$#F]))'
# rbl
echo ""
echo "RBL Check"
rip=`echo $my_ip | perl -ne 'chomp;@a=split(/\./);print join(".",reverse @a)'`
for r in "all.rbl.jp" "bl.spamcop.net" "sbl.spamhaus.org"
do
if host $rip.$r > /dev/null 2>&1
then
echo "$my_ip listed in $r"
fi
done
# mail send
exec 1>&3
cat $tmpfile | /usr/sbin/sendmail $to_address
messages
25 sent
6 deferred
1 bounced
60 reject
Per-Hour Traffic Summary
time sent deferred bounced rejected
---------------------------------------------------------
0000-0100 1 0 0 5
0001-0101 0 0 0 5
0002-0102 0 0 0 1
0003-0103 1 0 0 1
0004-0104 0 0 0 2
0005-0105 0 0 0 1
0006-0106 1 0 0 3
0007-0107 0 0 0 1
0008-0108 2 0 0 2
0009-0109 1 0 0 1
0010-0110 2 0 0 2
0011-0111 0 0 0 2
0012-0112 2 0 0 0
0013-0113 3 0 0 8
0014-0114 4 0 0 2
0015-0115 2 0 0 3
0016-0116 0 0 0 3
0017-0117 0 0 0 4
0018-0118 0 0 0 2
0019-0119 3 0 0 1
0020-0120 0 2 1 3
0021-0121 1 2 0 3
0022-0122 2 1 0 2
0023-0123 0 1 0 3
top 10 sent by message count
8 hoge@example.com
5 huga@example.com
4 foo@example.com
1 bar@example.com
message deferred detail
1 host example.com[xxx.xxx.xxx.xxx] refused to talk to me: 554 ESMTP server not available if you do not have a reverse dns mapping, ...
RBL Check
xxx.xxx.xxx.xxx listed in all.rbl.jp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment