#!/usr/bin/perl -w
use strict;

#
# Plugin to monitor the number of mails processed by sympa
# Heavily based on exim_mailstats
#
# Usage: copy or link into /etc/munin/node.d/
#
# Parameters:
#
# 	config   (required)
# 	autoconf (optional - used by munin-config)
#
# Config variables:
#
# 	logfile       - Where to find the syslog-information
#
# Magic markers (optional - used by munin-config and some installation
# scripts):
#
#%# family=auto
#%# capabilities=autoconf


my $statefile = "/var/lib/munin/plugin-state/plugin-sympa_stats.state";

my $pos   = undef;
my $badFiles = 0;
my $oldFiles = 0;
my $senderNotAllowed = 0;
my $keyToEditors = 0;
my $msgAccepted = 0;
my $msgArchived = 0;
$pos = 0; 
my $logfile = $ENV{'logfile'} || '/opt/sympa/log/syslog';
my $rotlogfile = '';


if ( $ARGV[0] and $ARGV[0] eq "autoconf" )
{
   if(! -e $logfile) {
	    print "no (logfile does not exist)\n";
	    exit(1);
	}
    if (-r $logfile) {
	    print "yes\n";
	    exit 0;
	}
	else
	{
	    print "no (logfile not readable)\n";
	}

    exit 1;
}



if (-f "$logfile.0")
{
    $rotlogfile = $logfile . ".0";
}
elsif (-f "$logfile.1")
{
    $rotlogfile = $logfile . ".1";
}
elsif (-f "$logfile.01")
{
    $rotlogfile = $logfile . ".01";
}


if ( $ARGV[0] and $ARGV[0] eq "config" )
{
    print "graph_title some sympa-stats\n";
    print "graph_args --base 1000 -l 0\n";
    print "graph_vlabel messages/\${graph_period}\n";
    print "graph_scale  no\n";
    print "graph_category sympa\n";
    
    print "badFiles.label bad Files\n";
    print "badFiles.type DERIVE\n";
    print "badFiles.min 0\n";
    
    print "oldFiles.label old Files\n";
    print "oldFiles.type DERIVE\n";
    print "oldFiles.min 0\n";
    
    print "senderNotAllowed.label rejected\n";
    print "senderNotAllowed.type DERIVE\n";
    print "senderNotAllowed.min 0\n";
    
    print "keyToEditors.label keyToEditors\n";
    print "keyToEditors.type DERIVE\n";
    print "keyToEditors.min 0\n";
    
    print "msgAccepted.label msgAccepted\n";
    print "msgAccepted.type DERIVE\n";
    print "msgAccepted.min 0\n";
    
    print "msgArchived.label msgArchived\n";
    print "msgArchived.type DERIVE\n";
    print "msgArchived.min 0\n";

    
    exit 0;
}

if (! -f $logfile and ! -f $rotlogfile)
{
    print "badFiles.value U\n";
    print "oldFiles.value U\n";
    print "senderNotAllowed.value U\n";
    print "keyToEditors.value U\n";
    print "msgAccepted.value U\n";
    print "msgArchived.value U\n";
    exit 0;
}

if (-f "$statefile")
{
    open (IN, "$statefile") or exit 4;
	my $in = <IN>;
    if ($in =~ /^(\d+):(\d+):(\d+):(\d+):(\d+):(\d+):(\d+)/)
    {
	($pos, $badFiles, $oldFiles, $senderNotAllowed, $keyToEditors, $msgAccepted, $msgArchived) = ($1, $2, $3, $4, $5, $6, $7);
    }
    close IN;
}

my $startsize = (stat $logfile)[7];

if (!defined $pos)
{
    # Initial run.
    $pos = $startsize;
}

if ($startsize < $pos)
{
    # Log rotated
    parseLogfile ($rotlogfile, $pos, (stat $rotlogfile)[7]);
    $pos = 0;

}

parseLogfile ($logfile, $pos, $startsize);
$pos = $startsize;
print "badFiles.value $badFiles\n";
print "oldFiles.value $oldFiles\n";
print "senderNotAllowed.value $senderNotAllowed\n";
print "keyToEditors.value $keyToEditors\n";
print "msgAccepted.value $msgAccepted\n"; 
print "msgArchived.value $msgArchived\n";



if(-l $statefile) {
	die("$statefile is a symbolic link, refusing to touch it.");
}				
open (OUT, ">$statefile") or exit 4;
print OUT "$pos:$badFiles:$oldFiles:$senderNotAllowed:$keyToEditors:$msgAccepted:$msgArchived\n";
close OUT;

sub parseLogfile 
{    
    my ($fname, $start, $stop) = @_;
    open (LOGFILE, $fname) or exit 3;
    seek (LOGFILE, $start, 0) or exit 2;
    while (tell (LOGFILE) < $stop) 
    {
	my $line =<LOGFILE>;

	chomp ($line);

	if ($line=~/Moving bad file \S+ to bad/) 
	{
	    $badFiles++;
	} 
	elsif ($line=~/Deleting old file /)
	{
	    $oldFiles++;
	}
        elsif ($line=~/rejected\(\) because sender not allowed/)
        {
            $senderNotAllowed++;
        }
	elsif ($line=~/Key \S+ for list \S+ from \S+ sent to editors, /)
        {
            $keyToEditors++;
        }
	elsif ($line=~/Message for \S+ from \S+ accepted /)
        {
            $msgAccepted++;
        }
	elsif ($line=~/Archiving \S+ for list/) 
	{
	    $msgArchived++;
        }

	
    }
    close(LOGFILE);    
}

# vim:syntax=perl
