contrib-munin/plugins/mail/imap_bandwidth

221 lines
5.2 KiB
Bash
Executable File

#!/bin/sh
#
# Revision 1.1 2012/02/26 03:43:27
# Improved labels
#
# Revision 1.0 2012/02/25 21:31:16
# Initial release
#
: <<=cut
=head1 NAME
imap_bandwidth - Munin plugin to measure the current bandwidth of one or more remote IMAP servers.
=head1 APPLICABLE SYSTEMS
Any Linux system with the package "isync" (or "mbsync") installed.
=head1 CONFIGURATION
This configuration section shows a usable example for two imap servers:
[imap_bandwidth]
env.imap_servers internal=imap-internal.example.org external=imap.example.org
env.cert_file /etc/munin-imap-cert.pem
env.username foo_user
env.password secret
env.transfer_volume_kbyte 100
env.use_ssl yes
Both "use_ssl" and "transfer_volume_kbyte" are optional and default to the above
values.
All other parameters are required.
Generate the certificate file by running "mbsync-get-cert imap.example.org".
"imap_servers" is a space-separated list of key=value combinations. "key" is
used as a label in munin graphs. "value" is the full hostname or IP of the IMAP
server. All IMAP servers need to share the same authentication database (i.e.
accept the same username/password).
Reduce the "transfer_volume_kbyte" parameter if you need to minimize traffic.
Maybe you need to specify the "timeout" setting for this plugin if it takes
longer than munin's default timeout.
=head1 INTERPRETATION
The plugin simply shows the average bandwidth during one IMAP upload and one
IMAP download of a file containing random bytes.
You need to be aware that this measurement obviously increases the load on
your IMAP servers for the duration of the measurement.
You also need to be aware of the safety implications imposed by storing
sensitive information (username and password combinations) on your monitoring
server in plaintext.
=head1 VERSION
Version 1.0
=head1 BUGS
None known
Set the environment variable DEBUG=1 if you need to investigate problems.
=head1 AUTHOR
Lars Kruse <devel@sumpfralle.de>
=head1 LICENSE
GPLv3 or higher
=cut
set -eu
#%# family=auto
#%# capabilities=autoconf
TRANSFER_SIZE=${transfer_volume_kbyte:-100}
USE_SSL=${use_ssl:-yes}
IMAP_USERNAME=${username}
IMAP_PASSWORD=${password}
CERT_FILE=${cert_file}
# example value:
# internal=imap-internal.example.org external=imap.example.org
SERVERS="$imap_servers"
if test -n "${DEBUG:-}"; then
TRANSFER_SIZE=20
set -x
fi
. $MUNIN_LIBDIR/plugins/plugin.sh
if [ "$1" = "autoconf" ]; then
if ( which mbsync >/dev/null 2>&1 ); then
echo yes
exit 0
else
echo "no (could not run \"mbsync\")"
exit 0
fi
fi
if [ "$1" = "config" ]; then
echo 'graph_title IMAP bandwidth'
echo 'graph_vlabel to (+) / from (-) server [bit/s]'
echo 'graph_category network'
for item in $SERVERS; do
key="$(echo "$item" | cut -f 1 -d =)"
clean_name="$(clean_fieldname "$key")"
echo "download_${clean_name}.graph no"
echo "download_${clean_name}.label download"
echo "upload_${clean_name}.label $key"
echo "upload_${clean_name}.negative download_${clean_name}"
done
exit 0
fi
create_dummy_file() {
dd if=/dev/urandom "of=$DUMMY_FILENAME" bs=1K count=${TRANSFER_SIZE} 2>/dev/null
}
is_dummy_file_missing() {
test ! -e "$DUMMY_FILENAME"
}
remove_mail_files() {
get_mail_files | while read fname; do rm "$fname"; done
}
get_mail_files() {
find "$MAILDIR" -type f | grep -v "/\."
}
# run the synchronization
run_sync() {
if test -n "${DEBUG:-}"; then
echo yes | mbsync --config "$SYNCRC" sync || true
else
echo yes | mbsync --config "$SYNCRC" sync >/dev/null 2>/dev/null || true
fi
}
# run the synchronization and determine the duration of this operation
speed_sync() {
start=$(date +%s%N)
run_sync
end=$(date +%s%N)
# did we wrap a minute?
test "$end" -lt "$start" && end=$((end + 60 * 1000000000))
delay=$((end - start))
# use "bit" multiplier
echo "$((8 * TRANSFER_SIZE * 1024 * 1000000000 / delay))"
}
for item in $SERVERS; do
key="$(echo "$item" | cut -f 1 -d =)"
host="$(echo "$item" | cut -f 2- -d =)"
clean_name="$(clean_fieldname "$key")"
MAILDIR="$(mktemp -d)"
# this file needs to include a dot at the beginning - otherwise it gets cleaned up ...
SYNCRC="$MAILDIR/.mbsyncrc"
SYNC_STATE_FILE_PREFIX="$MAILDIR/.syncstate-"
cat - >"$SYNCRC" <<- EOF
SyncState $SYNC_STATE_FILE_PREFIX
Expunge Both
MaildirStore local
Path $MAILDIR
Inbox $MAILDIR
IMAPStore remote
Host $host
UseIMAPS $USE_SSL
User $IMAP_USERNAME
Pass $IMAP_PASSWORD
CertificateFile $CERT_FILE
Channel sync
Master :local:
Slave :remote:
EOF
mkdir "$MAILDIR/new" "$MAILDIR/tmp" "$MAILDIR/cur"
DUMMY_FILENAME="$MAILDIR/new/$(date +%N)"
# download all existing files
run_sync
# remove all local files -> to be purged remotely later
remove_mail_files
# create dummy file for upload
create_dummy_file "$MAILDIR"
output="upload_${clean_name}.value $(speed_sync)"
is_dummy_file_missing && echo "$output" || echo >&2 "upload failed"
# remove local file
remove_mail_files "$MAILDIR"
# persuade mbsync that we have never seen the dummy file ...
rm "$SYNC_STATE_FILE_PREFIX"*
output="download_${clean_name}.value $(speed_sync)"
get_mail_files | grep -q . && echo "$output" || echo >&2 "download failed"
# remove the new file from the imap server
remove_mail_files
run_sync
# clean up
rm -r "$MAILDIR"
done