2 # $Id: Collectd.pm 7 2006-12-07 06:13:12Z formorer $
6 Collectd - plugin for filling collectd with stats
10 Just copy Collectd.pm into your SpamAssassin Plugin path
11 (e.g /usr/share/perl5/Mail/SpamAssassin/Plugin/) and
12 add a loadplugin call into your init.pre file.
16 loadplugin Mail::SpamAssassin::Plugin::Collectd
22 =item collectd_socket [ socket path ] (default: /tmp/.collectd-email)
24 Where the collectd socket is
28 =item collectd_buffersize [ size ] (default: 256)
30 the email plugin uses a fixed buffer, if a line exceeds this size
31 it has to be continued in another line. (This is of course handled internally)
32 If you have changed this setting please get it in sync with the SA Plugin
38 This modules uses the email plugin of collectd from Sebastian Harl to
39 collect statistical informations in rrd files to create some nice looking
40 graphs with rrdtool. They communicate over a unix socket that the collectd
41 plugin creates. The generated graphs will be placed in /var/lib/collectd/email
45 Alexander Wirt <formorer@formorer.de>
49 Copyright 2006 Alexander Wirt <formorer@formorer.de>
51 This program is free software; you can redistribute it and/or modify
52 it under the the terms of either:
54 a) the Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
58 b) the GPL (http://www.gnu.org/copyleft/gpl.html)
60 use whatever you like more.
64 package Mail::SpamAssassin::Plugin::Collectd;
66 use Mail::SpamAssassin::Plugin;
67 use Mail::SpamAssassin::Logger;
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,
115 $conf->{parser}->register_commands(\@cmds);
119 my ($self, $params) = @_;
120 my $message_status = $params->{permsgstatus};
121 #create new connection to our socket
123 local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
126 alarm $self->{main}->{conf}->{collectd_timeout};
128 my $sock = new IO::Socket::UNIX ( $self->{main}->{conf}->{collectd_socket});
129 # debug some informations if collectd is not running or anything else went
132 dbg("collect: could not connect to " .
133 $self->{main}->{conf}->{collectd_socket} . ": $! - collectd plugin
139 my $score = $message_status->{score};
140 #get the size of the message
141 my $body = $message_status->{msg}->{pristine_body};
143 my $len = length($body);
145 if ($message_status->{score} >= $self->{main}->{conf}->{required_score} ) {
147 print $sock "e:spam:$len\n";
149 print $sock "e:ham:$len\n";
151 print $sock "s:$score\n";
153 my @tests = @{$message_status->{test_names_hit}};
155 my $buffersize = $self->{main}->{conf}->{collectd_buffersize};
156 dbg("collectd: buffersize: $buffersize");
158 while (scalar(@tests) > 0) {
159 push (@tmp_array, pop(@tests));
160 if (length(join(',', @tmp_array) . '\n') > $buffersize) {
161 push (@tests, pop(@tmp_array));
162 if (length(join(',', @tmp_array) . '\n') > $buffersize or scalar(@tmp_array) == 0) {
163 dbg("collectd: this shouldn't happen. Do you have tests"
164 ." with names that have more than ~ $buffersize Bytes?");
167 dbg ( "collectd: c:" . join(',', @tmp_array) . "\n" );
168 print $sock "c:" . join(',', @tmp_array) . "\n";
172 } elsif ( scalar(@tests) == 0 ) {
173 dbg ( "collectd: c:" . join(',', @tmp_array) . '\n' );
174 print $sock "c:" . join(',', @tmp_array) . "\n";
180 if ($@ eq "alarm\n") {
181 info("Connection to collectd timed out");
188 # vim: syntax=perl sw=4 ts=4 noet shiftround