Category: | Networking Code |
Author/Contact Info | djw |
Description: | SNMP query tool for reporting interface utilization stats. Does a get_request for sysUpTime, ifInOctets, and ifOutOctets and does a utilization calculation based on the difference of two samples and interface speed. Right now its setup to run every 5 minutes for an 8am-5pm workday. You can see a sample of the graph plotted by GD::Graph here: http://perldev.org/projects/snmp/ Thanks, djw UPDATE: If you plan on using this, you will have to check your ethernet device's MIB OID. ifInOctets and ifOutOctets are the first two items in the @oids list, the last one is system uptime which you shouldn't have to change. |
#!/usr/bin/perl -w use strict; use Net::SNMP qw(ticks_to_time); use GD::Graph::lines; use GD::Graph::colour; use constant HOUR_IN_SECS => 3600; my ($session, $error, $response, $run, $time, $upTime); my (@utilizationRec, @utilizationOut, @runTimes); my ($octetOutUtil, $octetInUtil, @timeSamples); # Change these to match your needs # -------------------------------------------- my $host = "IP_ADDRESS"; # The host we want to monitor my $hostname = "SERVERNAME"; # its fancy netbios name my $community = "public"; # The community name to read from my $ifSpeed = "IFSPEED"; # The speed of your interface my $numRuns = 108; # +$pauseTime+$sleepTime dictates runt +ime length my $pauseTime = 290; # 5 minutes - total right now is set t +o one day my $sleepTime = 10; # from 8am to 5pm my $htmlFile = "utilization.shtml"; my $runTime = localtime; my $runLength = ($pauseTime + $sleepTime) * $numRuns / HOUR_IN_SECS; my $value = 0; my $recMax = 0; my $outMax = 0; my $outTotal = 0; my $recTotal = 0; my $recAvg = 0; my $outAvg = 0; # These are our specific SNMP OID's for # querying in and out octets and uptime # -------------------------------------------- my @oids = ('1.3.6.1.2.1.2.2.1.10.16777219', '1.3.6.1.2.1.2.2.1.16.167 +77219', '1.3.6.1.2.1.1.3.0'); # This runs our SNMP get request so that I can # populate our data for the graphs - calls the # snmpRun() sub. # -------------------------------------------- print "Begin data collection for $host - Runs: $numRuns\n"; for ($run = 1; $run <= $numRuns; $run++) { print "Starting run $run\\$numRuns - "; snmpRun(); unless ($run == $numRuns) { sleep("$pauseTime"); } } # Now that our data is nicely entered into # our arrays, we can plot our graphs out # ------------------------------------------- createUtilGraph(); getAvgs(); upTime(); writeHTML(); sub snmpRun { # get the time use Time::localtime; my $tm = localtime; my ($hour, $min) = ($tm->hour, $tm->min); if ($min =~ /^\d$/) { $min = "0$min"; $time = "$hour:$min"; } else { $time = "$hour:$min"; } # Run number 1 # -------------------------------------- ($session, $error) = Net::SNMP->session( -hostname => $host, -community => $community, -port => 161, -version => "2c", -translate => [ -timeticks => 0x0 ], ); $session or die "Session error: $error\n"; $response = $session->get_request(@oids); $response or die "Response error:" . "$session->error()" . "\n"; $session->hostname(); my $bytesIn = $response->{'1.3.6.1.2.1.2.2.1.10.16777219'}; my $bytesOut = $response->{'1.3.6.1.2.1.2.2.1.16.16777219'}; my $sysUpTime = $response->{'1.3.6.1.2.1.1.3.0'}; $session->close(); # Sleep till we go for the next run # -------------------------------------- sleep("$sleepTime"); # Run number 2 # -------------------------------------- ($session, $error) = Net::SNMP->session( -hostname => $host, -community => $community, -port => 161, -version => "2c", -translate => [ -timeticks => 0x0 ], ); $session or die "Session error: $error\n"; $response = $session->get_request(@oids); $response or die "Response error:" . "$session->error()" . "\n"; $session->hostname(); my $bytesIn2 = $response->{'1.3.6.1.2.1.2.2.1.10.16777219'}; my $bytesOut2 = $response->{'1.3.6.1.2.1.2.2.1.16.16777219'}; my $sysUpTime2 = $response->{'1.3.6.1.2.1.1.3.0'}; $session->close(); # Data is collected, now do our calculation # Delta(octetType) * 8 # --- => octetType Utilization # Delta(sysUpTime)*10000 # ----------------------------------------- my $bytesInDiff = $bytesIn2 - $bytesIn; my $bytesOutDiff = $bytesOut2 - $bytesOut; my $sysUpTimeDiff = $sysUpTime2 - $sysUpTime; if ($bytesInDiff == 0) { $octetInUtil = "0.00"; } else { my $octetInTemp = ($bytesInDiff * 8) / ($sysUpTimeDiff * $if +Speed); $octetInTemp =~ /(\d+)\.(\d\d)/; $octetInUtil = "$1.$2"; } if ($bytesOutDiff == 0) { my $octetOutUtil = "0.00"; } else { my $octetOutTemp = ($bytesOutDiff * 8) / ($sysUpTimeDiff * $if +Speed); $octetOutTemp =~ /(\d+)\.(\d\d)/; $octetOutUtil = "$1.$2"; } print "In: $octetInUtil Out: $octetOutUtil Time: $time\n"; push( @utilizationRec, $octetInUtil ); # Push the data into + our push( @utilizationOut, $octetOutUtil); # arrays for use in +our graphs push( @timeSamples, $time); # Push the time from the ru +n } sub createUtilGraph { my @outData = ( [ (@timeSamples) ], [ (@utilizationOut) ] ); my @recData = ( [ (@timeSamples) ], [ (@utilizationRec) ] ); my $graph = GD::Graph::lines->new(650,200); $graph->set( r_margin => '4', title => 'Ethernet Utilization', x_label => 'Time (5 minute intervals with a 10 secon +d sample pause)', y_label => 'Utilization %', x_label_skip => '12', tick_length => '-4', y_max_value => '100', y_min_value => '0', transparent => '1', interlaced => '1', valuesclr => 'black', bgclr => 'white', fgclr => 'black', accentclr => 'black', shadowclr => 'dgreen', labelclr => 'black', axislabelclr => 'black', textclr => 'black', dclrs => [ qw(green) ], ); my $gd = $graph->plot( \@outData ); $graph->set( dclrs => [ qw(red) ] ); $gd = $graph->plot( \@recData ); open(IMG, "+>UtilData.png") || die "Can't create object: ($!)\n"; binmode IMG; print IMG $gd->png; close(IMG); print "Utilization Graph Completed - Run length: $runLength hours\ +n"; } sub getAvgs { # Here we figure out some avg's and peaks # from our collected octet data # ------------------------------------------- foreach $value (@utilizationRec) { if ($value > $recMax) { $recMax = $value; } $recTotal += $value; } foreach $value (@utilizationOut) { if ($value > $outMax) { $outMax = $value; } $outTotal += $value; } my $recAvgTemp = $recTotal / $numRuns; my $outAvgTemp = $outTotal / $numRuns; $recAvgTemp =~ /(\d+)\.(\d\d)/; $recAvg = "$1.$2"; $outAvgTemp =~ /(\d+)\.(\d\d)/; $outAvg = "$1.$2"; } sub upTime { ($session, $error) = Net::SNMP->session( -hostname => $host, -community => $community, -port => 161, ); $session or die "Session error: $error\n"; my $sysUpTime = '1.3.6.1.2.1.1.3.0'; $response = $session->get_request($sysUpTime); $response or die "Response error:" . $session->error() . "\n"; $session->hostname(); $upTime = $response->{$sysUpTime}; $session->close(); } sub writeHTML { open(HTML, "+>$htmlFile") || die "Can't open file $htmlFile: ($!)\ +n"; print HTML "<!--#include virtual=\"header.shtml\"-->\n"; print HTML "<table border=\"0\" width=\"300\" cellspacing=\"2\">\n +"; print HTML "<tr><td class=\"framed\"><small>\n"; print HTML "<table border=\"0\" cellpadding=\"0\" width=\"300\">\n +"; print HTML "<tr>\n"; print HTML "<td align=\"right\"><small>Host:</small></td>\n"; print HTML "<td align=\"right\"><b><small><b>$hostname ($host)</b> +</small></b></td>\n"; print HTML "</tr>\n"; print HTML "<tr>\n"; print HTML "<td align=\"right\"><small>Last run time:</small></td> +\n"; print HTML "<td align=\"right\"><small><b>$runTime</b></small></td +>\n"; print HTML "</tr>\n"; print HTML "<tr>\n"; print HTML "<td align=\"right\"><small>System Uptime:</small></td> +\n"; print HTML "<td align=\"right\"><small><b>$upTime</b></small></td> +\n"; print HTML "</tr>\n"; print HTML "<tr>\n"; print HTML "<td align=\"right\"><small>Received Max:</small></td>\ +n"; print HTML "<td align=\"right\"><small><b>$recMax %</b></small></t +d>\n"; print HTML "</tr>"; print HTML "<tr>\n"; print HTML "<td align=\"right\"><small>Outgoing Max:</small></td>\ +n"; print HTML "<td align=\"right\"><small><b>$outMax %</b></small></t +d>\n"; print HTML "</tr>"; print HTML "<tr>\n"; print HTML "<td align=\"right\"><small>Received Average:</small></ +td>\n"; print HTML "<td align=\"right\"><small><b>$recAvg %</b></small></t +d>\n"; print HTML "</tr>"; print HTML "<tr>\n"; print HTML "<td align=\"right\"><small>Outgoing Average:</small></ +td>\n"; print HTML "<td align=\"right\"><small><b>$outAvg %</b></small></t +d>\n"; print HTML "</tr>"; print HTML "</table>\n"; print HTML "</small></td></tr></table><br>\n"; print HTML "<small>Incoming: <font color=\"red\"><b>Red</b></font> +</small><br>\n"; print HTML "<small>Outgoing:</smal><font color=\"green\"><b>Green< +/b></font></small>\n"; print HTML "<br><br>"; print HTML "<table border=\"0\"><tr><td class=\"framed\">\n"; print HTML "<img src=\"UtilData.png\" border=\"0\">\n"; print HTML "</td></tr></table>\n"; print HTML "<!--#include virtual=\"footer.shtml\"-->\n"; close(HTML); } print "Generation complete.\n"; |
Back to
Code Catacombs