diff --git a/roles/munin_client/files/cpu_by_process b/roles/munin_client/files/cpu_by_process new file mode 100644 index 0000000..b72f236 --- /dev/null +++ b/roles/munin_client/files/cpu_by_process @@ -0,0 +1,111 @@ +#!/usr/bin/perl +# +# Copyright 2012 Chris Wilson +# Copyright 2006 Holger Levsen +# +# This plugin monitors ALL processes on a system. No exceptions. It can +# produce very big graphs! But if you want to know where your CPU time +# is going without knowing what to monitor in advance, this can help; +# or in addition to one of the more specific CPU plugins to monitor +# just Apache or MySQL, for example. +# +# It's not obvious what the graph heights actually mean, even to me. +# Each counter is a DERIVE (difference since the last counter reading) +# of the CPU time usage (in seconds) accounted to each process, summed +# by the process name, so all Apache and all MySQL processes are grouped +# together. Processes with no CPU usage at all are ignored. Processes +# that die may not appear on the graph, and anyway their last chunk of +# CPU usage before they died is lost. You could modify this plugin to +# read SAR/psacct records if you care about that. +# +# 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. + +#scriptname=`basename $0` +#vsname=`echo $scriptname | perl -ne '/^vserver_proc_VM_(.*)/ and print $1'` + +#if [ "$1" = "suggest" ]; then +# ls -1 /etc/vservers +# exit 0 +#elif [ -z "$vsname" ]; then +# echo "Must be used with a vserver name; try '$0 suggest'" >&2 +# exit 2 +#fi + +use strict; +use warnings; + +my $cmd = "ps -eo time,comm h"; +open PS, "$cmd|" or die "Failed to run ps command: $cmd: $!"; + +# my $header_line = ; +my %total_cpu_by_process; + +while () +{ + my @fields = split; + my $cputime = $fields[0]; + my $process = $fields[1]; + + # remove any / and everything after it from the process name, + # e.g. kworker/0:2 -> kworker + $process =~ s|/.*||; + + # remove any . at the end of the name (why does this appear?) + # $process =~ s|\.$||; + + # change any symbol that's not allowed in a munin variable name to _ + $process =~ tr|a-zA-Z0-9|_|c; + + my @times = split /:/, $cputime; + my @days = split /-/, $times[0]; + if ($days[1]) { + $cputime = ((($days[0] * 24) + $days[1]) * 60 + $times[1]) * 60 + $times[2]; + } else { + $cputime = (($times[0] * 60) + $times[1]) * 60 + $times[2]; + } + $total_cpu_by_process{$process} += $cputime; +} + +foreach my $process (keys %total_cpu_by_process) +{ + # remove all processes with 0 cpu time + if (not $total_cpu_by_process{$process}) + { + delete $total_cpu_by_process{$process}; + } +} + +close(PS); + +if (@ARGV and $ARGV[0] eq "config") +{ + print <; + while (<>) + { + @a = split; + $proc = $a[10]; + $label = $proc; + $proc =~ s/ .*//; + if($proc =~ /^\[/) { $proc =~ s|/.*||; } else { $proc =~ s|.*/||; } + $proc =~ s/:.*//; + $proc =~ tr/[]//d; + $proc =~ tr/A-Za-z0-9/_/c; + $vsz = $a[4]; + $total{$proc} += $vsz; + $labels{$proc} = $label; + } + my $stack = 0; + sub draw() { return $stack++ ? "STACK" : "AREA" } + print map + { + "$_.label " . $labels{$_} . "\n" . + "$_.min 0\n" . + "$_.draw " . draw() . "\n" . + "$_.cdef $_,1024,*\n" + } + sort keys %total; + ' + exit 0 +else + ps auxww | perl -e ' + $junk = <>; + while (<>) + { + @a = split; + $proc = $a[10]; + if($proc =~ /^\[/) { $proc =~ s|/.*||; } else { $proc =~ s|.*/||; } + $proc =~ s/:.*//; + $proc =~ tr/[]//d; + $proc =~ tr/A-Za-z0-9/_/c; + $vsz = $a[4]; + $total{$proc} += $vsz; + } + print map {"$_.value $total{$_}\n"} sort keys %total' +fi