Beefy Boxes and Bandwidth Generously Provided by pair Networks Joe
Keep It Simple, Stupid
 
PerlMonks  

Ethernet Utilization

by djw (Vicar)
on Oct 24, 2001 at 00:26 UTC ( #120895=sourcecode: print w/ replies, xml ) Need Help??

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";

Comment on Ethernet Utilization
Download Code
Re: Ethernet Utilization
by andyselby (Acolyte) on Apr 16, 2009 at 21:45 UTC

Back to Code Catacombs

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://120895]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (6)
As of 2014-04-20 12:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (485 votes), past polls