Code
#!/usr/bin/perl -w # -*- cperl -*- use JSON; =head1 NAME cpu_per_core - plugin to monitor CPU usage for each CPU core =head1 CONFIGURATION =head1 NOTES =head1 AUTHOR Matija Grabnar =head1 LICENSE GPLv2 =head1 MAGIC MARKERS #%# family=system #%# capabilities=autoconf =cut use strict; use Munin::Plugin; my $cache = "/tmp/cpu_per_core.json"; my( $cpu, $user, $nice, $system, $idle, $iowait, $irq, $softirq, $steal, $guest, $guest_nice); my @cpu; sub print_values { my ($json,$str); if (open(CACHE,"<","$cache")) { my $str=<CACHE>; eval { $json = decode_json($str); }; } print "multigraph cpu_per_core\n"; open(INP,"<","/proc/stat") || die "Can not open /proc/stat/: $!\n"; while (<INP>) { next unless /^cpu(\d+)\s+(\d+)(\s+\d+)?(\s+\d+)?(\s+\d+)?(\s+\d+)?(\s+\d+)?(\s+\d+)?(\s+\d+)?(\s+\d+)?(\s+\d+)?\s+/; $cpu = $1; $user = $2; $nice = $3 || 0; $system = $4 || 0; $idle = $5 || 0; $iowait = $6 || 0; $irq = $7 || 0; $softirq = $8 || 0; $steal = $9 || 0; $guest = $10 || 0; $guest_nice = $11 || 0; push(@cpu,{ cpu => $1, user => $2, nice => $3 || 0, system => $4 || 0, idle => $5 || 0, iowait => $6 || 0, irq => $7 || 0, softirq => $8 || 0, steal => $9 || 0, guest => $10 || 0, guest_nice => $11 || 0, }); if (defined($json->[$cpu])) { $user = $cpu[$cpu]->{user} - $json->[$cpu]->{user}; $nice = $cpu[$cpu]->{nice} - $json->[$cpu]->{nice}; $system = $cpu[$cpu]->{system} - $json->[$cpu]->{system}; $idle = $cpu[$cpu]->{idle} - $json->[$cpu]->{idle}; $iowait = $cpu[$cpu]->{iowait} - $json->[$cpu]->{iowait}; $irq = $cpu[$cpu]->{irq} - $json->[$cpu]->{irq}; $softirq = $cpu[$cpu]->{softirq} - $json->[$cpu]->{softirq}; $steal = $cpu[$cpu]->{steal} - $json->[$cpu]->{steal}; $guest = $cpu[$cpu]->{guest} - $json->[$cpu]->{guest}; $guest_nice = $cpu[$cpu]->{guest_nice} - $json->[$cpu]->{guest_nice}; } else { $user = $cpu[$cpu]->{user}; $nice = $cpu[$cpu]->{nice}; $system = $cpu[$cpu]->{system}; $idle = $cpu[$cpu]->{idle}; $iowait = $cpu[$cpu]->{iowait}; $irq = $cpu[$cpu]->{irq}; $softirq = $cpu[$cpu]->{softirq}; $steal = $cpu[$cpu]->{steal}; $guest = $cpu[$cpu]->{guest}; $guest_nice = $cpu[$cpu]->{guest_nice}; } my $usage = int(100-100*($idle/($user+$nice+$system+$idle+$iowait+ $irq+$softirq+$steal+$guest+$guest_nice))); print sprintf "cpu%d_usage.value %d\n",$cpu,$usage; } foreach my $cpu (sort {$a->{cpu}<=>$b->{cpu}} @cpu) { if (defined($json->[$cpu->{cpu}])) { $user = $cpu->{user} - $json->[$cpu->{cpu}]->{user}; $nice = $cpu->{nice} - $json->[$cpu->{cpu}]->{nice}; $system = $cpu->{system} - $json->[$cpu->{cpu}]->{system}; $idle = $cpu->{idle} - $json->[$cpu->{cpu}]->{idle}; $iowait = $cpu->{iowait} - $json->[$cpu->{cpu}]->{iowait}; $irq = $cpu->{irq} - $json->[$cpu->{cpu}]->{irq}; $softirq = $cpu->{softirq} - $json->[$cpu->{cpu}]->{softirq}; $steal = $cpu->{steal} - $json->[$cpu->{cpu}]->{steal}; $guest = $cpu->{guest} - $json->[$cpu->{cpu}]->{guest}; $guest_nice = $cpu->{guest_nice} - $json->[$cpu->{cpu}]->{guest_nice}; } else { $user = $cpu->{user}; $nice = $cpu->{nice}; $system = $cpu->{system}; $idle = $cpu->{idle}; $iowait = $cpu->{iowait}; $irq = $cpu->{irq}; $softirq = $cpu->{softirq}; $steal = $cpu->{steal}; $guest = $cpu->{guest}; $guest_nice = $cpu->{guest_nice}; } my $total = $user + $nice + $system + $idle + $iowait + $irq + $softirq + $steal + $guest + $guest_nice; my $factor = 100/$total; print sprintf "multigraph cpu_per_core.cpu%d\n",$cpu->{cpu}; print sprintf "cpu%d_system.value %3.6f\n",$cpu->{cpu},$system * $factor; print sprintf "cpu%d_user.value %3.6f\n",$cpu->{cpu},$user * $factor; print sprintf "cpu%d_nice.value %3.6f\n",$cpu->{cpu},$nice * $factor; print sprintf "cpu%d_idle.value %3.6f\n",$cpu->{cpu},$idle * $factor; print sprintf "cpu%d_iowait.value %3.6f\n",$cpu->{cpu},$iowait * $factor; print sprintf "cpu%d_irq.value %3.6f\n",$cpu->{cpu},$irq * $factor; print sprintf "cpu%d_softirq.value %3.6f\n",$cpu->{cpu},$softirq * $factor; print sprintf "cpu%d_steal.value %3.6f\n",$cpu->{cpu},$steal * $factor; print sprintf "cpu%d_guest.value %3.6f\n",$cpu->{cpu},$guest * $factor; print sprintf "cpu%d_guest_nice.value %3.6f\n",$cpu->{cpu},$guest_nice * $factor; } $str = encode_json(\@cpu); open(CACHE,">",$cache) || die "Can not write to cache file $cache : $!\n"; print CACHE $str; close(CACHE); } need_multigraph(); $ARGV[0]='' unless defined($ARGV[0]); if ( $ARGV[0] eq "autoconf" ) { if (open(INP,"<","/proc/stat")) { print "yes\n"; exit 0; } else { print "no\n"; exit 0; } } if ( $ARGV[0] eq "config" ) { # The headers print "multigraph cpu_per_core\n"; print "graph_info Monitoring CPU per core\n"; print "graph_title CPU per Core usage\n"; print "graph_vlabel %\n"; print "graph_category system\n"; print "graph_scale no\n"; print "graph_args --upper-limit 100 --lower-limit 0 --rigid\n"; print "graph_vlabel %\n"; open(INP,"<","/proc/stat") || die "Can not open /proc/stat/: $!\n"; while (<INP>) { next unless /^cpu(\d+)\s+(\d+)(\s+\d+)?(\s+\d+)?(\s+\d+)?(\s+\d+)?(\s+\d+)?(\s+\d+)?(\s+\d+)?(\s+\d+)?(\s+\d+)?\s+/; $cpu = $1; $user = $2; $nice = $3 || 0; $system = $4 || 0; $idle = $5 || 0; $iowait = $6 || 0; $irq = $7 || 0; $softirq = $8 || 0; $steal = $9 || 0; $guest = $10 || 0; $guest_nice = $11 || 0; push(@cpu,{ cpu => $1, user => $2, nice => $3 || 0, system => $4 || 0, idle => $5 || 0, iowait => $6 || 0, irq => $7 || 0, softirq => $8 || 0, steal => $9 || 0, guest => $10 || 0, guest_nice => $11 || 0, }); print "cpu${cpu}_usage.label CPU core $cpu - % busy\n"; print "cpu${cpu}_usage.type GAUGE\n"; print "cpu${cpu}_usage.max 100\n"; print "cpu${cpu}_usage.warning 0:85\n"; print "cpu${cpu}_usage.critical 0:90\n"; } foreach my $cpu (sort {$a->{cpu}<=>$b->{cpu}} @cpu) { print sprintf "multigraph cpu_per_core.cpu%d\n",$cpu->{cpu}; print sprintf "graph_info CPU core %d\n",$cpu->{cpu}; print sprintf "graph_title CPU core %d usage\n",$cpu->{cpu}; print "graph_scale no\n"; print "graph_args --upper-limit 100 --lower-limit 0 --rigid\n"; print "graph_vlabel %\n"; print "graph_category mandarina\n"; print sprintf "cpu%d_system.label system\n",$cpu->{cpu}; print sprintf "cpu%d_system.draw AREA\n",$cpu->{cpu}; print sprintf "cpu%d_system.type GAUGE\n",$cpu->{cpu}; print sprintf "cpu%d_system.info CPU time spent in system state\n",$cpu->{cpu}; print sprintf "cpu%d_user.label user\n",$cpu->{cpu}; print sprintf "cpu%d_user.draw STACK\n",$cpu->{cpu}; print sprintf "cpu%d_user.type GAUGE\n",$cpu->{cpu}; print sprintf "cpu%d_user.info CPU time spent in user state\n",$cpu->{cpu}; print sprintf "cpu%d_nice.label nice\n",$cpu->{cpu}; print sprintf "cpu%d_nice.draw STACK\n",$cpu->{cpu}; print sprintf "cpu%d_nice.type GAUGE\n",$cpu->{cpu}; print sprintf "cpu%d_nice.info CPU time spent in nice state\n",$cpu->{cpu}; print sprintf "cpu%d_idle.label idle\n",$cpu->{cpu}; print sprintf "cpu%d_idle.draw STACK\n",$cpu->{cpu}; print sprintf "cpu%d_idle.type GAUGE\n",$cpu->{cpu}; print sprintf "cpu%d_idle.info CPU time spent in idle state\n",$cpu->{cpu}; print sprintf "cpu%d_iowait.label iowait\n",$cpu->{cpu}; print sprintf "cpu%d_iowait.draw STACK\n",$cpu->{cpu}; print sprintf "cpu%d_iowait.type GAUGE\n",$cpu->{cpu}; print sprintf "cpu%d_iowait.info CPU time spent in iowait state\n",$cpu->{cpu}; print sprintf "cpu%d_irq.label irq\n",$cpu->{cpu}; print sprintf "cpu%d_irq.draw STACK\n",$cpu->{cpu}; print sprintf "cpu%d_irq.type GAUGE\n",$cpu->{cpu}; print sprintf "cpu%d_irq.info CPU time spent in irq state\n",$cpu->{cpu}; print sprintf "cpu%d_softirq.label softirq\n",$cpu->{cpu}; print sprintf "cpu%d_softirq.draw STACK\n",$cpu->{cpu}; print sprintf "cpu%d_softirq.type GAUGE\n",$cpu->{cpu}; print sprintf "cpu%d_softirq.info CPU time spent in softirq state\n",$cpu->{cpu}; print sprintf "cpu%d_steal.label steal\n",$cpu->{cpu}; print sprintf "cpu%d_steal.draw STACK\n",$cpu->{cpu}; print sprintf "cpu%d_steal.type GAUGE\n",$cpu->{cpu}; print sprintf "cpu%d_steal.info CPU time spent in steal state\n",$cpu->{cpu}; print sprintf "cpu%d_guest.label guest\n",$cpu->{cpu}; print sprintf "cpu%d_guest.draw STACK\n",$cpu->{cpu}; print sprintf "cpu%d_guest.type GAUGE\n",$cpu->{cpu}; print sprintf "cpu%d_guest.info CPU time spent in guest state\n",$cpu->{cpu}; print sprintf "cpu%d_guest_nice.label guest_nice\n",$cpu->{cpu}; print sprintf "cpu%d_guest_nice.draw STACK\n",$cpu->{cpu}; print sprintf "cpu%d_guest_nice.type GAUGE\n",$cpu->{cpu}; print sprintf "cpu%d_guest_nice.info CPU time spent in guest_nice state\n",$cpu->{cpu}; } exit 0; } print_values();
Problembehebung
Falls beim Testen folgende Fehlermeldung erscheint, fehlt das Paket "libjson-perl:
/etc/munin/plugins # munin-run cpu_per_core Can't locate JSON.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.14.2 /usr/local/share/perl/5.14.2 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.14 /usr/share/perl/5.14 /usr/local/lib/site_perl .) at /etc/munin/plugins/cpu_per_core line 3. BEGIN failed--compilation aborted at /etc/munin/plugins/cpu_per_core line 3.
Das Paket kann mit "apt-get install libjson-perl" installiert werden.