From 6f0a884e19748475339ac26071278569235c1935 Mon Sep 17 00:00:00 2001 From: Mrten Date: Tue, 4 Jun 2013 00:28:33 +0300 Subject: [PATCH 1/3] Create dovecot, plugin to monitor dovecot connections Based very heavily on exim_mailrejects --- plugins/dovecot/dovecot | 253 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 plugins/dovecot/dovecot diff --git a/plugins/dovecot/dovecot b/plugins/dovecot/dovecot new file mode 100644 index 00000000..4236279b --- /dev/null +++ b/plugins/dovecot/dovecot @@ -0,0 +1,253 @@ +#!/usr/bin/perl + +#%# family=auto +#%# capabilities=autoconf + + +$statefile = "/var/lib/munin-node/plugin-state/root/plugin-dovecot.state"; +$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/[^\/]+$//; + +$logfile = $ENV{'LOGFILE'} || '/var/log/mail.log'; +$DOVEADM = "/usr/bin/doveadm"; + + +if ( $ARGV[0] and $ARGV[0] eq "autoconf" ) { + + if (! -x $DOVEADM) { + print "no (no doveadm)\n"; + exit(1); + } + + if (! -f $logfile) { + print "no (logfile $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"; +} 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 dovecot\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 dovecot\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 dovecot\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; + +if (-f "$statefile") { + if (!open (IN, "$statefile")) { + print "Cannot open statefile $statefile for reading: $!\n"; + exit 4; + } + my $in = ; + if ($in =~ /^(\d+)$/) { + ($pos) = ($1); + } + close IN; +} + +$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; + +if (-l $statefile) { + die("$statefile is a symbolic link, refusing to touch it."); +} + +if (!open (OUT, ">$statefile")) { + print "Cannot open statefile $statefile for writing: $!\n"; + exit 4; +} +print OUT "$pos\n"; +close OUT; + +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 =; + chomp ($line); + + if ($line !~ m/dovecot/) { next; } + + 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 From cdfe518d363b9555c9adbb09841bfd54867fb7c6 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Fri, 19 Jul 2013 10:59:36 +0200 Subject: [PATCH 2/3] use Munin::Plugin for statefiles --- plugins/dovecot/dovecot | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/plugins/dovecot/dovecot b/plugins/dovecot/dovecot index 4236279b..3452a071 100644 --- a/plugins/dovecot/dovecot +++ b/plugins/dovecot/dovecot @@ -3,8 +3,8 @@ #%# family=auto #%# capabilities=autoconf +use Munin::Plugin; -$statefile = "/var/lib/munin-node/plugin-state/root/plugin-dovecot.state"; $pos = undef; $connected = 0; $connectedimap = 0; @@ -24,7 +24,6 @@ $aborted = 0; $logfile = $ENV{'LOGFILE'} || '/var/log/mail.log'; $DOVEADM = "/usr/bin/doveadm"; - if ( $ARGV[0] and $ARGV[0] eq "autoconf" ) { if (! -x $DOVEADM) { @@ -161,17 +160,7 @@ $connectionspop3 =~ s/\s+$//; $connected = $connectedimap + $connectedpop3; $connections = $connectionsimap + $connectionspop3; -if (-f "$statefile") { - if (!open (IN, "$statefile")) { - print "Cannot open statefile $statefile for reading: $!\n"; - exit 4; - } - my $in = ; - if ($in =~ /^(\d+)$/) { - ($pos) = ($1); - } - close IN; -} +my ($pos) = restore_state(); $startsize = (stat $logfile)[7]; @@ -189,16 +178,7 @@ if ($startsize < $pos) { parseDovecotfile ($logfile, $pos, $startsize); $pos = $startsize; -if (-l $statefile) { - die("$statefile is a symbolic link, refusing to touch it."); -} - -if (!open (OUT, ">$statefile")) { - print "Cannot open statefile $statefile for writing: $!\n"; - exit 4; -} -print OUT "$pos\n"; -close OUT; +save_state($pos); print "multigraph dovecot_connections\n"; print "connections.value $connections\n"; From 03135541dc74a8a5eda9f7b82caf2790af906710 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Fri, 19 Jul 2013 11:02:09 +0200 Subject: [PATCH 3/3] always use plain $PATH --- plugins/dovecot/dovecot | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/dovecot/dovecot b/plugins/dovecot/dovecot index 3452a071..b23b73e1 100644 --- a/plugins/dovecot/dovecot +++ b/plugins/dovecot/dovecot @@ -22,7 +22,9 @@ $aborted = 0; ($dirname = $0) =~ s/[^\/]+$//; $logfile = $ENV{'LOGFILE'} || '/var/log/mail.log'; -$DOVEADM = "/usr/bin/doveadm"; + +# Use an overrided $PATH for all external programs if needed +$DOVEADM = "doveadm"; if ( $ARGV[0] and $ARGV[0] eq "autoconf" ) {