source: postfix-logtools/poststat/poststat @ 631

Last change on this file since 631 was 631, checked in by ben, 9 years ago

adding message status and cleaning unused vitrual, see #28

  • Property svn:executable set to *
File size: 6.9 KB
Line 
1#!/usr/bin/env perl
2
3# 2010-06-26 vschmitt@bearstech.com
4# 2009-04-23 vcaron@bearstech.com
5
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19# Grep Postfix logs and gather various counters in JSON format,
20# one file per counter (useful to feed to some Flotr based graph)
21# Note:
22# - no real need to filter ou mon probes (24 checks/day)
23# - need to be careful to filter a/v email reinjections
24
25use strict;
26use warnings;
27use Getopt::Long;
28
29my %stat = (
30  ce_blacklist       => 0,
31  ce_hangup          => 0,
32  ce_helo_no_dns     => 0,
33  ce_helo_not_fqdn   => 0,
34  ce_ok              => 0,
35  ce_proto_error     => 0,
36  ce_psbl            => 0,
37  ce_sorbs           => 0,
38  ce_spamhaus        => 0,
39  ce_ssl_error       => 0,
40  ce_timeout         => 0,
41  ci_brute_force     => 0,
42  ci_connect_auth    => 0,
43  ci_connect_ext     => 0,
44  ci_connect_ext_tot => 0,
45  ci_connect_global  => 0,
46  ci_connect_int_tot => 0,
47  ci_connect_lan     => 0,
48  ci_connect_local   => 0,
49  ci_connect_mx      => 0,
50  ci_connect_tot     => 0,
51  ci_connect_wm      => 0,
52  grey_spf           => 0,
53  grey_delayed       => 0,
54  grey_autowl        => 0,
55  grey_hard_wl       => 0,
56  me_no_relay        => 0,
57  me_no_target       => 0,
58  me_sender_no_dns   => 0,
59  me_sender_not_fqdn => 0,
60  mi_bounced         => 0,
61  mi_count           => 0,
62  mi_deliver         => 0,
63  mi_ham             => 0,
64  mi_inbox           => 0,
65  mi_robot           => 0,
66  mi_size            => 0,
67  mi_spam            => 0,
68  mi_tot             => 0,
69  mi_unsure          => 0,
70  mi_vir_amav        => 0,
71  mi_vir_milt        => 0,
72  mo_bounced         => 0,
73  mo_deferred        => 0,
74  mo_sent            => 0,
75);
76my @backupmx;
77my @lanservers;
78my @spamdir;
79my @unsuredir;
80GetOptions(
81  "backup-mx=s{,}"   => \@backupmx,
82  "lan-servers=s{,}" => \@lanservers,
83  "spam-dir=s{,}"    => \@spamdir,
84  "unsure-dir=s{,}"  => \@unsuredir
85);
86
87while (<STDIN>) {
88  # get greylisting info
89  $stat{grey_spf}++,            next if /.* milter-greylist: .* are SPF-compliant/;
90  $stat{grey_delayed}++,        next if /.* milter-greylist: .* delayed for/;
91  $stat{grey_autowl}++,         next if /.* milter-greylist: .* autowhitelisted for another/;
92  $stat{grey_hard_wl}++,        next if /.* milter-greylist: .* skipping greylist because.*is whitelisted/;
93
94  # spam
95  if (@spamdir) {
96      foreach my $spam (@spamdir) {
97          $stat{mi_spam}++,     next if /deliver\(.* mail .*$spam/;
98      }
99  }
100  if (@unsuredir) {
101      foreach my $unsure (@unsuredir) {
102           $stat{mi_unsure}++,  next if /deliver\(.* mail .*$unsure/;
103      }
104  }
105  $stat{mi_deliver}++,          next if /deliver\(.* mail /;
106
107  # virus with amavis
108  $stat{mi_vir_amav}++,         next if / amavis.*quarantine: .*virus-/;
109
110  next if !s/.* postfix\/(.*?)\[\d+\]: //;
111  my $prog = $1;
112  my $local_qid;
113
114  if ($prog eq 'smtpd') {
115    # Incoming SMTP connexions
116    if (@backupmx) {
117        foreach my $mx (@backupmx) {
118            $stat{ci_connect_mx}++,       next if /^connect from $mx/;
119        }
120    }
121    if (@lanservers) {
122         foreach my $lan (@lanservers) {
123            $stat{ci_connect_lan}++,      next if /^connect from $lan/;
124        }
125    }
126    $stat{ci_connect_wm}++,      next if /^([[:xdigit:]]{8,16}): client=localhost\[.*, sasl_username=/;
127    $stat{ci_connect_auth}++,    next if /^([[:xdigit:]]{8,16}): .*, sasl_username=/;
128    $stat{ci_connect_local}++,   next if /^connect from localhost/;
129    $stat{ci_connect_global}++,  next if /^connect/;
130    $stat{ci_brute_force}++,     next if /SASL LOGIN authentication failed/;
131
132    # Rejected connexions (no delivery)
133    $stat{ce_proto_error}++,     next if /^too many errors/;
134    $stat{ce_ssl_error}++,       next if /^SSL_accept error/;
135    $stat{ce_helo_not_fqdn}++,   next if /Helo command rejected: need fully-qualified hostname/;
136    $stat{ce_helo_no_dns}++,     next if /Helo command rejected: Host not found/;
137    # FIXME Did never match in tests
138    # try with /Recipient address rejected/ ?
139    $stat{ce_blacklist}++,       next if /Client host rejected/;
140    $stat{ce_psbl}++,            next if /blocked using psbl\.surriel\.com/;
141    $stat{ce_sorbs}++,           next if /blocked using dnsbl\.sorbs\.net/;
142    $stat{ce_spamhaus}++,        next if /blocked using sbl-xbl\.spamhaus\.org/;
143    $stat{ce_timeout}++,         next if /^timeout/;
144    $stat{ce_hangup}++,          next if /^lost connection/;
145
146    # Rejected messages
147    $stat{me_no_relay}++,        next if /Relay access denied/;
148    $stat{me_no_target}++,       next if /User unknown in (local recipient|virtual mailbox) table/;
149    $stat{me_sender_not_fqdn}++, next if /Sender address rejected: need fully-qualified address/;
150    $stat{me_sender_no_dns}++,   next if /Sender address rejected: Domain not found/;
151
152    $local_qid = $1 if /^([[:xdigit:]]{8,16}): client=localhost/;
153
154    #next if /^disconnect/;
155    #next if /^warning:/;
156    #next if /^table/;
157    next; # Ignore all other smtpd messages
158  }
159
160  if ($prog eq 'qmgr') {
161    next if !/^([[:xdigit:]]{8,16}): .*, size=(\d+), nrcpt=(\d+)/;
162    next if defined $local_qid and $1 eq $local_qid; # Ignore local emails (reinjections from a/v)
163
164    # Messages input (what's submitted)
165    $stat{mi_size} += $2;
166    $stat{mi_count} += $3;
167
168    next;
169  }
170
171  if ($prog eq 'cleanup') {
172    # virus with milter
173    $stat{mi_vir_milt}++,        next if / virus found: /;
174
175    next;
176  }
177
178  if ($prog eq 'pipe') {
179    $stat{mi_inbox}++,           next if / status=sent \(delivered via dovecot service\)/;
180    $stat{mi_bounced}++,         next if / status=bounced /;
181   
182    next;
183  }
184
185  if ($prog eq 'local') {
186    $stat{mi_robot}++,           next if / status=sent \(delivered to command/;
187   
188    next;
189  }
190
191  if ($prog eq 'smtp') {
192    $stat{mo_sent}++,            next if / status=sent /;
193    $stat{mo_bounced}++,         next if / status=bounced /;
194    $stat{mo_deferred}++,        next if / status=deferred /;
195
196  }
197}
198
199$stat{mi_ham}             = $stat{mi_deliver} - $stat{mi_spam} - $stat{mi_unsure};
200
201$stat{ci_connect_ext_tot} = $stat{ci_connect_global} - $stat{ci_connect_auth};
202$stat{ci_connect_ext}     = $stat{ci_connect_ext_tot} - $stat{ci_connect_mx} - $stat{ci_connect_lan};
203$stat{ci_connect_int_tot} = $stat{ci_connect_auth} + $stat{ci_connect_wm};
204$stat{ci_connect_tot}     = $stat{ci_connect_ext_tot} + $stat{ci_connect_int_tot};
205
206$stat{mi_tot} = $stat{mi_inbox} + $stat{mi_robot} + $stat{mi_bounced} + $stat{mo_sent} + $stat{mo_bounced};
207
208printf("%-20s: %u\n", $_, $stat{$_}) foreach sort keys %stat;
209
Note: See TracBrowser for help on using the repository browser.