pflogsumm - Produce Postfix MTA logfile summary
-Copyright (C) 1998-2025 by James S. Seymour, Release 1.1.8
+Copyright (C) 1998-2025 by James S. Seymour, Release 1.1.9
=head1 SYNOPSIS
If your postfix install has an SRS plugin running, many
addresses in the report will contain the SRS-formatted
- email addresses, also for non-local adresses (f.i.
+ email addresses, also for non-local addresses (f.i.
senders). This option will try to undo the "damage".
Addresses of the form:
my $hasDateCalc = $@ ? 0 : 1;
my $mailqCmd = "mailq";
-my $release = "1.1.8";
+my $release = "1.1.9";
# Variables and constants used throughout pflogsumm
use vars qw(
$cmd, $qid, $addr, $orig_to, $size, $relay, $status, $delay,
$dateStr, $dateStrRFC3339,
%panics, %fatals, %warnings, %masterMsgs,
- %msgSizes,
%deferred, %bounced,
%noMsgSize, %msgDetail,
$msgsRcvd, $msgsDlvrd, $sizeRcvd, $sizeDlvrd,
if($rejSubTyp eq "reject" or $rejSubTyp eq "milter-reject") {
++$rejects{$cmd}{$rejReas}{$rejRmdr} unless($opts{'rejectDetail'} == 0);
++$msgsRjctd;
+ --$msgsRcvd; # It will have already been counted as "Received," even though it ultimately is not
} elsif($rejSubTyp eq "warning") {
++$warns{$cmd}{$rejReas}{$rejRmdr} unless($opts{'rejectDetail'} == 0);
++$msgsWrnd;
++$discards{$cmd}{$rejReas}{$rejRmdr} unless($opts{'rejectDetail'} == 0);
++$msgsDscrdd;
}
+ delete($rcvdMsg{$qid}); # We're done with this
++$rejPerHr[$msgHr];
++${$msgsPerDay{$revMsgDateStr}}[4];
} elsif($qid eq 'warning') {
++$rcvPerHr[$msgHr];
++${$msgsPerDay{$revMsgDateStr}}[0];
++$msgsRcvd;
- $rcvdMsg{$qid} = gimme_domain($1); # Whence it came
- # DEBUG DEBUG DEBUG
- #print STDERR "Received: $qid\n";
+ $rcvdMsg{$qid}{'whence'} = gimme_domain($1); # Whence it came
} elsif(my($rejSubTyp) = $logRmdr =~ /\[\d+\]: \w+: (reject(?:_warning)?|hold|discard): /) {
if($rejSubTyp eq 'reject') {
proc_smtpd_reject($logRmdr, \%rejects, \$msgsRjctd,
my $toRmdr;
if((($addr, $size) = $logRmdr =~ /from=<([^>]*)>, size=(\d+)/) == 2)
{
- next if($msgSizes{$qid}); # avoid double-counting!
+ next if($rcvdMsg{$qid}{'size'}); # avoid double-counting!
if($addr) {
if($opts{'m'} && $addr =~ /^(.*!)*([^!]+)!([^!@]+)@([^\.]+)$/) {
$addr = "$4!" . ($1? "$1" : "") . $3 . "\@$2";
} else {
$addr = "from=<>"
}
- $msgSizes{$qid} = $size;
+ $rcvdMsg{$qid}{'size'} = $size;
push(@{$msgDetail{$qid}}, $addr) if($opts{'e'});
# Avoid counting forwards
- if($rcvdMsg{$qid}) {
+ if($rcvdMsg{$qid}{'whence'}) {
# Get the domain out of the sender's address. If there is
- # none: Use the client hostname/IP-address
+ # none: Use the client domain/IP-address
my $domAddr;
unless((($domAddr = $addr) =~ s/^[^@]+\@(.+)$/$1/) == 1) {
- $domAddr = $rcvdMsg{$qid} eq "pickup"? $addr : $rcvdMsg{$qid};
+ $domAddr = $rcvdMsg{$qid}{'whence'} eq "pickup"? $addr : $rcvdMsg{$qid}{'whence'};
}
++$sendgDomCnt
unless(${$sendgDom{$domAddr}}[MSG_CNT_I]);
++${$sendgUser{$addr}}[MSG_CNT_I];
${$sendgUser{$addr}}[MSG_SIZE_I] += $size;
$sizeRcvd += $size;
- delete($rcvdMsg{$qid}); # limit hash size
}
}
elsif((($addr, $orig_to, $relay, $delay, $status, $toRmdr) = $logRmdr =~
if($status eq 'sent') {
# was it actually forwarded, rather than delivered?
- if($toRmdr =~ /forwarded as /) {
+ if((my $newQid) = ($toRmdr =~ /\(forwarded as ([^\)]+)\)/)) {
++$msgsFwdd;
+ delete($rcvdMsg{$qid}); # We're done with this
next;
}
++$recipDomCnt unless(${$recipDom{$domAddr}}[MSG_CNT_I]);
++$dlvPerHr[$msgHr];
++${$msgsPerDay{$revMsgDateStr}}[1];
++$msgsDlvrd;
- # DEBUG DEBUG DEBUG
- #print STDERR "Delivered: $qid\n";
- if($msgSizes{$qid}) {
- ${$recipDom{$domAddr}}[MSG_SIZE_I] += $msgSizes{$qid};
- ${$recipUser{$addr}}[MSG_SIZE_I] += $msgSizes{$qid};
- $sizeDlvrd += $msgSizes{$qid};
+ if($rcvdMsg{$qid}{'size'}) {
+ ${$recipDom{$domAddr}}[MSG_SIZE_I] += $rcvdMsg{$qid}{'size'};
+ ${$recipUser{$addr}}[MSG_SIZE_I] += $rcvdMsg{$qid}{'size'};
+ $sizeDlvrd += $rcvdMsg{$qid}{'size'};
} else {
${$recipDom{$domAddr}}[MSG_SIZE_I] += 0;
${$recipUser{$addr}}[MSG_SIZE_I] += 0;
my ($bounceReas) = $logRmdr =~ /, status=bounced \((.+)\)/;
unless(defined($opts{'verbMsgDetail'})) {
$bounceReas = said_string_trimmer($bounceReas, 66);
- $bounceReas =~ s/^\d{3} //;
}
++$bounced{$relay}{$bounceReas};
}
++$rcvPerHr[$msgHr];
++${$msgsPerDay{$revMsgDateStr}}[0];
++$msgsRcvd;
- $rcvdMsg{$qid} = "pickup"; # Whence it came
+ $rcvdMsg{$qid}{'whence'} = "pickup"; # Whence it came
}
elsif($cmd eq 'smtp' && $opts{'smtpDetail'} != 0) {
# Was an IPv6 problem here
print $unProcd "$_\n" if $unProcd;
}
}
+ elsif($cmd =~ /^n?qmgr$/ && $logRmdr =~ /\bremoved$/) {
+ delete($rcvdMsg{$qid}); # We're done with this
+ }
else
{
print $unProcd "$_\n" if $unProcd;
my $slashSepRegex = '([^\s\/]+)\/((?:\d{1,3}\.){3}\d{1,3}|[\da-fA-F:]+(?:::(?:[\da-fA-F:]+)?)?|[\da-fA-F:]+:(?:\d{1,3}\.){3}\d{1,3})';
my ($fqdn, $ipaddr);
- print STDERR "dbg: \$_: \"$_\"\n" if(/unknown=0/);
unless((($fqdn, $ipaddr) = /$bracketRegex/i) == 2) {
($fqdn, $ipaddr) = /$slashSepRegex/i;
}