5 Collectd - plugin for filling collectd with stats
9 Just copy Collectd.pm into your SpamAssassin Plugin path
10 (e.g /usr/share/perl5/Mail/SpamAssassin/Plugin/) and
11 add a loadplugin call into your init.pre file.
15 loadplugin Mail::SpamAssassin::Plugin::Collectd
21 =item collectd_socket [ socket path ] (default: /tmp/.collectd-email)
23 Where the collectd socket is
27 =item collectd_buffersize [ size ] (default: 256)
29 the email plugin uses a fixed buffer, if a line exceeds this size
30 it has to be continued in another line. (This is of course handled internally)
31 If you have changed this setting please get it in sync with the SA Plugin
37 This modules uses the email plugin of collectd from Sebastian Harl to
38 collect statistical informations in rrd files to create some nice looking
39 graphs with rrdtool. They communicate over a unix socket that the collectd
40 plugin creates. The generated graphs will be placed in /var/lib/collectd/email
44 Alexander Wirt <formorer@formorer.de>
48 Copyright 2006 Alexander Wirt <formorer@formorer.de>
50 This program is free software; you can redistribute it and/or modify
51 it under the the terms of either:
53 a) the Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
57 b) the GPL (http://www.gnu.org/copyleft/gpl.html)
59 use whatever you like more.
63 package Mail::SpamAssassin::Plugin::Collectd;
65 use Mail::SpamAssassin::Plugin;
66 use Mail::SpamAssassin::Logger;
70 use Time::HiRes qw(usleep);
74 @ISA = qw(Mail::SpamAssassin::Plugin);
77 my ($class, $mailsa) = @_;
79 # the usual perlobj boilerplate to create a subclass object
80 $class = ref($class) || $class;
81 my $self = $class->SUPER::new($mailsa);
82 bless ($self, $class);
84 # register our config options
85 $self->set_config($mailsa->{conf});
87 # and return the new plugin object
92 my ($self, $conf) = @_;
96 setting => 'collectd_buffersize',
99 $Mail::SpamAssassin::Conf::CONF_TYPE_NUMERIC,
103 setting => 'collectd_socket',
104 default => '/tmp/.collectd-email',
105 type => $Mail::SpamAssassin::Conf::CONF_TYPE_STRING,
109 setting => 'collectd_timeout',
112 $Mail::SpamAssassin::Conf::CONF_TYPE_NUMERIC,
116 setting => 'collectd_retries',
119 $Mail::SpamAssassin::Conf::CONF_TYPE_NUMERIC,
123 $conf->{parser}->register_commands(\@cmds);
127 my ($self, $params) = @_;
128 my $message_status = $params->{permsgstatus};
129 #create new connection to our socket
131 local $SIG{ALRM} = sub { die "Sending to collectd timed out.\n" }; # NB: \n required
134 alarm $self->{main}->{conf}->{collectd_timeout};
137 #try at least $self->{main}->{conf}->{collectd_retries} to get a
139 for (my $i = 0; $i < $self->{main}->{conf}->{collectd_retries} ; ++$i) {
140 last if $sock = new IO::Socket::UNIX
141 ($self->{main}->{conf}->{collectd_socket});
142 #sleep a random value between 0 and 50 microsecs to try for a new
144 usleep(int(rand(50)));
147 die("could not connect to " .
148 $self->{main}->{conf}->{collectd_socket} . ": $! - collectd plugin disabled") unless $sock;
152 my $score = $message_status->{score};
153 #get the size of the message
154 my $body = $message_status->{msg}->{pristine_body};
156 my $len = length($body);
158 if ($message_status->{score} >= $self->{main}->{conf}->{required_score} ) {
160 print $sock "e:spam:$len\n";
162 print $sock "e:ham:$len\n";
164 print $sock "s:$score\n";
166 my @tests = @{$message_status->{test_names_hit}};
168 my $buffersize = $self->{main}->{conf}->{collectd_buffersize};
169 dbg("collectd: buffersize: $buffersize");
171 while (scalar(@tests) > 0) {
172 push (@tmp_array, pop(@tests));
173 if (length(join(',', @tmp_array) . '\n') > $buffersize) {
174 push (@tests, pop(@tmp_array));
175 if (length(join(',', @tmp_array) . '\n') > $buffersize or scalar(@tmp_array) == 0) {
176 dbg("collectd: this shouldn't happen. Do you have tests"
177 ." with names that have more than ~ $buffersize Bytes?");
180 dbg ( "collectd: c:" . join(',', @tmp_array) . "\n" );
181 print $sock "c:" . join(',', @tmp_array) . "\n";
185 } elsif ( scalar(@tests) == 0 ) {
186 dbg ( "collectd: c:" . join(',', @tmp_array) . '\n' );
187 print $sock "c:" . join(',', @tmp_array) . "\n";
196 info("collectd: $message");
203 # vim: syntax=perl sw=4 ts=4 noet shiftround