1#!@@PERL@@ -w 2# -*- perl -*- 3 4=head1 NAME 5 6snmp__sensors_mbm_volt - Plugin to fetch sensor data from Windows 7boxes running Motherboard Monitor <http://mbm.livewiredev.com/> and 8SNMP-Informant - MBM agent <http://www.snmp-informant.com/>. 9 10=head1 CONFIGURATION 11 12The following environment variables are used by this plugin: 13 14 host - SNMP host 15 port - SNMP port 16 community - SNMP community 17 18=head1 AUTHOR 19 20Copyright (C) 2004 Jimmy Olsen 21 22=head1 LICENSE 23 24This program is free software; you can redistribute it and/or 25modify it under the terms of the GNU General Public License 26as published by the Free Software Foundation; version 2 dated June, 271991. 28 29This program is distributed in the hope that it will be useful, 30but WITHOUT ANY WARRANTY; without even the implied warranty of 31MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 32GNU General Public License for more details. 33 34You should have received a copy of the GNU General Public License 35along with this program; if not, write to the Free Software 36Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 37 38=head1 MAGIC MARKERS 39 40 #%# family=snmpauto 41 #%# capabilities=snmpconf 42 43=cut 44 45use strict; 46use Net::SNMP; 47 48my $MAXLABEL = 20; 49 50my $host = $ENV{host} || undef; 51my $port = $ENV{port} || 161; 52my $community = $ENV{community} || "public"; 53my $iface = $ENV{interface} || undef; 54 55my $response; 56 57if (defined $ARGV[0] and $ARGV[0] eq "snmpconf") 58{ 59 print "require 1.3.6.1.4.1.9600.1.10.6.1.1.\n"; 60 print "require 1.3.6.1.4.1.9600.1.10.6.1.3. 2\n"; # Type=voltage 61 print "require 1.3.6.1.4.1.9600.1.10.6.1.7. [1-9]\n"; # Low value != 0 62 print "require 1.3.6.1.4.1.9600.1.10.6.1.9. [1-9]\n"; # High value != 0 63 64 exit 0; 65} 66 67if ($0 =~ /^(?:|.*\/)snmp_([^_]+)_sensors_mbm_volt$/) 68{ 69 $host = $1; 70 if ($host =~ /^([^:]+):(\d+)$/) 71 { 72 $host = $1; 73 $port = $2; 74 } 75} 76elsif (!defined($host)) 77{ 78 print "# Debug: $0 -- $1\n" if $Munin::Plugin::SNMP::DEBUG; 79 die "# Error: couldn't understand what I'm supposed to monitor."; 80} 81 82# The OIDs we're after 83my $mbmDeviceType = "1.3.6.1.4.1.9600.1.10.6.1.3."; # Should be 2 (volt) 84my $mbmHighWatermark = "1.3.6.1.4.1.9600.1.10.6.1.7."; # Should be non-zero 85my $mbmLowWatermark = "1.3.6.1.4.1.9600.1.10.6.1.9."; # Should be non-zero 86my $mbmName = "1.3.6.1.4.1.9600.1.10.6.1.2."; # Name of sensor 87my $mbmValue = "1.3.6.1.4.1.9600.1.10.6.1.6."; # Data point 88 89my ($session, $error) = Net::SNMP->session( 90 -hostname => $host, 91 -community => $community, 92 -port => $port 93 ); 94 95if (!defined ($session)) 96{ 97 die "Croaking: $error"; 98} 99 100# First we want to find the harddisks... 101my $correct_type = get_by_regex ($session, $mbmDeviceType, "^2\$"); 102my $correct_high = get_by_regex ($session, $mbmHighWatermark, "[1-9]"); 103my $correct_low = get_by_regex ($session, $mbmLowWatermark, "[1-9]"); 104 105my @keep = (); 106 107foreach my $id (keys %$correct_type) 108{ 109 if (exists $correct_high->{$id} and 110 exists $correct_low->{$id}) 111 { 112 push (@keep, $id); 113 } 114} 115 116my %sensors; 117 118foreach my $kept (@keep) # For each temp sensor... 119{ 120 $sensors{$kept}{name} = get_single ($session, $mbmName . "$kept"); 121} 122 123if (defined $ARGV[0] and $ARGV[0] eq "config") 124{ 125 print "host_name $host\n" unless $host eq 'localhost'; 126 print "graph_title Voltages\n"; 127 print "graph_vlabel Volt\n"; 128 print "graph_category sensors\n"; 129 print "graph_info This graph shows voltages in the system.\n"; 130 131 foreach my $sensor (sort(keys %sensors)) 132 { 133 print (&get_name_by_sensor ($sensors{$sensor}{name}), ".label "); 134 print (length($sensors{$sensor}{name})<=$MAXLABEL ? $sensors{$sensor}{name} : "...".substr($sensors{$sensor}{name},-($MAXLABEL-3))); 135 print ("\n"); 136 print (&get_name_by_sensor ($sensors{$sensor}{name}), ".info Voltage readout from the motherboard sensor \"$sensors{$sensor}{name}\".\n"); 137 } 138 exit 0; 139} 140 141foreach my $sensor (keys %sensors) 142{ 143 my $val = get_single ($session, $mbmValue . $sensor); 144 print (&get_name_by_sensor ($sensors{$sensor}{name}), ".value $val\n"); 145} 146 147sub get_single 148{ 149 my $handle = shift; 150 my $oid = shift; 151 152 print "# Getting single \"$oid\"..." if $Munin::Plugin::SNMP::DEBUG; 153 154 $response = $handle->get_request ($oid); 155 156 if (!defined $response->{$oid}) 157 { 158 print "undef\n" if $Munin::Plugin::SNMP::DEBUG; 159 return undef; 160 } 161 else 162 { 163 print "\"$response->{$oid}\"\n" if $Munin::Plugin::SNMP::DEBUG; 164 return $response->{$oid}; 165 } 166} 167 168sub get_by_regex 169{ 170 my $handle = shift; 171 my $oid = shift; 172 my $regex = shift; 173 my $result = {}; 174 my $num = 0; 175 my $ret = $oid . "0"; 176 my $response; 177 178 print "# Starting browse of $oid...\n" if $Munin::Plugin::SNMP::DEBUG; 179 180 while (1) 181 { 182 if ($num == 0) 183 { 184 print "# Checking for $ret...\n" if $Munin::Plugin::SNMP::DEBUG; 185 $response = $handle->get_request ($ret); 186 } 187 if ($num or !defined $response) 188 { 189 print "# Checking for sibling of $ret...\n" if $Munin::Plugin::SNMP::DEBUG; 190 $response = $handle->get_next_request ($ret); 191 } 192 if (!$response) 193 { 194 return undef; 195 } 196 my @keys = keys %$response; 197 $ret = $keys[0]; 198 print "# Analyzing $ret (compared to $oid)...\n" if $Munin::Plugin::SNMP::DEBUG; 199 last unless ($ret =~ /^$oid/); 200 $num++; 201 next unless ($response->{$ret} =~ /$regex/); 202 @keys = split (/\./, $ret); 203 $result->{$keys[-1]} = $response->{$ret};; 204 print "# Index $num: ", $keys[-1], " (", $response->{$ret}, ")\n" if $Munin::Plugin::SNMP::DEBUG; 205 }; 206 return $result; 207} 208 209sub get_name_by_sensor 210{ 211 my $mp = shift; 212 $mp =~ s/[^a-z0-9_]/_/gi; 213 $mp =~ tr/A-Z/a-z/; 214 return "p" . $mp; 215} 216