File: //usr/share/munin/plugins/vserver_cpu_
#!/bin/bash
# -*- sh -*-
: <<'=cut'
=head1 NAME
vserver_cpu_ - Wildcard plugin to graph CPU usage types per vserver
=head1 CONFIGURATION
[vserver_cpu_*]
env.vservers - List of vservers to include in the graph, or "all"
=head2 DEFAULT CONFIGURATION
[vserver_cpu_*]
env.vservers all
=head1 USAGE
Configuration variables
vservers - specify the vservers to include in the graph (default: all)
NOTE: If no configuration variable is set, the default will be used
see vserver_resources for example uses of configuration files
or links to define what to monitor:
vserver_cpu_ -> monitor cpu usage of all vservers on all cpus
vserver_hold_ -> monitor hold on all vservers on all cpus
vserver_hold_0 -> monitor hold on all vservers on cpu0
vserver_hold_1 -> monitor hold on all vservers on cpu1
vserver_hold_foo -> monitor hold on all cpus on vserver named foo
vserver_sys_foo -> monitor cpu usage on all cpus on vserver named foo
=head1 AUTHOR
Copyright (C) 2006-2008 Holger Levsen and Micah Anderson
=head1 LICENSE
GNU GPLv2
=begin comment
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; version 2 dated June, 1991.
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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA.
=end comment
=head1 TODO
=over 4
=item Less shell subprocesses
The plugin uses lots and lots of shell subprocesses. Maybe factor
common vserver plugin code into Munin::Plugin::Linux::Vserver?
=item Comments
Comment the code or go mad
=item Jiffies per second
Add info how many jiffies per second are available on a machine
=item Split CPU time
User and system cpu are always added to each other, make it optional
to split them?
=item Less use of /proc
use /proc less often (100 times more overhead than talking to the
kernel directly) i.e. use something like pagesize=\`perl -MPOSIX -e
'print POSIX::sysconf(_SC_PAGESIZE), "\n";'\`
(Accoding to many using /proc is a feature not a bug - Nicoali
Langfeldt 2009-12-23)
=back
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf suggest
=cut
if [ "$1" = "autoconf" ]; then
if [ -r /proc/virtual/info ]; then
echo yes
else
echo "no (/proc/virtual/info not found)"
fi
exit 0
fi
if [ "$1" = "suggest" ]; then
if [ ! -r /proc/virtual/info ]; then
exit 1
fi
#
# 'else' clause is after XIDS definition
#
fi
VSERVERS="$vservers"
INFO=(`sed 's/.*:\t//' /proc/virtual/info 2>/dev/null || echo '<none>'`)
KCIN="$[ 16#${INFO[2]} ]";
# If this is 1, then VCI_SPACES is present in the kernel (new in 2.6.19)
if [ $[ (KCIN >> 10) & 1 ] -eq 1 ]
then
NAMELOC="nsproxy"
else
NAMELOC="cvirt"
fi
if [ -z "$VSERVERS" ] ; then
XIDS=`find /proc/virtual/* -type d -exec basename {} \;`
else
# it's really more performant to specify vservers by ids or by linking but not in the configuration-file by name
XIDS=""
for i in $VSERVERS ; do
if [ -d /proc/virtual/$i ] ; then
XIDS="${XIDS}${i} "
else
for j in `find /proc/virtual/* -type d -exec basename {} \;` ; do
if [ "$i" = "`cat /proc/virtual/$j/$NAMELOC |grep NodeName |cut -f2`" ] ; then
XIDS="${XIDS}${j} "
fi
done
fi
done
fi
if [ "$1" = "suggest" ]; then
if [ -r /proc/virtual/info ]; then
for i in $XIDS ; do
LABEL=`cat /proc/virtual/$i/$NAMELOC |grep NodeName |cut -f2`
echo $LABEL
done
exit 0
fi
fi
BASEPARAM=`basename $0 | sed 's/^vserver_//'`
MODE=`echo $BASEPARAM | sed 's/^hold.*//'`
#debug=true
if [ -z "$MODE" ] ; then
MODE=hold
TARGET=`echo $BASEPARAM | sed 's/^hold_//'`
else
MODE=cpu
TARGET=`echo $BASEPARAM | sed 's/^cpu_//'`
fi
CPU1=0
if [ -n "$TARGET" ] ; then
if [ "${#TARGET}" == 1 ] ; then
if [ $debug ] ; then echo $MODE, only on cpu $TARGET, for all vservers ; fi
WHAT=ALLVSERVER
CPU1=$TARGET
else
if [ $debug ] ; then echo $MODE on all cpus together, only for vserver $TARGET ; fi
WHAT=VSERVER
fi
else
if [ $debug ] ; then echo $MODE for all cpus, for all vservers ; fi
WHAT=ALLVSERVER
fi
CPUS=$[ `grep ^processor /proc/cpuinfo|wc -l` -1 ]
CPUS=`seq $CPU1 $CPUS`
if [ $debug ] ; then
echo cpus= $CPUS
echo baseparam= $BASEPARAM
echo mode= $MODE
echo target= $TARGET
echo what= $WHAT
fi
if [ "$1" = "config" ]; then
echo 'graph_category vserver'
echo 'graph_args --base 1000'
if [ "$MODE" == "cpu" ] ; then
echo 'graph_title Vserver cpu usage'
echo 'graph_vlabel jiffies used per cpu per ${graph_period}'
echo 'graph_info Shows jiffies used per cpu on each vserver.'
else
echo 'graph_title Vserver cpu on hold'
echo 'graph_vlabel jiffies on hold per cpu per ${graph_period}'
echo 'graph_info Shows jiffies on hold used per cpu on each vserver.'
fi
for j in $CPUS ; do
A=0
for i in $XIDS ; do
LABEL=`cat /proc/virtual/$i/$NAMELOC |grep NodeName |cut -f2`
if [ "$WHAT" == "ALLVSERVER" ] || [ "$TARGET" == "$LABEL" ] ; then
NAME=`echo $LABEL | cut -d. -f1 | tr '-' '_'`
if [ "$MODE" == "cpu" ] ; then
echo "${NAME}_$j.label cpu usage for cpu $j on $LABEL"
echo "${NAME}_$j.info cpu usage for cpu $j on $LABEL."
else
echo "${NAME}_$j.label on hold for cpu $j on $LABEL"
echo "${NAME}_$j.info on hold for cpu $j on $LABEL."
fi
echo "${NAME}_$j.type COUNTER"
if [ "$A" == 0 ] ; then
echo "${NAME}_$j.draw AREA"
A=1
else
echo "${NAME}_$j.draw STACK"
fi
fi
done
done
exit 0
fi
for j in $CPUS ; do
for i in $XIDS ; do
LABEL=`cat /proc/virtual/$i/$NAMELOC |grep NodeName |cut -f2`
if [ "$WHAT" == "ALLVSERVER" ] || [ "$TARGET" == "$LABEL" ] ; then
NAME=`echo $LABEL | cut -d. -f1 | tr '-' '_'`
echo -n "${NAME}_$j.value "
if [ "$MODE" == "cpu" ] ; then
USERCPU=`cat /proc/virtual/$i/sched |grep "cpu $j"| cut -d' ' -f3`
SYSCPU=`cat /proc/virtual/$i/sched |grep "cpu $j"| cut -d' ' -f4`
echo $[$USERCPU + $SYSCPU]
else
cat /proc/virtual/$i/sched |grep "cpu $j"| cut -d' ' -f5
fi
fi
done
done