munin-contrib/plugins/powermta/pmta_

252 lines
8.7 KiB
Bash
Executable File

#!/bin/bash
#######################################################################################################################
#
# = PowerMTA Munin multi-monitor =
#
# -- developer: aaron.zauner@emarsys.com
# -- start date: 11.11.2011
#
#
# = LICENSE =
#
# Copyright (c) 2011, emarsys eMarketing Systems AG
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are permitted provided that
# the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this list of conditions and the
# following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials provided with the
# distribution. Neither the name of the emarsys eMarketing Systems AG nor the names of its contributors may
# be used to endorse or promote products derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#
#######################################################################################################################
#
# -> "xpath" cli tool required (ships with your linux distribution)
# -> install:
#
# o check config (/etc/munin/plugin-conf.d) set "env.REMOTEHOST" and "env.PORT", e.g.:
# [pmta*]
# env.REMOTEHOST 127.0.0.1
# env.PORT 8080
#
# o chmod +x pmta_
#
# o link:
# lrwxrwxrwx 1 root root 5 2011-11-14 14:52 pmta_traffic_in -> pmta_
# lrwxrwxrwx 1 root root 5 2011-11-14 14:52 pmta_traffic_out -> pmta_
# lrwxrwxrwx 1 root root 5 2011-11-14 14:52 pmta_conn_in -> pmta_
# lrwxrwxrwx 1 root root 5 2011-11-14 14:52 pmta_conn_out -> pmta_
# lrwxrwxrwx 1 root root 5 2011-11-14 14:52 pmta_queue_domains -> pmta_
# lrwxrwxrwx 1 root root 5 2011-11-14 14:52 pmta_queue_recipients -> pmta_
# lrwxrwxrwx 1 root root 5 2011-11-14 14:52 pmta_queue_megabytes -> pmta_
# lrwxrwxrwx 1 root root 5 2011-11-15 16:31 pmta_top_domains -> pmta_
#
# o alternative multi-host configuration:
# you can also link the pmta_ script to various hosts and configure munin to respond
# to multiple REMOTEHOSTs, just link pmta_ in this schema and configure munin
# accordingly - DO NOT USE DOTS IN YOUR IDENTIFIER VARIABLE, USE UNDERSCORE INSTEAD!
# for example:
# lrwxrwxrwx 1 root root 5 2011-11-18 12:18 mailhost1_domain_com_pmta_top_domains -> pmta_
# lrwxrwxrwx 1 root root 5 2011-11-18 12:18 mailhost2_domain_com_pmta_top_domains -> pmta_
# lrwxrwxrwx 1 root root 5 2011-11-18 12:18 mailhost3_domain_com_pmta_top_domains -> pmta_
# lrwxrwxrwx 1 root root 5 2011-11-18 12:18 mailhost4_domain_com_pmta_top_domains -> pmta_
# [...]
#
# conf.:
# [mailhost1_domain_com_pmta*]
# env.REMOTEHOST somehostORip
# env.PORT portnumber
# [mailhost2_domain_com_pmta*]
# env.REMOTEHOST someotherhostORip
# env.PORT portnumber
# [...]
#
# o restart munin.
#
###################################################################################################################
# debug (munin-run --pidebug --debug <script>):
if [ "$MUNIN_DEBUG" = "1" ]; then
set -vx
fi
NAME_SELF=`basename ${0}`
trap 'echo "\n$NAME_SELF - >> interrupt. \n$NAME_SELF - >> exiting."' 1 2 9 11 15
if [ -z "${REMOTEHOST}" ] || [ -z "${PORT}" ]; then
echo "\n$NAME_SELF - >> no environment variable set for host and/or port. \n$NAME_SELF - >> exiting."
exit 1
fi
fetch_xml() {
# o arg1 specifies xpath or false
# o arg2 specifies sed/regex or false
# o arg3 specifies category ('status', 'domains',..) or false
HTTPQUERY="GET /${3}?format=xml HTTP/1.1\n\n"
REMOTE=`echo ${HTTPQUERY} | nc -q 1 -w 5 ${REMOTEHOST} ${PORT} | tail -1`
XML_DATA=${REMOTE}
SED="s/.*<$2>\([^<]*\)<\/$2>.*/\1/p"
if [ "$3" = "status" ]; then
RET=`echo $XML_DATA | xpath -q -e $1 | sed -n $SED | cut -f1 -d '.'`
elif [ "$3" = "domains" ]; then
RET=`echo $XML_DATA | xpath -q -e '//domain/*[self::name or self::rcp]' | sed 's/<[^>]*>//g' | sed 's/\./_/g'`
fi
if [ "$RET" ]; then
echo $RET
return 0
else
echo 'no_result'
return 1
fi
}
case $NAME_SELF in
*pmta_traffic_in | *pmta_traffic_out)
if [ `expr match "$NAME_SELF" ".*pmta_traffic_in"` != 0 ]; then
WHAT="in"
elif [ `expr match "$NAME_SELF" ".*pmta_traffic_out"` != 0 ]; then
WHAT="out"
fi
CONF_TITLE="powermta ${WHAT}bound traffic"
CONF_LABEL="traffic_${WHAT}"
CONF_SELF="traffic_${WHAT}bound"
if [ -z $1 ]; then
GET=`fetch_xml //traffic//lastMin/${WHAT} kb status`
RETURN=`echo $GET / 1024 | bc`
RCPT=`fetch_xml //traffic//lastMin/${WHAT} rcp status`
MSGS=`fetch_xml //traffic//lastMin/${WHAT} msg status`
echo "megabytes.value $RETURN"
echo "recipients.value $RCPT"
echo "messages.value $MSGS"
exit 0
elif [ $1 = config ]; then
echo "megabytes.label megabytes"
echo "megabytes.draw AREA"
echo "megabytes.colour 0000A0"
echo "recipients.label recipients"
echo "recipients.draw STACK"
echo "recipients.colour FF0000"
echo "messages.label messages"
echo "messages.draw STACK"
echo "messages.colour FF6F00"
AUTOLABEL="no"
fi
;;
*pmta_conn_in | *pmta_conn_out)
if [ `expr match "$NAME_SELF" ".*pmta_conn_in"` != 0 ]; then
WHAT="In"
elif [ `expr match "$NAME_SELF" ".*pmta_conn_out"` != 0 ]; then
WHAT="Out"
fi
CONF_TITLE=`echo "powermta ${WHAT}bound connections" | tr [:upper:] [:lower:]`
CONF_LABEL=`echo "conn_${WHAT}" | tr [:upper:] [:lower:]`
CONF_SELF=`echo "connections_${WHAT}bound" | tr [:upper:] [:lower:]`
if [ -z $1 ]; then
GET=`fetch_xml //conn//smtp${WHAT} cur status`
echo "${CONF_SELF}.value $GET"
exit 0
elif [ $1 = config ]; then
echo "${CONF_SELF}.label ${WHAT}bound connections"
echo "${CONF_SELF}.draw LINE1"
echo "${CONF_SELF}.colour FF0000"
AUTOLABEL="no"
fi
;;
*pmta_queue_domains | *pmta_queue_recipients | *pmta_queue_megabytes)
if [ `expr match "$NAME_SELF" ".*pmta_queue_domains"` != 0 ]; then
WHAT="domains"
elif [ `expr match "$NAME_SELF" ".*pmta_queue_recipients"` != 0 ]; then
WHAT="recipients"
elif [ `expr match "$NAME_SELF" ".*pmta_queue_megabytes"` != 0 ]; then
WHAT="megabytes"
UNIT_KB="true"
fi
CONF_TITLE="powermta ${WHAT} in queue"
CONF_LABEL="queue_${WHAT}"
CONF_SELF="${WHAT}"
if [ -z $1 ]; then
if [ !$UNIT_KB ]; then
GET=`fetch_xml //queue/smtp dom status`
echo "${CONF_SELF}.value $GET"
exit 0
else
GET=`fetch_xml //queue/smtp kb status`
RETURN=`echo $GET / 1024 | bc`
echo "${CONF_SELF}.value $RETURN"
exit 0
fi
fi
;;
*pmta_top_domains)
CONF_TITLE="powermta top 10 domains by recipients"
CONF_LABEL="top_domains"
CONF_SELF="domains"
AUTOLABEL="no"
GET=`fetch_xml false false domains`
if [ -z $1 ]; then
for values in $GET; do
if [ $values -ge 0 2>/dev/null ]; then
echo $values
else
echo -n "$values.value#"
fi
done | tr ' ' '\n' | tr '#' ' ' # restore newline - replace hashtag with whitespace
exit 0
elif [ $1 = config ]; then
for values in $GET; do
[ $values -ge 0 2>/dev/null ] || echo "$values.label $values\n$values.draw LINE2"
done
fi
;;
esac
case $1 in
suggest)
if [ $NAME_SELF = "pmta_" ]; then
# suggest plugins to munin:
echo "traffic_in\ntraffic_out\nconn_in\nconn_out\nqueue_domains\nqueue_recipients\nqueue_megabytes\ntop_domains"
exit 0
fi
;;
config)
if [ -n "$CONF_TITLE" ] && [ -n "$CONF_LABEL" ]; then
echo "graph_category mail"
echo "graph_title $CONF_TITLE on ${REMOTEHOST}"
echo "graph_vlabel $CONF_LABEL"
echo "graph_scale yes"
echo "graph_width 1400"
echo "graph_height 450"
echo "graph_args --step 10 --rigid --base 1000 -l 0"
if [ "$AUTOLABEL" != "no" ]; then
echo "${CONF_SELF}.label $CONF_LABEL"
echo "${CONF_SELF}.draw AREA"
echo "${CONF_SELF}.colour FF6F00"
fi
fi
exit 0
;;
autoconf)
# tell munin this script supports autoconfiguration:
echo "yes"
;;
*)
exit 1
;;
esac
#EOF