File Coverage

blib/lib/Log/Saftpresse/Plugin/Postfix/Delivered.pm
Criterion Covered Total %
statement 6 104 5.7
branch 0 56 0.0
condition 0 6 0.0
subroutine 2 6 33.3
pod 0 3 0.0
total 8 175 4.5


line stmt bran cond sub pod time code
1             package Log::Saftpresse::Plugin::Postfix::Delivered;
2              
3 1     1   746 use Moose::Role;
  1         2  
  1         4  
4              
5             # ABSTRACT: plugin to gather postfix delivered messages statistics
6             our $VERSION = '1.4'; # VERSION
7              
8 1     1   3129 use Log::Saftpresse::Plugin::Postfix::Utils qw( verp_mung );
  1         1  
  1         984  
9              
10             requires 'deferred_detail';
11             requires 'ignore_case';
12             requires 'deferred_detail';
13             requires 'message_detail';
14             requires 'bounce_detail';
15             requires 'extended';
16             requires 'uucp_mung';
17             requires 'ignore_case';
18             requires 'verp_mung';
19              
20             sub process_delivered {
21 0     0 0   my ( $self, $stash, $notes ) = @_;
22 0           my $service = $stash->{'service'};
23 0           my $message = $stash->{'message'};
24              
25 0 0         if( $service eq 'smtpd') { return; }
  0            
26              
27 0           my ($addr, $size, $relay, $delay, $status, $text);
28              
29 0 0         if(( ($addr, $size) = $message =~ /from=<([^>]*)>, size=(\d+)/) == 2) {
    0          
30 0           $stash->{'size'} = $size;
31 0           $stash->{'from'} = $addr;
32 0           $self->process_from( $stash, $notes );
33             } elsif( (
34             ($addr, $relay, $delay, $status, $text) = $message =~
35             /to=<([^>]*)>, (?:orig_to=<[^>]*>, )?relay=([^,]+), (?:conn_use=[^,]+, )?delay=([^,]+), (?:delays=[^,]+, )?(?:dsn=[^,]+, )?status=(\S+)(.*)$/
36             ) >= 4) {
37 0           $stash->{'to'} = $addr;
38 0           $stash->{'relay'} = $relay;
39 0           $stash->{'delay'} = $delay;
40 0           $stash->{'status'} = $status;
41 0 0         if( $text =~ /forwarded as / ) {
42 0           $stash->{'forwarded'} = 'true';
43             }
44 0           $self->process_to( $stash, $notes );
45             }
46              
47 0           return;
48             }
49              
50             sub process_to {
51 0     0 0   my ( $self, $stash, $notes ) = @_;
52 0           my $message = $stash->{'message'};
53 0           my $qid = $stash->{'queue_id'};
54 0           my $delay = $stash->{'delay'};
55 0           my $status = $stash->{'status'};
56 0           my $time = $stash->{'time'};
57              
58 0           my $addr = $stash->{'to'} = $self->_get_addr_str( $stash->{'to'} );
59 0           (my $domAddr = $addr) =~ s/^[^@]+\@//; # get domain only
60              
61 0           my $relay = $stash->{'relay'};
62 0 0         $relay = lc($relay) if( $self->ignore_case );
63              
64 0 0 0       if( $self->extended && ( my $from = $notes->get('from-'.$qid) ) ) {
65 0           $stash->{'from'} = $from;
66             }
67              
68 0 0         if($status eq 'sent') {
    0          
    0          
69             # was it actually forwarded, rather than delivered?
70 0 0         if( defined $stash->{'forwarded'}) {
71 0           $self->incr_host_one($stash, 'forwarded');
72 0           return;
73             }
74 0           $self->incr_host_one( $stash, 'sent', 'total');
75 0           $self->incr_host_one( $stash, 'sent', 'by_domain', $domAddr);
76 0           $self->incr_host( $stash, 'sent', 'delay', 'by_domain', $domAddr, $delay);
77 0           $self->incr_host_max( $stash, 'sent', 'max_delay', 'by_domain', $domAddr, $delay);
78 0           $self->incr_host_one( $stash, 'sent', 'by_rcpt', $addr);
79 0 0         if( $self->saftsumm_mode ) {
80 0           $self->incr_host_one( $stash, 'sent', 'per_hr', $time->hour);
81 0           $self->incr_host_one( $stash, 'sent', 'per_day', $time->ymd);
82             }
83              
84 0 0         if( my $size = $notes->get('size-'.$qid) ) {
85 0           $stash->{'size'} = $size;
86 0           $self->incr_host( $stash, 'sent', 'size', 'by_domain', $domAddr, $size);
87 0           $self->incr_host( $stash, 'sent', 'size', 'by_rcpt', $addr, $size);
88 0           $self->incr_host( $stash, 'sent', 'size', 'total', $size);
89             } else {
90 0           $self->incr_host_one( $stash, 'sent', 'size', 'no_size');
91             }
92             # [benning] hum?
93             # push(@{$msgDetail{$qid}}, "(sender not in log)") if($opts{'e'});
94             # push(@{$msgDetail{$qid}}, $addr) if($opts{'e'});
95             } elsif($status eq 'deferred') {
96 0 0         if( $self->deferred_detail > 0 ) {
97 0           my ($deferredReas) = $message =~ /, status=deferred \(([^\)]+)/;
98 0 0         unless( $self->message_detail ) {
99 0           $deferredReas = said_string_trimmer($deferredReas, 65);
100 0           $deferredReas =~ s/^\d{3} //;
101 0           $deferredReas =~ s/^connect to //;
102             }
103 0           $self->incr_host_one( $stash, 'deferred', $stash->{'service'}, $deferredReas);
104             }
105 0           $self->incr_host_one( $stash, 'deferred', 'total');
106 0 0         if( $self->saftsumm_mode ) {
107 0           $self->incr_host_one( $stash, 'deferred', 'per_hr', $time->hour);
108 0           $self->incr_host_one( $stash, 'deferred', 'per_day', $time->ymd);
109             }
110 0           $self->incr_host_one( $stash, 'deferred', 'by_domain', $domAddr);
111 0           $self->incr_host_max( $stash, 'deferred', 'max_delay', 'by_domain', $domAddr, $delay);
112             } elsif($status eq 'bounced') {
113 0 0         if( $self->bounce_detail > 0 ) {
114 0           my ($bounceReas) = $message =~ /, status=bounced \((.+)\)/;
115 0 0         unless( $self->message_detail ) {
116 0           $bounceReas = said_string_trimmer($bounceReas, 66);
117 0           $bounceReas =~ s/^\d{3} //;
118             }
119 0           $self->incr_host_one( $stash, 'bounced', $relay, $bounceReas);
120             }
121 0           $self->incr_host_one( $stash, 'bounced', 'total');
122 0 0         if( $self->saftsumm_mode ) {
123 0           $self->incr_host_one( $stash, 'bounced', 'per_hr', $time->hour);
124 0           $self->incr_host_one( $stash, 'bounced', 'per_day', $time->ymd);
125             }
126             }
127             }
128              
129             sub process_from {
130 0     0 0   my ( $self, $stash, $notes ) = @_;
131 0           my $qid = $stash->{'queue_id'};
132 0           my $addr = $stash->{'from'} = $self->_get_addr_str( $stash->{'from'} );
133 0           my $size = $stash->{'size'};
134              
135 0 0         return if( $notes->get('size-'.$qid) ); # avoid double-counting!
136 0           $notes->set('size-'.$qid => $size);
137 0 0         $notes->set('from-'.$qid => $addr) if( $self->extended );
138              
139             # Avoid counting forwards
140 0 0         if( my $client = $notes->get('client-'.$qid) ) {
141             # Get the domain out of the sender's address. If there is
142             # none: Use the client hostname/IP-address
143 0           my $domAddr;
144 0 0         unless((($domAddr = $addr) =~ s/^[^@]+\@(.+)$/$1/) == 1) {
145 0 0         $domAddr = $client eq "pickup"? $addr : $client;
146             }
147              
148 0           $self->incr_host_one( $stash, 'recieved', 'total');
149 0           $self->incr_host( $stash, 'recieved', 'size', 'total', $size);
150              
151 0           $self->incr_host_one( $stash, 'recieved', 'by_domain', $domAddr);
152 0           $self->incr_host( $stash, 'recieved', 'size', 'by_domain', $domAddr, $size);
153              
154 0           $self->incr_host_one( $stash, 'recieved', 'by_sender', $addr);
155 0           $self->incr_host( $stash, 'recieved', 'size', 'by_sender', $addr, $size);
156             }
157 0           return;
158             }
159              
160             sub _get_addr_str {
161 0     0     my ( $self, $addr ) = @_;
162              
163 0 0         if($addr) {
164 0 0 0       if( $self->uucp_mung &&
165             $addr =~ /^(.*!)*([^!]+)!([^!@]+)@([^\.]+)$/) {
166 0 0         $addr = "$4!" . ($1? "$1" : "") . $3 . "\@$2";
167             }
168 0 0         $addr =~ s/(@.+)/\L$1/ unless( $self->ignore_case );
169 0 0         $addr = lc($addr) if( $self->ignore_case );
170 0           $addr = verp_mung( $self->verp_mung, $addr);
171             } else {
172 0           $addr = "<>"
173             }
174              
175 0           return( $addr );
176             }
177              
178             1;
179              
180             __END__
181              
182             =pod
183              
184             =encoding UTF-8
185              
186             =head1 NAME
187              
188             Log::Saftpresse::Plugin::Postfix::Delivered - plugin to gather postfix delivered messages statistics
189              
190             =head1 VERSION
191              
192             version 1.4
193              
194             =head1 AUTHOR
195              
196             Markus Benning <ich@markusbenning.de>
197              
198             =head1 COPYRIGHT AND LICENSE
199              
200             This software is Copyright (c) 1998 by James S. Seymour, 2015 by Markus Benning.
201              
202             This is free software, licensed under:
203              
204             The GNU General Public License, Version 2, June 1991
205              
206             =cut