postfixでqueueの保存期間を超えたメールをログから抽出

2017年1月24日

postfixでqueueの保存期間を超えたメールをログから抽出するスクリプト
ログを標準入力で食わせると、標準出力にCSV形式

log.pl

#!/usr/bin/perl

use strict;
use warnings;
use utf8;

my %logs;
print "\"Received Date\",\"From\",\"To\",\"Message-ID\",\"Queue ID\",\"Size\",\"Client\",\"Relay\",\"Remove Date\",\"Status\",\"Retry Dates\"\n";
while(<STDIN>) {
	chomp;
	if ( /^(.+\s+\d+\s+\d+:\d+:\d+) optplus postfix\/smtpd\[\d+\]: ([0-9A-F]+): client=(.+)$/ ) {
		if ( defined($logs{$2}) ) {
			next;
		}
		$logs{$2}{rdate} = $1;
		$logs{$2}{qid} = $2;
		$logs{$2}{client} = $3;
	}
	if ( /^(.+\s+\d+\s+\d+:\d+:\d+) optplus postfix\/cleanup\[\d+\]: ([0-9A-F]+): message-id=(.+)$/ ) {
		$logs{$2}{msgid} = $3;
	}
	if ( /^(.+\s+\d+\s+\d+:\d+:\d+) optplus postfix\/qmgr\[\d+\]: ([0-9A-F]+): from=(.+), size=(\d+), / ) {
		if ( defined($logs{$2}{from}) ) {
		# 再送
			$logs{$2}{resend} .= $1 . ",";
		} else {
			$logs{$2}{resend} = "";
			$logs{$2}{from} = $3;
			$logs{$2}{size} = $4;
		}
	}
	if ( /^(.+\s+\d+\s+\d+:\d+:\d+) optplus postfix\/smtp\[\d+\]: ([0-9A-F]+): to=(.+), relay=(.+), delay=(.+), delays=(.+), dsn=(.+) status=(.+) / ) {
		$logs{$2}{to} = $3;
		$logs{$2}{relay} = $4;
		$logs{$2}{status} = $8;
		$logs{$2}{enddate} = $1;
		if ( $logs{$2}{status} eq "sent" or $logs{$2}{status} eq "bounced" ) {
			undef($logs{$2});
		} elsif ( $logs{$2}{status} eq "expired" ) {
			print "\"$logs{$2}{rdate}\",";
			print "\"$logs{$2}{from}\",";
			print "\"$logs{$2}{to}\",";
			print "\"$logs{$2}{msgid}\",";
			print "\"$logs{$2}{qid}\",";
			print "\"$logs{$2}{size}\",";
			print "\"$logs{$2}{client}\",";
			print "\"$logs{$2}{relay}\",";
			print "\"$logs{$2}{enddate}\",";
			print "\"$logs{$2}{status}\",";
			print "\"$logs{$2}{resend}\",";
			print "\n";
			undef($logs{$2});
		}
	}
	if ( /^(.+\s+\d+\s+\d+:\d+:\d+) optplus postfix\/smtp\[\d+\]: ([0-9A-F]+): to=(.+), relay=(.+), conn_use=\d+, delay=(.+), delays=(.+), dsn=(.+) status=(.+) / ) {
		$logs{$2}{to} = $3;
		$logs{$2}{relay} = $4;
		$logs{$2}{status} = $8;
		$logs{$2}{enddate} = $1;
		if ( $logs{$2}{status} eq "sent" or $logs{$2}{status} eq "bounced" ) {
			undef($logs{$2});
		} elsif ( $logs{$2}{status} eq "expired" ) {
			print "\"$logs{$2}{rdate}\",";
			print "\"$logs{$2}{from}\",";
			print "\"$logs{$2}{to}\",";
			print "\"$logs{$2}{msgid}\",";
			print "\"$logs{$2}{qid}\",";
			print "\"$logs{$2}{size}\",";
			print "\"$logs{$2}{client}\",";
			print "\"$logs{$2}{relay}\",";
			print "\"$logs{$2}{enddate}\",";
			print "\"$logs{$2}{status}\",";
			print "\"$logs{$2}{resend}\",";
			print "\n";
			undef($logs{$2});
		}
	}

	if ( /^(.+\s+\d+\s+\d+:\d+:\d+) optplus postfix\/qmgr\[\d+\]: ([0-9A-F]+): from=(.+), status=(.+),/ ) {
		$logs{$2}{enddate} = $1;
		$logs{$2}{from} = $3;
		$logs{$2}{status} = $4;
		if ( $logs{$2}{status} eq "expired" ) {
			print "\"$logs{$2}{rdate}\",";
			print "\"$logs{$2}{from}\",";
			print "\"$logs{$2}{to}\",";
			print "\"$logs{$2}{msgid}\",";
			print "\"$logs{$2}{qid}\",";
			print "\"$logs{$2}{size}\",";
			print "\"$logs{$2}{client}\",";
			print "\"$logs{$2}{relay}\",";
			print "\"$logs{$2}{enddate}\",";
			print "\"$logs{$2}{status}\",";
			print "\"$logs{$2}{resend}\",";
			print "\n";
		}
		undef($logs{$2});
	}

}

log