X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=contrib%2FSpamAssassin%2FCollectd.pm;h=b53cf953fcf201f7fb21c98bf830afda70e8908b;hb=48efd3deb4c9139fd060ff3d289896e9031bcc7c;hp=d3b103e80bcaeffcf6c2dcff4f60478efb04a08c;hpb=1c5607a1a8d6d8c2963a14144c9d378d018fb7a7;p=collectd.git diff --git a/contrib/SpamAssassin/Collectd.pm b/contrib/SpamAssassin/Collectd.pm index d3b103e8..b53cf953 100644 --- a/contrib/SpamAssassin/Collectd.pm +++ b/contrib/SpamAssassin/Collectd.pm @@ -1,5 +1,4 @@ #!/usr/bin/perl -# $Id: Collectd.pm 4 2006-12-02 15:18:14Z formorer $ =head1 NAME @@ -19,7 +18,7 @@ add a loadplugin call into your init.pre file. =over 4 -=item collectd_socket [ socket path ] (default: /tmp/.collectd-email) +=item collectd_socket [ socket path ] (default: /var/run/collectd-email) Where the collectd socket is @@ -33,6 +32,21 @@ If you have changed this setting please get it in sync with the SA Plugin config. =cut + +=item collectd_timeout [ sec ] (default: 2) + +if sending data to to collectd takes too long the connection will be aborted. + +=cut + +=item collectd_retries [ tries ] (default: 3) + +the collectd plugin uses a tread pool, if this is empty the connection fails, +the SA Plugin then tries to reconnect. With this variable you can indicate how +often it should try. + +=cut + =head1 DESCRIPTION This modules uses the email plugin of collectd from Sebastian Harl to @@ -48,15 +62,16 @@ Alexander Wirt Copyright 2006 Alexander Wirt - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance - with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 Unless required - by applicable law or agreed to in writing, software distributed - under the License is distributed on an "AS IS" BASIS, WITHOUT - WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions - and limitations under the License. + This program is free software; you can redistribute it and/or modify + it under the the terms of either: + + a) the Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) + + or + + b) the GPL (http://www.gnu.org/copyleft/gpl.html) + + use whatever you like more. =cut @@ -67,6 +82,7 @@ use Mail::SpamAssassin::Logger; use strict; use bytes; use warnings; +use Time::HiRes qw(usleep); use IO::Socket; use vars qw(@ISA); @@ -100,10 +116,25 @@ sub set_config { push (@cmds, { setting => 'collectd_socket', - default => '/tmp/.collectd-email', + default => '/var/run/collectd-email', type => $Mail::SpamAssassin::Conf::CONF_TYPE_STRING, }); + push (@cmds, { + setting => 'collectd_timeout', + default => 2, + type => + $Mail::SpamAssassin::Conf::CONF_TYPE_NUMERIC, + }); + + push (@cmds, { + setting => 'collectd_retries', + default => 3, + type => + $Mail::SpamAssassin::Conf::CONF_TYPE_NUMERIC, + }); + + $conf->{parser}->register_commands(\@cmds); } @@ -111,56 +142,75 @@ sub check_end { my ($self, $params) = @_; my $message_status = $params->{permsgstatus}; #create new connection to our socket - my $sock = new IO::Socket::UNIX ( $self->{main}->{conf}->{collectd_socket}); - # debug some informations if collectd is not running or anything else went - # wrong - if ( ! $sock ) { - dbg("collect: could not connect to " . - $self->{main}->{conf}->{collectd_socket} . ": $! - collectd plugin - disabled"); - return 0; - } - $sock->autoflush(1); + eval { + local $SIG{ALRM} = sub { die "Sending to collectd timed out.\n" }; # NB: \n required + + #generate a timeout + alarm $self->{main}->{conf}->{collectd_timeout}; + + my $sock; + #try at least $self->{main}->{conf}->{collectd_retries} to get a + #connection + for (my $i = 0; $i < $self->{main}->{conf}->{collectd_retries} ; ++$i) { + my ($socket_path) = $self->{main}->{conf}->{collectd_socket} =~ /(.*)/; # Untaint path, which can contain any characters. + last if $sock = new IO::Socket::UNIX $socket_path; + #sleep a random value between 0 and 50 microsecs to try for a new + #thread + usleep(int(rand(50))); + } - my $score = $message_status->{score}; - #get the size of the message - my $body = $message_status->{msg}->{pristine_body}; + die("could not connect to " . + $self->{main}->{conf}->{collectd_socket} . ": $! - collectd plugin disabled") unless $sock; - my $len = length($body); + $sock->autoflush(1); - if ($message_status->{score} >= $self->{main}->{conf}->{required_score} ) { - #hey we have spam - print $sock "e:spam:$len\n"; - } else { - print $sock "e:ham:$len\n"; - } - print $sock "s:$score\n"; - my @tmp_array; - my @tests = @{$message_status->{test_names_hit}}; - - my $buffersize = $self->{main}->{conf}->{collectd_buffersize}; - dbg("collectd: buffersize: $buffersize"); - - while (scalar(@tests) > 0) { - push (@tmp_array, pop(@tests)); - if (length(join(',', @tmp_array) . '\n') > $buffersize) { - push (@tests, pop(@tmp_array)); - if (length(join(',', @tmp_array) . '\n') > $buffersize or scalar(@tmp_array) == 0) { - dbg("collectd: this shouldn't happen. Do you have tests" - ." with names that have more than ~ $buffersize Bytes?"); - return 1; - } else { - dbg ( "collectd: c:" . join(',', @tmp_array) . "\n" ); - print $sock "c:" . join(',', @tmp_array) . "\n"; - #clean the array - @tmp_array = (); - } - } elsif ( scalar(@tests) == 0 ) { - dbg ( "collectd: c:" . join(',', @tmp_array) . '\n' ); - print $sock "c:" . join(',', @tmp_array) . "\n"; + my $score = $message_status->{score}; + #get the size of the message + my $body = $message_status->{msg}->{pristine_body}; + + my $len = length($body); + + if ($message_status->{score} >= $self->{main}->{conf}->{required_score} ) { + #hey we have spam + print $sock "e:spam:$len\n"; + } else { + print $sock "e:ham:$len\n"; + } + print $sock "s:$score\n"; + my @tmp_array; + my @tests = @{$message_status->{test_names_hit}}; + + my $buffersize = $self->{main}->{conf}->{collectd_buffersize}; + dbg("collectd: buffersize: $buffersize"); + + while (scalar(@tests) > 0) { + push (@tmp_array, pop(@tests)); + if (length(join(',', @tmp_array) . '\n') > $buffersize) { + push (@tests, pop(@tmp_array)); + if (length(join(',', @tmp_array) . '\n') > $buffersize or scalar(@tmp_array) == 0) { + dbg("collectd: this shouldn't happen. Do you have tests" + ." with names that have more than ~ $buffersize Bytes?"); + return 1; + } else { + dbg ( "collectd: c:" . join(',', @tmp_array) . "\n" ); + print $sock "c:" . join(',', @tmp_array) . "\n"; + #clean the array + @tmp_array = (); + } + } elsif ( scalar(@tests) == 0 ) { + dbg ( "collectd: c:" . join(',', @tmp_array) . '\n' ); + print $sock "c:" . join(',', @tmp_array) . "\n"; + } } + close($sock); + alarm 0; + }; + if ($@) { + my $message = $@; + chomp($message); + info("collectd: $message"); + return -1; } - close($sock); } 1;