From b408390ae9311b7d703ce57c25a78dce23c31b16 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Wed, 10 Jun 2015 15:35:13 +0200 Subject: Configure munin nodes & master. Interhost communications are protected by stunnel4. The graphs are only visible on the master itself, and content is generated by Fast CGI. --- .../etc/logcheck/ignore.d.server/common-local | 2 + .../usr/local/share/munin/plugins/dovecot_logins | 119 ++++++++++++++++++ .../usr/local/share/munin/plugins/dovecot_stats_ | 135 +++++++++++++++++++++ .../usr/local/share/munin/plugins/dovecot_who | 43 +++++++ .../local/share/munin/plugins/postfix_mailqueue_ | 57 +++++++++ .../local/share/munin/plugins/postfix_mailvolume2 | 62 ++++++++++ .../usr/local/share/munin/plugins/postfix_sasl_ | 63 ++++++++++ .../usr/local/share/munin/plugins/postfix_stats_ | 113 +++++++++++++++++ 8 files changed, 594 insertions(+) create mode 100755 roles/common/files/usr/local/share/munin/plugins/dovecot_logins create mode 100755 roles/common/files/usr/local/share/munin/plugins/dovecot_stats_ create mode 100755 roles/common/files/usr/local/share/munin/plugins/dovecot_who create mode 100755 roles/common/files/usr/local/share/munin/plugins/postfix_mailqueue_ create mode 100755 roles/common/files/usr/local/share/munin/plugins/postfix_mailvolume2 create mode 100755 roles/common/files/usr/local/share/munin/plugins/postfix_sasl_ create mode 100755 roles/common/files/usr/local/share/munin/plugins/postfix_stats_ (limited to 'roles/common/files') diff --git a/roles/common/files/etc/logcheck/ignore.d.server/common-local b/roles/common/files/etc/logcheck/ignore.d.server/common-local index 887688a..67e9335 100644 --- a/roles/common/files/etc/logcheck/ignore.d.server/common-local +++ b/roles/common/files/etc/logcheck/ignore.d.server/common-local @@ -31,3 +31,5 @@ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ansible-([_a-z]+|): Invoked with ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (sympa\((command|distribute)\)|wwsympa|archived|bounced|bulk|task_manager)\[[[:digit:]]+\]: (info|notice)\s ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[[:digit:]]+\]: err .* main::check_action_parameters\(\) user not logged in$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rrdcached\[[[:digit:]]+\]: (flushing old values|rotating journals|started new journal /\S+$|removing old journal /\S+$) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rrdcached\[[[:digit:]]+\]: queue_thread_main: rrd_update_r \(([^)]+)\) failed with status -1. \(opening '\1': No such file or directory\) diff --git a/roles/common/files/usr/local/share/munin/plugins/dovecot_logins b/roles/common/files/usr/local/share/munin/plugins/dovecot_logins new file mode 100755 index 0000000..09b79d9 --- /dev/null +++ b/roles/common/files/usr/local/share/munin/plugins/dovecot_logins @@ -0,0 +1,119 @@ +#!/bin/sh + +# Munin plugin for monitoring Dovecot logins and IMAP throughput. +# Copyright © 2015 Guilhem Moulin +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +PATH=/usr/bin:/bin:/usr/sbin:/sbin + +LOGFILE="/var/log/${logfile:-mail.log}" +STATEFILE="$MUNIN_PLUGSTATE/${0##*/}.offset" + +. $MUNIN_LIBDIR/plugins/plugin.sh +is_multigraph + +case "${1:-}" in + config) cat <<- EOF + multigraph dovecot_login_status + graph_title Dovecot login status + graph_vlabel logins per \${graph_period} + graph_args --base 1000 -l 0 + graph_scale no + graph_period minute + graph_category dovecot + successful.label auth successful + successful.type DERIVE + successful.draw AREA + successful.min 0 + failed.label auth failed + failed.type DERIVE + failed.draw STACK + failed.min 0 + noauth.label no auth attempt + noauth.type DERIVE + noauth.draw STACK + noauth.min 0 + + multigraph dovecot_login_types + graph_title Dovecot login types + graph_vlabel logins per \${graph_period} + graph_args --base 1000 -l 0 + graph_scale no + graph_period minute + graph_category dovecot + imap.label IMAP + imap.type DERIVE + imap.draw AREA + imap.min 0 + pop3.label POP3 + pop3.type DERIVE + pop3.draw STACK + pop3.min 0 + managesieve.label managesieve + managesieve.type DERIVE + managesieve.draw STACK + managesieve.min 0 + + multigraph dovecot_imap_throughput + graph_title Dovecot IMAP throughput + graph_vlabel bytes per \${graph_period} + graph_args --base 1024 -l 0 + graph_scale yes + graph_period minute + graph_category dovecot + read.label read + read.type DERIVE + read.min 0 + written.label written + written.type DERIVE + written.min 0 + EOF + exit 0 + ;; +esac + +if [ ! -f "$LOGFILE" ]; then + for field in successful failed noauth imap pop3 managesieve read written; do + echo $field.value U + done + exit 0; +fi + +tmpfile="$(mktemp --tmpdir)" +trap 'rm -f "$tmpfile"' EXIT + +logtail -f"$LOGFILE" -o"$STATEFILE" | sed -nr "s#^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: ##p" >"$tmpfile" + +sum() { + awk 'BEGIN{x=0} {x+=$0} END{print x}' +} + +prefix="^(pop3|imap|managesieve)-login" +echo multigraph dovecot_login_status +echo successful.value $(grep -Ec "$prefix: Login: user=<[^>]+>,\s" "$tmpfile") +echo failed.value $(sed -nr "s#$prefix: Aborted login \(auth failed, ([[:digit:]]+) attempts in [[:digit:]]+ secs\): user=<[^>]*>, .*#\2#p" "$tmpfile" | sum) +echo noauth.value $(grep -Ec "$prefix: Aborted login \(no auth attempts in [[:digit:]]+ secs\): user=<>,\s" "$tmpfile") + + +echo multigraph dovecot_login_types +for type in imap pop3 managesieve; do + echo $type.value $(grep -Ec "^$type-login:\s" "$tmpfile") +done + + +regexp="^imap\([-_.@[:alnum:]]+\): .* in=([[:digit:]]+) out=([[:digit:]]+)$" +echo multigraph dovecot_imap_throughput +echo read.value $(sed -nr "s#$regexp#\1#p" "$tmpfile" | sum) +echo written.value $(sed -nr "s#$regexp#\2#p" "$tmpfile" | sum) diff --git a/roles/common/files/usr/local/share/munin/plugins/dovecot_stats_ b/roles/common/files/usr/local/share/munin/plugins/dovecot_stats_ new file mode 100755 index 0000000..7f0f51a --- /dev/null +++ b/roles/common/files/usr/local/share/munin/plugins/dovecot_stats_ @@ -0,0 +1,135 @@ +#!/bin/bash +: <<=cut + +=head1 NAME + +dovecot_stats_ - Munin plugin to display statistics for the dovecot mail server + +=head1 CONFIGURATION + +This plugin must be run with permissions to run "doveadm". That usually means root, but to test, run the following as any user: + + doveadm who + +If you get a permission denied message, check the permissions on the socket mentioned in the error line. + +=head1 MAGIC MARKERS + + #%# family=contrib + #%# capability=autoconf suggest + +=head1 AUTHOR + +Paul Saunders + +=cut + +. $MUNIN_LIBDIR/plugins/plugin.sh +is_multigraph + +if [[ "$1" == "autoconf" ]]; then + if [[ -x /usr/bin/doveadm ]]; then + echo yes + else + echo no + fi + exit 0 +fi + +if [[ "$1" == "suggest" ]]; then + doveadm stats dump domain|awk 'NR!=1 {print $1}' + exit 0 +fi + +domain=$(basename $0) +domain=${domain#dovecot_stats_} + +if [[ -z $domain ]]; then + exit 1 +fi + +if [[ "$1" == "config" ]]; then + cat < +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +PATH=/usr/bin:/bin:/usr/sbin:/sbin +set -u + +case "${1:-}" in + config) cat <<- EOF + graph_title Dovecot concurrent IMAP usage + graph_args --base 1000 -l 0 + graph_scale no + graph_category dovecot + connections.label connections + connections.min 0 + users.label unique users + users.min 0 + EOF + exit 0 + ;; +esac + +tmpfile="$(mktemp --tmpdir)" +trap 'rm -f "$tmpfile"' EXIT + +doveadm -f flow who -1 | sed -nr 's/^username=(\S+)\s+proto=imap\s.*/\1/p' >"$tmpfile" + +echo connections.value $(wc -l <"$tmpfile") +echo users.value $(sort -u "$tmpfile" | wc -l) diff --git a/roles/common/files/usr/local/share/munin/plugins/postfix_mailqueue_ b/roles/common/files/usr/local/share/munin/plugins/postfix_mailqueue_ new file mode 100755 index 0000000..31b6269 --- /dev/null +++ b/roles/common/files/usr/local/share/munin/plugins/postfix_mailqueue_ @@ -0,0 +1,57 @@ +#!/bin/sh + +# Munin plugin for monitoring the Postfix mail queue in multi-instance +# systems. Symlink/rename to 'postfix_mailqueue_$SPOOLDIR'. +# Copyright © 2015 Guilhem Moulin +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +PATH=/usr/bin:/bin:/usr/sbin:/sbin + +name="${0##*/}" +[ "${name#postfix_mailqueue_}" != "$name" ] && postfix="${name#postfix_mailqueue_}" || postfix= +SPOOLDIR="/var/spool/${postfix:-postfix}" + +. $MUNIN_LIBDIR/plugins/plugin.sh + +case "${1:-}" in + config) cat <<- EOF + graph_title Postfix mailqueue ($([ -n "$postfix" -a "$postfix" != postfix ] && echo "'${postfix#postfix-}'" || echo default) instance) + graph_vlabel Mails in queue + graph_args --base 1000 -l 0 + graph_scale no + graph_category postfix + graph_total Total + active.label active + deferred.label deferred + maildrop.label maildrop + incoming.label incoming + corrupt.label corrupt + hold.label held + EOF + for field in active deferred maildrop incoming corrupt hold; do + print_warning "$field" + print_critical "$field" + done + exit 0 + ;; +esac + +for field in active deferred maildrop incoming corrupt hold; do + if [ -d "$SPOOLDIR/$field" ]; then + echo $field.value $(find "$SPOOLDIR/$field" -type f | wc -l) + else + echo $field.value U + fi +done diff --git a/roles/common/files/usr/local/share/munin/plugins/postfix_mailvolume2 b/roles/common/files/usr/local/share/munin/plugins/postfix_mailvolume2 new file mode 100755 index 0000000..d16d88e --- /dev/null +++ b/roles/common/files/usr/local/share/munin/plugins/postfix_mailvolume2 @@ -0,0 +1,62 @@ +#!/bin/sh + +# Munin plugin for monitoring Postfix per-instance mail throughput. +# Copyright © 2015 Guilhem Moulin +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +PATH=/usr/bin:/bin:/usr/sbin:/sbin +set -u + +LOGFILE="/var/log/${logfile:-mail.log}" +STATEFILE="$MUNIN_PLUGSTATE/${0##*/}.offset" + +case "${1:-}" in + config) cat <<- EOF + graph_title Postfix per-instance bytes throughput + graph_vlabel bytes per \${graph_period} + graph_args --base 1024 -l 0 + graph_scale yes + graph_period minute + graph_category postfix + EOF + if [ $(echo "${postmulti:-postfix}" | wc -w) -gt 1 ]; then + echo graph_total total throughput + fi + for postfix in ${postmulti:-postfix}; do + echo "${postfix}_volume.label" "$postfix throughput" + echo "${postfix}_volume.type" DERIVE + echo "${postfix}_volume.min" 0 + done + exit 0 + ;; +esac + +if [ ! -f "$LOGFILE" ]; then + for postfix in ${postmulti:-postfix}; do + echo "${postfix}_volume.value U" + done + exit 0; +fi + +tmpfile="$(mktemp --tmpdir)" +trap 'rm -f "$tmpfile"' EXIT + +logtail -f"$LOGFILE" -o"$STATEFILE" >"$tmpfile" + +for postfix in ${postmulti:-postfix}; do + echo -n "${postfix}_volume.value " + sed -nr "s#^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ $postfix/qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: from=<[^>]*>, size=([[:digit:]]+), nrcpt=[[:digit:]]+ \(queue active\)\$#\1#p" "$tmpfile" \ + | awk 'BEGIN{x=0} {x+=$0} END{print x}' +done diff --git a/roles/common/files/usr/local/share/munin/plugins/postfix_sasl_ b/roles/common/files/usr/local/share/munin/plugins/postfix_sasl_ new file mode 100755 index 0000000..8dc1219 --- /dev/null +++ b/roles/common/files/usr/local/share/munin/plugins/postfix_sasl_ @@ -0,0 +1,63 @@ +#!/bin/sh + +# Munin plugin for monitoring Postfix SASL logins. Symlink/rename to +# 'postfix_sasl_$SYSLOGNAME'. +# Copyright © 2015 Guilhem Moulin +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +PATH=/usr/bin:/bin:/usr/sbin:/sbin +set -u + +LOGFILE="/var/log/${logfile:-mail.log}" +STATEFILE="$MUNIN_PLUGSTATE/${0##*/}.offset" + +name="${0##*/}" +[ "${name#postfix_sasl_}" != "$name" ] && postfix="${name#postfix_sasl_}" || postfix= + +case "${1:-}" in + config) cat <<- EOF + graph_title Postfix SASL ($([ -n "$postfix" -a "$postfix" != postfix ] && echo "'${postfix#postfix-}'" || echo default) instance) + graph_vlabel logins per \${graph_period} + graph_args --base 1000 -l 0 + graph_scale no + graph_period minute + graph_category postfix + successful.label successful + successful.type DERIVE + successful.draw AREA + successful.min 0 + failed.label failed + failed.type DERIVE + failed.draw STACK + failed.min 0 + EOF + exit 0 + ;; +esac + +if [ ! -f "$LOGFILE" ]; then + for postfix in ${postmulti:-postfix}; do + echo "${postfix}_volume.value U" + done + exit 0; +fi + +tmpfile="$(mktemp --tmpdir)" +trap 'rm -f "$tmpfile"' EXIT + +logtail -f"$LOGFILE" -o"$STATEFILE" | sed -nr "s#^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ $postfix/smtpd\[[[:digit:]]+\]: ##p" >"$tmpfile" + +echo successful.value $(grep -Ec "^warning: [-._[:alnum:]]+\[[.[:digit:]]+\]: SASL \S+ authentication failed(:.*)?$" "$tmpfile") +echo failed.value $(grep -Ec "^[[:xdigit:]]{10}: client=\S+, sasl_method=\S+, sasl_username=" "$tmpfile") diff --git a/roles/common/files/usr/local/share/munin/plugins/postfix_stats_ b/roles/common/files/usr/local/share/munin/plugins/postfix_stats_ new file mode 100755 index 0000000..5678870 --- /dev/null +++ b/roles/common/files/usr/local/share/munin/plugins/postfix_stats_ @@ -0,0 +1,113 @@ +#!/bin/sh + +# Munin plugin for monitoring Postfix per-service and per-instance +# usage. Symlink/rename to 'postfix_sasl_$SERVICE_$SYSLOGNAME'. +# Copyright © 2015 Guilhem Moulin +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +PATH=/usr/bin:/bin:/usr/sbin:/sbin +set -u + +LOGFILE="/var/log/${logfile:-mail.log}" +STATEFILE="$MUNIN_PLUGSTATE/${0##*/}.offset" + +name="${0##*/}" +name="${name#postfix_stats_}" + +if [ "${name#postscreen_}" != "$name" ]; then + postfix="${name#postscreen_}" + service=postscreen + fields='connected accepted passed' +elif [ "${name#smtpd_}" != "$name" ]; then + postfix="${name#smtpd_}" + service=smtpd + fields='connected accepted queued' +elif [ "${name#qmgr_}" != "$name" ]; then + postfix="${name#qmgr_}" + service=qmgr + fields='queued' +elif [ "${name#smtp_}" != "$name" ]; then + postfix="${name#smtp_}" + service=smtp + fields='sent deliverable deferred undeliverable bounced' +elif [ "${name#lmtp_}" != "$name" ]; then + postfix="${name#lmtp_}" + service=lmtp + fields='sent deliverable deferred undeliverable bounced' +elif [ "${name#pipe_}" != "$name" ]; then + postfix="${name#pipe_}" + service=pipe + fields='sent deliverable deferred undeliverable bounced' +fi + +case "${1:-}" in + config) cat <<- EOF + graph_title Postfix $service message throughput ($([ -n "$postfix" -a "$postfix" != postfix ] && echo "'${postfix#postfix-}'" || echo default) instance) + graph_vlabel mails per \${graph_period} + graph_args --base 1000 -l 0 + graph_scale no + graph_period minute + graph_category postfix + EOF + for field in $fields; do + echo "$field.label $field" + echo "$field.type DERIVE" + echo "$field.draw AREA" + echo "$field.min 0" + done + exit 0 + ;; +esac + +if [ ! -f "$LOGFILE" ]; then + for field in $fields; do + echo "$field.value U" + done + exit 0; +fi + +tmpfile="$(mktemp --tmpdir)" +trap 'rm -f "$tmpfile"' EXIT + +logtail -f"$LOGFILE" -o"$STATEFILE" | sed -nr "s#^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ $postfix/$service\[[[:digit:]]+\]: ##p" >"$tmpfile" + +case "$service" in + postscreen) + connected=$(grep -Ec "^CONNECT from\s" "$tmpfile") + rejected=$( grep -Ec "^NOQUEUE: reject:\s" "$tmpfile") + passed=$( grep -Ec "^(PASS (OLD|NEW)|WHITELISTED)\s" "$tmpfile") + echo connected.value $connected + echo accepted.value $(($rejected + $passed)) + echo passed.value $passed + ;; + smtpd) + connected=$(grep -Ec "^connect from\s" "$tmpfile") + rejected=$( grep -Ec "^NOQUEUE: reject:\s" "$tmpfile") + queued=$( grep -Ec "^[[:xdigit:]]+: client=" "$tmpfile") + echo connected.value $connected + echo accepted.value $(($rejected + $queued)) + echo queued.value $queued + ;; + qmgr) + queued=$(grep -Ec "^[[:xdigit:]]+: from=<\S+>, .*\(queue active\)$" "$tmpfile") + echo queued.value $queued + ;; + smtp|lmtp|pipe) + for field in $fields; do + v=$(grep -Ec "^[[:xdigit:]]+:( [^ =]+=\S+,)+ status=$field(\s.*)?$" "$tmpfile") + echo $field.value $v + done + ;; +esac -- cgit v1.2.3