summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Sulfrian <alex@spline.inf.fu-berlin.de>2014-05-14 02:35:45 +0200
committerwartung <wartung@vm-mail.spline.inf.fu-berlin.de>2014-05-14 02:35:58 +0200
commitb6660f01127b75ea1acf61a192931165318f4fb1 (patch)
treee687a209463836cc74e306c0f60b0f50265b2428
downloadspamd-stats-b6660f01127b75ea1acf61a192931165318f4fb1.tar.gz
spamd-stats-b6660f01127b75ea1acf61a192931165318f4fb1.tar.bz2
spamd-stats-b6660f01127b75ea1acf61a192931165318f4fb1.zip
Initial commit
-rwxr-xr-xlog.pl29
-rwxr-xr-xserver.pl59
-rwxr-xr-xstats.pl55
3 files changed, 143 insertions, 0 deletions
diff --git a/log.pl b/log.pl
new file mode 100755
index 0000000..468d322
--- /dev/null
+++ b/log.pl
@@ -0,0 +1,29 @@
+#!/usr/bin/perl -w
+
+use strict;
+use AnyEvent;
+use AnyEvent::Socket;
+use AnyEvent::Handle;
+
+my $log_socket = '/tmp/log.sock';
+
+my $cv = AnyEvent->condvar;
+
+tcp_connect 'unix/', $log_socket, sub {
+ my ($fh) = @_ or die "Unable to connect: $!";
+
+ my $h; $h = new AnyEvent::Handle
+ fh => $fh,
+ on_eof => sub { $h->destroy; $cv->send; },
+ on_error => sub { die("Connection closed."); };
+
+ while (<STDIN>) {
+ $h->push_write($_);
+ }
+
+ $h->push_shutdown;
+ $h->destroy;
+ $cv->send;
+};
+
+$cv->recv;
diff --git a/server.pl b/server.pl
new file mode 100755
index 0000000..e56b0b4
--- /dev/null
+++ b/server.pl
@@ -0,0 +1,59 @@
+#!/usr/bin/perl -w
+
+use strict;
+use AnyEvent;
+use AnyEvent::Handle;
+use AnyEvent::Socket;
+use Storable;
+
+my $stats = {
+ ham => 0,
+ spam => 0,
+ block => 0,
+};
+
+my $log_socket = '/tmp/log.sock';
+my $stats_socket = '/tmp/stats.sock';
+
+# regex to match the spamd log lines
+my $regex = '^[A-Z][a-z][a-z] ?\d{1,2} \d{2}:\d{2}:\d{2} vm-mail spamd\[\d+\]: spamd: result: ([Y.]) (-?\d+) ';
+
+tcp_server 'unix/', $log_socket, sub {
+ my $h; $h = new AnyEvent::Handle
+ fh => @_,
+ on_eof => sub { $h->destroy; },
+ on_error => sub { $h->destroy; },
+ on_read => sub {
+ $h->push_read(line => sub {
+ my ($fh, $line) = @_;
+
+ if ($line =~ m/$regex/) {
+ if ($1 eq '.') {
+ $stats->{ham}++;
+ }
+ elsif ($1 eq 'Y') {
+ if ($2 > 10) {
+ $stats->{block}++;
+ }
+ else {
+ $stats->{spam}++;
+ }
+ }
+ }
+ })
+ };
+};
+
+tcp_server 'unix/', $stats_socket, sub {
+ my $h; $h = new AnyEvent::Handle
+ fh => @_,
+ on_eof => sub { $h->destroy; },
+ on_error => sub { $h->destroy; };
+
+ $h->push_write(Storable::freeze($stats) . "\n");
+ $stats = { ham => 0, spam => 0, block => 0 };
+ $h->destroy;
+ undef $h;
+};
+
+AnyEvent->condvar->recv;
diff --git a/stats.pl b/stats.pl
new file mode 100755
index 0000000..5dd65a9
--- /dev/null
+++ b/stats.pl
@@ -0,0 +1,55 @@
+#!/usr/bin/perl -w
+
+use strict;
+use AnyEvent;
+use AnyEvent::Socket;
+use AnyEvent::Handle;
+use Storable;
+use Data::Dumper;
+
+# timeout in seconds
+my $timeout = 10;
+
+# socket
+my $socket = '/tmp/stats.sock';
+
+my $cv = AnyEvent->condvar;
+
+sub my_die {
+ print "UNKNOWN ";
+ print @_;
+ print "\n";
+
+ exit 3;
+}
+
+tcp_connect "unix/", $socket, sub {
+ my ($fh) = @_ or my_die("Unable to connect to socket: $!");;
+ my $h; $h = new AnyEvent::Handle
+ fh => $fh,
+ on_eof => sub {
+ $h->destroy;
+ my_die('Connection closed.');
+ },
+ on_read => sub {
+ $h->push_read(line => sub {
+ my ($h, $line) = @_;
+
+ # read stats data
+ my $stats = Storable::thaw($line);
+
+ print "OK | ham=$stats->{ham};;;0 spam=$stats->{spam};;;0 block=$stats->{block};;;0\n";
+ $cv->send;
+ });
+ };
+};
+
+# general timeout
+my $t; $t = AnyEvent->timer(
+ after => $timeout,
+ cb => sub {
+ my_die("Timeout after $timeout seconds.");
+ undef $t;
+ });
+
+$cv->recv;