#!/usr/bin/perl

#%# family=auto
#%# capabilities=autoconf

use Munin::Plugin;

$pos   = undef;
$connected = 0;
$connectedimap = 0;
$connectedpop3 = 0;
$connections = 0;
$connectionsimap = 0;
$connectionspop3 = 0;
$login = 0;
$pop3login = 0;
$imaplogin = 0;
$tls = 0;
$ssl = 0;
$aborted = 0;

($dirname = $0) =~ s/[^\/]+$//;

$dovelogfile = 0 ;

$logfile = $ENV{'LOGFILE'} || '/var/log/mail.log';

if ( $logfile =~ /dovecot/ ) {
 $dovelogfile = 1 ;
}

# Use an overrided $PATH for all external programs if needed
$DOVEADM = "doveadm";

if ( $ARGV[0] and $ARGV[0] eq "autoconf" ) {

  if (! -x $DOVEADM) {
    print "no (no doveadm)\n";
    exit(0);
  }

  if (! -f $logfile) {
    print "no (logfile $logfile does not exist)\n";
    exit(0);
  }

  if (-r "$logfile") {
    print "yes\n";
    exit 0;
  } else {
    print "no (logfile not readable)\n";
  }
  exit 0;
}

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

if ( $ARGV[0] and $ARGV[0] eq "config" ) {
  print "multigraph dovecot_connections\n";
  print "graph_title Dovecot connections\n";
  print "graph_args --base 1000 -l 0 --no-gridfit --slope-mode\n";
  print "graph_vlabel connections\n";
  print "graph_category mail\n";
  print "connections.label Connections open\n";
  print "connections.type GAUGE\n";
  print "connections.draw LINE1\n";
  print "connections.min 0\n";
  print "connectionsimap.label IMAP\n";
  print "connectionsimap.type GAUGE\n";
  print "connectionsimap.draw AREA\n";
  print "connectionsimap.min 0\n";
  print "connectionspop3.label POP3\n";
  print "connectionspop3.type GAUGE\n";
  print "connectionspop3.draw STACK\n";
  print "connectionspop3.min 0\n";

  print "multigraph dovecot_connected\n";
  print "graph_title Dovecot connected users\n";
  print "graph_args --base 1000 -l 0 --no-gridfit --slope-mode\n";
  print "graph_vlabel connections\n";
  print "graph_category mail\n";
  print "connected.label Connected users\n";
  print "connected.type GAUGE\n";
  print "connected.draw LINE1\n";
  print "connected.min 0\n";
  print "connectedimap.label IMAP\n";
  print "connectedimap.type GAUGE\n";
  print "connectedimap.draw AREA\n";
  print "connectedimap.min 0\n";
  print "connectedpop3.label POP3\n";
  print "connectedpop3.type GAUGE\n";
  print "connectedpop3.draw STACK\n";
  print "connectedpop3.min 0\n";

  print "multigraph dovecot_logins\n";
  print "graph_title Dovecot logins\n";
  print "graph_args --base 1000 -l 0 --no-gridfit --slope-mode\n";
  print "graph_vlabel logins/5 minute\n";
  print "graph_category mail\n";
  print "login.label Logins\n";
  print "login.type GAUGE\n";
  print "login.draw LINE1\n";
  print "login.min 0\n";
  print "imaplogin.label IMAP logins\n";
  print "imaplogin.type GAUGE\n";
  print "imaplogin.draw LINE1\n";
  print "imaplogin.min 0\n";
  print "pop3login.label POP3 logins\n";
  print "pop3login.type GAUGE\n";
  print "pop3login.draw LINE1\n";
  print "pop3login.min 0\n";
  print "tls.label TLS\n";
  print "tls.type GAUGE\n";
  print "tls.draw LINE1\n";
  print "tls.min 0\n";
  print "ssl.label SSL\n";
  print "ssl.type GAUGE\n";
  print "ssl.draw LINE1\n";
  print "ssl.min 0\n";
  print "aborted.label Aborted logins\n";
  print "aborted.type GAUGE\n";
  print "aborted.draw LINE1\n";
  print "aborted.min 0\n";
  exit 0;
}

if (! -f $logfile and ! -f $rotlogfile) {
  print "multigraph dovecot_connections\n";
  print "connections.value U";
  print "connectionsimap.value U";
  print "connectionspop3.value U";
  print "multigraph dovecot_connected\n";
  print "connected.value U\n";
  print "connectedimap.value U\n";
  print "connectedpop3.value U\n";
  print "multigraph dovecot_logins\n";
  print "login.value U\n";
  print "pop3login.value U\n";
  print "imaplogin.value U\n";
  print "tls.value U\n";
  print "ssl.value U\n";
  print "aborted.value U\n";

  exit 0;
}

# dit kan beter maar twee calls zijn toch nodig als we niet zelf aggegreren
#  suggestie: doveadm who -1  | awk '{print $1" "$2" "$4}' | sort | uniq -c
$connectedimap   = `$DOVEADM -f flow who    | grep imap | wc -l`;
$connectedpop3   = `$DOVEADM -f flow who    | grep pop3 | wc -l`;
$connectionsimap = `$DOVEADM -f flow who -1 | grep imap | wc -l`;
$connectionspop3 = `$DOVEADM -f flow who -1 | grep pop3 | wc -l`;

#trim
$connectedimap   =~ s/\s+$//;
$connectedpop3   =~ s/\s+$//;
$connectionsimap =~ s/\s+$//;
$connectionspop3 =~ s/\s+$//;

$connected   = $connectedimap   + $connectedpop3;
$connections = $connectionsimap + $connectionspop3;

my ($pos) = restore_state();

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

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

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

parseDovecotfile ($logfile, $pos, $startsize);
$pos = $startsize;

save_state($pos);

print "multigraph dovecot_connections\n";
print "connections.value $connections\n";
print "connectionsimap.value $connectionsimap\n";
print "connectionspop3.value $connectionspop3\n";
print "multigraph dovecot_connected\n";
print "connected.value $connected\n";
print "connectedimap.value $connectedimap\n";
print "connectedpop3.value $connectedpop3\n";
print "multigraph dovecot_logins\n";
print "login.value $login\n";
print "pop3login.value $pop3login\n";
print "imaplogin.value $imaplogin\n";
print "tls.value $tls\n";
print "ssl.value $ssl\n";
print "aborted.value $aborted\n";


sub parseDovecotfile {
  my ($fname, $start, $stop) = @_;
  open (logf, $fname) or exit 3;
  seek (logf, $start, 0) or exit 2;

  while (tell (logf) < $stop) {
    my $line =<logf>;
    chomp ($line);

    if ( $dovelogfile == 0 and $line !~ m/dovecot/) { next; }
    else {
     if ($line =~ m/Aborted/) {
       $aborted++;

     } elsif ($line =~ m/Login:/) {
       $login++;

       if (     $line =~ m/TLS/) {
         $tls++;
       } elsif ($line =~ m/SSL/) {
         $ssl++;
       }

       if (     $line =~ m/pop3-login:/) {
         $pop3login++;
       } elsif ($line =~ m/imap-login:/) {
         $imaplogin++;
       }
     }
    }
  }
  close(logf);
}

# vim:syntax=perl
