#!@@PERL@@ -w # -*- cperl -*- use strict; use Munin::Plugin; my @dircomponents = split('/',$0); my $me = pop(@dircomponents); my @suggest=qw(temp clock volt); =head1 NAME nvidia_ - Munin wildcard plugin to monitor nvidia graphics cards with the help of the nvclock command. Run as nvidia_temp, nvidia_clock or nvidia_volt =cut =head1 APPLICABLE SYSTEMS Any system with a nvclock command. Currently this is available on Linux, FreeBSD and Windows. =head1 CONFIGURATION Usually none is needed. This shows the default configuration: [nvidia_*] env.nvclock = /usr/bin/nvclock =cut my $nvclock = $ENV{nvclock} || '/usr/bin/nvclock'; =head1 INTERPRETATION The plugin invoked under the different aliases listed above will run the nvclock command and show the different measurements as found in the output of the program. =head1 VERSION Tested with nvclock version 0.8b3a on a nVidia Geforce 8600GT. =head1 BUGS None known =head1 FEATURES Requires Munin::Plugin as supplied in Munin 1.3.3 and 1.2.5. If the plugin complains about "Use of uninitialized value in string eq at /usr/lib/perl/5.8/lib.pm line 29." and so on please make this plugin configuration: [*] env.MUNIN_LIBDIR /usr/share/munin using the correct LIBDIR for your installation of course (the other standard value is /opt/munin/lib). =head1 AUTHOR Copyright (C) 2008-2009 Nicolai Langfeldt / Linpro AS, Oslo =head1 LICENSE GPLv2 =head1 MAGIC MARKERS #%# family=auto #%# capabilities=autoconf suggest =cut delete $ENV{'DISPLAY'}; sub collect_and_print ($$) { my ($todo,$function)=@_; my $cardinfo; my $config = $todo eq 'config'; my $NVC; open($NVC,"$nvclock -i |") or die "Could not run $nvclock: $!\n"; my @nvclock; @nvclock = <$NVC>; close($NVC) or die "Could not close command $nvclock: $!\n"; my $section; foreach (@nvclock) { if (/^-- (.*) --/) { $section=$1; # Remove the "info" or "informaiton" part $section =~ s/\s+info.*//; next; } my ($key,$value); ( $key,$value ) = split(':\s+',$_,2); next if ! defined($value); chomp $value; # Preprocessing special cases ($key eq 'Clock' ) && do { $key = "$section $key"; }; ($key eq 'Card' ) && do { $cardinfo = $value; }; ($key eq 'Version') && do { $cardinfo .= " Version $value"; }; ($key =~ /^Signon/) && do { $cardinfo .= " $value"; }; ($key eq 'Amount' ) && ($section eq 'Memory') && do { $cardinfo .= ", with $value"; }; ($key =~ 'Type' ) && ($section eq 'Memory') && do { $cardinfo .= " $value memory"; }; # Yes, the apperance of the $cardinfo related things will be # fairly order sensitive, tell me if it breaks. my $label = clean_fieldname($key); # Processing each case of the plugin ($key =~ /voltage/i) && ($function eq 'volt') && do { if ($config) { print "$label.label $key\n"; print "$label.type GAUGE\n"; } else { my ($volt) = $value =~ m/\s*(\d+\.\d+)V/; $volt = 'U' unless defined $volt; print "$label.value $volt\n"; } next; }; ($key =~ /clock/i) && ($function eq 'clock') && do { if ($config) { print "$label.label $key\n"; print "$label.type GAUGE\n"; } else { my ($hz,$scale) = $value =~ m/\s*(\d+\.\d+)\s*([Mk]?)Hz/; if (defined($hz)) { $scale = '' unless defined($scale); $hz=$hz*1000*1000 if $scale eq 'M'; $hz=$hz*1000 if $scale eq 'k'; } else { $hz='U'; } print "$label.value $hz\n"; } next; }; ($key =~ /temp/i) && ($function eq 'temp') && do { if ($config) { print "$label.label $key\n"; print "$label.type GAUGE\n"; } else { my ($temp) = $value =~ m/\s*(\d+(\.\d+)?)C/; $temp='U' unless defined($temp); print "$label.value $temp\n"; } next; } } if ($config) { if ($function eq 'volt') { print "graph_title Voltages of NVidia graphics card\n"; print "graph_vlabel Voltage\n"; } elsif ($function eq 'clock') { print "graph_title Clock speeds of NVidia graphics card\n"; print "graph_vlabel Hz\n"; } elsif ($function eq 'temp') { print "graph_title Temperatures of NVidia graphics card\n"; print "graph_vlabel Degrees Celcius\n"; } else { die "$me: Unknown function!\n"; } print "graph_category sensors\n"; print "graph_info Graphics card is a $cardinfo\n"; } } # Main my ($function) = ( $me =~ m/.*_(.*)/ ); if (defined($ARGV[0])) { if ($ARGV[0] eq 'autoconf') { if (-x $nvclock) { print "yes\n"; exit 0; } else { print "no (no nvclock executable at $nvclock, please configure)\n"; exit 0; } } elsif ($ARGV[0] eq 'suggest') { print join("\n",@suggest),"\n"; exit 0; } elsif ($ARGV[0] eq 'config') { collect_and_print('config',$function); exit 0; } elsif ($ARGV[0] eq '') { collect_and_print('fetch',$function); exit 0; } else { die "$me: Unknown argument: $ARGV[0]\n"; } } else { collect_and_print('fetch',$function); exit 0; } die "$me: Running over the edge of the plugin. Why?"