Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
214 lines (167 sloc) 5.43 KB
#!/bin/bash
# -*- sh -*-
: << =cut
=head1 NAME
if_ - Wildcard-plugin to monitor traffic and errors on network
interfaces.
=head1 CONFIGURATION
This plugin does not normally require configuration.
The plugin may need to run as root to determine the maximum speed of
the network interface. This is configured like this:
[if_*]
user root
If the interface speed cannot be determined automatically by this
plugin, you may manually configure the speed using the "speed"
environment variable, in megabits per second, like this:
[if_*]
env.speed 1000
To set warning and critical levels do like this:
[if_*]
env.warning 10000000
or
[if_*]
env.if_0_warning 10000000
This is a wildcard plugin. To monitor an interface, link
if_<interface> to this file. For example,
ln -s /usr/share/munin/plugins/if_ \
/etc/munin/plugins/if_eth0
will monitor eth0.
Most devices found in /proc/net/dev can be monitored. Examples include
ipsec*, eth*, irda*, and lo. Please note that aliases cannot be
monitored with this plugin.
=head1 AUTHOR
Original author unknown
Copyright (C) 2011 Diego Elio Pettenò <flameeyes@flameeyes.eu>
Modified by Steven MARTINS <steven.martins.fr@gmail.com>
=head1 LICENSE
GPLv2
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf suggest
=cut
. $MUNIN_LIBDIR/plugins/plugin.sh
INTERFACE=${0##*if_}
# Who whould have thought it's so much work to determine the
# maximum speed of a network interface. Buckle up!
findspeed_mbps() {
# Do not use interface name to guess technology. Many many
# wifi drivers use "eth*" names.
IWLIST=$(type -p iwlist)
if [[ -x "$IWLIST" ]]; then
SPEED=$($IWLIST $INTERFACE rate 2>&1 |
awk 'BEGIN { RATE="U" }
{ if ($2 == "Mb/s") RATE=$1; }
END { print RATE; }')
if [[ "$SPEED" != "U" ]]; then
echo $SPEED
return
fi
fi
# sysfs can report the speed if the driver supports it (but it
# doesn't work as well for wireless cards, thus why we check for
# iwlist first)
if [[ -r /sys/class/net/$INTERFACE/speed ]]; then
SPEED=$(cat /sys/class/net/$INTERFACE/speed 2>/dev/null)
if [[ -n "$SPEED" ]]; then
echo $SPEED
return
fi
fi
ETHTOOL=$(type -p ethtool)
if [[ -x "$ETHTOOL" ]]; then
SPEED=$($ETHTOOL $INTERFACE 2>&1 |
awk '/Speed:/ { gsub(/[^0-9]*/,"",$2); print $2; }')
if [[ $SPEED == [0-9]* ]]; then
echo $SPEED
return
fi
fi
MIITOOL=$(type -p mii-tool)
if [[ -x $MIITOOL ]]; then
case $($MIITOOL $INTERFACE 2>&1) in
*1000base*) echo 1000; return ;;
*100base*) echo 100; return ;;
*10base*) echo 10; return ;;
esac
fi
echo U
}
findspeed() {
if [[ "$speed" ]]; then
SPEED=$speed
else
SPEED=$(findspeed_mbps)
fi
if [[ -z "$SPEED" ]] || [[ "$SPEED" == "U" ]]; then
printf "sent.info Traffic of the %s interface. Unable to determine interface speed." $INTERFACE
if [[ $EUID -ne 0 ]]; then
echo " Please run the plugin as root."
else
echo " Please install ethtool, wireless-tools, mii-tool or whatever is appropriate for the interface."
fi
return
fi
BPS=$(( $SPEED * 1000 * 1000 ))
cat <<EOF
sent.max $BPS
sent.info Traffic of the $INTERFACE interface. Maximum speed is $SPEED Mb/s.
received.max $BPS
EOF
return
}
case $1 in
autoconf)
if [[ -r /proc/net/dev ]]; then
echo yes
exit 0
else
echo "no (/proc/net/dev not found)"
exit 0
fi
;;
suggest)
if [[ -r /proc/net/dev ]]; then
sed -rne '/^[[:space:]]*(lo|sit[[:digit:]]+):/d;s,^[[:space:]]*([^:]+):.*,\1,p' /proc/net/dev
fi
exit 0
;;
config)
echo "graph_order received sent"
echo "graph_title Traffic on $INTERFACE"
echo 'graph_args --base 1000 --lower-limit 0'
echo 'graph_vlabel Bits per ${graph_period}'
echo 'graph_category network'
echo "graph_info This graph shows the traffic of the $INTERFACE network interface. Please note that the traffic is shown in bits per second, not bytes."
echo 'received.label received'
echo 'received.type DERIVE'
# echo 'received.graph no'
echo 'received.cdef received,8,*'
echo 'received.draw AREA'
echo 'received.min 0'
echo 'sent.label sent'
echo 'sent.type DERIVE'
# echo 'sent.negative received'
echo 'sent.cdef sent,8,*'
echo 'sent.draw LINE1'
echo 'sent.min 0'
print_warning received
print_warning sent
print_critical received
print_critical sent
findspeed
exit 0
;;
esac
# Escape dots in the interface name (eg. vlans) before using it as a regex
if [[ -r /sys/class/net/$INTERFACE/statistics/rx_bytes ]]; then
echo "received.value $(cat /sys/class/net/$INTERFACE/statistics/rx_bytes)"
echo "sent.value $(cat /sys/class/net/$INTERFACE/statistics/tx_bytes)"
else
awk -v interface="$INTERFACE" \
'BEGIN { gsub(/\./, "\\.", interface) } \
$1 ~ "^" interface ":" {
split($0, a, /: */); $0 = a[2]; \
print "received.value " $1 "\nsent.value " $9 \
}' \
/proc/net/dev
fi