From f477021dff5e6b34bb22bd6ae163409cebf356bd Mon Sep 17 00:00:00 2001 From: Tim Small Date: Fri, 10 Dec 2010 16:30:45 +0100 Subject: [PATCH] Initial version --- plugins/other/openvzcpu | 289 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100755 plugins/other/openvzcpu diff --git a/plugins/other/openvzcpu b/plugins/other/openvzcpu new file mode 100755 index 00000000..d9a8ca9b --- /dev/null +++ b/plugins/other/openvzcpu @@ -0,0 +1,289 @@ +#!/usr/bin/perl -w +# -*- perl -*- +# vim: sts=8 sw=8 ts=8 + +# +# Run "perldoc thisfilename" to get a well-formated set of documentation +# for this munin plugin. +# +=head1 NAME + +openvzcpu - Munin plugin to monitor the amount of CPU used by each OpenVZ +container running on this machine. + +=head2 SYNOPSIS + +Draws a stacked graph showing system/user/nice CPU usage for each container +running on a OpenVZ hardware node. Must be run from outside of any container +in order to gain access to the values generated by the OpenVZ kernel code in +C + +=head1 CONFIGURATION + +The following perl libraries are used: + +Graphics::ColorNames +Graphics::ColorObject + +... on Debian based systems (i.e. Ubuntu etc.) you may just: + + aptitude install libcolor-calc-perl libgraphics-colorobject-perl + +Must be run as root in order to read C + +Place the following in a file such as C +B. + + [openvzcpu] + user root + +=head2 OPTIONS + +The following may be added to the file above, in order to enable the graphing +of idle and iowait times: + + env.drawidle 1 + +For kernels which have other than 100 jiffies per second (sic) n.b. this is +unlikely to be necessary - you may add the followin to the plugin-specific +configuration: + + env.HZ 1000 + + +If you have a high number of containers running on the machine, you may be +able to gain extra clarity by asking munin to create a "taller" graph by +adding the following to /etc/munin.conf, or in a file under +C if you are using Munin v1.4 or above: + + openvzcpu.graph_height 700 + +=head1 SEE ALSO + +http://wiki.openvz.org/Vestat + +=head1 TODO + +. Add Munin 1.4 multigraph support + +. Sort graphing order so that the smallest container is rendered at the + bottom of the graph. + +. Make the colour list into a configuration item. + +. Fix graphing of non-container CPU usage. + +=head1 VERSION + + 0.6 Initial Public Release + +=head1 AUTHOR + +Tim Small + +Patches welcome. + +=head1 LICENSE + +GPLv2 + + + +=head1 MAGIC MARKERS + + #%# family=auto + #%# capabilities=autoconf + +=cut + +use strict; +use Carp; +use Graphics::ColorNames 2.10; +use Graphics::ColorObject; + +my $vestat = '/proc/vz/vestat'; +my $stat = '/proc/stat'; + +my @vestatitems = ('user', 'system', 'nice'); + +my @colorlist = ('grey', 'purple', 'red', 'green', 'pink2', 'cyan', 'brown', 'blue', 'orange'); + +############ +# autoconf # +############ + +if ( defined $ARGV[0] && $ARGV[0] eq 'autoconf' ) { + if ( -r '/proc/stat' && -r '/proc/vz/vestat' ) { + print "yes\n"; + } else { + print "no\n"; + } + exit 0; +} + +my $hz = 100; + + +#use Data::Dumper; croak Dumper(\%ENV); + + +$hz = $ENV{'HZ'} if ( defined $ENV{'HZ'} ); + +my $drawidle = 0; + +$drawidle = $ENV{'drawidle'} if ( defined $ENV{'drawidle'} ); + +open VESTAT, "<$vestat" or croak "Failed to open $vestat\n"; + +my %vejif; + +while () { + my ($veid, $user, $nice, $system); + ($veid, $user, $nice, $system) = m,^\W+(\d+)\W+(\d+)\W+(\d+)\W+(\d+)\W+(\d+),; + if (defined $veid) { + $vejif{$veid}->{'user'} = $user; + $vejif{$veid}->{'nice'} = $nice; + $vejif{$veid}->{'system'} = $system; + } +} + +close VESTAT or croak "Failed to close $vestat\n"; + +open STAT, "<$stat" or croak "Failed to open $stat\n"; + +my $line = 0; +my $cores = 0; + +while () { + my ($user, $nice, $system, $idle, $iowait, $irq, $softirq); + ($user, $nice, $system, $idle, $iowait, $irq, $softirq) = m,^cpu\W+(\d+)\W+(\d+)\W+(\d+)\W+(\d+)\W+(\d+)\W+(\d+)\W+(\d+)\W+(\d+),; + if (defined $user) { + $vejif{'global'}->{'user'} = $user; + $vejif{'global'}->{'nice'} = $nice; + $vejif{'global'}->{'system'} = $system; + $vejif{'global'}->{'idle'} = $idle; + $vejif{'global'}->{'iowait'} = $iowait; + $vejif{'global'}->{'irq'} = $irq; + $vejif{'global'}->{'softirq'} = $softirq; + } + # Count number of CPU cores on this system while we are here + $cores++ if m,cpu\d,; +} + +$cores = 1 if $cores == 0; + +foreach my $thing (@vestatitems) { +##FIXME this doesn't appear to work on 2.6.32. OpenVZ bug? +## #Subtract total container usage from overall usage to get non-openvz +## # usage (AKA VEID 0) +## $vejif{'0'}->{$thing} = $vejif{'global'}->{$thing}; +## foreach my $veid (keys %vejif) { +## next if $veid eq 'global'; +## $vejif{'0'}->{$thing} = $vejif{'0'}->{$thing} - $vejif{$veid}->{$thing}; +## } + delete $vejif{'global'}->{$thing}; +} + + +########## +# config # +########## + +if ( defined $ARGV[0] && $ARGV[0] eq 'config' ) { + my $uplimit = $cores; + my $first = 1; + my $veprocessed = 0; +#print 'graph_args --base 1000 -r --lower-limit 0 --units-length 4 --y-grid 0.01:10'; +print 'graph_args --base 1000 -r --lower-limit 0 -Y'; +print " --upper-limit $uplimit" if $drawidle; +print <new_RGBhex( + $cnameobj->hex($color) + ))->as_LCHab() + }; + + foreach my $item ('system', 'user', 'nice') { + my @itemc; + @itemc = @lchab; + $itemc[0] = 1.3 * $itemc[0] if ($item eq 'nice'); + $itemc[0] = 0.7 * $itemc[0] if ($item eq 'system'); + my $itemcolor = Graphics::ColorObject->new_LCHab(\@itemc); + print "v${veid}${item}.label $vename $item\n"; + if($first) { + print "v${veid}${item}.draw AREA\n"; + $first = 0; + } else { + print "v${veid}${item}.draw STACK\n"; + } + print "v${veid}${item}.colour " . $itemcolor->as_RGBhex() . "\n"; + print "v${veid}${item}.min 0\n"; + print "v${veid}${item}.type DERIVE\n"; + print "v${veid}${item}.cdef v${veid}${item},100,/\n"; + } + } + print <{$datapoint} / $hz * 100; + } +}