File Coverage

blib/lib/Tail/Stat/Plugin/spamd.pm
Criterion Covered Total %
statement 12 38 31.5
branch 0 2 0.0
condition 0 5 0.0
subroutine 4 8 50.0
pod 4 4 100.0
total 20 57 35.0


line stmt bran cond sub pod time code
1             package Tail::Stat::Plugin::spamd;
2              
3             =head1 NAME
4              
5             Tail::Stat::Plugin::spamd - Statistics collector for SpamAssassin spamd
6              
7             =cut
8              
9 1     1   826 use strict;
  1         1  
  1         31  
10 1     1   4 use warnings qw(all);
  1         2  
  1         43  
11              
12              
13             =head1 SYNOPSIS
14              
15             tstatd -o usr spamd spamd.log
16              
17              
18             =head1 LOG FORMATS
19              
20             Plugin search spamd logs for records of two types:
21              
22             =over
23              
24             =item C<clean>
25              
26             spamd: clean message (3.1/5.0) for alex:1004 in 2.3 seconds, 1327 bytes.
27              
28             =item C<spam>
29              
30             spamd: identified spam (16.4/5.0) for andrew:1004 in 6.3 seconds, 2937 bytes.
31              
32             =back
33              
34              
35             =head1 OPTIONS
36              
37             =over
38              
39             =item C<usr>
40              
41             Turn on collecting per-user statistics.
42              
43             =back
44              
45              
46             =head1 STATISTICS
47              
48             =head2 Overall statistics
49              
50             =over
51              
52             =item C<clean_messages>
53              
54             Total number of messages identified as clean.
55              
56             =item C<spam_messages>
57              
58             Total number of messages identified as spam.
59              
60             =item C<clean_bytes>
61              
62             Total number of bytes for messages identified as clean.
63              
64             =item C<spam_bytes>
65              
66             Total number of bytes for messages identified as spam.
67              
68             =item C<clean:I<login>>
69              
70             Total number of messages identified as clean for I<login>
71             (B<usr> option is required).
72              
73             =item C<spam:I<login>>
74              
75             Total number of messages identified as spam for I<login>
76             (B<usr> option is required).
77              
78             =back
79              
80              
81             =head2 Last statistics
82              
83             =over
84              
85             =item C<last_clean_messages>
86              
87             Total number of last messages identified as clean.
88              
89             =item C<last_spam_messages>
90              
91             Total number of last messages identified as spam.
92              
93             =item C<last_clean_bytes>
94              
95             Total number of bytes from last messages identified as clean.
96              
97             =item C<last_spam_bytes>
98              
99             Total number of bytes from last messages identified as spam.
100              
101             =item C<last_clean_rate>
102              
103             Total rate of last messages identified as clean.
104              
105             =item C<last_spam_rate>
106              
107             Total rate of last messages identified as spam.
108              
109             =item C<last_clean_elapsed>
110              
111             Total number of seconds elapsed for processing last messages identified as clean.
112              
113             =item C<last_spam_elapsed>
114              
115             Total number of seconds elapsed for processing last messages identified as spam.
116              
117             =back
118              
119              
120             =cut
121              
122              
123 1     1   3 use base qw(Tail::Stat::Plugin);
  1         1  
  1         66  
124 1     1   4 use List::Util qw(sum);
  1         1  
  1         509  
125              
126              
127 0     0 1   sub regex { qr{
128              
129             spamd:
130             \s+
131             (?:
132             identified\s+(spam) # 'spam' [0]
133             |
134             (clean)\s+message # 'clean' [1]
135             )
136             \s+
137             \(
138             ([\d\.-]+) # rate [2]
139             /
140             ([\d\.-]+) # threshold [3]
141             \)
142             \s+
143             for
144             \s+
145             (\S+) # login [4]
146             :
147             (\d+) # uid [5]
148             \s+
149             in
150             \s+
151             ([\d\.-]+) # elapsed time [6]
152             \s+
153             seconds,
154             \s+
155             (\d+) # message size [7]
156             \s
157             bytes
158              
159             }x }
160              
161              
162             sub process_data {
163 0     0 1   my $self = shift;
164 0           my ($ref,$pub,$prv,$win) = @_;
165              
166 0   0       my $m = $ref->[0] || $ref->[1];
167              
168 0           $pub->{ $m.'_messages' }++;
169 0           $pub->{ $m.'_bytes'} += $ref->[7];
170 0 0         $pub->{ $m.':'.$ref->[4] }++ if $self->{usr};
171              
172 0           $win->{ $m.'_messages' }++;
173 0           $win->{ $m.'_bytes'} += $ref->[7];
174 0           $win->{ $m.'_rate'} += $ref->[2];
175 0           $win->{ $m.'_elapsed'} += $ref->[6];
176              
177 0           return 1;
178             }
179              
180              
181             sub process_window {
182 0     0 1   my $self = shift;
183 0           my ($pub,$prv,$wins) = @_;
184              
185 0           for my $m ( qw( clean spam ) ) {
186 0           for my $x ( qw( bytes elapsed messages rate ) ) {
187 0   0       $pub->{'last_'.$m.'_'.$x} = sum ( map { $_->{$m.'_'.$x} || 0 } @$wins ) || 0;
188             }
189             }
190             }
191              
192              
193             sub stats_zone {
194 0     0 1   my ($self,$zone,$pub,$prv,$wins) = @_;
195              
196             # required keys defaults
197 0           my %out;
198 0           for my $x ( qw( bytes messages ) ) {
199 0           $out{$_.'_'.$x} = 0 for qw( clean spam );
200             }
201 0           for my $x ( qw( bytes elapsed messages rate ) ) {
202 0           $out{'last_'.$_.'_'.$x} = 0 for qw( clean spam );
203             }
204              
205             # copy values as is
206 0           $out{$_} += $pub->{$_} for keys %$pub;
207              
208 0           map { $_.': '.$out{$_} } sort keys %out;
  0            
209             }
210              
211              
212             =head1 AUTHOR
213              
214             Oleg A. Mamontov, C<< <oleg@mamontov.net> >>
215              
216              
217             =head1 COPYRIGHT
218              
219             This program is free software; you can redistribute it and/or modify it
220             under the terms of either: the GNU General Public License as published
221             by the Free Software Foundation; or the Artistic License.
222              
223             See http://dev.perl.org/licenses/ for more information.
224              
225             =cut
226              
227             1;
228